Home » Modeling » OCL » Enum value not recognized?(Evaluation of derived attribute fails)
Enum value not recognized? [message #1259635] |
Fri, 28 February 2014 16:21 |
Wilbert Alberts Messages: 209 Registered: June 2010 |
Senior 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 |
Ed Willink Messages: 7655 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 |
Wilbert Alberts Messages: 209 Registered: June 2010 |
Senior 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
|
|
| | |
Goto Forum:
Current Time: Thu Mar 28 23:43:26 GMT 2024
Powered by FUDForum. Page generated in 0.23009 seconds
|