Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormvelten2013-03-26 14:22:38 +0000
committermvelten2013-03-26 14:22:38 +0000
commitd77c7c28d6f751df23beec08df03f072bd1ac593 (patch)
treeb73207b7bca136384a0aeaf80ea1c01492c9cfcd /plugins
parent37f2a2d722aecfd6c0e18e484de5a581098369a3 (diff)
downloadorg.eclipse.papyrus-d77c7c28d6f751df23beec08df03f072bd1ac593.tar.gz
org.eclipse.papyrus-d77c7c28d6f751df23beec08df03f072bd1ac593.tar.xz
org.eclipse.papyrus-d77c7c28d6f751df23beec08df03f072bd1ac593.zip
396735: [Read only] corrupted model because of half saved model
https://bugs.eclipse.org/bugs/show_bug.cgi?id=396735 simplify IReadOnlyHandler (remove editing domain in the interface methods since we retrieve it by adapting an editing domain) move most EMFHelper methods in infra.tools handle trackingModification in the modelset in a way similar to the one used in ResourceImpl, setTrackingModification can now be called directly on the ModelSet
Diffstat (limited to 'plugins')
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF3
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java8
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java59
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ProxyModificationTrackingAdapter.java74
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java31
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java19
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java8
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/IReadOnlyHandler.java2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyAdapterFactory.java4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java124
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyOneFileApprover.java4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java5
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/handlers/EnableWriteCommandHandler.java16
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java563
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.tools/META-INF/MANIFEST.MF6
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/EMFHelper.java593
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/PlatformHelper.java21
-rw-r--r--plugins/team/org.eclipse.papyrus.team.svn/src/org/eclipse/papyrus/team/svn/SVNLockHandler.java7
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.profile/src/org/eclipse/papyrus/uml/profile/readonly/AppliedProfileReadOnlyHandler.java16
21 files changed, 863 insertions, 706 deletions
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF b/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
index 7d66b71e8b5..f6995040046 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
@@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.papyrus.infra.core.sasheditor;bundle-version="0.10.0
org.eclipse.gef;bundle-version="3.8.1",
org.eclipse.emf.ecore.xmi;bundle-version="2.8.0",
org.eclipse.emf.workspace;bundle-version="1.5.1",
- com.google.guava;bundle-version="10.0.1"
+ com.google.guava;bundle-version="10.0.1",
+ org.eclipse.papyrus.infra.tools;bundle-version="0.10.0"
Export-Package: org.eclipse.papyrus.infra.core,
org.eclipse.papyrus.infra.core.contentoutline,
org.eclipse.papyrus.infra.core.editor,
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java
index 8a59fbc5e51..5443ae7e690 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java
@@ -36,7 +36,7 @@ public interface IReadOnlyHandler {
* boolean indicating whether any definitively is or they all
* definitively are not read-only
*/
- Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain);
+ Optional<Boolean> anyReadOnly(URI[] uris);
/**
* Attempt to ensure that the resources identified by the given URIs are
@@ -54,7 +54,7 @@ public interface IReadOnlyHandler {
* indicating that I made the resources writable ({@code true}) or
* they cannot be made writable ({@code false})
*/
- Optional<Boolean> makeWritable(URI[] uris, EditingDomain editingDomain);
+ Optional<Boolean> makeWritable(URI[] uris);
/**
* Queries whether an {@code eObject} is individually read-only in a given
@@ -71,7 +71,7 @@ public interface IReadOnlyHandler {
* present} boolean indicating whether it definitively is or is not
* read-only
*/
- Optional<Boolean> isReadOnly(EObject eObject, EditingDomain editingDomain);
+ Optional<Boolean> isReadOnly(EObject eObject);
/**
* Attempt to ensure that the given {@code eObject} is writable.
@@ -88,5 +88,5 @@ public interface IReadOnlyHandler {
* indicating that I made it writable ({@code true}) or it cannot be
* made writable ({@code false})
*/
- Optional<Boolean> makeWritable(EObject eObject, EditingDomain editingDomain);
+ Optional<Boolean> makeWritable(EObject eObject);
}
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java
index fa84506b13e..3dfc11f0381 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java
@@ -33,7 +33,6 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
@@ -47,6 +46,7 @@ import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.EditingDomainManager;
import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel;
+import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
import com.google.common.base.Optional;
@@ -96,6 +96,10 @@ public class ModelSet extends ResourceSetImpl {
*/
protected URI uriWithoutExtension;
+ protected Adapter modificationTrackingAdapter;
+
+ protected IReadOnlyHandler roHandler;
+
/**
*
* Constructor.
@@ -103,12 +107,11 @@ public class ModelSet extends ResourceSetImpl {
*/
public ModelSet() {
registerModel(additional);
+ setTrackingModification(true);
getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true);
getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
getLoadOptions().put(XMIResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
-
- this.eAdapters().add(new ProxyModificationTrackingAdapter());
}
/**
@@ -174,7 +177,7 @@ public class ModelSet extends ResourceSetImpl {
r = super.getResource(uri, loadOnDemand);
} catch (WrappedException e) {
if(ModelUtils.isDegradedModeAllowed(e.getCause())) {
- r = getResource(uri, false);
+ r = super.getResource(uri, false);
if(r == null) {
throw e;
}
@@ -183,6 +186,29 @@ public class ModelSet extends ResourceSetImpl {
return setResourceOptions(r);
}
+ public void setTrackingModification(boolean isTrackingModification) {
+ boolean oldIsTrackingModification = modificationTrackingAdapter != null;
+
+ if(oldIsTrackingModification != isTrackingModification) {
+ if(isTrackingModification) {
+ modificationTrackingAdapter = createModificationTrackingAdapter();
+ this.eAdapters().add(modificationTrackingAdapter);
+ } else {
+ Adapter oldModificationTrackingAdapter = modificationTrackingAdapter;
+ modificationTrackingAdapter = null;
+ this.eAdapters().remove(oldModificationTrackingAdapter);
+ }
+ }
+ }
+
+ protected Adapter createModificationTrackingAdapter() {
+ return new ProxyModificationTrackingAdapter();
+ }
+
+ public boolean isTrackingModification() {
+ return modificationTrackingAdapter != null;
+ }
+
/**
* @deprecated please use {@link #getAssociatedResource(EObject, String, boolean)} instead
*
@@ -238,7 +264,7 @@ public class ModelSet extends ResourceSetImpl {
URI trimmedModelURI = modelResource.getURI().trimFileExtension();
r = getResource(trimmedModelURI.appendFileExtension(associatedResourceExtension), loadOnDemand);
}
- return setResourceOptions(r);
+ return r;
}
/**
@@ -250,7 +276,7 @@ public class ModelSet extends ResourceSetImpl {
* @return the same resource for convenience
*/
protected Resource setResourceOptions(Resource r) {
- if(r != null && !r.isTrackingModification()) {
+ if(r != null && isTrackingModification() && !r.isTrackingModification()) {
r.setTrackingModification(true);
}
return r;
@@ -597,15 +623,12 @@ public class ModelSet extends ResourceSetImpl {
Collection<IModel> modelList = models.values();
monitor.beginTask("Saving resources", modelList.size());
- TransactionalEditingDomain editingDomain = getTransactionalEditingDomain();
- IReadOnlyHandler roHandler = getReadOnlyHandler();
-
- if(roHandler != null) {
+ if(isTrackingModification() && getReadOnlyHandler() != null) {
Set<URI> roUris = new HashSet<URI>();
for(IModel model : modelList) {
Set<URI> uris = model.getModifiedURIs();
for(URI u : uris) {
- Optional<Boolean> res = roHandler.anyReadOnly(new URI[]{ u }, editingDomain);
+ Optional<Boolean> res = getReadOnlyHandler().anyReadOnly(new URI[]{u});
if(res.isPresent() && res.get()) {
roUris.add(u);
}
@@ -613,7 +636,7 @@ public class ModelSet extends ResourceSetImpl {
}
if(!roUris.isEmpty()) {
- Optional<Boolean> authorizeSave = roHandler.makeWritable(roUris.toArray(new URI[roUris.size()]), editingDomain);
+ Optional<Boolean> authorizeSave = getReadOnlyHandler().makeWritable(roUris.toArray(new URI[roUris.size()]));
if(authorizeSave.isPresent() && !authorizeSave.get()) {
monitor.done();
@@ -715,12 +738,14 @@ public class ModelSet extends ResourceSetImpl {
}
public IReadOnlyHandler getReadOnlyHandler() {
- EditingDomain editingDomain = getTransactionalEditingDomain();
- Object handler = Platform.getAdapterManager().getAdapter(editingDomain, IReadOnlyHandler.class);
- if(handler instanceof IReadOnlyHandler) {
- return (IReadOnlyHandler)handler;
+ if(roHandler == null) {
+ EditingDomain editingDomain = getTransactionalEditingDomain();
+ Object handler = PlatformHelper.getAdapter(editingDomain, IReadOnlyHandler.class);
+ if(handler instanceof IReadOnlyHandler) {
+ roHandler = (IReadOnlyHandler)handler;
+ }
}
- return null;
+ return roHandler;
}
/**
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ProxyModificationTrackingAdapter.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ProxyModificationTrackingAdapter.java
index b76ff519bb7..59643e8ee46 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ProxyModificationTrackingAdapter.java
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ProxyModificationTrackingAdapter.java
@@ -15,7 +15,6 @@ package org.eclipse.papyrus.infra.core.resource;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
@@ -25,8 +24,8 @@ import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EContentAdapter;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.papyrus.infra.tools.util.EMFHelper;
/**
* This adapter handles "modified" flag of resources for tricky cases :
@@ -34,6 +33,9 @@ import org.eclipse.emf.ecore.util.EcoreUtil;
* - when there is a change in an URI all the resources containing a proxy
* to the modified resource should be marked as modified
*
+ * - when adding/removing objects from resources they should be marked as modified,
+ * and all the resources containing a proxy too
+ *
* - when doing control/uncontrol operations the resource of the parent object
* should be marked as modified
*
@@ -41,21 +43,21 @@ import org.eclipse.emf.ecore.util.EcoreUtil;
*
*/
public class ProxyModificationTrackingAdapter extends EContentAdapter {
-
+
@Override
protected void setTarget(Resource target) {
basicSetTarget(target);
}
-
+
@Override
protected void unsetTarget(Resource target) {
basicUnsetTarget(target);
}
-
+
@Override
protected void setTarget(EObject target) {
}
-
+
@Override
protected void unsetTarget(EObject target) {
}
@@ -70,26 +72,17 @@ public class ProxyModificationTrackingAdapter extends EContentAdapter {
if (n.getEventType() == Notification.SET && n.getFeatureID(Resource.class) == Resource.RESOURCE__URI) {
r.setModified(true);
- TreeIterator<Object> properContents = EcoreUtil.getAllProperContents(r, true);
+ TreeIterator<Object> properContents = EcoreUtil.getAllProperContents(r, false);
while(properContents.hasNext()) {
Object obj = properContents.next();
if (obj instanceof EObject) {
- EObject eObj = (EObject) obj;
- Collection<Setting> references = getUsages(eObj);
- for (Setting setting : references) {
- EStructuralFeature f = setting.getEStructuralFeature();
- if(setting.getEObject() != null && !f.isDerived() && !f.isTransient()) {
- Resource refResource = setting.getEObject().eResource();
- if(refResource != null) {
- refResource.setModified(true);
- }
- }
- }
+ setReferencingResourcesAsModified((EObject)obj);
}
}
} else {
List objects = new ArrayList();
+
switch(n.getEventType()) {
case Notification.ADD_MANY:
objects = (List<?>)n.getNewValue();
@@ -105,48 +98,31 @@ public class ProxyModificationTrackingAdapter extends EContentAdapter {
break;
}
+ if (!objects.isEmpty()) {
+ r.setModified(true);
+ }
+
for (Object o : objects) {
if (o instanceof EObject) {
- EObject parentEObj = ((EObject)o).eContainer();
- if (parentEObj != null && parentEObj.eResource() != null) {
- parentEObj.eResource().setModified(true);
- }
+ setReferencingResourcesAsModified((EObject)o);
}
}
}
}
-
+
super.notifyChanged(n);
}
- /**
- * Gets the usages.
- *
- * @param source
- * the source
- *
- * @return the usages or null if there is no usages
- */
- public static Collection<Setting> getUsages(EObject source) {
- if(source == null) {
- return Collections.emptyList();
- }
-
- ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(source);
- if(crossReferencer == null) {
- // try to register a cross referencer at the highest level
- crossReferencer = new ECrossReferenceAdapter();
- if(source.eResource() != null) {
- if(source.eResource().getResourceSet() != null) {
- crossReferencer.setTarget(source.eResource().getResourceSet());
- } else {
- crossReferencer.setTarget(source.eResource());
+ protected void setReferencingResourcesAsModified(EObject eObj) {
+ Collection<Setting> references = EMFHelper.getUsages(eObj);
+ for (Setting setting : references) {
+ EStructuralFeature f = setting.getEStructuralFeature();
+ if(setting.getEObject() != null && !f.isDerived() && !f.isTransient()) {
+ Resource refResource = setting.getEObject().eResource();
+ if(refResource != null) {
+ refResource.setModified(true);
}
- } else {
- crossReferencer.setTarget(source);
}
}
-
- return crossReferencer.getInverseReferences(source, true);
}
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java
index bce08fa627a..91c9168e20a 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java
@@ -1,3 +1,16 @@
+/*****************************************************************************
+ * Copyright (c) 2013 Atos
+ *
+ *
+ * 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:
+ * Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
import org.eclipse.emf.common.util.URI;
@@ -10,18 +23,28 @@ import com.google.common.base.Optional;
public abstract class AbstractReadOnlyHandler implements IReadOnlyHandler {
- public Optional<Boolean> isReadOnly(EObject eObject, EditingDomain editingDomain) {
+ private EditingDomain editingDomain;
+
+ public AbstractReadOnlyHandler(EditingDomain editingDomain) {
+ this.editingDomain = editingDomain;
+ }
+
+ public EditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ public Optional<Boolean> isReadOnly(EObject eObject) {
Resource res = eObject.eResource();
if (res != null && res.getURI() != null) {
- return anyReadOnly(new URI[] {res.getURI()}, editingDomain);
+ return anyReadOnly(new URI[] {res.getURI()});
}
return Optional.absent();
}
- public Optional<Boolean> makeWritable(EObject eObject, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(EObject eObject) {
Resource res = eObject.eResource();
if (res != null && res.getURI() != null) {
- return makeWritable(new URI[] {res.getURI()}, editingDomain);
+ return makeWritable(new URI[] {res.getURI()});
}
return Optional.absent();
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java
index 93cd67204cd..3a1d1828572 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java
@@ -1,3 +1,14 @@
+/*****************************************************************************
+ * Copyright (c) 2012 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
import org.eclipse.emf.common.util.URI;
@@ -8,7 +19,11 @@ import com.google.common.base.Optional;
public class EMFReadOnlyHandler extends AbstractReadOnlyHandler {
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
+ EMFReadOnlyHandler(EditingDomain editingDomain) {
+ super(editingDomain);
+ }
+
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
for(URI uri : uris) {
if(!uri.isPlatformResource()) {
return Optional.of(Boolean.TRUE);
@@ -18,7 +33,7 @@ public class EMFReadOnlyHandler extends AbstractReadOnlyHandler {
return Optional.absent();
}
- public Optional<Boolean> makeWritable(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(URI[] uris) {
return Optional.absent(); //We cannot change the read-only status
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java
index 2af579f5c4b..3f8957536bf 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java
@@ -29,7 +29,11 @@ import com.google.common.base.Optional;
public class FSReadOnlyHandler extends AbstractReadOnlyHandler {
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
+ public FSReadOnlyHandler(EditingDomain editingDomain) {
+ super(editingDomain);
+ }
+
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
for(URI uri : uris) {
IFile file = getFile(uri);
@@ -48,7 +52,7 @@ public class FSReadOnlyHandler extends AbstractReadOnlyHandler {
return null;
}
- public Optional<Boolean> makeWritable(final URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(final URI[] uris) {
final AtomicBoolean doEnableWrite = new AtomicBoolean();
Display.getCurrent().syncExec(new Runnable() {
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/IReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/IReadOnlyHandler.java
index 11a8c306139..587ed4f43c8 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/IReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/IReadOnlyHandler.java
@@ -18,7 +18,7 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.domain.EditingDomain;
/**
- * @deprecated Implement the {@link IReadOnlyHandler2} protocol, instead.
+ * @deprecated Implement the {@link org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler} protocol, instead.
*/
@Deprecated
public interface IReadOnlyHandler {
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
index 0d0c14eecb7..996485ee74f 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
@@ -33,13 +33,13 @@ public class PapyrusROTransactionalEditingDomain
@Override
public boolean isReadOnly(Resource resource) {
if (resource != null && resource.getURI() != null) {
- return ReadOnlyManager.getInstance().anyReadOnly(new URI[] {resource.getURI()}, this).get();
+ return ReadOnlyManager.getReadOnlyHandler(this).anyReadOnly(new URI[] {resource.getURI()}).get();
}
return false;
}
public boolean isReadOnly(EObject eObject) {
- return ReadOnlyManager.getInstance().isReadOnly(eObject, this).get();
+ return ReadOnlyManager.getReadOnlyHandler(this).isReadOnly(eObject).get();
}
@Override
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyAdapterFactory.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyAdapterFactory.java
index cd743c02e26..621235a1af2 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyAdapterFactory.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyAdapterFactory.java
@@ -21,8 +21,8 @@ import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
public class ReadOnlyAdapterFactory implements IAdapterFactory {
public Object getAdapter(Object adaptableObject, Class adapterType) {
- if(IReadOnlyHandler.class == adapterType && adaptableObject instanceof PapyrusROTransactionalEditingDomain) {
- return ReadOnlyManager.getInstance();
+ if(IReadOnlyHandler.class == adapterType && adaptableObject instanceof EditingDomain) {
+ return ReadOnlyManager.getReadOnlyHandler((EditingDomain) adaptableObject);
}
return null;
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java
index 7aa5b3f5058..a4752640f10 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java
@@ -14,11 +14,14 @@
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.WeakHashMap;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
@@ -29,20 +32,24 @@ import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
import com.google.common.base.Optional;
-public class ReadOnlyManager implements IReadOnlyHandler {
+@SuppressWarnings("deprecation")
+public class ReadOnlyManager implements IReadOnlyHandler {
- private static class ReadOnlyManagerHolder {
- public static final ReadOnlyManager INSTANCE = new ReadOnlyManager();
- }
+ protected static WeakHashMap<EditingDomain, IReadOnlyHandler> roHandlers = new WeakHashMap<EditingDomain, IReadOnlyHandler>();
- public static ReadOnlyManager getInstance() {
- return ReadOnlyManagerHolder.INSTANCE;
+ public static IReadOnlyHandler getReadOnlyHandler(EditingDomain editingDomain) {
+ IReadOnlyHandler roHandler = roHandlers.get(editingDomain);
+ if (roHandler == null) {
+ roHandler = new ReadOnlyManager(editingDomain);
+ roHandlers.put(editingDomain, roHandler);
+ }
+ return roHandler;
}
protected static class HandlerPriorityPair implements Comparable<HandlerPriorityPair> {
- public Object handler;
+ public Class<?> handlerClass;
public int priority;
@@ -57,9 +64,9 @@ public class ReadOnlyManager implements IReadOnlyHandler {
}
}
- protected final IReadOnlyHandler[] orderedHandlersArray;
+ protected static final Class<?>[] orderedHandlerClassesArray;
- private ReadOnlyManager() {
+ static {
IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.emf.readonly", "readOnlyHandler");
List<HandlerPriorityPair> handlerPriorityPairs = new LinkedList<HandlerPriorityPair>();
@@ -69,7 +76,9 @@ public class ReadOnlyManager implements IReadOnlyHandler {
if("readOnlyHandler".equals(elem.getName())) {
try {
HandlerPriorityPair handlerPriorityPair = new HandlerPriorityPair();
- handlerPriorityPair.handler = elem.createExecutableExtension("class");
+ String className = elem.getAttribute("class");
+ handlerPriorityPair.handlerClass = Platform.getBundle(elem.getContributor().getName()).loadClass(className);
+
handlerPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority"));
String id = elem.getAttribute("id");
if (id != null) {
@@ -98,54 +107,78 @@ public class ReadOnlyManager implements IReadOnlyHandler {
Collections.sort(handlerPriorityPairs);
- orderedHandlersArray = new IReadOnlyHandler[handlerPriorityPairs.size()];
+ orderedHandlerClassesArray = new Class<?>[handlerPriorityPairs.size()];
- for (int i = 0; i < orderedHandlersArray.length; i++) {
- Object handler = handlerPriorityPairs.get(i).handler;
- if (handler instanceof IReadOnlyHandler) {
- orderedHandlersArray[i] = (IReadOnlyHandler) handler;
- } else {
- @SuppressWarnings("deprecation")
- boolean isOldStyle = (handler instanceof org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler);
+ for (int i = 0; i < orderedHandlerClassesArray.length; i++) {
+ orderedHandlerClassesArray[i] = handlerPriorityPairs.get(i).handlerClass;
+ }
+ }
- if (isOldStyle) {
- @SuppressWarnings("deprecation")
- org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler oldStyle = (org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler) handler;
- orderedHandlersArray[i] = new HandlerAdapter(oldStyle);
+
+ protected static IReadOnlyHandler create(final Class<?> handlerClass, EditingDomain editingDomain) {
+ boolean isEditingDomainConstructor = true;
+ Constructor<?> constructor = null;
+ try {
+ constructor = handlerClass.getConstructor(EditingDomain.class);
+ if (constructor == null) {
+ isEditingDomainConstructor = false;
+ constructor = handlerClass.getConstructor();
+ }
+
+ if (IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) {
+ if (isEditingDomainConstructor) {
+ return (IReadOnlyHandler) constructor.newInstance(editingDomain);
} else {
- Activator.log.warn("Unsupported read-only handler type: " + handler);
+ return (IReadOnlyHandler) constructor.newInstance();
}
+ } else if (org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) {
+ return new HandlerAdapter((org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler) constructor.newInstance(), editingDomain) ;
+ }
+ } catch (Exception e) {}
+
+ return null;
+ }
+
+ protected IReadOnlyHandler[] orderedHandlersArray;
+
+ public ReadOnlyManager(EditingDomain editingDomain) {
+ ArrayList<IReadOnlyHandler> handlers = new ArrayList<IReadOnlyHandler>();
+ for (Class<?> roClass : orderedHandlerClassesArray) {
+ IReadOnlyHandler h = create(roClass, editingDomain);
+ if (h != null) {
+ handlers.add(h);
}
}
+ orderedHandlersArray = handlers.toArray(new IReadOnlyHandler[handlers.size()]);
}
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
Optional<Boolean> result = Optional.absent();
for (int i = 0; (i < orderedHandlersArray.length) && !result.isPresent(); i++) {
- result = orderedHandlersArray[i].anyReadOnly(uris, editingDomain);
+ result = orderedHandlersArray[i].anyReadOnly(uris);
}
return result.isPresent() ? result : Optional.of(Boolean.FALSE);
}
- public Optional<Boolean> isReadOnly(EObject eObject, EditingDomain editingDomain) {
+ public Optional<Boolean> isReadOnly(EObject eObject) {
Optional<Boolean> result = Optional.absent();
for (int i = 0; (i < orderedHandlersArray.length) && !result.isPresent(); i++) {
- result = orderedHandlersArray[i].isReadOnly(eObject, editingDomain);
+ result = orderedHandlersArray[i].isReadOnly(eObject);
}
return result.isPresent() ? result : Optional.of(Boolean.FALSE);
}
- public Optional<Boolean> makeWritable(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(URI[] uris) {
Boolean finalResult = true;
for (int i = 0; (i < orderedHandlersArray.length); i++) {
- Optional<Boolean> isRO = orderedHandlersArray[i].anyReadOnly(uris, editingDomain);
+ Optional<Boolean> isRO = orderedHandlersArray[i].anyReadOnly(uris);
if (isRO.isPresent() && isRO.get()) {
- Optional<Boolean> result = orderedHandlersArray[i].makeWritable(uris, editingDomain);
+ Optional<Boolean> result = orderedHandlersArray[i].makeWritable(uris);
// makeWritable should provide an answer since anyReadOnly returned a positive value
// if no answer consider it fails
if (!result.isPresent() || !result.get()) {
@@ -157,13 +190,13 @@ public class ReadOnlyManager implements IReadOnlyHandler {
return Optional.of(finalResult);
}
- public Optional<Boolean> makeWritable(EObject eObject, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(EObject eObject) {
Boolean finalResult = true;
for (int i = 0; (i < orderedHandlersArray.length); i++) {
- Optional<Boolean> isRO = orderedHandlersArray[i].isReadOnly(eObject, editingDomain);
+ Optional<Boolean> isRO = orderedHandlersArray[i].isReadOnly(eObject);
if (isRO.isPresent() && isRO.get()) {
- Optional<Boolean> result = orderedHandlersArray[i].makeWritable(eObject, editingDomain);
+ Optional<Boolean> result = orderedHandlersArray[i].makeWritable(eObject);
// makeWritable should provide an answer since anyReadOnly returned a positive value
// if no answer consider it fails
if (result.isPresent() && !result.get()) {
@@ -177,40 +210,35 @@ public class ReadOnlyManager implements IReadOnlyHandler {
private static final class HandlerAdapter extends AbstractReadOnlyHandler {
- @SuppressWarnings("deprecation")
private final org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler delegate;
- @SuppressWarnings("deprecation")
- HandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler) {
- super();
+ HandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler, EditingDomain editingDomain) {
+ super(editingDomain);
this.delegate = handler;
}
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
// the old API contract is that handlers only return true if they
// know it to be true, because the manager takes the first positive
// answer
- @SuppressWarnings("deprecation")
- boolean delegateResult = delegate.isReadOnly(uris, editingDomain);
+ boolean delegateResult = delegate.isReadOnly(uris, getEditingDomain());
return delegateResult
- ? Optional.of(Boolean.TRUE)
- : Optional.<Boolean> absent();
+ ? Optional.of(Boolean.TRUE)
+ : Optional.<Boolean> absent();
}
- public Optional<Boolean> makeWritable(URI[] uris,
- EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(URI[] uris) {
// the old API contract is that handlers only return false if they
// tried to but could not make the resources writable, because the
// manager takes the first negative answer (this is opposite to the
// isReadOnly logic)
- @SuppressWarnings("deprecation")
- boolean delegateResult = delegate.enableWrite(uris, editingDomain);
+ boolean delegateResult = delegate.enableWrite(uris, getEditingDomain());
return delegateResult
- ? Optional.<Boolean> absent()
- : Optional.of(Boolean.FALSE);
+ ? Optional.<Boolean> absent()
+ : Optional.of(Boolean.FALSE);
}
}
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyOneFileApprover.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyOneFileApprover.java
index c9e474d05b3..b65196de99d 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyOneFileApprover.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyOneFileApprover.java
@@ -88,8 +88,8 @@ public class ReadOnlyOneFileApprover implements IOperationApprover2 {
EditingDomain editingDomain = getEditingDomain(operation);
URI[] filesToCheckForLockArray = filesToCheckForLock.toArray(new URI[filesToCheckForLock.size()]);
- if(ReadOnlyManager.getInstance().anyReadOnly(filesToCheckForLockArray, editingDomain).get()) {
- Optional<Boolean> ok = ReadOnlyManager.getInstance().makeWritable(filesToCheckForLockArray, editingDomain);
+ if(ReadOnlyManager.getReadOnlyHandler(editingDomain).anyReadOnly(filesToCheckForLockArray).get()) {
+ Optional<Boolean> ok = ReadOnlyManager.getReadOnlyHandler(editingDomain).makeWritable(filesToCheckForLockArray);
if(!ok.get()) {
return Status.CANCEL_STATUS;
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java
index 14b71e01f26..5e2dadd3410 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java
@@ -40,9 +40,8 @@ public class ReadOnlyTester extends PropertyTester {
EObject eObject = (EObject) businessObject;
Resource resource = eObject.eResource();
if ((resource != null) && (resource.getResourceSet() != null)) {
- return ReadOnlyManager.getInstance().isReadOnly(eObject,
- WorkspaceEditingDomainFactory.INSTANCE
- .getEditingDomain(resource.getResourceSet())).get();
+ return ReadOnlyManager.getReadOnlyHandler(WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(resource.getResourceSet()))
+ .isReadOnly(eObject).get();
}
}
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/handlers/EnableWriteCommandHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/handlers/EnableWriteCommandHandler.java
index 8b70b05d112..f90850f4ff1 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/handlers/EnableWriteCommandHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/handlers/EnableWriteCommandHandler.java
@@ -1,3 +1,16 @@
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin
+ *
+ *
+ * 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:
+ * Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly.handlers;
import org.eclipse.core.commands.AbstractHandler;
@@ -38,7 +51,8 @@ public class EnableWriteCommandHandler extends AbstractHandler {
associatedUris[i] = URI.createPlatformResourceURI(associatedFiles[i].getFullPath().toString(), true);
}
- ReadOnlyManager.getInstance().makeWritable(associatedUris, WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(rs));
+ ReadOnlyManager.getReadOnlyHandler(WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(rs))
+ .makeWritable(associatedUris);
}
}
return null;
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF
index a0b61c80f37..48e7278020f 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF
@@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.emf.facet.infra.browser.custom;bundle-version="0.2.0",
org.eclipse.emf.facet.infra.facet.core;bundle-version="0.2.0",
org.eclipse.emf.facet.infra.browser.custom.core;bundle-version="0.2.0",
- org.eclipse.papyrus.infra.tools;bundle-version="0.10.0",
+ org.eclipse.papyrus.infra.tools;bundle-version="0.10.0";visibility:=reexport,
org.eclipse.emf.transaction;bundle-version="1.4.0",
org.eclipse.emf.ecore.xmi,
org.eclipse.emf.facet.custom.metamodel;bundle-version="0.2.0",
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java
index c1b180e593c..789af901a69 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java
@@ -14,45 +14,22 @@
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.utils;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EEnum;
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.EStructuralFeature.Setting;
-import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
-import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
-import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.facet.custom.ui.CustomizedContentProviderUtils;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
-import org.eclipse.papyrus.infra.core.resource.ProxyModificationTrackingAdapter;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
-import org.eclipse.papyrus.infra.emf.Activator;
+import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
/**
* A Helper class for manipulating EMF Objects
@@ -60,101 +37,7 @@ import org.eclipse.papyrus.infra.emf.Activator;
* @author Camille Letavernier
*/
//TODO : Check implementations. Most of them are old and don't always match the specification
-public class EMFHelper {
-
- /**
- * Returns the EClass corresponding to the given nsUri and className
- *
- * @param nsUri
- * The NSURI of the EClass' EPackage
- * @param className
- * The EClass' name
- * @return
- * The EClass instance, or null if the EClass couldn't be found
- */
- public static EClass getEClass(final String nsUri, final String className) {
- EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
- if(ePackage == null) {
- Activator.log.warn("Cannot find an EPackage matching the nsURI " + nsUri); //$NON-NLS-1$
- return null;
- }
- return getEClass(ePackage, className);
- }
-
- /**
- * Return the EClass corresponding to the given EPackage and className
- *
- * @param metamodel
- * The EClass' EPackage
- * @param className
- * The EClass' name
- * @return
- * The EClass instance, or null if the EClass couldn't be found
- */
- public static EClass getEClass(final EPackage metamodel, final String className) {
- EClassifier classifier = metamodel.getEClassifier(className);
- if(classifier == null) {
- Activator.log.warn("Classifier " + className + " not found in metamodel " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- }
- if(classifier instanceof EClass) {
- return (EClass)classifier;
- } else {
- Activator.log.warn("Classifier " + className + " in " + metamodel.getName() + " (" + metamodel.getNsURI() + ") is not an EClass"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- }
-
- return null;
- }
-
- /**
- * Tests if an Object is an instance of the given EClass
- *
- * @param element
- * The EObject to test
- * @param className
- * The name of the EClass
- * @param metamodel
- * The EPackage owning the EClass
- * @return
- * True if the EObject is an instance of the EClass, or of one of the EClass' subtypes
- */
- public static boolean isInstance(final EObject element, final String className, final EPackage metamodel) {
-
- EClassifier theClass = metamodel.getEClassifier(className);
-
- if(theClass == null) {
- Activator.log.warn("Class " + className + " not found in Metamodel : " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- return false;
- }
-
- return theClass.isInstance(element);
- }
-
- /**
- * Tests if the given eClass is a Subclass of fromClass
- * Also returns true when eClass == fromClass
- *
- * @param eClass
- * @param fromClass
- * @return
- * true if eClass is a subclass of fromClass
- */
- public static boolean isSubclass(final EClass eClass, final EClass fromClass) {
- //Everything is an EObject
- if(eClass != null && fromClass == EcorePackage.eINSTANCE.getEObject()) {
- return true;
- }
-
- if(eClass == fromClass) {
- return true;
- }
-
- List<EClass> superTypes = eClass.getEAllSuperTypes();
- if(superTypes.contains(fromClass)) {
- return true;
- }
-
- return false;
- }
+public class EMFHelper extends org.eclipse.papyrus.infra.tools.util.EMFHelper {
/**
* Returns the EObject corresponding to the input object
@@ -189,38 +72,6 @@ public class EMFHelper {
}
/**
- * Queries whether an {@code object} is an EMF model element, an instance of
- * some {@link EClass} from an EMF model. This isn't as simple as checking
- * whether the object is an {@link EObject} because there are edge cases
- * where objects are {@code EObject}s but shouldn't be treated as
- * "model content". But, a minimum requirement is that the {@code object} is
- * an {@link EObject}.
- *
- * @param object
- * an object
- * @return whether it is "model content"
- *
- * @see EMFHelper#asEMFModelElement(Object)
- */
- public static boolean isEMFModelElement(Object object) {
- return (object instanceof EObject) && !(object instanceof Resource);
- }
-
- /**
- * Casts an {@code object} as an EMF model element, if appropriate.
- *
- * @param object
- * an object
- * @return the object as an EMF model element, or {@code null} if it is not
- * an EMF model element
- *
- * @see #isEMFModelElement(Object)
- */
- public static EObject asEMFModelElement(Object object) {
- return isEMFModelElement(object) ? (EObject)object : null;
- }
-
- /**
* Retrieve the EditingDomain for the given source object. The object is first
* resolved to an EObject through #getEObject when possible.
*
@@ -252,185 +103,6 @@ public class EMFHelper {
}
/**
- * Return the eClassifier' qualified name. The qualified name is obtained by the concatenation
- * of its package hierarchy with the class name, separated by the given separator
- *
- * @param eClassifier
- * @param separator
- * The separator used between each package name
- * @return
- * The EClassifier' qualified name
- */
- public static String getQualifiedName(final EClassifier eClassifier, final String separator) {
- return getQualifiedName(eClassifier.getEPackage(), separator) + separator + eClassifier.getName();
- }
-
- /**
- * Return the ePackage's qualified name. The qualified name is obtained by the concatenation
- * of its superPackage hierarchy with the ePackage name, separated by the given separator
- *
- * @param ePackage
- * @param separator
- * The separator used between each package name
- * @return
- * The EPackage's qualified name
- */
- public static String getQualifiedName(final EPackage ePackage, final String separator) {
- if(ePackage.getESuperPackage() == null) {
- return ePackage.getName();
- }
- return getQualifiedName(ePackage.getESuperPackage(), separator) + separator + ePackage.getName();
- }
-
-
- /**
- * Loads and returns the first EObject at the given URI.
- * The EObject is loaded in the given resourceSet.
- *
- * @param resourceSet
- * The ResourceSet in which the model will be loaded
- * @param uri
- * The URI describing the location of the model to load
- * @return
- * The first EObject located at the given URI
- * @throws IOException
- * When the URI cannot be loaded
- */
- public static EObject loadEMFModel(ResourceSet resourceSet, final URI uri) throws IOException {
- if(resourceSet == null) {
- resourceSet = new ResourceSetImpl();
- }
- try {
- Resource resource = resourceSet.getResource(uri, true);
- if(resource != null) {
- if(!resource.getContents().isEmpty()) {
- return resource.getContents().get(0);
- }
- }
- } catch (Exception ex) {
- IOException exception = new IOException(ex.toString());
- exception.initCause(ex);
- throw exception;
- }
-
- return null;
- }
-
- /**
- * Return the root package containing the given package, or the package
- * itself if it is already the root
- *
- * @param ePackage
- * @return
- * The Root package
- */
- public static EPackage getRootPackage(final EPackage ePackage) {
- if(ePackage == null) {
- return null;
- }
-
- if(ePackage.getESuperPackage() == null) {
- return ePackage;
- }
- return getRootPackage(ePackage.getESuperPackage());
- }
-
-
- /**
- * Return the list of EClasses that are subtypes
- * of the given EClass
- *
- * @param type
- * @param concreteClassesOnly
- * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
- * @return
- * The list of EClasses implementing or extending the given EClass
- */
- public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly) {
- Set<EClass> result = new LinkedHashSet<EClass>();
- if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) {
- result.add(type);
- }
-
- EPackage ePackage = getRootPackage(type.getEPackage());
- getSubclassesOf(type, ePackage, result, concreteClassesOnly);
- return new LinkedList<EClass>(result);
- }
-
- /**
- * Return the list of EClasses that are sub types
- * of the given EClass
- *
- * @param type
- * @param concreteClassesOnly
- * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
- * @param packagesToBrowse
- * The EPackages in which the EClasses should be retrieved
- * @return
- * The list of EClasses implementing or extending the given EClass
- */
- public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly, Collection<EPackage> packagesToBrowse) {
- Set<EClass> result = new LinkedHashSet<EClass>();
- if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) {
- result.add(type);
- }
-
- for(EPackage ePackage : packagesToBrowse) {
- getSubclassesOf(type, ePackage, result, concreteClassesOnly);
- }
-
- return new LinkedList<EClass>(result);
- }
-
- /**
- * Return the list of EClasses that are sub types of the given EClass
- *
- * @param type
- * @param concreteClassesOnly
- * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
- * @param browseAllRegisteredPackages
- * If true, all registered EPackages will be navigated to retrieve the matching EClasses. Otherwise,
- * only the current EPackage will be used.
- * @return
- * The list of EClasses implementing or extending the given EClass
- */
- public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly, final boolean browseAllRegisteredPackages) {
- //If the current package is a dynamic package, it may not be registered (?). Add it directly
- EPackage currentPackage = getRootPackage(type.getEPackage());
-
- Set<EPackage> allPackages = new LinkedHashSet<EPackage>();
- allPackages.add(currentPackage);
-
- if(browseAllRegisteredPackages) {
- //FIXME // WARNING: This loop will load all EPackages. The first call is expensive.
- Set<String> allUris = new HashSet<String>(EPackage.Registry.INSTANCE.keySet());
-
- for(String nsURI : allUris) {
- allPackages.add(EPackage.Registry.INSTANCE.getEPackage(nsURI));
- }
- }
-
- return getSubclassesOf(type, concreteClassesOnly, allPackages);
- }
-
- private static void getSubclassesOf(final EClass type, final EPackage fromPackage, final Set<EClass> result, final boolean concreteClassesOnly) {
- for(EClassifier classifier : fromPackage.getEClassifiers()) {
- if(classifier instanceof EClass) {
- EClass eClass = (EClass)classifier;
- if(eClass.getEAllSuperTypes().contains(type)) {
- if(!concreteClassesOnly || (!eClass.isAbstract() && !eClass.isInterface())) {
- result.add(eClass);
- }
- }
- }
- }
-
- for(EPackage subPackage : fromPackage.getESubpackages()) {
- getSubclassesOf(type, subPackage, result, concreteClassesOnly);
- }
- }
-
- /**
* Tests if an EObject is read only
* Delegates to the EObject's editing domain if it can be found
*
@@ -455,9 +127,9 @@ public class EMFHelper {
*/
public static boolean isReadOnly(final EObject eObject, final EditingDomain domain) {
if(domain != null) {
- Object handler = Platform.getAdapterManager().getAdapter(domain, IReadOnlyHandler.class);
+ Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
if(handler instanceof IReadOnlyHandler) {
- return ((IReadOnlyHandler)handler).isReadOnly(eObject, domain).get();
+ return ((IReadOnlyHandler)handler).isReadOnly(eObject).get();
}
if(eObject.eResource() != null) {
@@ -482,9 +154,9 @@ public class EMFHelper {
}
if(domain != null && resource.getURI() != null) {
- Object handler = Platform.getAdapterManager().getAdapter(domain, IReadOnlyHandler.class);
+ Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
if(handler instanceof IReadOnlyHandler) {
- return ((IReadOnlyHandler)handler).anyReadOnly(new URI[]{ resource.getURI() }, domain).get();
+ return ((IReadOnlyHandler)handler).anyReadOnly(new URI[]{ resource.getURI() }).get();
}
return domain.isReadOnly(resource);
}
@@ -502,227 +174,4 @@ public class EMFHelper {
return readOnly == null ? false : readOnly;
}
- /**
- * Tests if the given EStructuralFeature is required (ie. should always
- * have a value)
- *
- * A feature is required if at least of one the following conditions if
- * true :
- *
- * - It has a defaultValue
- * - Its lowerBound is at least 1
- * - It is an enumeration (Enumerations always have a default value)
- * - It is a Java primitive type, and is not marked as Unsettable
- *
- * @param feature
- * the feature to test
- * @return
- * true if the feature is required, false otherwise
- */
- public static boolean isRequired(final EStructuralFeature feature) {
- //EEnums are always required, as an EEnum always has a default value
- if(feature.getEType() instanceof EEnum) {
- return true;
- }
-
- //At least one value means it is required
- if(feature.getLowerBound() >= 1) {
- return true;
- }
-
- //Java primitive types cannot have a null value
- //if the feature is not specifically marked as unsettable, then it is required
- if(feature.getEType().getInstanceClass().isPrimitive() && !feature.isUnsettable()) {
- return true;
- }
-
- //If there is a default value, there is always a value
- if(feature.getDefaultValueLiteral() != null) {
- return true;
- }
-
- return false; //The property if not required
- }
-
- /**
- * Returns all objects of type T contained in the resource
- *
- * @param resource
- * @param type
- * @return
- */
- public static <T> Set<T> allInstances(final Resource resource, Class<T> type) {
- TreeIterator<EObject> iterator = resource.getAllContents();
- Set<T> result = new LinkedHashSet<T>();
-
- while(iterator.hasNext()) {
- EObject element = iterator.next();
- if(type.isInstance(element)) {
- result.add(type.cast(element));
- }
- }
-
- return result;
- }
-
- /**
- * Returns all the EPackages and nested EPackages contained in this resource
- *
- * @param resource
- * @return
- */
- public static Set<EPackage> getAllEPackages(final Resource resource) {
- Set<EPackage> result = new LinkedHashSet<EPackage>();
-
- for(EObject rootElement : resource.getContents()) {
- if(rootElement instanceof EPackage) {
- result.add((EPackage)rootElement);
- result.addAll(getAllNestedPackages((EPackage)rootElement));
- }
- }
-
- return result;
- }
-
- /**
- * Returns all packages nested in the given EPackage (recursively). Does not
- * include the base EPackage.
- *
- * @param basePackage
- * @return
- */
- public static Set<EPackage> getAllNestedPackages(EPackage basePackage) {
- Set<EPackage> result = new LinkedHashSet<EPackage>();
-
- for(EPackage nestedPackage : basePackage.getESubpackages()) {
- result.add(nestedPackage);
- result.addAll(getAllNestedPackages(nestedPackage));
- }
-
- return result;
- }
-
- /**
- *
- * @param resource
- * a resource
- *
- * @return
- * the list of the metamodels known by the resource
- */
- public static Set<EPackage> getMetamodels(final Resource resource) {
- Set<EPackage> metamodels = new HashSet<EPackage>();
- if(resource != null) {
- final List<EObject> contents = new ArrayList<EObject>(resource.getContents());
- for(final EObject current : contents) {
- metamodels.add(current.eClass().getEPackage());
- }
- }
- return metamodels;
- }
-
- /**
- *
- * Returns the XMI ID of the given {@link EObject} or <code>null</code> if it cannot be resolved.
- *
- * @param object
- * Object which we seek the XMI ID of.
- * @return <code>object</code>'s XMI ID, <code>null</code> if not applicable.
- */
- public static final String getXMIID(final EObject object) {
- String objectID = null;
- if(object != null && object.eResource() instanceof XMIResource) {
- objectID = ((XMIResource)object.eResource()).getID(object);
- }
- return objectID;
- }
-
-
-
- /**
- * Gets the usages.
- *
- * @param source
- * the source
- *
- * @return the usages or null if there is no usages
- */
- public static Collection<Setting> getUsages(EObject source) {
- // the functional code is defined in core because we need it in infra.core
- // but infra.core can't depend on infra.emf (circular dependency)
- return ProxyModificationTrackingAdapter.getUsages(source);
- }
-
-
- /**
- * <pre>
- * Test if the used element is referenced by other elements than the known
- * referencer (except its container). It ignores references from an other meta-model.
- * </pre>
- *
- * @param usedObject
- * the used object
- * @param knownReferencer
- * the known referencer
- * @return true if the known referencer is the only referencer.
- */
- public static boolean isOnlyUsage(EObject usedObject, EObject knownReferencer) {
- boolean isUsed = false;
- EPackage mmPackage = usedObject.eClass().getEPackage();
-
- // Retrieve the list of elements referencing the usedObject.
- Set<EObject> crossReferences = new HashSet<EObject>();
- for(Setting setting : getUsages(usedObject)) {
- EObject eObj = setting.getEObject();
- if(eObj.eClass().getEPackage().equals(mmPackage)) {
- crossReferences.add(eObj);
- }
- }
-
- // Remove the container of used object.
- crossReferences.remove(usedObject.eContainer());
- // Remove the knownReferencer from the list of references.
- crossReferences.remove(knownReferencer);
-
- // If no referencer remains in the list, the known element is the only
- // usage.
- if(crossReferences.isEmpty()) {
- isUsed = true;
- }
-
- return isUsed;
- }
-
- /**
- *
- * @param superType
- * an eclassifier
- * @param subType
- * another eClassifier
- * @return
- * <code>true</code> if the 2nd {@link EClassifier} is a subtype of the first one
- */
- public static boolean isSuperType(final EClassifier superType, final EClassifier subType) {
- if(superType == subType) {
- return true;
- }
-
- if(superType instanceof EClass && subType instanceof EClass) {
- // special case because isSuperTypeOf doesn't handle it
- if(superType == EcorePackage.eINSTANCE.getEObject()) {
- return true;
- }
-
- EClass superTypeEClass = (EClass)superType;
- EClass subTypeEClass = (EClass)subType;
- return superTypeEClass.isSuperTypeOf(subTypeEClass);
- }
-
- //manage EDtataType
- if(superType == EcorePackage.eINSTANCE.getEDataType() && subType instanceof EDataType) {
- return true;
- }
-
- return false;
- }
}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.tools/META-INF/MANIFEST.MF b/plugins/infra/org.eclipse.papyrus.infra.tools/META-INF/MANIFEST.MF
index 04fac5a3597..b475a062a06 100644
--- a/plugins/infra/org.eclipse.papyrus.infra.tools/META-INF/MANIFEST.MF
+++ b/plugins/infra/org.eclipse.papyrus.infra.tools/META-INF/MANIFEST.MF
@@ -2,7 +2,11 @@ Manifest-Version: 1.0
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.papyrus.infra.core.log;bundle-version="0.10.0",
- org.eclipse.core.databinding;bundle-version="1.4.1"
+ org.eclipse.core.databinding;bundle-version="1.4.1",
+ org.eclipse.emf.common;bundle-version="2.9.0",
+ org.eclipse.emf.ecore;bundle-version="2.9.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.9.0",
+ org.eclipse.emf.edit;bundle-version="2.9.0"
Export-Package: org.eclipse.papyrus.infra.tools.databinding,
org.eclipse.papyrus.infra.tools.util
Bundle-Vendor: Eclipse Modeling Project
diff --git a/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/EMFHelper.java b/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/EMFHelper.java
new file mode 100644
index 00000000000..a4cdb708847
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/EMFHelper.java
@@ -0,0 +1,593 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - filter out EObjects that are Resources (CDO)
+ * Christian W. Damus (CEA) - Support read-only state at object level (CDO)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.tools.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.papyrus.infra.tools.Activator;
+
+
+public class EMFHelper {
+
+ /**
+ * Returns the EClass corresponding to the given nsUri and className
+ *
+ * @param nsUri
+ * The NSURI of the EClass' EPackage
+ * @param className
+ * The EClass' name
+ * @return
+ * The EClass instance, or null if the EClass couldn't be found
+ */
+ public static EClass getEClass(final String nsUri, final String className) {
+ EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if(ePackage == null) {
+ Activator.log.warn("Cannot find an EPackage matching the nsURI " + nsUri); //$NON-NLS-1$
+ return null;
+ }
+ return getEClass(ePackage, className);
+ }
+
+ /**
+ * Return the EClass corresponding to the given EPackage and className
+ *
+ * @param metamodel
+ * The EClass' EPackage
+ * @param className
+ * The EClass' name
+ * @return
+ * The EClass instance, or null if the EClass couldn't be found
+ */
+ public static EClass getEClass(final EPackage metamodel, final String className) {
+ EClassifier classifier = metamodel.getEClassifier(className);
+ if(classifier == null) {
+ Activator.log.warn("Classifier " + className + " not found in metamodel " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ if(classifier instanceof EClass) {
+ return (EClass)classifier;
+ } else {
+ Activator.log.warn("Classifier " + className + " in " + metamodel.getName() + " (" + metamodel.getNsURI() + ") is not an EClass"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ return null;
+ }
+
+ /**
+ * Tests if an Object is an instance of the given EClass
+ *
+ * @param element
+ * The EObject to test
+ * @param className
+ * The name of the EClass
+ * @param metamodel
+ * The EPackage owning the EClass
+ * @return
+ * True if the EObject is an instance of the EClass, or of one of the EClass' subtypes
+ */
+ public static boolean isInstance(final EObject element, final String className, final EPackage metamodel) {
+
+ EClassifier theClass = metamodel.getEClassifier(className);
+
+ if(theClass == null) {
+ Activator.log.warn("Class " + className + " not found in Metamodel : " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ return false;
+ }
+
+ return theClass.isInstance(element);
+ }
+
+ /**
+ * Tests if the given eClass is a Subclass of fromClass
+ * Also returns true when eClass == fromClass
+ *
+ * @param eClass
+ * @param fromClass
+ * @return
+ * true if eClass is a subclass of fromClass
+ */
+ public static boolean isSubclass(final EClass eClass, final EClass fromClass) {
+ //Everything is an EObject
+ if(eClass != null && fromClass == EcorePackage.eINSTANCE.getEObject()) {
+ return true;
+ }
+
+ if(eClass == fromClass) {
+ return true;
+ }
+
+ List<EClass> superTypes = eClass.getEAllSuperTypes();
+ if(superTypes.contains(fromClass)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Queries whether an {@code object} is an EMF model element, an instance of
+ * some {@link EClass} from an EMF model. This isn't as simple as checking
+ * whether the object is an {@link EObject} because there are edge cases
+ * where objects are {@code EObject}s but shouldn't be treated as
+ * "model content". But, a minimum requirement is that the {@code object} is
+ * an {@link EObject}.
+ *
+ * @param object
+ * an object
+ * @return whether it is "model content"
+ *
+ * @see EMFHelper#asEMFModelElement(Object)
+ */
+ public static boolean isEMFModelElement(Object object) {
+ return (object instanceof EObject) && !(object instanceof Resource);
+ }
+
+ /**
+ * Casts an {@code object} as an EMF model element, if appropriate.
+ *
+ * @param object
+ * an object
+ * @return the object as an EMF model element, or {@code null} if it is not
+ * an EMF model element
+ *
+ * @see #isEMFModelElement(Object)
+ */
+ public static EObject asEMFModelElement(Object object) {
+ return isEMFModelElement(object) ? (EObject)object : null;
+ }
+
+ /**
+ * Return the eClassifier' qualified name. The qualified name is obtained by the concatenation
+ * of its package hierarchy with the class name, separated by the given separator
+ *
+ * @param eClassifier
+ * @param separator
+ * The separator used between each package name
+ * @return
+ * The EClassifier' qualified name
+ */
+ public static String getQualifiedName(final EClassifier eClassifier, final String separator) {
+ return getQualifiedName(eClassifier.getEPackage(), separator) + separator + eClassifier.getName();
+ }
+
+ /**
+ * Return the ePackage's qualified name. The qualified name is obtained by the concatenation
+ * of its superPackage hierarchy with the ePackage name, separated by the given separator
+ *
+ * @param ePackage
+ * @param separator
+ * The separator used between each package name
+ * @return
+ * The EPackage's qualified name
+ */
+ public static String getQualifiedName(final EPackage ePackage, final String separator) {
+ if(ePackage.getESuperPackage() == null) {
+ return ePackage.getName();
+ }
+ return getQualifiedName(ePackage.getESuperPackage(), separator) + separator + ePackage.getName();
+ }
+
+
+ /**
+ * Loads and returns the first EObject at the given URI.
+ * The EObject is loaded in the given resourceSet.
+ *
+ * @param resourceSet
+ * The ResourceSet in which the model will be loaded
+ * @param uri
+ * The URI describing the location of the model to load
+ * @return
+ * The first EObject located at the given URI
+ * @throws IOException
+ * When the URI cannot be loaded
+ */
+ public static EObject loadEMFModel(ResourceSet resourceSet, final URI uri) throws IOException {
+ if(resourceSet == null) {
+ resourceSet = new ResourceSetImpl();
+ }
+ try {
+ Resource resource = resourceSet.getResource(uri, true);
+ if(resource != null) {
+ if(!resource.getContents().isEmpty()) {
+ return resource.getContents().get(0);
+ }
+ }
+ } catch (Exception ex) {
+ IOException exception = new IOException(ex.toString());
+ exception.initCause(ex);
+ throw exception;
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the root package containing the given package, or the package
+ * itself if it is already the root
+ *
+ * @param ePackage
+ * @return
+ * The Root package
+ */
+ public static EPackage getRootPackage(final EPackage ePackage) {
+ if(ePackage == null) {
+ return null;
+ }
+
+ if(ePackage.getESuperPackage() == null) {
+ return ePackage;
+ }
+ return getRootPackage(ePackage.getESuperPackage());
+ }
+
+
+ /**
+ * Return the list of EClasses that are subtypes
+ * of the given EClass
+ *
+ * @param type
+ * @param concreteClassesOnly
+ * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
+ * @return
+ * The list of EClasses implementing or extending the given EClass
+ */
+ public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly) {
+ Set<EClass> result = new LinkedHashSet<EClass>();
+ if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) {
+ result.add(type);
+ }
+
+ EPackage ePackage = getRootPackage(type.getEPackage());
+ getSubclassesOf(type, ePackage, result, concreteClassesOnly);
+ return new LinkedList<EClass>(result);
+ }
+
+ /**
+ * Return the list of EClasses that are sub types
+ * of the given EClass
+ *
+ * @param type
+ * @param concreteClassesOnly
+ * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
+ * @param packagesToBrowse
+ * The EPackages in which the EClasses should be retrieved
+ * @return
+ * The list of EClasses implementing or extending the given EClass
+ */
+ public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly, Collection<EPackage> packagesToBrowse) {
+ Set<EClass> result = new LinkedHashSet<EClass>();
+ if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) {
+ result.add(type);
+ }
+
+ for(EPackage ePackage : packagesToBrowse) {
+ getSubclassesOf(type, ePackage, result, concreteClassesOnly);
+ }
+
+ return new LinkedList<EClass>(result);
+ }
+
+ /**
+ * Return the list of EClasses that are sub types of the given EClass
+ *
+ * @param type
+ * @param concreteClassesOnly
+ * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
+ * @param browseAllRegisteredPackages
+ * If true, all registered EPackages will be navigated to retrieve the matching EClasses. Otherwise,
+ * only the current EPackage will be used.
+ * @return
+ * The list of EClasses implementing or extending the given EClass
+ */
+ public static List<EClass> getSubclassesOf(final EClass type, final boolean concreteClassesOnly, final boolean browseAllRegisteredPackages) {
+ //If the current package is a dynamic package, it may not be registered (?). Add it directly
+ EPackage currentPackage = getRootPackage(type.getEPackage());
+
+ Set<EPackage> allPackages = new LinkedHashSet<EPackage>();
+ allPackages.add(currentPackage);
+
+ if(browseAllRegisteredPackages) {
+ //FIXME // WARNING: This loop will load all EPackages. The first call is expensive.
+ Set<String> allUris = new HashSet<String>(EPackage.Registry.INSTANCE.keySet());
+
+ for(String nsURI : allUris) {
+ allPackages.add(EPackage.Registry.INSTANCE.getEPackage(nsURI));
+ }
+ }
+
+ return getSubclassesOf(type, concreteClassesOnly, allPackages);
+ }
+
+ private static void getSubclassesOf(final EClass type, final EPackage fromPackage, final Set<EClass> result, final boolean concreteClassesOnly) {
+ for(EClassifier classifier : fromPackage.getEClassifiers()) {
+ if(classifier instanceof EClass) {
+ EClass eClass = (EClass)classifier;
+ if(eClass.getEAllSuperTypes().contains(type)) {
+ if(!concreteClassesOnly || (!eClass.isAbstract() && !eClass.isInterface())) {
+ result.add(eClass);
+ }
+ }
+ }
+ }
+
+ for(EPackage subPackage : fromPackage.getESubpackages()) {
+ getSubclassesOf(type, subPackage, result, concreteClassesOnly);
+ }
+ }
+
+ /**
+ * Tests if the given EStructuralFeature is required (ie. should always
+ * have a value)
+ *
+ * A feature is required if at least of one the following conditions if
+ * true :
+ *
+ * - It has a defaultValue
+ * - Its lowerBound is at least 1
+ * - It is an enumeration (Enumerations always have a default value)
+ * - It is a Java primitive type, and is not marked as Unsettable
+ *
+ * @param feature
+ * the feature to test
+ * @return
+ * true if the feature is required, false otherwise
+ */
+ public static boolean isRequired(final EStructuralFeature feature) {
+ //EEnums are always required, as an EEnum always has a default value
+ if(feature.getEType() instanceof EEnum) {
+ return true;
+ }
+
+ //At least one value means it is required
+ if(feature.getLowerBound() >= 1) {
+ return true;
+ }
+
+ //Java primitive types cannot have a null value
+ //if the feature is not specifically marked as unsettable, then it is required
+ if(feature.getEType().getInstanceClass().isPrimitive() && !feature.isUnsettable()) {
+ return true;
+ }
+
+ //If there is a default value, there is always a value
+ if(feature.getDefaultValueLiteral() != null) {
+ return true;
+ }
+
+ return false; //The property if not required
+ }
+
+ /**
+ * Returns all objects of type T contained in the resource
+ *
+ * @param resource
+ * @param type
+ * @return
+ */
+ public static <T> Set<T> allInstances(final Resource resource, Class<T> type) {
+ TreeIterator<EObject> iterator = resource.getAllContents();
+ Set<T> result = new LinkedHashSet<T>();
+
+ while(iterator.hasNext()) {
+ EObject element = iterator.next();
+ if(type.isInstance(element)) {
+ result.add(type.cast(element));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns all the EPackages and nested EPackages contained in this resource
+ *
+ * @param resource
+ * @return
+ */
+ public static Set<EPackage> getAllEPackages(final Resource resource) {
+ Set<EPackage> result = new LinkedHashSet<EPackage>();
+
+ for(EObject rootElement : resource.getContents()) {
+ if(rootElement instanceof EPackage) {
+ result.add((EPackage)rootElement);
+ result.addAll(getAllNestedPackages((EPackage)rootElement));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns all packages nested in the given EPackage (recursively). Does not
+ * include the base EPackage.
+ *
+ * @param basePackage
+ * @return
+ */
+ public static Set<EPackage> getAllNestedPackages(EPackage basePackage) {
+ Set<EPackage> result = new LinkedHashSet<EPackage>();
+
+ for(EPackage nestedPackage : basePackage.getESubpackages()) {
+ result.add(nestedPackage);
+ result.addAll(getAllNestedPackages(nestedPackage));
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param resource
+ * a resource
+ *
+ * @return
+ * the list of the metamodels known by the resource
+ */
+ public static Set<EPackage> getMetamodels(final Resource resource) {
+ Set<EPackage> metamodels = new HashSet<EPackage>();
+ if(resource != null) {
+ final List<EObject> contents = new ArrayList<EObject>(resource.getContents());
+ for(final EObject current : contents) {
+ metamodels.add(current.eClass().getEPackage());
+ }
+ }
+ return metamodels;
+ }
+
+ /**
+ *
+ * Returns the XMI ID of the given {@link EObject} or <code>null</code> if it cannot be resolved.
+ *
+ * @param object
+ * Object which we seek the XMI ID of.
+ * @return <code>object</code>'s XMI ID, <code>null</code> if not applicable.
+ */
+ public static String getXMIID(final EObject object) {
+ String objectID = null;
+ if(object != null && object.eResource() instanceof XMIResource) {
+ objectID = ((XMIResource)object.eResource()).getID(object);
+ }
+ return objectID;
+ }
+
+
+
+ /**
+ * Gets the usages.
+ *
+ * @param source
+ * the source
+ *
+ * @return the usages or null if there is no usages
+ */
+ public static Collection<Setting> getUsages(EObject source) {
+ if(source == null) {
+ return Collections.emptyList();
+ }
+
+ ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(source);
+ if(crossReferencer == null) {
+ // try to register a cross referencer at the highest level
+ crossReferencer = new ECrossReferenceAdapter();
+ if(source.eResource() != null) {
+ if(source.eResource().getResourceSet() != null) {
+ crossReferencer.setTarget(source.eResource().getResourceSet());
+ } else {
+ crossReferencer.setTarget(source.eResource());
+ }
+ } else {
+ crossReferencer.setTarget(source);
+ }
+ }
+
+ return crossReferencer.getInverseReferences(source, true);
+ }
+
+
+ /**
+ * <pre>
+ * Test if the used element is referenced by other elements than the known
+ * referencer (except its container). It ignores references from an other meta-model.
+ * </pre>
+ *
+ * @param usedObject
+ * the used object
+ * @param knownReferencer
+ * the known referencer
+ * @return true if the known referencer is the only referencer.
+ */
+ public static boolean isOnlyUsage(EObject usedObject, EObject knownReferencer) {
+ boolean isUsed = false;
+ EPackage mmPackage = usedObject.eClass().getEPackage();
+
+ // Retrieve the list of elements referencing the usedObject.
+ Set<EObject> crossReferences = new HashSet<EObject>();
+ for(Setting setting : getUsages(usedObject)) {
+ EObject eObj = setting.getEObject();
+ if(eObj.eClass().getEPackage().equals(mmPackage)) {
+ crossReferences.add(eObj);
+ }
+ }
+
+ // Remove the container of used object.
+ crossReferences.remove(usedObject.eContainer());
+ // Remove the knownReferencer from the list of references.
+ crossReferences.remove(knownReferencer);
+
+ // If no referencer remains in the list, the known element is the only
+ // usage.
+ if(crossReferences.isEmpty()) {
+ isUsed = true;
+ }
+
+ return isUsed;
+ }
+
+ /**
+ *
+ * @param superType
+ * an eclassifier
+ * @param subType
+ * another eClassifier
+ * @return
+ * <code>true</code> if the 2nd {@link EClassifier} is a subtype of the first one
+ */
+ public static boolean isSuperType(final EClassifier superType, final EClassifier subType) {
+ if(superType == subType) {
+ return true;
+ }
+
+ if(superType instanceof EClass && subType instanceof EClass) {
+ // special case because isSuperTypeOf doesn't handle it
+ if(superType == EcorePackage.eINSTANCE.getEObject()) {
+ return true;
+ }
+
+ EClass superTypeEClass = (EClass)superType;
+ EClass subTypeEClass = (EClass)subType;
+ return superTypeEClass.isSuperTypeOf(subTypeEClass);
+ }
+
+ //manage EDtataType
+ if(superType == EcorePackage.eINSTANCE.getEDataType() && subType instanceof EDataType) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/PlatformHelper.java b/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/PlatformHelper.java
new file mode 100644
index 00000000000..afb2db195ee
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.tools/src/org/eclipse/papyrus/infra/tools/util/PlatformHelper.java
@@ -0,0 +1,21 @@
+package org.eclipse.papyrus.infra.tools.util;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+
+
+public class PlatformHelper {
+
+ public static Object getAdapter(Object adaptable, Class<?> adapterType) {
+ if (adapterType.isInstance(adaptable)) {
+ return adaptable;
+ }
+ if (adaptable instanceof IAdaptable) {
+ Object result = ((IAdaptable)adaptable).getAdapter(adapterType);
+ if (result != null) {
+ return result;
+ }
+ }
+ return Platform.getAdapterManager().getAdapter(adaptable, adapterType);
+ }
+}
diff --git a/plugins/team/org.eclipse.papyrus.team.svn/src/org/eclipse/papyrus/team/svn/SVNLockHandler.java b/plugins/team/org.eclipse.papyrus.team.svn/src/org/eclipse/papyrus/team/svn/SVNLockHandler.java
index fd82e369c43..f40ac894de2 100644
--- a/plugins/team/org.eclipse.papyrus.team.svn/src/org/eclipse/papyrus/team/svn/SVNLockHandler.java
+++ b/plugins/team/org.eclipse.papyrus.team.svn/src/org/eclipse/papyrus/team/svn/SVNLockHandler.java
@@ -36,14 +36,15 @@ public class SVNLockHandler extends AbstractReadOnlyHandler {
FileModificationValidator validator = null;
- public SVNLockHandler() {
+ public SVNLockHandler(EditingDomain editingDomain) {
+ super(editingDomain);
try {
validator = new SVNTeamModificationValidator();
} catch (NoClassDefFoundError e) {
}
}
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
if (validator != null) {
IResource[] needsLockResources = FileUtility.filterResources(getIFiles(uris), IStateFilter.SF_NEEDS_LOCK, IResource.DEPTH_ZERO);
@@ -57,7 +58,7 @@ public class SVNLockHandler extends AbstractReadOnlyHandler {
return Optional.absent();
}
- public Optional<Boolean> makeWritable(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(URI[] uris) {
if (validator != null) {
IStatus result = validator.validateEdit(getIFiles(uris), FileModificationValidationContext.VALIDATE_PROMPT);
return Optional.of(result.isOK());
diff --git a/plugins/uml/org.eclipse.papyrus.uml.profile/src/org/eclipse/papyrus/uml/profile/readonly/AppliedProfileReadOnlyHandler.java b/plugins/uml/org.eclipse.papyrus.uml.profile/src/org/eclipse/papyrus/uml/profile/readonly/AppliedProfileReadOnlyHandler.java
index 698f02c8d2d..6c13310f271 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.profile/src/org/eclipse/papyrus/uml/profile/readonly/AppliedProfileReadOnlyHandler.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.profile/src/org/eclipse/papyrus/uml/profile/readonly/AppliedProfileReadOnlyHandler.java
@@ -24,11 +24,15 @@ import com.google.common.base.Optional;
public class AppliedProfileReadOnlyHandler extends AbstractReadOnlyHandler {
- public Optional<Boolean> anyReadOnly(URI[] uris, EditingDomain editingDomain) {
- if(editingDomain != null) {
+ public AppliedProfileReadOnlyHandler(EditingDomain editingDomain) {
+ super(editingDomain);
+ }
+
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
+ if(getEditingDomain() != null) {
Resource mainUmlResource = null;
- if(editingDomain.getResourceSet() instanceof ModelSet) {
- UmlModel umlModel = (UmlModel)((ModelSet)editingDomain.getResourceSet()).getModel(UmlModel.MODEL_ID);
+ if(getEditingDomain().getResourceSet() instanceof ModelSet) {
+ UmlModel umlModel = (UmlModel)((ModelSet)getEditingDomain().getResourceSet()).getModel(UmlModel.MODEL_ID);
if(umlModel == null) {
return Optional.absent();
}
@@ -36,7 +40,7 @@ public class AppliedProfileReadOnlyHandler extends AbstractReadOnlyHandler {
}
for(URI uri : uris) {
- Resource resource = editingDomain.getResourceSet().getResource(uri, false);
+ Resource resource = getEditingDomain().getResourceSet().getResource(uri, false);
if(isProfileResource(resource) && mainUmlResource != resource) {
return Optional.of(Boolean.TRUE);
}
@@ -58,7 +62,7 @@ public class AppliedProfileReadOnlyHandler extends AbstractReadOnlyHandler {
return false;
}
- public Optional<Boolean> makeWritable(URI[] uris, EditingDomain editingDomain) {
+ public Optional<Boolean> makeWritable(URI[] uris) {
return Optional.absent(); //Applied profiles should remain read-only
}

Back to the top