Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2013-08-21 20:03:39 +0000
committerChristian W. Damus2013-09-16 20:02:43 +0000
commit0ec9e1b02391f4f16ff3ddc8c10d2bec0e284050 (patch)
tree85ea90e6e8b0ec21987efd9f430bd35895ed7a67 /extraplugins
parent8d4fc1035f951a55263c89748dc9bcec6b761042 (diff)
downloadorg.eclipse.papyrus-0ec9e1b02391f4f16ff3ddc8c10d2bec0e284050.tar.gz
org.eclipse.papyrus-0ec9e1b02391f4f16ff3ddc8c10d2bec0e284050.tar.xz
org.eclipse.papyrus-0ec9e1b02391f4f16ff3ddc8c10d2bec0e284050.zip
415369: [CDO] Support controlled resources and lazy loading
https://bugs.eclipse.org/bugs/show_bug.cgi?id=415369 Initial implementation of controlled unit creation for CDO models.
Diffstat (limited to 'extraplugins')
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/META-INF/MANIFEST.MF5
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/plugin.xml7
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java45
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/CDOUtils.java46
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOControlModeParticipant.java275
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOProxyManager.java144
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/importer/DependencyAdapter.java13
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/editors/PapyrusCDOEditorInput.java13
8 files changed, 529 insertions, 19 deletions
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/META-INF/MANIFEST.MF b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/META-INF/MANIFEST.MF
index 323fb7cac90..99515fda954 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/META-INF/MANIFEST.MF
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/META-INF/MANIFEST.MF
@@ -5,6 +5,7 @@ Export-Package: org.eclipse.papyrus.cdo.core,
org.eclipse.papyrus.cdo.core.resource,
org.eclipse.papyrus.cdo.core.util,
org.eclipse.papyrus.cdo.internal.core;x-friends:="org.eclipse.papyrus.cdo.core.tests,org.eclipse.papyrus.cdo.ui,org.eclipse.papyrus.cdo.ui.tests,org.eclipse.papyrus.cdo.uml.diagram.ui,org.eclipse.papyrus.cdo.uml.ui,org.eclipse.papyrus.cdo.ui.customization.properties,org.eclipse.papyrus.cdo.uml.ui.tests,org.eclipse.papyrus.cdo.uml.search.ui,org.eclipse.papyrus.cdo.uml.search.ui.tests",
+ org.eclipse.papyrus.cdo.internal.core.controlmode;x-internal:=true,
org.eclipse.papyrus.cdo.internal.core.exporter;x-friends:="org.eclipse.papyrus.cdo.core.tests,org.eclipse.papyrus.cdo.ui",
org.eclipse.papyrus.cdo.internal.core.expressions;x-friends:="org.eclipse.papyrus.cdo.core.tests,org.eclipse.papyrus.cdo.ui",
org.eclipse.papyrus.cdo.internal.core.importer;x-friends:="org.eclipse.papyrus.cdo.core.tests,org.eclipse.papyrus.cdo.ui",
@@ -33,7 +34,9 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.gmf.runtime.notation;bundle-version="[1.5.0,2.0.0)",
org.eclipse.equinox.security;bundle-version="[1.1.100,2.0.0)",
org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
- com.google.guava;bundle-version="[11.0.2,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,12.0.0)",
+ org.eclipse.papyrus.infra.services.controlmode;bundle-version="0.10.1",
+ org.eclipse.gmf.runtime.emf.commands.core;bundle-version="[1.7.0,2.0.0)"
Bundle-Vendor: %providerName
Bundle-Version: 0.10.1.qualifier
Bundle-ManifestVersion: 2
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/plugin.xml b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/plugin.xml
index b7ed909af27..c9d7cd69706 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/plugin.xml
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/plugin.xml
@@ -80,4 +80,11 @@
</propertyTester>
</extension>
+ <extension
+ point="org.eclipse.papyrus.infra.services.controlmode.participant">
+ <participant
+ class="org.eclipse.papyrus.cdo.internal.core.controlmode.CDOControlModeParticipant">
+ </participant>
+ </extension>
+
</plugin>
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java
index d8bb7243031..4f5f74ede8b 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java
@@ -31,6 +31,7 @@ import org.eclipse.net4j.util.event.IListener;
import org.eclipse.papyrus.cdo.core.IPapyrusRepository;
import org.eclipse.papyrus.cdo.core.IPapyrusRepositoryManager;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
+import org.eclipse.papyrus.cdo.internal.core.controlmode.CDOProxyManager;
import org.eclipse.papyrus.infra.core.resource.ModelMultiException;
import org.eclipse.papyrus.infra.services.resourceloading.OnDemandLoadingModelSet;
@@ -44,6 +45,8 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet {
private final ThreadLocal<Boolean> inGetResource = new ThreadLocal<Boolean>();
+ private final CDOProxyManager proxyManager = new CDOProxyManager(this);
+
private final IPapyrusRepositoryManager repositoryManager;
private IPapyrusRepository repository;
@@ -59,13 +62,22 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet {
@Override
public EObject getEObject(URI uri, boolean loadOnDemand) {
- return CDOUtils.isCDOURI(uri) ? basicGetEObject(uri, loadOnDemand) : super.getEObject(uri, loadOnDemand);
+ return CDOUtils.isCDOURI(uri) ? getCDOObject(uri, loadOnDemand) : super.getEObject(uri, loadOnDemand);
}
- protected EObject basicGetEObject(URI uri, boolean loadOnDemand) {
- Resource resource = getResource(uri.trimFragment(), loadOnDemand);
+ protected EObject getCDOObject(URI uri, boolean loadOnDemand) {
+ EObject result = null;
+
+ if(CDOProxyManager.isCDOProxyURI(uri)) {
+ // get a real proxy object, out of thin air, to give CDO the non-null
+ // instance that it needs (otherwise the 'non-null constraint' of
+ // all kinds of reference lists will be violated)
+ result = proxyManager.getProxy(uri);
+ } else {
+ result = super.getEObject(uri, loadOnDemand);
+ }
- return (resource == null) ? null : resource.getEObject(uri.fragment());
+ return result;
}
@Override
@@ -153,21 +165,21 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet {
try {
super.unload();
} finally {
- if((repository != null) && (getCDOView() != null)) {
- CDOView view = getCDOView();
- if(view != null) {
- view.removeListener(getInvalidationListener());
- }
- invalidationListener = null;
+ if((repository != null) && (getCDOView() != null)) {
+ CDOView view = getCDOView();
+ if(view != null) {
+ view.removeListener(getInvalidationListener());
+ }
+ invalidationListener = null;
- // dispose the transaction
- repository.close(this);
+ // dispose the transaction
+ repository.close(this);
// now, we can remove the CDOViewSet adapter
eAdapters().clear();
- }
+ }
- repository = null;
+ repository = null;
}
}
@@ -193,6 +205,11 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet {
}
@Override
+ public boolean isUserModelResource(URI uri) {
+ return super.isUserModelResource(uri) || CDOUtils.isCDOURI(uri);
+ }
+
+ @Override
public EList<Adapter> eAdapters() {
if(eAdapters == null) {
eAdapters = new EAdapterList<Adapter>(this) {
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/CDOUtils.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/CDOUtils.java
index 605975314d6..27aad1fdf53 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/CDOUtils.java
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/CDOUtils.java
@@ -11,12 +11,17 @@
*****************************************************************************/
package org.eclipse.papyrus.cdo.internal.core;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getFirst;
+
import java.util.Set;
import java.util.concurrent.Executor;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.cdo.CDOLock;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.dawn.spi.DawnState;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
@@ -27,8 +32,11 @@ import org.eclipse.emf.cdo.view.CDOViewSet;
import org.eclipse.emf.common.notify.Notifier;
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;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
@@ -59,8 +67,14 @@ public class CDOUtils {
if(type.isInstance(object)) {
result = type.cast(object);
- } else if(object instanceof IAdaptable) {
- result = type.cast(((IAdaptable)object).getAdapter(type));
+ } else {
+ if(object instanceof IAdaptable) {
+ result = type.cast(((IAdaptable)object).getAdapter(type));
+ }
+
+ if((result == null) && object instanceof Notifier) {
+ result = getFirst(filter(((Notifier)object).eAdapters(), type), null);
+ }
}
return result;
@@ -113,6 +127,11 @@ public class CDOUtils {
return result;
}
+ public static CDOID getCDOID(EObject object) {
+ CDOObject cdo = getCDOObject(object);
+ return (cdo == null) ? CDOIDUtil.createExternal(EcoreUtil.getURI(object).toString()) : cdo.cdoID();
+ }
+
public static CDOView getView(ResourceSet resourceSet) {
CDOView result = null;
@@ -180,6 +199,29 @@ public class CDOUtils {
return Iterables.transform(cdoObjects, CDOFunctions.getEObject());
}
+ public static Iterable<EStructuralFeature.Setting> crossReference(EObject object) {
+ Iterable<EStructuralFeature.Setting> result;
+
+ ECrossReferenceAdapter adapter = adapt(object, ECrossReferenceAdapter.class);
+ if(adapter != null) {
+ result = adapter.getInverseReferences(object);
+ } else {
+ EObject tree = EcoreUtil.getRootContainer(object);
+ Resource resource = tree.eResource();
+ ResourceSet rset = (resource == null) ? null : resource.getResourceSet();
+
+ if(rset != null) {
+ result = EcoreUtil.UsageCrossReferencer.find(object, rset);
+ } else if(resource != null) {
+ result = EcoreUtil.UsageCrossReferencer.find(object, resource);
+ } else {
+ result = EcoreUtil.UsageCrossReferencer.find(object, tree);
+ }
+ }
+
+ return result;
+ }
+
/**
* <p>
* Runs a code block that broadcasts notification of {@link ResourceSetChangeEvent}s, {@link CDOViewInvalidationEvent}s, etc. to listeners using
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOControlModeParticipant.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOControlModeParticipant.java
new file mode 100644
index 00000000000..8b8ba4b65ae
--- /dev/null
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOControlModeParticipant.java
@@ -0,0 +1,275 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.cdo.internal.core.controlmode;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.spi.cdo.CDOStore;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.common.core.command.IdentityCommand;
+import org.eclipse.papyrus.cdo.internal.core.Activator;
+import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
+import org.eclipse.papyrus.infra.services.controlmode.ControlModeRequest;
+import org.eclipse.papyrus.infra.services.controlmode.commands.AbstractControlCommand;
+import org.eclipse.papyrus.infra.services.controlmode.participants.IControlCommandParticipant;
+import org.eclipse.papyrus.infra.services.controlmode.participants.IControlModeParticipant;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+
+/**
+ * A {@link IControlModeParticipant} for CDO resources that handles replacing references to controlled
+ * elements with proxies that, even in a CDO view, must be resolved by the usual EMF mechanism.
+ */
+public class CDOControlModeParticipant implements IControlCommandParticipant {
+
+ private static final Set<CDOState> TEMPORARY_ID_STATES = EnumSet.of(CDOState.TRANSIENT, CDOState.NEW);
+
+ public CDOControlModeParticipant() {
+ super();
+ }
+
+ public String getID() {
+ return CDOControlModeParticipant.class.getName();
+ }
+
+ public int getPriority() {
+ return 255;
+ }
+
+ public boolean provideControlCommand(ControlModeRequest request) {
+ return CDOUtils.isCDOURI(request.getSourceURI());
+ }
+
+ public ICommand getPreControlCommand(ControlModeRequest request) {
+ return IdentityCommand.INSTANCE;
+ }
+
+ public ICommand getPostControlCommand(ControlModeRequest request) {
+ return new AbstractControlCommand("CDO aspects", Collections.emptyList(), request) {
+
+ private List<Update> updates;
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ final ImmutableList.Builder<Update> updates = ImmutableList.builder();
+
+ for(final EObject object : getAllPersistentSubunitContents(getRequest())) {
+ if(isPersistentObject(object)) {
+ // replace references to the element by a proxy
+ final CDOID proxy = CDOIDUtil.createExternal(CDOProxyManager.createPapyrusCDOURI(object).toString());
+ for(EStructuralFeature.Setting next : getExternalCrossReferences(object)) {
+ updates.add(new Update(next, object, proxy));
+ }
+ }
+ }
+
+ this.updates = updates.build();
+
+ applyUpdates();
+
+ return CommandResult.newOKCommandResult();
+ }
+
+ @Override
+ protected IStatus doUndo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ IStatus result = super.doUndo(monitor, info);
+
+ if(result.isOK()) {
+ // setting proxies in the way we did is not recorded by EMF, so we have to undo it ourselves
+ revertUpdates();
+ }
+
+ return result;
+ }
+
+ @Override
+ protected IStatus doRedo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ IStatus result = super.doRedo(monitor, info);
+
+ if(result.isOK()) {
+ // setting proxies in the way we did is not recorded by EMF, so we have to redo it ourselves
+ applyUpdates();
+ }
+
+ return result;
+ }
+
+ private void applyUpdates() {
+ for(Update next : updates) {
+ next.apply();
+ }
+ }
+
+ private void revertUpdates() {
+ for(ListIterator<Update> iter = updates.listIterator(updates.size()); iter.hasPrevious();) {
+ iter.previous().revert();
+ }
+ }
+ };
+ }
+
+ /**
+ * Get all cross-references to an {@code object} from outside of its own controlled unit.
+ *
+ * @param object
+ * an object being controlled
+ * @return references to it from outside of its (new) controlled unit
+ */
+ Iterable<EStructuralFeature.Setting> getExternalCrossReferences(final EObject object) {
+ return Iterables.filter(CDOUtils.crossReference(object), new Predicate<EStructuralFeature.Setting>() {
+
+ public boolean apply(EStructuralFeature.Setting input) {
+ boolean result = false;
+
+ EStructuralFeature ref = input.getEStructuralFeature();
+ if((ref != EresourcePackage.Literals.CDO_RESOURCE__CONTENTS) && ref.isChangeable() && !ref.isDerived()) {
+ result = !inSameUnit(input.getEObject(), object);
+ }
+
+ return result;
+ }
+ });
+
+ }
+
+ static boolean isPersistentObject(EObject object) {
+ CDOObject cdo = CDOUtils.getCDOObject(object);
+ return (cdo != null) && !TEMPORARY_ID_STATES.contains(cdo.cdoState());
+ }
+
+ static boolean inSameUnit(EObject object, EObject other) {
+ // get the extension-less model URIs
+ URI uri = object.eResource().getURI().trimFileExtension();
+ URI otherURI = other.eResource().getURI().trimFileExtension();
+
+ return uri.equals(otherURI);
+ }
+
+ static Iterable<EObject> getAllPersistentSubunitContents(final ControlModeRequest request) {
+ final URI base = request.getNewURI().trimFileExtension();
+ Iterable<Resource> resources = filter(request.getModelSet().getResources(), new Predicate<Resource>() {
+
+ public boolean apply(Resource input) {
+ return input.getURI().trimFileExtension().equals(base);
+ }
+ });
+
+ Iterable<EObject> result = concat(transform(resources, new Function<Resource, Iterable<EObject>>() {
+
+ public Iterable<EObject> apply(final Resource input) {
+ return new Iterable<EObject>() {
+
+ public Iterator<EObject> iterator() {
+ return EcoreUtil.getAllProperContents(input, false);
+ }
+ };
+ }
+ }));
+
+ result = filter(result, new Predicate<EObject>() {
+
+ public boolean apply(EObject input) {
+ return isPersistentObject(input);
+ }
+ });
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ private static final class Update {
+
+ final EStructuralFeature.Setting setting;
+
+ final EObject originalObject;
+
+ final CDOID proxy;
+
+ final CDOStore store;
+
+ final int index;
+
+ Update(EStructuralFeature.Setting setting, EObject originalObject, CDOID proxy) {
+ this.setting = setting;
+ this.originalObject = originalObject;
+ this.proxy = proxy;
+
+ EStructuralFeature feature = setting.getEStructuralFeature();
+ InternalEObject owner = (InternalEObject)setting.getEObject();
+ CDOObject cdoOwner = CDOUtil.getCDOObject(owner);
+
+ InternalCDOView view = (InternalCDOView)cdoOwner.cdoView();
+ store = view.getStore();
+
+ if(!feature.isMany()) {
+ index = CDOStore.NO_INDEX;
+ } else {
+ index = store.indexOf(owner, feature, originalObject);
+ if(index < 0) {
+ Activator.log.error("Setting does not include the object being replaced by a proxy.", null);
+ }
+ }
+ }
+
+ void apply() {
+ EStructuralFeature feature = setting.getEStructuralFeature();
+
+ if((index >= 0) || !feature.isMany()) {
+ InternalEObject owner = (InternalEObject)setting.getEObject();
+ store.set(owner, feature, index, proxy);
+ }
+ }
+
+ void revert() {
+ EStructuralFeature feature = setting.getEStructuralFeature();
+
+ if(index >= 0 || !feature.isMany()) {
+ InternalEObject owner = (InternalEObject)setting.getEObject();
+ store.set(owner, feature, index, originalObject);
+ }
+ }
+ }
+}
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOProxyManager.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOProxyManager.java
new file mode 100644
index 00000000000..23d4ce3e150
--- /dev/null
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/controlmode/CDOProxyManager.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.cdo.internal.core.controlmode;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.net4j.util.ref.Interner;
+import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
+
+
+/**
+ * A canonical cache of proxy {@link EObject}s by URI.
+ */
+public class CDOProxyManager {
+
+ private static final String URI_SCHEME = CDOURIUtil.PROTOCOL_NAME;
+
+ private final ResourceSet resourceSet;
+
+ private final ProxyInterner proxies = new ProxyInterner();
+
+ public CDOProxyManager(ResourceSet resourceSet) {
+ this.resourceSet = resourceSet;
+ }
+
+ public EObject getProxy(URI proxyURI) {
+ return proxies.intern(proxyURI);
+ }
+
+ protected InternalEObject createProxy(URI uri) {
+ InternalEObject result = null;
+
+ CDOID cdoid = CDOIDUtil.read(uri.fragment());
+ long oid = CDOIDUtil.getLong(cdoid);
+ CDOClassifierRef typeRef = CDOIDUtil.getClassifierRef(cdoid);
+
+ EClassifier resolvedType = typeRef.resolve(resourceSet.getPackageRegistry());
+
+ if(resolvedType instanceof EClass) {
+ EClass actualType = (EClass)resolvedType;
+ result = (InternalEObject)EcoreUtil.create(actualType);
+
+ StringBuilder fragment = new StringBuilder();
+ CDOIDUtil.write(fragment, CDOIDUtil.createLong(oid));
+
+ result.eSetProxyURI(uri.trimFragment().appendFragment(fragment.toString()));
+ }
+
+ return result;
+ }
+
+ public static boolean isCDOProxyURI(URI uri) {
+ boolean result = uri.hasFragment() && URI_SCHEME.equals(uri.scheme());
+
+ if(result) {
+ CDOID oid = CDOIDUtil.read(uri.fragment());
+ result = oid instanceof CDOClassifierRef.Provider;
+ }
+
+ return result;
+ }
+
+ public static String createPapyrusCDOURI(EObject object) {
+ long oid = CDOIDUtil.getLong(CDOUtils.getCDOID(object));
+ CDOClassifierRef typeRef = new CDOClassifierRef(object.eClass());
+ CDOID oidWithTypeRef = CDOIDUtil.createLongWithClassifier(oid, typeRef);
+
+ StringBuilder result = new StringBuilder();
+ result.append(object.eResource().getURI());
+ result.append('#');
+ CDOIDUtil.write(result, oidWithTypeRef);
+
+ return result.toString();
+ }
+
+ //
+ // Nested types
+ //
+
+ private final class ProxyInterner extends Interner<InternalEObject> {
+
+ public synchronized InternalEObject intern(URI proxyURI) {
+ InternalEObject result = null;
+
+ long oid = CDOIDUtil.getLong(CDOIDUtil.read(proxyURI.fragment()));
+ final int hashCode = hashCode(oid);
+
+ for(Entry<InternalEObject> entry = getEntry(hashCode); (entry != null) && (result == null); entry = entry.getNextEntry()) {
+ result = entry.get();
+
+ if((result != null) && getOID(result) != oid) {
+ result = null;
+ }
+ }
+
+ if(result == null) {
+ result = createProxy(proxyURI);
+ addEntry(createEntry(result, hashCode));
+ }
+
+ return result;
+ }
+
+ private long getOID(InternalEObject object) {
+ long result;
+
+ if(object.eIsProxy()) {
+ result = CDOIDUtil.getLong(CDOIDUtil.read(object.eProxyURI().fragment()));
+ } else {
+ result = CDOIDUtil.getLong(CDOUtils.getCDOID(object));
+ }
+
+ return result;
+ }
+
+ @Override
+ protected int hashCode(InternalEObject proxy) {
+ return hashCode(getOID(proxy));
+ }
+
+ int hashCode(long oid) {
+ return (int)(oid & 0xFFFFFFFF);
+ }
+ }
+
+}
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/importer/DependencyAdapter.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/importer/DependencyAdapter.java
index e5f145708c4..6254b035849 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/importer/DependencyAdapter.java
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/importer/DependencyAdapter.java
@@ -20,6 +20,7 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
import org.eclipse.papyrus.infra.core.sashwindows.di.SashWindowsMngr;
@@ -133,8 +134,16 @@ public class DependencyAdapter extends AdapterImpl {
}
boolean isUserModelResource(URI uri) {
- return // config.hasResource(uri) &&
- (uri.isPlatformResource() || uri.isFile() || CDOUtils.isCDOURI(uri)) && !uri.isArchive();
+ ModelSet modelSet = getModelSet();
+ boolean result = (modelSet != null) ? modelSet.isUserModelResource(uri) :
+ // config.hasResource(uri) &&
+ uri.isPlatformResource() || uri.isFile() || CDOUtils.isCDOURI(uri);
+
+ return result && !uri.isArchive();
+ }
+
+ private ModelSet getModelSet() {
+ return CDOUtils.adapt(getResource().getResourceSet(), ModelSet.class);
}
public static boolean isDIResource(Resource resource) {
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/editors/PapyrusCDOEditorInput.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/editors/PapyrusCDOEditorInput.java
index 3849736fcc2..e9751bf156f 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/editors/PapyrusCDOEditorInput.java
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/editors/PapyrusCDOEditorInput.java
@@ -37,6 +37,19 @@ public class PapyrusCDOEditorInput extends URIEditorInput {
public IPersistableElement getPersistable() {
return null;
}
+
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ Object result;
+
+ if(adapter == URI.class) {
+ result = getURI();
+ } else {
+ result = super.getAdapter(adapter);
+ }
+
+ return result;
+ }
/**
* A specialization of the CDO editor input that supports specifying editor pages to open in addition.

Back to the top