Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Redor2015-01-12 15:16:21 +0000
committerLaurent Redor2015-01-16 16:52:34 +0000
commit7e5459cfdad25200ed915beb539d9e2989f1b540 (patch)
tree5604f9f03da8f50a9e749b950b9674d4b7c36d7d
parent3e0bf7d092196b06cf105655a29aff858cf1114f (diff)
downloadorg.eclipse.sirius-7e5459cfdad25200ed915beb539d9e2989f1b540.tar.gz
org.eclipse.sirius-7e5459cfdad25200ed915beb539d9e2989f1b540.tar.xz
org.eclipse.sirius-7e5459cfdad25200ed915beb539d9e2989f1b540.zip
[452681] Avoid wrong cross-references result after unload/reload
This commit adds a new kind of ECrossReferenceAdapter with the capability to resolve all proxy cross-references to a given Resource. It is currently used by the Session for the semantic cross referencer, especially in case of unload/reload of a resource after detecting an external change. Bug: 452681 Change-Id: I2ad5f33463fe3b45b780e7d313e2c3c67104a3fa Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/ECrossReferenceAdapterWithUnproxyCapability.java94
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/LazyCrossReferencer.java33
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.html22
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.textile5
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java9
5 files changed, 148 insertions, 15 deletions
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/ECrossReferenceAdapterWithUnproxyCapability.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/ECrossReferenceAdapterWithUnproxyCapability.java
new file mode 100644
index 0000000000..adb7113080
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/ECrossReferenceAdapterWithUnproxyCapability.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.common.tools.api.util;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+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.ECrossReferenceAdapter;
+
+/**
+ * {@link ECrossReferenceAdapter} that provides the capability to resolve all
+ * proxy cross reference to a given resource.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class ECrossReferenceAdapterWithUnproxyCapability extends ECrossReferenceAdapter {
+ /**
+ * InverseCrossReferencer to allow access to {@link #removeProxies(URI)} in
+ * '@link InternalCrossReferencer}.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+ private class LocalInverseCrossReferencer extends InverseCrossReferencer {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected List<EObject> removeProxies(URI uri) {
+ return super.removeProxies(uri);
+ }
+ }
+
+ /**
+ * Default constructor that uses its own {@link InverseCrossReferencer}.
+ */
+ public ECrossReferenceAdapterWithUnproxyCapability() {
+ inverseCrossReferencer = new LocalInverseCrossReferencer();
+ }
+
+ /**
+ * Look at all EObjects of the specified resource and resolve proxy cross
+ * reference that reference these EObjects.<BR>
+ * A part of {@link #resolveAll(EObject)} has been duplicated to avoid the
+ * time consumption of accessing to resourceURI for each objects of the same
+ * resource.
+ *
+ * @param resource
+ * Each cross reference pointing to a proxy of this
+ * <code>resource</code> will be resolved.
+ */
+ public void resolveProxyCrossReferences(Resource resource) {
+ if (resource != null) {
+ URI resourceURI = resource.getURI();
+ if (resourceURI != null) {
+ ResourceSet resourceSet = resource.getResourceSet();
+ if (resourceSet != null) {
+ resourceURI = resourceSet.getURIConverter().normalize(resourceURI);
+ }
+ }
+ final Iterator<EObject> it = resource.getAllContents();
+ while (it.hasNext()) {
+ EObject eObject = it.next();
+ URI eObjectURI;
+ if (resourceURI != null) {
+ eObjectURI = resourceURI.appendFragment(resource.getURIFragment(eObject));
+ } else {
+ eObjectURI = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject));
+ }
+ List<EObject> proxies = ((LocalInverseCrossReferencer) inverseCrossReferencer).removeProxies(eObjectURI);
+ if (proxies != null) {
+ for (int i = 0, size = proxies.size(); i < size; ++i) {
+ EObject proxy = proxies.get(i);
+ for (EStructuralFeature.Setting setting : getInverseReferences(proxy, false)) {
+ resolveProxy(resource, eObject, proxy, setting);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/LazyCrossReferencer.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/LazyCrossReferencer.java
index 73c8c9f437..cad35199fe 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/LazyCrossReferencer.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/util/LazyCrossReferencer.java
@@ -16,18 +16,21 @@ import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.ecore.resource.Resource;
import com.google.common.collect.Iterables;
/**
- * A lazy cross referencer which does nothing until one of its method is called. <BR><BR>
+ * A lazy cross referencer which does nothing until one of its method is called. <BR>
+ * <BR>
* This cross referencer also reacts to {@link EObject} removal from their
* containing reference : it removes itself automatically from their adapters
- * and recursively from those of their contents. <BR><BR>
+ * and recursively from those of their contents. <BR>
+ * <BR>
* This cross referencer also provide a way to disable the resolution of proxy.
* This can be useful to avoid reloading of a resource during the unloading of
- * it (caused by resolution of some proxy with crossReferencer).<BR><BR>
+ * it (caused by resolution of some proxy with crossReferencer).<BR>
+ * <BR>
*
* @see {@link org.eclipse.emf.transaction.impl.ResourceSetManager#observe(org.eclipse.emf.ecore.resource.Resource, Notification)}
* and message
@@ -36,12 +39,12 @@ import com.google.common.collect.Iterables;
*
* @author mchauvin
*/
-public class LazyCrossReferencer extends ECrossReferenceAdapter {
+public class LazyCrossReferencer extends ECrossReferenceAdapterWithUnproxyCapability {
private boolean resolveEnabled = true;
private boolean initialized;
- private ECrossReferenceAdapter adapter = new InternalCrossReferencer();
+ private ECrossReferenceAdapterWithUnproxyCapability adapter = new InternalCrossReferencer();
/**
* Subclasses should override, and call super.initialize().
@@ -197,9 +200,25 @@ public class LazyCrossReferencer extends ECrossReferenceAdapter {
}
/**
+ * Look at all EObjects of this resource and resolve proxy cross reference
+ * that reference these EObjects.
+ *
+ * @param resource
+ * Each cross reference pointing to a proxy of this
+ * <code>resource</code> will be resolved.
+ */
+ public void resolveProxyCrossReferences(Resource resource) {
+ if (initialized) {
+ // The resolution of proxy is called only is the cross-referencer
+ // has already been initialized.
+ adapter.resolveProxyCrossReferences(resource);
+ }
+ }
+
+ /**
* @see LazyCrossReferencer. This class is the delegated adapter.
*/
- private class InternalCrossReferencer extends ECrossReferenceAdapter {
+ private class InternalCrossReferencer extends ECrossReferenceAdapterWithUnproxyCapability {
/**
* {@inheritDoc}
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
index 578fb0020c..5fc9277187 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
@@ -71,6 +71,20 @@
<code>org.eclipse.sirius.tools.api.ui.RefreshEditorsPrecommitListener.disable()</code> has been added to disable the next refresh attempt in the current precommit loop iteration.
</li>
</ul>
+ <h4 id="Changesinorg.eclipse.sirius.common">Changes in
+ <code>org.eclipse.sirius.common</code>
+ </h4>
+ <ul>
+ <li>
+ <code>org.eclipse.sirius.common.tools.api.util.ECrossReferenceAdapterWithUnproxyCapability</code> is a specific kind of ECrossReferenceAdapter. It provides the capability to resolve all proxy cross references to a given resource. It is now used by the Session as semantic cross referencer. This type is exposed as API but it is not intended to be used/referenced/extended by user code (as the below
+ <code>LazyCrossReferencer</code> type).
+ </li>
+ <li>
+ <code>org.eclipse.sirius.common.tools.api.util.LazyCrossReferencer</code> now extends
+ <code>ECrossReferenceAdapterWithUnproxyCapability</code> and implements
+ <code>resolveProxyCrossReferences(Resource)</code>.
+ </li>
+ </ul>
<h4 id="Changesinorg.eclipse.sirius.ecore.extender">Changes in
<code>org.eclipse.sirius.ecore.extender</code>
</h4>
@@ -335,7 +349,7 @@
<code>findViewpointByName()</code> to correct a wrong rebranding.
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common2">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -892,7 +906,7 @@
</ul>
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common2">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common3">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -1520,7 +1534,7 @@ if (rootPackage != null &amp;&amp; rootPackage.getNsURI().equals(DiagramPackage.
</ul>
<h3 id="APIChanges7">API Changes</h3>
<p>Sirius 1.0.0M4 includes a lots of API-breaking changes, as part of a global effort to improve the quality of the Sirius internals. In this milestone in particular, most of the APIs which were marked as deprecated in previous versions of Sirius (and before that of Viewpoint) have been either removed (if a replacement exists) or marked as non-deprecated (if no replacement exists yet).</p>
- <h4 id="Changesinorg.eclipse.sirius.common3">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common4">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -2117,4 +2131,4 @@ void removeSelectedView(DView view);
<li>The ability to print table representations has been disabled for the 0.9 release due to an external dependency issue (see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=422223" target="_blank">bug #422223</a>: for the details). It should be re-introduced in 1.0.</li>
</ul>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
index 0fd7d45d94..4795f52171 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
@@ -23,6 +23,11 @@ h4. Changes in @org.eclipse.sirius@
* The method @org.eclipse.sirius.business.api.migration.IMigrationParticipant.updateCreatedObject(EObject newObject, String loadedVersion)@ has been added to update object values in VSM before loading this objects from XML file.
* The method @org.eclipse.sirius.tools.api.ui.RefreshEditorsPrecommitListener.disable()@ has been added to disable the next refresh attempt in the current precommit loop iteration.
+h4. Changes in @org.eclipse.sirius.common@
+
+* @org.eclipse.sirius.common.tools.api.util.ECrossReferenceAdapterWithUnproxyCapability@ is a specific kind of ECrossReferenceAdapter. It provides the capability to resolve all proxy cross references to a given resource. It is now used by the Session as semantic cross referencer. This type is exposed as API but it is not intended to be used/referenced/extended by user code (as the below @LazyCrossReferencer@ type).
+* @org.eclipse.sirius.common.tools.api.util.LazyCrossReferencer@ now extends @ECrossReferenceAdapterWithUnproxyCapability@ and implements @resolveProxyCrossReferences(Resource)@.
+
h4. Changes in @org.eclipse.sirius.ecore.extender@
* The method @org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor.eRemoveInverseCrossReferences()@ has been changed to return the list of changed objects by the inverse cross references removal.
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 5e52b71e38..c3863a8d05 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
@@ -47,7 +47,6 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.ResourceSetListenerImpl;
@@ -106,6 +105,7 @@ import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.resource.ResourceSetSync;
import org.eclipse.sirius.common.tools.api.resource.ResourceSetSync.ResourceStatus;
import org.eclipse.sirius.common.tools.api.resource.ResourceSyncClient;
+import org.eclipse.sirius.common.tools.api.util.ECrossReferenceAdapterWithUnproxyCapability;
import org.eclipse.sirius.common.tools.api.util.EqualityHelper;
import org.eclipse.sirius.common.tools.api.util.LazyCrossReferencer;
import org.eclipse.sirius.ecore.extender.business.api.accessor.EcoreMetamodelDescriptor;
@@ -317,7 +317,7 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
private SessionService services;
- private ECrossReferenceAdapter crossReferencer;
+ private ECrossReferenceAdapterWithUnproxyCapability crossReferencer;
private IInterpreter interpreter;
@@ -1309,7 +1309,7 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
}
@Override
- public ECrossReferenceAdapter getSemanticCrossReferencer() {
+ public ECrossReferenceAdapterWithUnproxyCapability getSemanticCrossReferencer() {
if (crossReferencer == null) {
// use a lazy cross referencer to avoid big memory consumption on
// session load
@@ -1330,7 +1330,7 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
*
* @return a new cross referencer adapter
*/
- protected ECrossReferenceAdapter createSemanticCrossReferencer() {
+ protected ECrossReferenceAdapterWithUnproxyCapability createSemanticCrossReferencer() {
return new SessionLazyCrossReferencer(this);
}
@@ -1715,6 +1715,7 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
try {
resource.load(Collections.EMPTY_MAP);
EcoreUtil.resolveAll(resource);
+ getSemanticCrossReferencer().resolveProxyCrossReferences(resource);
} catch (IOException e) {
setResult(e);
}

Back to the top