Sparx Systems Forum

Enterprise Architect => General Board => Topic started by: shimon on October 22, 2023, 04:18:11 pm

Title: Finding messages that are not operations
Post by: shimon on October 22, 2023, 04:18:11 pm
Hi,
We have a conceptual System Engineering model which is implemented in various Subsystems by many subcontractors.
We use DDS topics to communicate between these subsystems.
I imported these topics as operations (this was a compromise, not the preferred way of doing it) and now I want to replace a large part of the messages with these operations / topics.
As a first step, I would like to find all messages, that don’t correspond to operations at all, and then I would like to find messages on specific diagrams that don’t correspond with the imported Topics.
I will continue to describe what I did so far, but would appreciate any input if this was already done.
Sincerely,
Shimon

P.S. I edited the post and changed methods to operations, as per qwerty's comment.
Title: Re: Finding messages that are not methods
Post by: Richard Freggi on October 23, 2023, 12:39:59 am
Hmm if you are using UML sequence or collaboration diagrams for your application architecture you should be able to use messages (that require methods in the receiving class) and signals (that don't require methods).  This would make replacing, tracking and reporting really easy.
Title: Re: Finding messages that are not methods
Post by: shimon on October 23, 2023, 12:43:12 am
We are using UML but EA does not "force" you to use Methods, so many of the messages are free text.
Title: Re: Finding messages that are not methods
Post by: shimon on October 23, 2023, 01:03:43 am
I created a search of diagrams and connector names where connector type ==sequence and then went on to create a search for methods and checked if they match.
The problem is that the connector name includes parentheses (and parameters). I needed to trim from  the parentheses till  the end of the connector name.
I found how to do this for SQL server and for JET, but I didn't figure out how to use the function in the second select, where I check if connector.name  in (select method names . . . )
I only have a printout of the SQL, but I'll try to post it.
Shimon
Title: Re: Finding messages that are not methods
Post by: qwerty on October 23, 2023, 10:48:07 am
I had never looked into that, but t_connector.target2 seems to hold a non-zero value for messages coming from an operation (method is behavior!). I'll look into that tomorrow in detail.

q.
Title: Re: Finding messages that are not operations
Post by: qwerty on October 24, 2023, 10:34:32 am
That number was a non-causal coincidence. Still no idea why this very test example created a number there. However, I think I can say that "dummy" operations have no brackets at the end in t_connrctor.name while the "real" ones do. That's probably the way EA figures when an operation is renamed so the message is too. Will put that for further investigation on my list for Inside EA.

q.
Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 24, 2023, 05:23:08 pm
IIRC there's a tagged value on the connector with the operationID

Geert
Title: Re: Finding messages that are not operations
Post by: shimon on October 24, 2023, 05:57:39 pm
Geert is right (as usual)
The OperationGUID is in the t_connectortag.VALUE.
When using this in SQL, you should probably use the Property as well. It is operation_guid in my small example.

Q, thanks for your input. So far I made a union between messages that contain a parentheses and messages that don't contain parentheses. You got me thinking that it might be possible to add parentheses without choosing an operation.
To check what you wrote, I added a message with the same spelling of an Operation and added parentheses, and then renamed the Operation to see if it will be reflected on the sequence diagram. It did not.
The next thing I did was export this small project to XMI and try to find the messages. The ones that were chosen from the Operation list had signature="   GUID ###########" added to the end of the line, so I understood that this must be saved somewhere.
After seeing Geert's comment, I looked through all the tables that start with t_connector and found the answer.

I just checked the consistency in the case that I choose on Operation of a Base Class or Interface, and it shows the correct operation.

The inconsistency is in the case that I delete an operation. The entry in the t_connectortag table is not deleted.
Using Geert's navigator, choosing the message and clicking on "Operation" gets the error, "Missing Operation". The message text displays the exact issue.
So I guess that I should still keep the check that the trimmed message is an existing Operation.
I haven't figured out how to check that an Operation is in the recieving Object or any of its base classes or any of its interfaces.
Sincerely,
Shimon


Title: Re: Finding messages that are not operations
Post by: qwerty on October 24, 2023, 10:04:53 pm
Hi Shimon,
as a matter of fact I'm already old and don't stop getting older. Also I'm no longer an EA power user for various reasons. You might send a bug report (or Sparx would likely only see it as feature request) that deleting an operation should warn about existing messages and/or clear the dangling links. I wouldn't bet much on seeing any Sparx activity in that area, though.

q.
Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 24, 2023, 10:33:32 pm
I haven't figured out how to check that an Operation is in the recieving Object or any of its base classes or any of its interfaces.

An operation has a ParentID that corresponds to the Object_ID of the owner in t_object

Geert
Title: Re: Finding messages that are not operations
Post by: shimon on October 25, 2023, 04:19:27 pm
Hi Shimon,
as a matter of fact I'm already old and don't stop getting older. Also I'm no longer an EA power user for various reasons. You might send a bug report (or Sparx would likely only see it as feature request) that deleting an operation should warn about existing messages and/or clear the dangling links. I wouldn't bet much on seeing any Sparx activity in that area, though.

q.

Wishing you many more years of getting older in good health.
Shimon
Title: Re: Finding messages that are not operations
Post by: shimon on October 25, 2023, 04:28:27 pm
I haven't figured out how to check that an Operation is in the recieving Object or any of its base classes or any of its interfaces.

An operation has a ParentID that corresponds to the Object_ID of the owner in t_object

Geert

I figured that out, but I now have to join all parents and grandparents, as it is perfectly legitimate to invoke an Operation of a Base Class.
Yesterday I figured that out too, by joinng the End_Object_ID of the relations (where  Connetor_type in Generalization and Realisation ) of the recieving Class etc.
I'll probably have to adjust it to include interfaces of ports. I hope to post the search soon.
Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 25, 2023, 05:24:23 pm
Yeah, you'll want to join a few levels.

In a somewhat sane design you shouldn't have more than 3 or 4 levels, so if you go up to 5 or 6 you should be good.

Geert
Title: Re: Finding messages that are not operations
Post by: shimon on October 25, 2023, 10:10:12 pm
I went up 6 levels but got it to work only on SQL Server.
It ain't pretty.

I have to check why this is not working via  JET ( local eapx file).

Server.

Title: Re: Finding messages that are not operations
Post by: shimon on October 26, 2023, 12:21:56 am
Find messages that are not operations of recieving class - V3
SELECT distinct  t_diagram.ea_guid AS CLASSGUID, 't_diagram' as CLASSTABLE, t_diagram.Diagram_Type AS CLASSTYPE, t_diagram.Name as diagramName ,sender.Name as msg_Sender,t_connector.Name as full_name,rcvr.Name as msg_Rcvr, t_connector.DiagramID,t_connector.SeqNo
FROM (((
t_connector
inner join t_diagram on t_connector.DiagramID = t_diagram.Diagram_ID)
inner join t_object as sender on t_connector.Start_Object_ID = sender.Object_ID )
inner join t_object as rcvr on t_connector.End_Object_ID = rcvr.Object_ID )
where t_connector.Connector_Type = 'Sequence'
and rcvr.Object_Type = 'Class'

#DB=SQLSVR# -- and t_diagram.Name = 'Nominal Seq.' #DB=SQLSVR#

#DB=SQLSVR# -- the following lines finds all messages that have a parentheses and don't match operations of recieving class
#DB=SQLSVR#
AND   
 
t_connector.Name LIKE '#WC#(#WC#'
#DB=SQLSVR#   AND left (t_connector.Name, CHARINDEX ('(',t_connector.Name)-1) #DB=SQLSVR#
#DB=JET# and left (t_connector.Name, InStr (t_connector.Name,'(')-1)  #DB=JET#
NOT IN ( select  name from t_operation where Object_ID =rcvr.Object_ID)
 
#DB=SQLSVR# -- the following lines finds all messages that have a parentheses and don't match operations of recieving class Base Classes
#DB=SQLSVR#

#DB=SQLSVR#   AND left (t_connector.Name, CHARINDEX ('(',t_connector.Name)-1) #DB=SQLSVR#
#DB=JET# and left (t_connector.Name, InStr (t_connector.Name,'(')-1)  #DB=JET#

NOT IN (

select  name from t_operation where Object_ID in
(
select distinct relatedObjects.Object_Id as objectid from (
select  'level_0' as level_, conn1.Start_Object_ID  as StartObject, conn1.Start_Object_ID  as Object_Id from 
t_connector   conn1
where  conn1.Connector_Type IN ('Realisation' , 'Generalization')
 
and ( conn1.Start_Object_id = rcvr.Object_ID) 

union all

select  'level_1' as level_, conn1.Start_Object_ID  as StartObject, conn1.End_Object_ID   from 
t_connector   conn1
where  conn1.Connector_Type IN ('Realisation' , 'Generalization')
 
and ( conn1.Start_Object_id = rcvr.Object_ID) 
 

union all

select   'level_2' as level_,conn1.Start_Object_ID  as StartObject, conn2.end_Object_ID   as Object_Id  from (
t_connector   conn1
inner join t_connector conn2 on conn1.End_Object_id = conn2.Start_Object_id)

where conn1.Connector_Type IN ('Realisation' , 'Generalization')
and  conn2.Connector_Type  IN ('Realisation' , 'Generalization')

and ( conn1.Start_Object_id = rcvr.Object_ID) 

 
union all

select   'level_3' as level_,conn1.Start_Object_ID  as StartObject, conn3.end_Object_ID   as Object_Id  from
((t_connector   conn1
inner join t_connector conn2 on conn1.End_Object_id = conn2.Start_Object_id)
inner join t_connector conn3 on conn2.End_Object_id = conn3.Start_Object_id)

where conn1.Connector_Type IN ('Realisation' , 'Generalization')
and  conn2.Connector_Type  IN ('Realisation' , 'Generalization')
and  conn3.Connector_Type  IN ('Realisation' , 'Generalization')

and ( conn1.Start_Object_id = rcvr.Object_ID) 

union all

select   'level_4' as level_,conn1.Start_Object_ID  as StartObject, conn4.end_Object_ID   as Object_Id  from
(((t_connector   conn1
inner join t_connector conn2 on conn1.End_Object_id = conn2.Start_Object_id)
inner join t_connector conn3 on conn2.End_Object_id = conn3.Start_Object_id)
inner join t_connector conn4 on conn3.End_Object_id = conn4.Start_Object_id)

where conn1.Connector_Type IN ('Realisation' , 'Generalization')
and  conn2.Connector_Type  IN ('Realisation' , 'Generalization')
and  conn3.Connector_Type  IN ('Realisation' , 'Generalization')
and conn4.Connector_Type   IN ('Realisation' , 'Generalization')
and ( conn1.Start_Object_id = rcvr.Object_ID) 
 
 
 union all


select   'level_5' as level_,conn1.Start_Object_ID  as StartObject, conn5.end_Object_ID   as Object_Id  from
((((t_connector   conn1
inner join t_connector conn2 on conn1.End_Object_id = conn2.Start_Object_id)
inner join t_connector conn3 on conn2.End_Object_id = conn3.Start_Object_id)
inner join t_connector conn4 on conn3.End_Object_id = conn4.Start_Object_id)
inner join t_connector conn5 on conn4.End_Object_id = conn5.Start_Object_id)


where conn1.Connector_Type IN ('Realisation' , 'Generalization')
and  conn2.Connector_Type  IN ('Realisation' , 'Generalization')
and  conn3.Connector_Type  IN ('Realisation' , 'Generalization')
and conn4.Connector_Type   IN ('Realisation' , 'Generalization')
and conn5.Connector_Type   IN ('Realisation' , 'Generalization')
and ( conn1.Start_Object_id = rcvr.Object_ID)   

) AS relatedObjects
)

)


 
union all

#DB=SQLSVR# -- the following lines finds all messages that don't have parentheses   #DB=SQLSVR#

SELECT distinct  t_diagram.ea_guid AS CLASSGUID, 't_diagram' as CLASSTABLE, t_diagram.Diagram_Type AS CLASSTYPE, t_diagram.Name as diagramName ,sender.Name as msg_Sender,t_connector.Name as full_name,rcvr.Name as msg_Rcvr, t_connector.DiagramID,t_connector.SeqNo
FROM (((
t_connector
inner join t_diagram on t_connector.DiagramID = t_diagram.Diagram_ID)
inner join t_object as sender on t_connector.Start_Object_ID = sender.Object_ID )
inner join t_object as rcvr on t_connector.End_Object_ID = rcvr.Object_ID )
where t_connector.Connector_Type = 'Sequence'

AND t_connector.Name NOT LIKE '#WC#(#WC#'

 #DB=SQLSVR# -- Find messages that are not operations of recieving class - V3 END
 #DB=SQLSVR#

;
Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 26, 2023, 12:34:08 am
Wow, that's quite the query.

What I sometimes do to simplify hiearchies like this, is to do left joins like this.
That often eliminates the need for unions on each level.

Code: [Select]
select o.* from (((((t_connector   conn1
left join t_connector conn2 on (conn1.End_Object_id = conn2.Start_Object_id
                                             conn1.Connector_Type IN ('Realisation' , 'Generalization')))
left join t_connector conn3 on conn2.End_Object_id = conn3.Start_Object_id)
                                             conn2.Connector_Type IN ('Realisation' , 'Generalization')))
left join t_connector conn4 on conn3.End_Object_id = conn4.Start_Object_id)
                                             conn3.Connector_Type IN ('Realisation' , 'Generalization')))
