Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [emf] question on ordering elements in ecore model
[emf] question on ordering elements in ecore model [message #719414] Fri, 26 August 2011 21:38 Go to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Hi all, I am fairly new to EMF so please bare with me Smile

In my ecore model I define two nodes: A and B where A extends from B:

node A (contains some other elements x,y,z):
A -> B
x
y
z

node B (contains elements a, b ; abstract=true):
B
a
b

When I generate the output XML what happens is this:

<A>
<a/>
<b/>
<x/>
<y/>
<z/>
</A>

Is there _any_ way to tell EMF that I really want

<A>
<x/>
<y/>
<z/>
<a/>
<b/>
</A>

because I have to conform to an external schema which has a sequence that have to adhere to for A.
I guess I am asking is there any way to tell EMF I want the elements of the concrete node A to be printed _before_ elements of the abstract node that it extends?

Thanks for any input!
Re: [emf] question on ordering elements in ecore model [message #719434 is a reply to message #719414] Sat, 27 August 2011 01:47 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
Comments below.

On 26/08/2011 6:38 PM, tsurdilo wrote:
> Hi all, I am fairly new to EMF so please bare with me :)
>
> In my ecore model I define two nodes: A and B where A extends from B:
>
> node A (contains some other elements x,y,z):
> A -> B
> x
> y
> z
>
> node B (contains elements a, b ; abstract=true):
> B
> a
> b
>
> When I generate the output XML what happens is this:
>
> <A>
> <a/>
> <b/>
> <x/>
> <y/>
> <z/>
> </A>
>
> Is there _any_ way to tell EMF that I really want
>
> <A>
> <x/>
> <y/>
> <z/>
> <a/>
> <b/>
> </A>
By specializing the serializer, but...
>
> because I have to conform to an external schema which has a sequence
> that have to adhere to for A.
How is the external schema defining A and B? If B is a complex type
and A extends it then then order would be exactly as it is in EMF, i.e.,
with B's elements first followed by A's extension, so I'm confused how
it could be otherwise.
> I guess I am asking is there any way to tell EMF I want the elements
> of the concrete node A to be printed _before_ elements of the abstract
> node that it extends?
What you describe sounds contradictory... Can you show an example of a
schema that does what you describe?
>
> Thanks for any input!
>
Re: [emf] question on ordering elements in ecore model [message #719514 is a reply to message #719434] Sat, 27 August 2011 11:14 Go to previous messageGo to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Hi Ed, thank your for the reply. Here is the concrete example of what I am working with (BPMN2):

OMG Semantic.xsd schema: http://www.omg.org/spec/BPMN/20100501/Semantic.xsd has defined for the process element:

<xsd:element name="process" type="tProcess" substitutionGroup="rootElement"/>
	<xsd:complexType name="tProcess">
		<xsd:complexContent>
			<xsd:extension base="tCallableElement">
				<xsd:sequence>
					<xsd:element ref="auditing" minOccurs="0" maxOccurs="1"/>
					<xsd:element ref="monitoring" minOccurs="0" maxOccurs="1"/>
					<xsd:element ref="property" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element ref="laneSet" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element ref="flowElement" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element ref="artifact" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element ref="resourceRole" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element ref="correlationSubscription" minOccurs="0" maxOccurs="unbounded"/>
					<xsd:element name="supports" type="xsd:QName" minOccurs="0" maxOccurs="unbounded"/>
				</xsd:sequence>
				<xsd:attribute name="processType" type="tProcessType" default="None"/>
				<xsd:attribute name="isClosed" type="xsd:boolean" default="false"/>
				<xsd:attribute name="isExecutable" type="xsd:boolean"/>
				<xsd:attribute name="definitionalCollaborationRef" type="xsd:QName" use="optional"/>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>


eclipse.bpmn2 model (BPMN20.ecore -> https://github.com/eclipse/bpmn2/tree/master/org.eclipse.bpmn2/model) has:

http://i.imgur.com/0ELBG.png

and the abstract node it extends (FlowElementContainer for example) has:

http://i.imgur.com/xjFur.png

When generating output bpmn2 with the eclipse.bpmn2 api (this is just one example) the process element in the xml output first includes the elements of the FlowElementContainer node, then it includes the elements that are within the Process node (for for example laneset would come _before_ property) and in any bpm runtime engine that does schema validation, this fails unfortunately and I have to manually rearrange the bpmn2 to get it to conform to Semantic.xml, unless I turn off schema validation completely.

Hope this is what you were asking. Any input is much appreciated!

Thanks.
Re: [emf] question on ordering elements in ecore model [message #719535 is a reply to message #719514] Sat, 27 August 2011 12:42 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
Comments below.

On 27/08/2011 8:14 AM, tsurdilo wrote:
> Hi Ed, thank your for the reply. Here is the concrete example of what
> I am working with (BPMN2):
>
> OMG Semantic.xsd schema:
> http://www.omg.org/spec/BPMN/20100501/Semantic.xsd has defined for the
> process element:
Oh, one of those semi-useless OMG schemas. Your model uses multiple
inheritance but that's not supported in XML Schema, so one does a bunch
of copying to "approximate" it or one uses model and attribute groups
which are no better than a macro.
>
>
> <xsd:element name="process" type="tProcess"
> substitutionGroup="rootElement"/>
> <xsd:complexType name="tProcess">
> <xsd:complexContent>
> <xsd:extension base="tCallableElement">
> <xsd:sequence>
> <xsd:element ref="auditing" minOccurs="0" maxOccurs="1"/>
> <xsd:element ref="monitoring" minOccurs="0" maxOccurs="1"/>
> <xsd:element ref="property" minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element ref="laneSet" minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element ref="flowElement" minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element ref="artifact" minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element ref="resourceRole" minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element ref="correlationSubscription" minOccurs="0"
> maxOccurs="unbounded"/>
> <xsd:element name="supports" type="xsd:QName" minOccurs="0"
> maxOccurs="unbounded"/>
> </xsd:sequence>
> <xsd:attribute name="processType" type="tProcessType" default="None"/>
> <xsd:attribute name="isClosed" type="xsd:boolean" default="false"/>
> <xsd:attribute name="isExecutable" type="xsd:boolean"/>
> <xsd:attribute name="definitionalCollaborationRef" type="xsd:QName"
> use="optional"/>
> </xsd:extension>
> </xsd:complexContent>
> </xsd:complexType>
>
>
> eclipse.bpmn2 model (BPMN20.ecore ->
> https://github.com/eclipse/bpmn2/tree/master/org.eclipse.bpmn2/model)
> has:
Given the specification is defining both a schema and a model, it's
rather stupid they'd define an order that puts base class features in
the middle of the locally defined features. A problem with the OMG is
that they focus on specifications with reference implementations as an
afterthought. Actually, reference implementations aren't even
considered, so problems crop of long after the specification has been
cast in stone.
>
>
>
> and the abstract node it extends (FlowElementContainer for example) has:
>
>
>
> When generating output bpmn2 with the eclipse.bpmn2 api (this is just
> one example) the process element in the xml output first includes the
> elements of the FlowElementContainer node, then it includes the
> elements that are within the Process node (for for example laneset
> would come _before_ property) and in any bpm runtime engine that does
> schema validation, this fails unfortunately and I have to manually
> rearrange the bpmn2 to get it to conform to Semantic.xml, unless I
> turn off schema validation completely.
> Hope this is what you were asking. Any input is much appreciated!
Using OPTION_USE_CACHED_LOOKUP_TABLE you could create your own
implementation of XMLSaveImpl.Lookup where you could override
getFeatures to return features in the order you want them to appear in
the XML.
>
> Thanks.
Re: [emf] question on ordering elements in ecore model [message #719538 is a reply to message #719535] Sat, 27 August 2011 12:56 Go to previous messageGo to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
I agree it is semi-useless and that they did not think of actual implementations of the spec Smile

Do you by any chance have examples using OPTION_USE_CACHED_LOOKUP_TABLE and how to do what you mention? I always struggle finding reference examples other than the javadoc and would love to try implementing a solution over the weekend Smile

Thanks!
Re: [emf] question on ordering elements in ecore model [message #719547 is a reply to message #719538] Sat, 27 August 2011 14:24 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
No, there aren't examples. You can look at where the Lookup class is
used in XMLSaveImpl to get the idea...


On 27/08/2011 9:56 AM, tsurdilo wrote:
> I agree it is semi-useless and that they did not think of actual
> implementations of the spec :)
> Do you by any chance have examples using
> OPTION_USE_CACHED_LOOKUP_TABLE and how to do what you mention? I
> always struggle finding reference examples other than the javadoc and
> would love to try implementing a solution over the weekend :)
>
> Thanks!
Re: [emf] question on ordering elements in ecore model [message #730634 is a reply to message #719547] Wed, 28 September 2011 14:43 Go to previous messageGo to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Hi Ed, I found some time for this now, and looking at XmlSaveImpl in it's init method it first gets the OPTION_USE_CACHED_LOOKUP_TABLE object via:

 @SuppressWarnings("unchecked") List<Object> lookup = (List<Object>)options.get(XMLResource.OPTION_USE_CACHED_LOOKUP_TABLE);


and if the lookup table is provided (not emty) it tries to cast it to the Lookup class:

featureTable = (Lookup)lookup.get(INDEX_LOOKUP);


the Lookup class has signature:
protected static class Lookup {
...
}


This then (unless I am wrong) does not allow me to create own impl of the Lookup class outside of org.eclipse.emf.ecore.xmi.impl package. I would want to be able to do this in the client app code instead if possible.

Thanks.

[Updated on: Wed, 28 September 2011 14:43]

Report message to a moderator

Re: [emf] question on ordering elements in ecore model [message #730639 is a reply to message #730634] Wed, 28 September 2011 14:51 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
You'll be able to create a derived class, but it will have to be nested
in a subclass of XMLSaveImpl. Note that it's static, so such a Lookup
subclass will not have to exist in an actual instance of that (dummy)
containing XMLSaveImpl suclass.


On 28/09/2011 11:43 AM, tsurdilo wrote:
> Hi Ed, I found some time for this now, and looking at XmlSaveImpl in
> it's init method it first gets the OPTION_USE_CACHED_LOOKUP_TABLE
> object via:
>
>
> @SuppressWarnings("unchecked") List<Object> lookup =
> (List<Object>)options.get(XMLResource.OPTION_USE_CACHED_LOOKUP_TABLE);
>
>
> and if the lookup table is actually provided (not emty) it tries to
> actually cast it to the Lookup class:
>
>
> featureTable = (Lookup)lookup.get(INDEX_LOOKUP);
>
>
> the Lookup class has signature:
>
> protected static class Lookup {
> ..
> }
>
>
> This then (unless I am wrong) does not allow me to create own impl of
> the Lookup class outside of org.eclipse.emf.ecore.xmi.impl package. I
> would want to be able to do this in the client app code instead if
> possible.
>
> Thanks.
Re: [emf] question on ordering elements in ecore model [message #730718 is a reply to message #730639] Wed, 28 September 2011 20:58 Go to previous messageGo to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Thanks for the help Ed! Looking into overriding getFeatures now and if it all goes well I will write a blog on this Smile

[Updated on: Wed, 28 September 2011 21:40]

Report message to a moderator

Re: [emf] question on ordering elements in ecore model [message #730749 is a reply to message #730718] Thu, 29 September 2011 00:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
Comments below.

On 28/09/2011 5:58 PM, tsurdilo wrote:
> Thanks, I have now:
>
>
> public class MyXMLSaveImpl extends XMLSaveImpl {
> public MyXMLSaveImpl(XMLHelper helper) {
> super(helper);
> }
> ...
> public static class Lookup {
It's extending the one from the base?
> ....
> }
> }
>
>
> I see the constructor being called during debug,
What's on the stack? I.e., who is calling the constructor?
> but still the XMLSaveImpl.Lookup is being called in the XMLSaveImpl
> init method..not sure what I'm missing here?
You still have to pass your instance via the options. Nothing magical
is going to create your derived Lookup just because it exists.
Re: [emf] question on ordering elements in ecore model [message #731321 is a reply to message #730749] Fri, 30 September 2011 12:12 Go to previous messageGo to next message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Hi Ed, I got a lot further on this, got it actually working, however when I modify the featureList in my override getFeatures method (just swapped a couple of elements in the order - did not remove or add any) I get this:

[junit] java.lang.ClassCastException: org.eclipse.emf.ecore.util.EObjectContainmentEList cannot be cast to org.eclipse.emf.ecore.InternalEObject
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedSingle(XMLSaveImpl.java:2369)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1527)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedMany(XMLSaveImpl.java:2386)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1533)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.writeTopObject(XMLSaveImpl.java:680)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.traverse(XMLSaveImpl.java:588)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:256)
    [junit] 	at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206)
    [junit] 	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)



This happens when actually an element is in the bpmn2 for which the order has been swapped, if there are no elements with swapped features, stuff works as expected.

Any input would be great to have.

Thanks.
Re: [emf] question on ordering elements in ecore model [message #731329 is a reply to message #731321] Fri, 30 September 2011 12:43 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25949
Registered: July 2009
Senior Member
Comments below.

On 30/09/2011 9:12 AM, tsurdilo wrote:
> Hi Ed, I got a lot further on this, got it actually working, however
> when I modify the featureList in my override getFeatures method (just
> swapped a couple of elements in the order - did not remove or add any)
> I get this:
>
>
> [junit] java.lang.ClassCastException:
> org.eclipse.emf.ecore.util.EObjectContainmentEList cannot be cast to
> org.eclipse.emf.ecore.InternalEObject
So something is returning a list where a single EObject is expected.
It's hard to say why that would happen. The debugger is very helpful in
this situation (and in general).
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedSingle(XMLSaveImpl.java:2369)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1527)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1174)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(XMLSaveImpl.java:1035)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveContainedMany(XMLSaveImpl.java:2386)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1533)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2685)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.writeTopObject(XMLSaveImpl.java:680)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.traverse(XMLSaveImpl.java:588)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:256)
> [junit] at
> org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206)
> [junit] at
> org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)
>
>
>
> This happens when actually an element is in the bpmn2 for which the
> order has been swapped, if there are no elements with swapped
> features, stuff works as expected.
>
> Any input would be great to have.
>
> Thanks.
>
Re: [emf] question on ordering elements in ecore model [message #731335 is a reply to message #731329] Fri, 30 September 2011 12:57 Go to previous message
tsurdilo  is currently offline tsurdilo
Messages: 41
Registered: February 2011
Member
Thanks Ed, the issue ended up in my modified getFeatures method ==> I changed featureList array, but did not update the classes and featureKinds arrays. When I updated them also:

EStructuralFeature[] modifiedFeatureList =  getModifiedProcessFeatureSet(featureList);
				if (c == null) {
					classes[index] = cls;
					features[index] = modifiedFeatureList;
					featureKinds[index] = listKinds(modifiedFeatureList);
				}


things are now working as expected. Thanks so much for all the help!!!
Previous Topic:XSD import: creating base packages
Next Topic:Saving using Resource.OPTION_ZIP - Can I add other files?
Goto Forum:
  


Current Time: Fri Aug 01 10:07:59 EDT 2014

Powered by FUDForum. Page generated in 0.02225 seconds