diff options
| author | Mickael LANOE | 2015-03-19 09:36:41 +0000 |
|---|---|---|
| committer | Mickael LANOE | 2015-03-19 11:17:08 +0000 |
| commit | 04035c773c9954245cde4b0b4c7a852ec956972f (patch) | |
| tree | df1262a95b834741f5a54aca01c2e2a4639e4e2e | |
| parent | 8e8e1ac2397afaa634773377db8fdabbb4aed681 (diff) | |
| download | org.eclipse.sirius-04035c773c9954245cde4b0b4c7a852ec956972f.tar.gz org.eclipse.sirius-04035c773c9954245cde4b0b4c7a852ec956972f.tar.xz org.eclipse.sirius-04035c773c9954245cde4b0b4c7a852ec956972f.zip | |
[432133] Correctly detect semantic roots for XSD-based models
Use ExtendedMetaData API to detect semantic root for XSD-based models.
Fix NotificationQuery to detect modification for XSD-based models
containing a DocumentRoot.
Bug: 432133
Change-Id: Iff310fa7ebb63ba665c6630b0c041e01266fb99f
Signed-off-by: Mickael LANOE <mickael.lanoe@obeo.fr>
2 files changed, 26 insertions, 66 deletions
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java index 4ebdf62172..67962cad05 100644 --- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java +++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java @@ -11,12 +11,9 @@ package org.eclipse.sirius.common.tools.api.query; import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EAnnotation; -import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.util.ExtendedMetaData; import com.google.common.base.Preconditions; @@ -69,43 +66,15 @@ public class NotificationQuery { private boolean isContainedThroughTransientFeature(EObject obj) { EObject current = obj; while (current.eContainer() != null) { - if (current.eContainingFeature().isTransient() && !isFeatureMap(current.eContainer())) { - return true; - } - current = current.eContainer(); - } - return false; - } + EObject container = current.eContainer(); - /** - * Return true if the EObject is a feature map as defined in section 3.5 of - * https - * ://www.eclipse.org/modeling/emf/docs/overviews/XMLSchemaToEcoreMapping - * .pdf - * - * @param obj - * object to test - * @return true if the EObject is a feature map - */ - private boolean isFeatureMap(EObject obj) { - - EAnnotation annotation = obj.eClass().getEAnnotation("http:///org/eclipse/emf/ecore/util/ExtendedMetaData"); - if (annotation != null && annotation.getDetails() != null) { - String kind = annotation.getDetails().get("kind"); - // Is it sufficient to test kind.equals("mixed")? - if ("mixed".equals(kind)) { - // If not (or just to be safe), check if type is - // EFeatureMapEntry - - // Not exactly sure the difference between getEAllAttributes - // and getEAttributes. - EList<EAttribute> attribs = obj.eClass().getEAllAttributes(); - for (EAttribute eAttribute : attribs) { - if (eAttribute.getEType().equals(EcorePackage.eINSTANCE.getEFeatureMapEntry())) { - return true; - } - } + // Do not consider transient containing feature when the container + // is a DocumentRoot. See section 1.5 of + // https://www.eclipse.org/modeling/emf/docs/overviews/XMLSchemaToEcoreMapping.pdf + if (current.eContainingFeature().isTransient() && !ExtendedMetaData.INSTANCE.isDocumentRoot(container.eClass())) { + return true; } + current = container; } return false; } diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java index e1c9e5de7b..6daa6e36ed 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java @@ -30,16 +30,17 @@ import org.eclipse.emf.common.command.BasicCommandStack; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.transaction.RunnableWithResult; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.TransactionalEditingDomain; @@ -609,34 +610,21 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements EObject root = res.getContents().get(0); /* - * Attempt to determine if the eCore model was generated from XSD by + * Attempt to determine if the Ecore model was generated from XSD by * inspecting the annotation on the root. XSD->ECore will use the * ExtendedMetaData as the annotation source, set the 'name' to an empty * string (since the generated DocumentRoot doesn't have an underlying * Element name), and have a 'kind' of 'mixed'. */ - EClass eCls = root.eClass(); - boolean isXSD = Iterables.any(eCls.getEAnnotations(), new Predicate<EAnnotation>() { - - @Override - public boolean apply(EAnnotation annotation) { - boolean isExtMetadata = "http:///org/eclipse/emf/ecore/util/ExtendedMetaData".equals(annotation.getSource()); - if (isExtMetadata) { - EMap<String, String> details = annotation.getDetails(); - if (details.containsKey("name") && details.get("name").isEmpty() && details.containsKey("kind") && "mixed".equals(details.get("kind"))) { - return true; - } - } - return false; - } - }); + EClass eClass = root.eClass(); + ExtendedMetaData extendedMetaData = ExtendedMetaData.INSTANCE; + if (extendedMetaData.isDocumentRoot(eClass)) { - if (isXSD) { /* * Step over the "mixed", "xMLNSPrefixMap", and "xSISchemaLocation" * features of the injected DocumentRoot found in an XSD generated - * ECore model Excerpts from https://www - * .eclipse.org/modeling/emf/docs/overviews/ XMLSchemaToEcoreMapping + * Ecore model extracted from https://www + * .eclipse.org/modeling/emf/docs/overviews/XMLSchemaToEcoreMapping * .pdf (section 1.5) ... The document root EClass looks like one * corresponding to a mixed complex type (see section 3.4) including * a "mixed" feature, and derived implementations for the other @@ -647,17 +635,20 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements * (xMLNSPrefixMap) and xsi:schemaLocation mappings * (xSISchemaLocation) of an XML instance document. */ - for (int featureID = 0; featureID < eCls.getFeatureCount(); featureID++) { - EStructuralFeature eFeature = eCls.getEStructuralFeature(featureID); - String name = eFeature.getName(); - if (!"mixed".equals(name) && !"xMLNSPrefixMap".equals(name) && !"xSISchemaLocation".equals(name)) { - Object obj = root.eGet(eFeature); + EReference xmlnsPrefixMapFeature = extendedMetaData.getXMLNSPrefixMapFeature(eClass); + EReference xsiSchemaLocationFeature = extendedMetaData.getXSISchemaLocationMapFeature(eClass); + EAttribute mixedFeatureFeature = extendedMetaData.getMixedFeature(eClass); + + for (int featureID = 0; featureID < eClass.getFeatureCount(); featureID++) { + EStructuralFeature feature = eClass.getEStructuralFeature(featureID); + if (feature != mixedFeatureFeature && feature != xmlnsPrefixMapFeature && feature != xsiSchemaLocationFeature) { + Object obj = root.eGet(feature); if (obj instanceof EObject) { root = (EObject) obj; break; } } - } + } // for } return root; } |
