Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Enum value not recognized?(Evaluation of derived attribute fails)
Enum value not recognized? [message #1259635] Fri, 28 February 2014 16:21 Go to next message
Wilbert Alberts is currently offline Wilbert AlbertsFriend
Messages: 96
Registered: June 2010
Member
Hi,

I created a meta model containing various classes, properties and enumerations. Some classes contain derived properties which require evaluation of certain enumeration values. Somehow the evaluation of the derivation fails and I suspect a relation with the enumeration literal not being recognized.

I chose for the option of generating java code for the OCL derived attributes. In that generated java code I set a breakpoint and after hitting, and stepping a little bit I got the following stack trace:
EclipseRuntime [Eclipse Application]	
	org.eclipse.equinox.launcher.Main at localhost:55129	
		Thread [main] (Suspended)	
			owns: SelectionAggregator$8  (id=109)	
			EcoreIdResolver(AbstractIdResolver).boxedValueOfEnumerator(Enumerator) line: 350	
			EcoreIdResolver(AbstractIdResolver).boxedValueOf(Object) line: 308	
			EcoreIdResolver(AbstractIdResolver).createSetOfAll(CollectionTypeId, Iterable<Object>) line: 476	
			BuildingBlockImpl.getProvidedIfs() line: 227	
			BuildingBlockImpl.eGet(int, boolean, boolean) line: 523	
			BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature, boolean, boolean) line: 1011	
			BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature, boolean) line: 1003	
			BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature) line: 998	
			ItemPropertyDescriptor.getValue(EObject, EStructuralFeature) line: 1312	


So the derived property is getProvidedIfs and somewhere in its evaluation it needs to create a set of calculated enumeration values. I verified that the enumerator, offered to boxedValueOfEnumerator indeed represents an enumeration value/literal. I opened the source of AbstractIdResolver which takes care of the implementation of boxedValueOfEnumerator.

