Home » Eclipse Projects » Papyrus for Real Time » Access message recipients programmatically(Using EMF )
| | |
Re: Access message recipients programmatically [message #1752646 is a reply to message #1752638] |
Wed, 25 January 2017 17:46 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
Rereading the original post it looks like you have access to the port role (i.e. the instance of the port in a part).
Assuming that you are working with a UML element, you can get the recipients as follows: a port role is represented in UML as a ConnectorEnd. A ConnectorEnd is owned by a Connector (itself owned by a Capsule) and has two references: "partWithPort" and "role". The "partWithPort" points to the part that owns the "port role", while the "role" points to the actual port owned by some other capsule.
So suppose you have a model like this (using our textual syntax for UML-RT, which will hopefully be self-explanatory):
model M
{
protocol P {}
capsule A
{
port p : P; // (1)
}
capsule B
{
conjugate port q : P;
}
capsule Top
{
part a : A;
part b : B;
connect a:p to b:q; // (2)
}
}
In this syntax, you see a connector in (2) with two ConnectorEnds: a:p and b:q. The first one has partWithPort == a and role == p. So p must be a port in the (Capsule) type of part a, and you can see that in line (1). Similarly, b:q has partWithPort == b and role == q.
So if you have access to a ConnectorEnd, you can get its owner, the Connector, which has a list "ends" of size 2 (in UML-RT it's always 2, in general UML, it can be larger than 2). You can use this to get the other connector-end.
In Java, this could be something like this
ConnectorEnd getOtherEnd(ConnectorEnd element) {
Connector conn = (Connector)element.getOwner();
int elementIndex = conn.getEnds().indexOf(element);
int otherEndIndex = elementIndex == 0 ? 1 : 0;
return conn.getEnds().get(otherEndIndex);
}
Once you have the other end of the connector, you can navigate to the part or to the port, and via either of them, to the capsule:
getOtherEnd(element).getPartWithPort().getType()
or
getOtherEnd(element).getRole().getOwner()
I hope this helps.
|
|
| |
Re: Access message recipients programmatically [message #1752758 is a reply to message #1752756] |
Thu, 26 January 2017 22:01 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
Hi John. So you have actually a Port to start your search, rather than a Port instance (role)?
In that case, then yes, your approach seems feasible, but of course that gives you only a list of *candidates*. And that's natural because when you have a reference to a Port, you are referring to a *definition*, as opposed to a point of use or instance (e.g. a "port in a capsule part"). And of course, a definition can be used in many different contexts, so at the point of definition you do not know who are all the possible recipients. That's why you need to traverse the model.
My previous reply assumed that you had a reference to the port in a part, rather than the port itself. In that case, as indicated, it is rather easy to get to the other end of a connector.
Two comments:
1) When you talk of "the owner of the capsule of the ports" sounds that you are using "capsule" to refer to a *capsule part*, i.e. a property whose type is a Capsule, or in other words the point of use of a Capsule, where you have Capsule instances, whereas a "Capsule" is the definition of the Capsule type itself. Just want to make sure the terminology is clear.
2) It's OK to look for conjugated ports, but beware that you may be missing a special case: symmetric protocols: a symmetric protocol is a protocol where all messages are "inout". In that case, it is possible to connect two ports of the same conjugation.
|
|
|
Re: Access message recipients programmatically [message #1752797 is a reply to message #1752758] |
Fri, 27 January 2017 12:15 |
Peter Cigehn Messages: 49 Registered: September 2014 |
Member |
|
|
Hi John,
As Ernesto pointed out, your approach only gives potential receivers, since you are not traversing any connectors in the model (as I tried to describe in my post). If you really want to make sure, then you should traverse all delegation connectors "going outside" until you find the assembly connector and the traverse all delegation connectors "going inside" until you reach the final behavior port again. But sure, if the port you have is an SAP or an SPP, then you're approach is perfectly okay, since an SAP/SPP is unwired (isWired = false) and never have a connector and the communicatoion is established based on a name based approach, i.e. an SAP is connected to the SPP registered with the same name.
But if the port that you are starting your traversal at is a wired port (isWired = true), then you should really follow the connectors in the model as I tried to describe, to find the (behavior) port(s) in the other end of that chain of connectors to truly locate the intended receiver.
Regarding the conjugation aspect, the tooling in Papyrus-RT should give you guidance to ensure that the conjugation of the ports always are correct when you create a connector, i.e. ports at the ends of a delegation connector always have the same conjugation, and ports at the ends of an assembly connector always have the opposite conjugation. Ernesto mentions the special case of symmetrical protocols, but personally I find that special case to be a bit too "theoretical". In practice >I would recommend that you should always follow those simple rules delegation connector -> same conjugation, assembly connector -> opposite conjugation, since those rules always works disregarding if the protocol is symmetrical or asymmetrical.
/Peter Cigéhn
|
|
| |
Re: Access message recipients programmatically [message #1752873 is a reply to message #1752861] |
Mon, 30 January 2017 08:07 |
Peter Cigehn Messages: 49 Registered: September 2014 |
Member |
|
|
John Dawes wrote on Mon, 30 January 2017 01:10
Ernesto, just to be confirmed about my understanding, when you mention about the term "Port role", do you mean "Protocol role"? Or, are they two different terminologies? The way I understand it, in uml-rt, a protocol can have two roles: base and conjugate. And, a port is an instance of one of these roles. So, a port instance is represented by a protocol role. Please let me know if I get anything wrong here.
What Ernesto refers to as "port role" is the aspect of ports on capsule parts, where you must distinguish between the same port being available on different capsule parts.
Unfortunately this is a bit confusing since the UML 2.X meta-model does not have a concept of "port role". In an older legacy version of UML-RT (used in Rose RealTime), which were based on UML 1.X, it existed a "port role" concept, where each capsule part (or "capsule role" as it was called back then) had a number of "port roles" which were the "projection" of the corresponding port on the capsule used for typing the capsule part.
In UML 2.X this was simplified/changed and there are no longer a "port role" on the capsule part. But to be able to distinguish between the same port on different capsule parts, it has instead become responsibility of the connector end, and thus it now have two references, the "role" which references the port (as owned by the capsule), and the "partWithPort" which references the specific capsule part (typed by the capsule).
In this way the connector end unambiguously can reference a port on a specific capsule part, even though the same port can be available on another capsule part (typed by the same capsule or possibly a subclass capsule).
I hope this clarifies this about "port role". Personally though, I think that we shall stay away from talking about "port role" since that concept no longer exist in the UML 2 meta-model which UML-RT is based on. It is better to talk about the connector end and how it distinguishes between (potentially the same) port on different capsule parts.
/Peter Cigéhn
|
|
| | |
Goto Forum:
Current Time: Tue Dec 10 09:34:34 GMT 2024
Powered by FUDForum. Page generated in 0.04521 seconds
|