| Summary: | XML Serialization: incorrect order of children | ||
|---|---|---|---|
| Product: | [Modeling] MDT.BPMN2 | Reporter: | Henning Heitkoetter <hheitkoetter> |
| Component: | Core | Assignee: | Project Inbox <mdt-bpmn2-inbox> |
| Status: | NEW --- | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | reiner.hille-doering, tsurdilovic |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| URL: | http://www.eclipse.org/forums/index.php/t/236798/ | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 323167 | ||
|
Description
Henning Heitkoetter
Hi Henning, here is description of a fix. I can create a diff for it so it can be merged, just let me know if I am supposed to create a diff off of the github repo or some other repository. Thanks:
1) Update org.eclipse.bpmn2.util.Bpmn2ResourceFactoryImpl:
add:
result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_CACHED_LOOKUP_TABLE, new ArrayList<Object>());
to the createResource method
2) Update org.eclipse.bpmn2.util.Bpmn2ResourceImpl:
change:
return new XMLSaveImpl(createXMLHelper()) { ...
to
return new Bpmn2XMLSaveImpl(createXMLHelper()) { ...
3) Create new class Bpmn2XMLSaveImpl:
You can use this implementation if you wish:
public class Bpmn2XMLSaveImpl extends XMLSaveImpl {
public Bpmn2XMLSaveImpl(XMLHelper helper) {
super(helper);
}
@Override
protected void init(XMLResource resource, Map<?, ?> options) {
super.init(resource, options);
featureTable = new Bpmn2XMLSaveImpl.Bpmn2Lookup(map, extendedMetaData, elementHandler);
}
@Override
public void traverse(List<? extends EObject> contents) {
for(EObject e : contents) {
if(e instanceof Definitions) {
List<RootElement> roots = ((Definitions) e).getRootElements();
Process p = null;
for(RootElement root : roots) {
if(root instanceof Process) {
p = (Process) root;
}
}
if(p != null) {
((Definitions) e).getRootElements().remove(p);
((Definitions) e).getRootElements().add(p);
}
}
}
super.traverse(contents);
}
public static class Bpmn2Lookup extends XMLSaveImpl.Lookup {
public Bpmn2Lookup(XMLMap map, ExtendedMetaData extendedMetaData, ElementHandler elementHandler) {
super(map, extendedMetaData, elementHandler);
}
@Override
public EStructuralFeature[] getFeatures(EClass cls) {
int index = getIndex(cls);
EClass c = classes[index];
if (c == cls) {
return features[index];
}
EStructuralFeature[] featureList = listFeatures(cls);
if (c == null) {
classes[index] = cls;
features[index] = featureList;
featureKinds[index] = listKinds(featureList);
}
if(cls.getName().equalsIgnoreCase("Process")) {
EStructuralFeature[] modifiedFeatureList = getModifiedProcessFeatureSet(featureList);
if (c == null) {
classes[index] = cls;
features[index] = modifiedFeatureList;
featureKinds[index] = listKinds(modifiedFeatureList);
}
return modifiedFeatureList;
}
return featureList;
}
}
private static EStructuralFeature[] getModifiedProcessFeatureSet(EStructuralFeature[] processFeatureList) {
/**
Feature list for Process provided by eclipse.bpmn2:
- extensionDefinitions (0)
- id (1)
- anyAttribute (2)
- name (3)
- definitionalCollaborationRef (4)
- isClosed (5)
- isExecutable (6)
- processType (7)
- extensionValues (8)
- documentation (9)
- supportedInterfaceRefs (10)
- ioSpecification (11)
- ioBinding (12)
- laneSets (13)
- flowElements (14)
- auditing (15)
- monitoring (16)
- properties (17)
- artifacts (18)
- resources (19)
- correlationSubscriptions (20)
- supports (21)
Semantic.xsd sequence definition for Process:
<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>
Moving auditing, monitoring, property above flowElements...
*/
EStructuralFeature[] retArray = new EStructuralFeature[processFeatureList.length];
for(int i=0; i<13; i++) {
retArray[i] = processFeatureList[i];
}
retArray[13] = processFeatureList[15]; // auditing
retArray[14] = processFeatureList[16]; // monitoring
retArray[15] = processFeatureList[17]; // properties
retArray[16] = processFeatureList[13]; // lanesets
retArray[17] = processFeatureList[14]; // flow elements
retArray[18] = processFeatureList[18]; // artifacts
retArray[19] = processFeatureList[19]; // resources
retArray[20] = processFeatureList[20]; // correlationSubscriptions
retArray[21] = processFeatureList[21]; // supports
return retArray;
}
}
Hope this helps.
Thanks.
Thanks. I'm aware of the problem, and the use of strict sequences in BPMN 2.0 XSD is really a problem. Not only for the EMF metamodel, but also for the XSLT transforms between XML and XMI. The XSLTs also simulate the multiple inheritance aspect of the CMOF metamodel and thus can produce invalid XMLs in the sense of the sequence of features. About your proposal: It looks right, but I would prefer a more generic approach. I think we could store the order information in EMF annotations and let the serializer consider it from there. Ideally we generate the annotations from the original BPMN 2.0 XSD. This is possible, as I anyway used a merge tool to generate the Ecore. Unfortunately this will take some time - and my time for BPMN2 is currently very limmited. Reiner. Some addition: I have checked my merge tool (in http://git.eclipse.org/c/bpmn2/tree/org.eclipse.bpmn2.tools.ecoremerger/src/org/eclipse/bpmn2/tools/ecoremerger/Processor.java ). I do consider feature sorting of the XSD, but not in cases of Multi Inheritance. I now plan to extend the merge tool that i writes an annotation to each class with the original XSD feature order. The XmlSave.traverse then can easily take this information and walk accordingly. |