public @Nullable Object boxedValueOfEnumerator(@NonNull Enumerator unboxedValue) {
   Map<Enumerator, EnumerationLiteralId> enumerator2enumerationLiteralId2 = enumerator2enumerationLiteralId;
   if (enumerator2enumerationLiteralId2 == null) {
      synchronized (this) {
         enumerator2enumerationLiteralId2 = enumerator2enumerationLiteralId;
         if (enumerator2enumerationLiteralId2 == null) {
            enumerator2enumerationLiteralId = enumerator2enumerationLiteralId2 = new HashMap<Enumerator, EnumerationLiteralId>();
            for (DomainPackage dPackage : standardLibrary.getAllPackages()) {
               for (DomainType dType : dPackage.getOwnedType()) {
                  if (dType instanceof DomainEnumeration) {
                     for (DomainEnumerationLiteral dEnumerationLiteral : ((DomainEnumeration) dType).getEnumerationLiterals()) {
                        Enumerator enumerator = dEnumerationLiteral.getEnumerator();
                        EnumerationLiteralId enumerationLiteralId = dEnumerationLiteral.getEnumerationLiteralId();
                        enumerator2enumerationLiteralId.put(enumerator, enumerationLiteralId);
                     }
                  }
               }
            }
         }
      }      
   }


I suspect that this piece of code starts with creation of a set of all enum types and values in my model. It does this by retrieving all packages from standardLibrary (and consequently by iterating over the enumeration types).

However, when I arrive at getAllPackages, I end up in AbstractStandardLibrary which throws an UnsupportedOperationException. The actual type implementing the standard library seems to be ExecutorStandardLibrary. Inspecting the fields of this class shows that the ePackageMap seems to hold a reference to my meta model. However as the AbstractStandardLibrary does not implement anything to follow that reference, no chance exists that my enumeration types are being read.

Or am I on the wrong track here?

Anybody knows why my evaluation fails? Just for the record, I'm using Luna M5 at this moment so maybe I'm a little bit on shaky grounds. But any help would be appreciated.

Greetings,
Wilbert.




Re: Enum value not recognized? [message #1259672 is a reply to message #1259635] Fri, 28 February 2014 17:11 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 4153
Registered: July 2009
Senior Member
Hi

I've fixed a problem in this area, but I think the fix is in M5.

The Java code generation is steadily improving, but I'm afraid it's not
yet perfect.

Can you provide a trimmed example containing just the Enum aspect of
your code?

[Yes the enum code has to scan all enumerators once because
unfortunately EMF's Enumerator is a hierarchical element whose parent is
not accessible.]

Regards

Ed Willink

On 28/02/2014 16:21, Wilbert Alberts wrote:
> Hi,
>
> I created a meta model containing various classes, properties and
> enumerations. Some classes contain derived properties which require
> evaluation of certain enumeration values. Somehow the evaluation of
> the derivation fails and I suspect a relation with the enumeration
> literal not being recognized.
>
> I chose for the option of generating java code for the OCL derived
> attributes. In that generated java code I set a breakpoint and after
> hitting, and stepping a little bit I got the following stack trace:
>
> EclipseRuntime [Eclipse Application]
> org.eclipse.equinox.launcher.Main at localhost:55129
> Thread [main] (Suspended)
> owns: SelectionAggregator$8 (id=109)
> EcoreIdResolver(AbstractIdResolver).boxedValueOfEnumerator(Enumerator)
> line: 350
> EcoreIdResolver(AbstractIdResolver).boxedValueOf(Object) line: 308
> EcoreIdResolver(AbstractIdResolver).createSetOfAll(CollectionTypeId,
> Iterable<Object>) line: 476
> BuildingBlockImpl.getProvidedIfs() line: 227
> BuildingBlockImpl.eGet(int, boolean, boolean) line: 523
> BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature, boolean,
> boolean) line: 1011
> BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature, boolean)
> line: 1003
> BuildingBlockImpl(BasicEObjectImpl).eGet(EStructuralFeature) line: 998
> ItemPropertyDescriptor.getValue(EObject,
> EStructuralFeature) line: 1312
>
>
> So the derived property is getProvidedIfs and somewhere in its
> evaluation it needs to create a set of calculated enumeration values.
> I verified that the enumerator, offered to boxedValueOfEnumerator
> indeed represents an enumeration value/literal. I opened the source of
> AbstractIdResolver which takes care of the implementation of
> boxedValueOfEnumerator.
>
> public @Nullable Object boxedValueOfEnumerator(@NonNull Enumerator
> unboxedValue) {
> Map<Enumerator, EnumerationLiteralId>
> enumerator2enumerationLiteralId2 = enumerator2enumerationLiteralId;
> if (enumerator2enumerationLiteralId2 == null) {
> synchronized (this) {
> enumerator2enumerationLiteralId2 =
> enumerator2enumerationLiteralId;
> if (enumerator2enumerationLiteralId2 == null) {
> enumerator2enumerationLiteralId =
> enumerator2enumerationLiteralId2 = new HashMap<Enumerator,
> EnumerationLiteralId>();
> for (DomainPackage dPackage :
> standardLibrary.getAllPackages()) {
> for (DomainType dType : dPackage.getOwnedType()) {
> if (dType instanceof DomainEnumeration) {
> for (DomainEnumerationLiteral dEnumerationLiteral
> : ((DomainEnumeration) dType).getEnumerationLiterals()) {
> Enumerator enumerator =
> dEnumerationLiteral.getEnumerator();
> EnumerationLiteralId enumerationLiteralId =
> dEnumerationLiteral.getEnumerationLiteralId();
> enumerator2enumerationLiteralId.put(enumerator, enumerationLiteralId);
> }
> }
> }
> }
> }
> } }
>
> I suspect that this piece of code starts with creation of a set of all
> enum types and values in my model. It does this by retrieving all
> packages from standardLibrary (and consequently by iterating over the
> enumeration types).
> However, when I arrive at getAllPackages, I end up in
> AbstractStandardLibrary which throws an UnsupportedOperationException.
> The actual type implementing the standard library seems to be
> ExecutorStandardLibrary. Inspecting the fields of this class shows
> that the ePackageMap seems to hold a reference to my meta model.
> However as the AbstractStandardLibrary does not implement anything to
> follow that reference, no chance exists that my enumeration types are
> being read.
> Or am I on the wrong track here?
>
> Anybody knows why my evaluation fails? Just for the record, I'm using
> Luna M5 at this moment so maybe I'm a little bit on shaky grounds. But
> any help would be appreciated.
>
> Greetings,
> Wilbert.
>
>
>
>
>
Re: Enum value not recognized? [message #1262028 is a reply to message #1259672] Mon, 03 March 2014 07:27 Go to previous messageGo to next message
Wilbert Alberts is currently offline Wilbert AlbertsFriend
Messages: 96
Registered: June 2010
Member
Hi Ed,

I tried to create a smaller example but unfortunately I can not get it to reproduce exactly. However I do get something else that might be related. (I noticed the behavior described below also with my 'bigger' model.)

Based on the meta model shown below, I created the obvious model, edit and editor packages. Then I ran the model as an eclipse application and created an instance of the model using the generated (tree) editor. I saved the model, closed the eclipse runtime, restarted and reopened it.

If I select the Subsystem SS1, before selecting anything else, its properties do not show a value for the derived attribute 'interfaces'. However, after I select one of the enclosed components CC1 or CC2, and then go back to SS1, the 'interfaces' attribute is calculated correctly.

Furthermore, from the meta model you see that a component contains 'provided' and 'defined' interfaces and that the 'interfaces' of a component consists of the union of both of them. Whenever I add a provided interface, two entries appear in the tree. I seems that one of them is the (provided) one I just added and the other one is the one representing the derived 'interfaces' outcome. I would have expected the 'interfaces' entries to appear in the properties view. It is like that if I create a dynamic instance of 'Model' in the development runtime of eclipse.

Anyway: the meta model:

package oclbug : oclbug = 'http://wilbert.oclbug/1.0'
{
	class Model
	{
		property subsystems : Subsystem[*] { ordered composes };
	}
	class Subsystem
	{
		attribute id : String;
		property components : Component[*] { ordered composes };
		property interfaces : Interface[*] { derived readonly transient volatile }
		{
			derivation: components.interfaces->select(i | i.level->includes(InterfaceLevel::PUBLIC));
		}
	}
	class Component
	{
		attribute id : String;
		property defined : Interface[*] { ordered composes };
		property provided : Interface[*] { ordered composes };
		property interfaces : Interface[*] { derived readonly transient volatile }
		{
			derivation: defined->union(provided);
		}
	}
	class Interface
	{
		attribute id : String;
		attribute level : InterfaceLevel[*];
	}
	enum InterfaceLevel { serializable }
	{
		literal PRIVATE = 1;
		literal PUBLIC = 2;
	}
}


and the instance model that I used in the description above.

<?xml version="1.0" encoding="UTF-8"?>
<oclbug:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:oclbug="http://wilbert.oclbug/1.0">
  <subsystems id="SS1">
    <components id="CC1">
      <defined id="DI1">
        <level>PUBLIC</level>
      </defined>
    </components>
    <components id="CC2">
      <provided id="PI1"/>
    </components>
  </subsystems>
</oclbug:Model>

[Updated on: Mon, 03 March 2014 07:28]

Report message to a moderator

Re: Enum value not recognized? [message #1262046 is a reply to message #1262028] Mon, 03 March 2014 07:47 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 4153
Registered: July 2009
Senior Member
Hi

No genmodel, not loadable ... https://wiki.eclipse.org/OCL/ForumNetiquette

Regards

Ed Willink

On 03/03/2014 07:27, Wilbert Alberts wrote:
> package oclbug : oclbug = 'http://wilbert.oclbug/1.0'
> {
> class Model
> {
> property subsystems : Subsystem[*] { ordered composes };
> }
> class Subsystem
> {
> attribute id : String;
> property components : Component[*] { ordered composes };
> property interfaces : Interface[*] { derived readonly
> transient volatile }
> {
> derivation: components.interfaces->select(i |
> i.level->includes(InterfaceLevel::PUBLIC));
> }
> }
> class Component
> {
> attribute id : String;
> property defined : Interface[*] { ordered composes };
> property provided : Interface[*] { ordered composes };
> property interfaces : Interface[*] { derived readonly
> transient volatile }
> {
> derivation: defined->union(provided);
> }
> }
> class Interface
> {
> attribute id : String;
> attribute level : InterfaceLevel[*];
> }
> enum InterfaceLevel { serializable }
> {
> literal PRIVATE = 1;
> literal PUBLIC = 2;
> }
> }
Re: Enum value not recognized? [message #1262051 is a reply to message #1262046] Mon, 03 March 2014 07:54 Go to previous message
Wilbert Alberts is currently offline Wilbert AlbertsFriend
Messages: 96
Registered: June 2010
Member
Hi Ed,

Excuse me.

I attached the project. I think that should include all necessary things.

Greetings,
Wilbert.
  • Attachment: oclbug.zip
    (Size: 49.75KB, Downloaded 11 times)
Previous Topic:OCL and Xtext
Next Topic:Constraints with OCLInEcore across multiple model files
Goto Forum:
  


Current Time: Mon Nov 24 16:45:39 GMT 2014

Powered by FUDForum. Page generated in 0.04145 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software