OCL in UML Profile [message #1747164] |
Thu, 10 November 2016 11:40 |
Vetle Volden-Freberg Messages: 39 Registered: February 2016 |
Member |
|
|
Hello! I am working on a project where I need to define a relatively simple Constraint on a <<Stereotype>> of the <<Metaclass>> Message using OCL. I want to check if the Lifeline on the receiving end of the message is of a certain stereotype.
I am a newbie with OCL and I've been going through a steep learning curve lately.
So let's say you have a profile "MyProfile" that defines a stereotype: <<MyMessage>> that extends <<Metaclass>> Message and a stereotype: <<MyLifeline>> that extends <<Metaclass>> Lifeline.
How could you write an OCL invariant in an OpaqueExpression that ensures that the lifeline on the receiveEvent of the <<myMessage>> stereotype is of type <<MyLifeline>>?
So far I have experimented with some OpaqueExpressions that sadly do not work as I intended. There is most likely something I've misunderstood when it comes to using OCL.
A result of my experiments is the OpaqueExpression:
self.base_Message.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered.oclIsKindOf(MyProfile::MyLifeline)
It is syntactically correct according to the OCL editor, but when I try it out it always yields the result that the invariant has been violated. I also tried to replace the MyProfile::MyLifeline with extension_MyLifeline but that is not accepted by the parser.
I tried to study the constraint used in the UML 2.5.0 Metamodel EPackage that checks if the ordering of the sendEvent & receiveEvent is correct for Messages that has receiveEvent & sendEvent pointing to the same Lifeline.
That (OCL) constraint looks like this:
receiveEvent.oclIsKindOf(MessageOccurrenceSpecification)
implies
let f : Lifeline = sendEvent->select(oclIsKindOf(MessageOccurrenceSpecification)).oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first().covered in
f = receiveEvent->select(oclIsKindOf(MessageOccurrenceSpecification)).oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first().covered implies
f.events->indexOf(sendEvent.oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first() ) <
f.events->indexOf(receiveEvent.oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first() )
I tried to see if there was anything in that constraint I could use to my advantage in my case, but nothing has worked so far..
Any ideas on how I can solve this issue?
(I am using Papyrus Neon to make the UML profile)
Cheers, Vetle VF.
[Updated on: Fri, 11 November 2016 13:05] Report message to a moderator
|
|
|
|
Re: OCL in UML Profile [message #1747168 is a reply to message #1747165] |
Thu, 10 November 2016 12:44 |
Vetle Volden-Freberg Messages: 39 Registered: February 2016 |
Member |
|
|
"I'm not sure what you mean by " OCL invariant in an OpaqueExpression". An OCL invariant is a Constraint. OpaqueExpressions are the base of ExpressionInOCL for queries." --> Okay, I see.
I tried your suggestion Ed using the Xtext OCL Console, and the result was:
Null source for $uml$::Message::receiveEvent
I also tried just: self.base_Message which gave the result:
null.
So for some reason the OCL treats the base_Message property in my stereotype as null.
I suppose it is because in the console there hasn't been created any objects yet..
When I try your suggestion in a model it gives this error message:
The 'MyMessage::ReceiverIsMyLifeline' constraint is invalid for '<<MyMessage>>RootElement::Interaction1Message' - Failed to evaluate 'UML::Lifeline::extension_MyLifeline' for 'Sequence{org....}' and 'self.base_Message.receiveEvent.oclAsType(UML::MessageOccurrenceSpecification).covered.extension_MyLifeline')
This error message doesn't say much though .. (to me)
Regards, Vetle VF.
[Updated on: Fri, 11 November 2016 11:09] Report message to a moderator
|
|
|
|
Re: OCL in UML Profile [message #1747189 is a reply to message #1747173] |
Thu, 10 November 2016 15:33 |
Vetle Volden-Freberg Messages: 39 Registered: February 2016 |
Member |
|
|
Thanks Ed. This made it a lot easier to check what the result of each statement would be.
Now, for the;
self.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered.extension_MyLifeline <> null
I get:
Results:
Failed to evaluate 'UML::Lifeline::extension_MyLifeline' for 'Sequence{or...}' and 'self.receiveEvent.oclAsType(UML::MessageOccurrenceSpecification).covered.extension_MyLifeline'
java.lang.ClassCastException: org.eclipse.ocl.pivot.internal.values.SparseSequenceValueImpl cannot be cast to org.eclipse.emf.ecore.EObject
If I change context to <<MyLifeline>> and do:
self.getAppliedStereotypes() I get:
MyProfile::MyLifeline.
If I then change the context back to <<MyMessage>> and do:
self.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered.getAppliedStereotypes() I get:
Results:
'Object' rather than 'Sequence($0)<$0:$uml$::Lifeline>' value required.
So I think when I do self.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered I get the object in question, but as a "org.eclipse.ocl.pivot.internal.values.SparseSequenceValueImp". So I assume there is nothing I can do with the query to make this cast possible. And I don't think there is any way I can go around this problem ..
Regards, Vetle VF.
[Updated on: Thu, 10 November 2016 17:47] Report message to a moderator
|
|
|
|
|
|
Re: OCL in UML Profile [message #1747267 is a reply to message #1747260] |
Fri, 11 November 2016 12:53 |
Vetle Volden-Freberg Messages: 39 Registered: February 2016 |
Member |
|
|
Ok. So I have reproduced the same issue. This is not my project, however this example illustrates the same problem and is a reproduction of the same effects.
See the attached compressed folder for example files.
The compressed folder includes one Papyrus Project folder with the following contents; Papyrus Model (UML Profile) named myprofile.profile and a Papyrus Model (UML) named myprofileTest.
The UML Profile contains three stereotypes. Two of them are stereotypes of <<Metaclass>> Lifeline <<Stereotype>> MyLifeline1 and <<Stereotype>> MyLifeline2 respectively. The last stereotype is a stereotype of <<Metaclass>> Message called <<Stereotype>> MyMessage.
What I want to accomplish is to create a constraint such that the recepient of <<MyMessage>> can only be a lifeline of stereotype <<MyLifeline2>>.
To reproduce, import the project in Papyrus (I used Neon), open myprofileTest, open the interactive xtext console, click the Message of the <<MyMessage>> stereotype (to set the context of self in the console).
Try the following (using the interactive xtext console):
(1) self.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered.extension_MyLifeline2 <> null
(2) self.receiveEvent.oclAsType(MessageOccurrenceSpecification).covered->collect(getAppliedStereotypes())
Regards, Vetle VF.
[Updated on: Fri, 11 November 2016 16:55] Report message to a moderator
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03967 seconds