Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Fasani2015-03-16 15:13:29 +0000
committerLaurent Fasani2015-03-19 16:35:22 +0000
commit5970f86a46468f349f844dd9a4d691c0239b447d (patch)
tree20e903bafc414377a802f17983d76c504f52e0a1
parentf26c2739fdad4a6a3a9d2cf718328972b9643f27 (diff)
downloadorg.eclipse.sirius-5970f86a46468f349f844dd9a4d691c0239b447d.tar.gz
org.eclipse.sirius-5970f86a46468f349f844dd9a4d691c0239b447d.tar.xz
org.eclipse.sirius-5970f86a46468f349f844dd9a4d691c0239b447d.zip
[462213] Properly remove the semantic root from aird model tag
A map is used to maintain reference between the root of the semantic resource which is set as models in aird AND its resource which contains it. This allows to properly remove the root from the aird model tag when its resource is empty due to unload because of an external deletion for instance. Bug: 462213 Change-Id: Ifb47d4baf2e6be64f99000400a17ed3862f80475 Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java96
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SemanticResourcesUpdater.java78
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesTracker.java19
3 files changed, 146 insertions, 47 deletions
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 393e2a13d6..48176e54c1 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,6 +30,7 @@ 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.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
@@ -616,48 +617,53 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
}
private EObject findSemanticRoot(final Resource res) {
- EObject root = res.getContents().get(0);
-
- /*
- * 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 eClass = root.eClass();
- ExtendedMetaData extendedMetaData = ExtendedMetaData.INSTANCE;
- if (extendedMetaData.isDocumentRoot(eClass)) {
+ EObject root = null;
+ EList<EObject> contents = res.getContents();
+ if (contents != null && contents.size() > 0) {
+ root = contents.get(0);
/*
- * Step over the "mixed", "xMLNSPrefixMap", and "xSISchemaLocation"
- * features of the injected DocumentRoot found in an XSD generated
- * 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
- * features in the class. This allows it to maintain comments and
- * white space that appears in the document, before the root
- * element. A document root class contains two more EMap features,
- * both String to String, to record the namespace to prefix mappings
- * (xMLNSPrefixMap) and xsi:schemaLocation mappings
- * (xSISchemaLocation) of an XML instance document.
+ * 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'.
*/
- 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;
+ EClass eClass = root.eClass();
+ ExtendedMetaData extendedMetaData = ExtendedMetaData.INSTANCE;
+ if (extendedMetaData.isDocumentRoot(eClass)) {
+
+ /*
+ * Step over the "mixed", "xMLNSPrefixMap", and
+ * "xSISchemaLocation" features of the injected DocumentRoot
+ * found in an XSD generated 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 features in the class. This allows it to maintain
+ * comments and white space that appears in the document, before
+ * the root element. A document root class contains two more
+ * EMap features, both String to String, to record the namespace
+ * to prefix mappings (xMLNSPrefixMap) and xsi:schemaLocation
+ * mappings (xSISchemaLocation) of an XML instance document.
+ */
+ 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
+ } // for
+ }
}
return root;
}
@@ -716,12 +722,16 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
protected void doRemoveSemanticResource(final Resource res, final ResourceSet set) {
set.getResources().remove(res);
- if (res.getContents().size() > 0) {
- final EObject root = findSemanticRoot(res);
- for (final DAnalysis analysis : this.allAnalyses()) {
- analysis.getModels().remove(root);
- }
+ // update models in aird resource
+ // The semantic resources are updated by the SemanticResourcesUpdater
+ EObject rootObject = tracker.getRootObjectFromResourceURI(res.getURI().toString());
+ if (rootObject == null) {
+ rootObject = findSemanticRoot(res);
+ }
+ for (final DAnalysis analysis : this.allAnalyses()) {
+ analysis.getModels().remove(rootObject);
}
+
unregisterResourceInCrossReferencer(res);
if (!isFromPackageRegistry(set, res)) {
disableCrossReferencerResolve(res);
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SemanticResourcesUpdater.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SemanticResourcesUpdater.java
index b020ac4bf6..6ff396e7ae 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SemanticResourcesUpdater.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SemanticResourcesUpdater.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012-2015 THALES GLOBAL SERVICES.
+ * Copyright (c) 2012, 2015 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,16 +11,21 @@
package org.eclipse.sirius.business.internal.session.danalysis;
import java.util.Collection;
+import java.util.Map;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.sirius.business.api.session.SessionListener;
import org.eclipse.sirius.viewpoint.DAnalysis;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
+import com.google.common.collect.Maps;
+
/**
* A {@link Adapter} to update the collection of semantic resources in a
* Session.
@@ -34,17 +39,30 @@ public class SemanticResourcesUpdater extends AdapterImpl implements Adapter {
private Collection<Resource> semanticResources;
/**
+ * This map allows to retrieve the eObject of the
+ * {@link DAnalysis.getModels} from its resource. This is useful in the
+ * event of the resource has been unloaded and eObject.eResource()==null
+ */
+ private Map<String, EObject> resourceToRootEObjectMap = Maps.newHashMap();
+
+ /**
* Default constructor.
*
* @param dAnalysisSessionImpl
* the {@link DAnalysisSessionImpl} referencing the semantic
* resource
+ */
+ public SemanticResourcesUpdater(DAnalysisSessionImpl dAnalysisSessionImpl) {
+ this.dAnalysisSessionImpl = dAnalysisSessionImpl;
+ }
+
+ /**
+ * Initialize the semantic resources of the session.
*
* @param semanticResources
* the collection of semantic resources of the Session
*/
- public SemanticResourcesUpdater(DAnalysisSessionImpl dAnalysisSessionImpl, Collection<Resource> semanticResources) {
- this.dAnalysisSessionImpl = dAnalysisSessionImpl;
+ public void setSemanticResources(Collection<Resource> semanticResources) {
for (DAnalysis dAnalysis : this.dAnalysisSessionImpl.allAnalyses()) {
if (!dAnalysis.eAdapters().contains(this)) {
dAnalysis.eAdapters().add(this);
@@ -60,6 +78,17 @@ public class SemanticResourcesUpdater extends AdapterImpl implements Adapter {
&& (msg.getFeature() == ViewpointPackage.Literals.DANALYSIS_SESSION_EOBJECT__ANALYSES || msg.getFeature() == ViewpointPackage.Literals.DANALYSIS__REFERENCED_ANALYSIS
|| msg.getFeature() == ViewpointPackage.Literals.DANALYSIS_SESSION_EOBJECT__ANALYSES || msg.getFeature() == ViewpointPackage.Literals.DANALYSIS__MODELS || msg.getFeature() == ViewpointPackage.Literals.DANALYSIS_SESSION_EOBJECT__CONTROLLED_RESOURCES)) {
// CHECKSTYLE:ON
+
+ // update the map resource-EObject
+ if (msg.getFeature() == ViewpointPackage.Literals.DANALYSIS__MODELS) {
+ int eventType = msg.getEventType();
+ if (eventType == Notification.ADD || eventType == Notification.ADD_MANY) {
+ addAssociatedResource(msg.getNewValue());
+ } else if (eventType == Notification.REMOVE || eventType == Notification.REMOVE_MANY) {
+ removeAssociatedResource(msg.getOldValue());
+ }
+ }
+
RunnableWithResult<Collection<Resource>> semanticResourcesGetter = new SemanticResourceGetter(dAnalysisSessionImpl);
semanticResourcesGetter.run();
Collection<Resource> updatedSemanticResources = semanticResourcesGetter.getResult();
@@ -86,6 +115,48 @@ public class SemanticResourcesUpdater extends AdapterImpl implements Adapter {
}
}
+ private void addAssociatedResource(Object value) {
+ if (value instanceof EObject) {
+ Resource eResource = ((EObject) value).eResource();
+ if (eResource != null) {
+ resourceToRootEObjectMap.put(eResource.getURI().toString(), (EObject) value);
+ }
+ } else if (value instanceof EList<?>) {
+ EList<?> eListNotifier = (EList<?>) value;
+ for (Object object : eListNotifier) {
+ addAssociatedResource(object);
+ }
+ }
+ }
+
+ private void removeAssociatedResource(Object value) {
+ if (value instanceof EObject) {
+ for (String resource : resourceToRootEObjectMap.keySet()) {
+ if (value.equals(resourceToRootEObjectMap.get(resource))) {
+ resourceToRootEObjectMap.remove(resource);
+ break;
+ }
+ }
+ } else if (value instanceof EList<?>) {
+ EList<?> eListNotifier = (EList<?>) value;
+ for (Object object : eListNotifier) {
+ removeAssociatedResource(object);
+ }
+ }
+ }
+
+ /**
+ * Return the root EObject associated to the resource. The root EObject is
+ * part of {@link DAnalysis.getModels}
+ *
+ * @param resourceURI
+ * the URI of the resource
+ * @return the eObject
+ */
+ public EObject getRootObjectFromResourceURI(String resourceURI) {
+ return resourceToRootEObjectMap.get(resourceURI);
+ }
+
/**
* Dispose this updater.
*/
@@ -97,5 +168,6 @@ public class SemanticResourcesUpdater extends AdapterImpl implements Adapter {
}
dAnalysisSessionImpl = null;
semanticResources = null;
+ resourceToRootEObjectMap.clear();
}
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesTracker.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesTracker.java
index c142da8810..017d1aeea8 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesTracker.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesTracker.java
@@ -18,6 +18,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.emf.transaction.util.TransactionUtil;
@@ -120,7 +121,11 @@ class SessionResourcesTracker {
Collection<Resource> getSemanticResources() {
if (semanticResources == null) {
semanticResources = new CopyOnWriteArrayList<Resource>();
- semanticResourcesUpdater = new SemanticResourcesUpdater(session, semanticResources);
+ if (semanticResourcesUpdater == null) {
+ semanticResourcesUpdater = new SemanticResourcesUpdater(session);
+ }
+ semanticResourcesUpdater.setSemanticResources(semanticResources);
+
RunnableWithResult<Collection<Resource>> semanticResourcesGetter = new SemanticResourceGetter(session);
try {
TransactionUtil.runExclusive(session.getTransactionalEditingDomain(), semanticResourcesGetter);
@@ -132,6 +137,18 @@ class SessionResourcesTracker {
return Collections.unmodifiableCollection(semanticResources);
}
+ /**
+ * Return the root EObject associated to the resource. The root EObject is
+ * part of {@link DAnalysis.getModels}
+ *
+ * @param resourceURI
+ * the URI of the resource
+ * @return the eObject
+ */
+ public EObject getRootObjectFromResourceURI(String resourceURI) {
+ return semanticResourcesUpdater.getRootObjectFromResourceURI(resourceURI);
+ }
+
void handlePossibleControlledResources() {
// Detect actual controlled resources.
if (controlledResourcesDetector != null) {

Back to the top