left join t_connector conn5 on conn4.End_Object_id = conn5.Start_Object_id)
                                             conn4.Connector_Type IN ('Realisation' , 'Generalization')))
inner join t_object o on o.Object_ID in (conn1.End_Object_id , conn2.End_Object_id , conn3.End_Object_id , conn4.End_Object_id ))
where con1.start_object_ID = ...

Also, be ware of the spelling of Realization and Generalization. I think they might have been mixed up in the past, so I would cater for both Realization and Realisation

Geert
Title: Re: Finding messages that are not operations
Post by: qwerty on October 26, 2023, 03:34:14 am
For me it's almost every time easier to have a simple query and code a bit in my standard language. Allows me to have queries which can be kept on a general level to work across multiple platforms.

q.
Title: Re: Finding messages that are not operations
Post by: shimon on October 26, 2023, 06:27:48 pm
Geert,
Your solution is much neater than mine.
I couldn't get it to work  on JET for two reasons. It does not allow me to join on two criteria and does not allow to join on IN ( t1.id, t2.id).

Q,
You are right that is better to keep things simple, and that is the reason that I built the monster query in pieces.
I work in a closed (security conscious) environment, where I have no access to any programming environment.
I doubt that they'll allow me in bring any addon in.
Shimon

Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 26, 2023, 06:50:36 pm
Joining on two conditions can be done using extra parentheses

left join table x on (x.columnA = y and x.ColumnB = z)

You can replace the IN () with
on (
o.Object_ID in = conn1.End_Object_id 
or o.Object_ID in =  conn2.End_Object_id
or o.Object_ID in =   conn3.End_Object_id
or o.Object_ID in =   conn4.End_Object_id )


or you move the IN() to the where clause. Since it's an inner join, that has the same result.

Geert
Title: Re: Finding messages that are not operations
Post by: Geert Bellekens on October 26, 2023, 06:52:33 pm
I work in a closed (security conscious) environment, where I have no access to any programming environment.
I doubt that they'll allow me in bring any addon in.
Shimon
Have you tried the internal scripting of EA?
You IT Security department may consider that a risk though.

Geert
Title: Re: Finding messages that are not operations
Post by: qwerty on October 26, 2023, 08:09:35 pm
The internal IT security. You could make a sitcom from that :-/

q.
Title: Re: Finding messages that are not operations
Post by: shimon on October 29, 2023, 09:58:17 pm
Ha Ha Ha,
The server based environment does not allow scripting. If I do choose to go that way (learn and use scripting), I will probably get them to create a group and allow this group to script.
Shimon
Title: Re: Finding messages that are not operations
Post by: Jan van Duuren on December 21, 2023, 06:13:58 pm
I use the following SQL query (MySQL) to retrieve the linked operation of a message in a sequence diagram.

SELECT CONN.CONNECTOR_ID, IFACE.OBJECT_ID AS [INTERFACE_ID], IFACE.NAME AS [INTERFACE], IFACE.OBJECT_TYPE, OPER.OPERATIONID, OPER.NAME AS [OPERATION],
OPER.STYLE AS [REQUEST], OPER.TYPE AS [RETURN], CONN.PDATA4 AS [IS_RETURN]
FROM T_CONNECTOR CONN
LEFT JOIN T_CONNECTORTAG CONNTAG ON CONN.CONNECTOR_ID=CONNTAG.ELEMENTID AND CONNTAG.PROPERTY='operation_guid'
LEFT JOIN T_OPERATION OPER ON OPER.EA_GUID=CONNTAG.[VALUE]
LEFT JOIN T_OBJECT IFACE ON OPER.OBJECT_ID=IFACE.OBJECT_ID
WHERE CONN.CONNECTOR_ID IN (83509, 89807)


result:
CONNECTOR_ID;INTERFACE_ID;INTERFACE         ;OBJECT_TYPE;OPERATIONID;OPERATION         ;REQUEST;RETURN;IS_RETURN;
83509       ;32126       ;OneApp Vehicle API;Interface  ;11076      ;getParkingPosition;       ;void  ;0        ;
89807       ;            ;                  ;           ;           ;                  ;       ;      ;0        ;


first connector does have a linked operation
second connector does not have a linked operation