Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-03-07 03:51:57 +0000
committerChristian W. Damus2014-03-07 21:45:37 +0000
commitb97cafff961eaf540abf031e047b42674b7b68b0 (patch)
treec64e3461846de625a3e0363d11b9ca33584762a2 /plugins/infra
parent44365ad33949a1212cca04b234d6ecf1317cce67 (diff)
downloadorg.eclipse.papyrus-b97cafff961eaf540abf031e047b42674b7b68b0.tar.gz
org.eclipse.papyrus-b97cafff961eaf540abf031e047b42674b7b68b0.tar.xz
org.eclipse.papyrus-b97cafff961eaf540abf031e047b42674b7b68b0.zip
429826: [Read-Only] Orthogonal Classification of Read-Only Concerns
https://bugs.eclipse.org/bugs/show_bug.cgi?id=429826 Add classification of orthogonal axes of concern to the API for read-only queries.
Diffstat (limited to 'plugins/infra')
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java20
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler2.java120
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ReadOnlyAxis.java67
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/AbstractReadOnlyHandler.java36
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/EMFReadOnlyHandler.java25
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/FSReadOnlyHandler.java45
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java25
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java185
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyTester.java25
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReferencedModelReadOnlyHandler.java141
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/SashModelReadOnlyHandler.java17
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java113
12 files changed, 607 insertions, 212 deletions
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 5443ae7e690..8c69dd47aa2 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
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2011, 2013 Atos Origin, CEA, and others.
+ * Copyright (c) 2011, 2014 Atos Origin, CEA, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -9,7 +9,7 @@
*
* Contributors:
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
- * Christian W. Damus (CEA)
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.core.resource;
@@ -20,6 +20,14 @@ import org.eclipse.emf.edit.domain.EditingDomain;
import com.google.common.base.Optional;
+/**
+ * A pluggable handler determining whether a resource is "read only" (not writable). Implementations
+ * of this interface, if they do not implement {@link IReadOnlyHandler2}, implicitly determine
+ * read-only-ness according to the {@linkplain ReadOnlyAxis#PERMISSION permission axis}.
+ *
+ * @see IReadOnlyHandler2
+ * @see ReadOnlyAxis#PERMISSION
+ */
public interface IReadOnlyHandler {
/**
@@ -28,8 +36,6 @@ public interface IReadOnlyHandler {
*
* @param uris
* the URIs about which read-only-ness is to be determined
- * @param editingDomain
- * the domain in the context of which editing is being done
*
* @return {@link Optional#absent() absent} if I do not know whether any of
* the URIs is read-only or a {@link Optional#isPresent() present}
@@ -45,8 +51,6 @@ public interface IReadOnlyHandler {
* @param uris
* the URIs of resources to make writable (not all are
* necessarily read-only)
- * @param editingDomain
- * the domain in the context of which editing is being done
*
* @return {@link Optional#absent() absent} if I do not know how to make
* these resources writable and the next provider should be given a
@@ -63,8 +67,6 @@ public interface IReadOnlyHandler {
*
* @param eObject
* an element in some model resource
- * @param editingDomain
- * the contextual editing domain
*
* @return {@link Optional#absent() absent} if I do not know whether the
* {@code eObject} is read-only or a {@link Optional#isPresent()
@@ -79,8 +81,6 @@ public interface IReadOnlyHandler {
* @param eObject
* a {@linkplain #isReadOnly(EObject, EditingDomain) read-only}
* element in some model resource
- * @param editingDomain
- * the domain in the context of which editing is being done
*
* @return {@link Optional#absent() absent} if I do not know how to make
* this object writable and the next provider should be given a
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler2.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler2.java
index 8c266376d1c..21b34aa2fb8 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler2.java
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler2.java
@@ -12,34 +12,144 @@
*/
package org.eclipse.papyrus.infra.core.resource;
+import java.util.Set;
+
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.domain.EditingDomain;
import com.google.common.base.Optional;
/**
- * An optional extension interface for {@linkplain IReadOnlyHandler read-only handlers} that support making files writable.
+ * An optional extension interface for {@linkplain IReadOnlyHandler read-only handlers} that support making files writable
+ * and pertain to other concerns than simply {@linkplain ReadOnlyAxis#PERMISSION permissions}.
+ *
+ * @see ReadOnlyAxis
*/
public interface IReadOnlyHandler2 extends IReadOnlyHandler {
/**
- * Queries whether I can make the resources indicated by the given URIs writable.
+ * A shortcut for {@link #anyReadOnly(Set, URI[])} with a singleton set
+ * of {@linkplain ReadOnlyAxis#PERMISSION}.
+ *
+ * @deprecated Use {@linkplain #anyReadOnly(Set, URI[])}, instead.
+ */
+ Optional<Boolean> anyReadOnly(URI[] uris);
+
+ /**
+ * A shortcut for {@link #makeWritable(Set, URI[])} with a singleton set
+ * of {@linkplain ReadOnlyAxis#PERMISSION}.
+ *
+ * @deprecated Use {@linkplain #makeWritable(Set, URI[])}, instead.
+ */
+ Optional<Boolean> makeWritable(URI[] uris);
+
+ /**
+ * A shortcut for {@link #isReadOnly(Set, EObject)} with a singleton set
+ * of {@linkplain ReadOnlyAxis#PERMISSION}.
+ *
+ * @deprecated Use {@linkplain #isReadOnly(Set, EObject)}, instead.
+ */
+ Optional<Boolean> isReadOnly(EObject eObject);
+
+ /**
+ * A shortcut for {@link #makeWritable(Set, EObject)} with a singleton set
+ * of {@linkplain ReadOnlyAxis#PERMISSION}.
+ *
+ * @deprecated Use {@linkplain #makeWritable(Set, EObject)}, instead.
+ */
+ Optional<Boolean> makeWritable(EObject eObject);
+
+ /**
+ * Queries whether any of the resources identified by the given URIs is
+ * read-only in any of the given {@code axes} of concern.
+ *
+ * @param axes
+ * the set of axes on which to query read-only state
+ * @param uris
+ * the URIs about which read-only-ness is to be determined
+ *
+ * @return {@link Optional#absent() absent} if I do not know whether any of
+ * the URIs is read-only or a {@link Optional#isPresent() present}
+ * boolean indicating whether any definitively is or they all
+ * definitively are not read-only
+ */
+ Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris);
+
+ /**
+ * Attempt to ensure that the resources identified by the given URIs are
+ * writable in any of the given {@code axes} of concern.
+ *
+ * @param axes
+ * the set of axes on which to query read-only state
+ * @param uris
+ * the URIs of resources to make writable (not all are
+ * necessarily read-only)
+ *
+ * @return {@link Optional#absent() absent} if I do not know how to make
+ * these resources writable and the next provider should be given a
+ * chance, or a {@link Optional#isPresent() present} boolean
+ * indicating that I made the resources writable ({@code true}) or
+ * they cannot be made writable ({@code false})
+ */
+ Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris);
+
+ /**
+ * Queries whether an {@code eObject} is individually read-only in a given
+ * editing domain, if it is in a resource that supports object-level
+ * read/write permissions in any of the given {@code axes} of concern.
+ *
+ * @param axes
+ * the set of axes on which to query read-only state
+ * @param eObject
+ * an element in some model resource
+ *
+ * @return {@link Optional#absent() absent} if I do not know whether the
+ * {@code eObject} is read-only or a {@link Optional#isPresent()
+ * present} boolean indicating whether it definitively is or is not
+ * read-only
+ */
+ Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject);
+
+ /**
+ * Attempt to ensure that the given {@code eObject} is writable in any of the given {@code axes} of concern.
+ *
+ * @param axes
+ * the set of axes on which to query read-only state
+ * @param eObject
+ * a {@linkplain #isReadOnly(EObject, EditingDomain) read-only}
+ * element in some model resource
+ *
+ * @return {@link Optional#absent() absent} if I do not know how to make
+ * this object writable and the next provider should be given a
+ * chance, or a {@link Optional#isPresent() present} boolean
+ * indicating that I made it writable ({@code true}) or it cannot be
+ * made writable ({@code false})
+ */
+ Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject);
+
+ /**
+ * Queries whether I can make the resources indicated by the given URIs writable in any of the given {@code axes} of concern.
*
+ * @param axes
+ * the set of axes on which to query read-only state
* @param uris
* indicate a set of resources (presumed read-only)
* @return a {@linkplain Optional#isPresent() present} boolean indicating either that I can make the resources writable or that I handle these
* kinds of resources and they cannot be made writable; an {@linkplain Optional#absent() absent} value, otherwise
*/
- Optional<Boolean> canMakeWritable(URI[] uris);
+ Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris);
/**
- * Queries whether I can make the given {@code object} writable.
+ * Queries whether I can make the given {@code object} writable in any of the given {@code axes} of concern.
*
+ * @param axes
+ * the set of axes on which to query read-only state
* @param object
* a model element (presumed read-only)
* @return a {@linkplain Optional#isPresent() present} boolean indicating either that I can make the {@code object writable or that I handle its
* kind of resources and it cannot be made writable; an {@linkplain Optional#absent() absent} value, otherwise
*/
- Optional<Boolean> canMakeWritable(EObject object);
+ Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, EObject object);
}
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ReadOnlyAxis.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ReadOnlyAxis.java
new file mode 100644
index 00000000000..c404a86a125
--- /dev/null
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ReadOnlyAxis.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 CEA and others.
+ *
+ * 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.infra.core.resource;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+
+/**
+ * The "read-only-ness" of resources can be partitioned according to a number of othogonal concerns, or <em>axes</em>.
+ * Being orthogonal, these concerns are independent, although any particular resource may be considered as read-only
+ * according to more than one of these simultaneously (or one or none at all).
+ */
+public enum ReadOnlyAxis {
+ /**
+ * The most basic and obvious axis is the permission, or access control, concern. This typically maps to
+ * permissions in the storage layer (file system, database, network, etc.).
+ */
+ PERMISSION,
+
+ /**
+ * Some resources may be considered as read-only for discretionary reasons: there is no obstacle of {@linkplain #PERMISSION permissions}, but
+ * merely that the user is discouraged from making modifications
+ * to such a resource or its contents as a matter of policy.
+ */
+ DISCRETION;
+
+ private static final Set<ReadOnlyAxis> ANY_AXIS = Sets.immutableEnumSet(EnumSet.allOf(ReadOnlyAxis.class));
+
+ private static final Set<ReadOnlyAxis> PERMISSION_AXES = Collections.singleton(PERMISSION);
+
+ private static final Set<ReadOnlyAxis> DISCRETION_AXES = Collections.singleton(DISCRETION);
+
+ /**
+ * The set of axes for queries pertaining to any axis. That is to say, the complete set of all axes.
+ */
+ public static Set<ReadOnlyAxis> anyAxis() {
+ return ANY_AXIS;
+ }
+
+ /**
+ * The set of axes for queries pertaining to permission. That is to say, the singleton containing {@link #PERMISSION}.
+ */
+ public static Set<ReadOnlyAxis> permissionAxes() {
+ return PERMISSION_AXES;
+ }
+
+ /**
+ * The set of axes for queries pertaining to discretion. That is to say, the singleton containing {@link #DISCRETION}.
+ */
+ public static Set<ReadOnlyAxis> discretionAxes() {
+ return DISCRETION_AXES;
+ }
+}
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 e378e43c022..2b7cfa8e57b 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
@@ -10,15 +10,21 @@
* Contributors:
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import static org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis.permissionAxes;
+
+import java.util.Set;
+
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import com.google.common.base.Optional;
@@ -34,18 +40,38 @@ public abstract class AbstractReadOnlyHandler implements IReadOnlyHandler2 {
return editingDomain;
}
+ @Deprecated
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
+ return anyReadOnly(permissionAxes(), uris);
+ }
+
+ @Deprecated
public Optional<Boolean> isReadOnly(EObject eObject) {
+ return isReadOnly(permissionAxes(), eObject);
+ }
+
+ public Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject) {
Resource res = eObject.eResource();
if (res != null && res.getURI() != null) {
- return anyReadOnly(new URI[] {res.getURI()});
+ return anyReadOnly(axes, new URI[] {res.getURI()});
}
return Optional.absent();
}
+ @Deprecated
+ public Optional<Boolean> makeWritable(URI[] uris) {
+ return makeWritable(permissionAxes(), uris);
+ }
+
+ @Deprecated
public Optional<Boolean> makeWritable(EObject eObject) {
+ return makeWritable(permissionAxes(), eObject);
+ }
+
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject) {
Resource res = eObject.eResource();
if (res != null && res.getURI() != null) {
- return makeWritable(new URI[] {res.getURI()});
+ return makeWritable(axes, new URI[] {res.getURI()});
}
return Optional.absent();
}
@@ -53,14 +79,14 @@ public abstract class AbstractReadOnlyHandler implements IReadOnlyHandler2 {
/**
* By default, we do not handle writability of these resources.
*/
- public Optional<Boolean> canMakeWritable(URI[] uris) {
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
return Optional.absent();
}
- public Optional<Boolean> canMakeWritable(EObject object) {
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, EObject object) {
Resource res = object.eResource();
if((res != null) && (res.getURI() != null)) {
- return canMakeWritable(new URI[]{ res.getURI() });
+ return canMakeWritable(axes, 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 c30bbe21ba6..88d2d3732cc 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,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2012 CEA LIST.
+ * Copyright (c) 2012, 2014 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,32 +8,41 @@
*
* Contributors:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 429826
+ *
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import java.util.Set;
+
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import com.google.common.base.Optional;
-
+/**
+ * The EMF read-only handler is permission-based.
+ */
public class EMFReadOnlyHandler extends AbstractReadOnlyHandler {
public EMFReadOnlyHandler(EditingDomain editingDomain) {
super(editingDomain);
}
- public Optional<Boolean> anyReadOnly(URI[] uris) {
- for(URI uri : uris) {
- if(!uri.isPlatformResource()) {
- return Optional.of(Boolean.TRUE);
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
+ if(axes.contains(ReadOnlyAxis.PERMISSION)) {
+ for(URI uri : uris) {
+ if(!uri.isPlatformResource()) {
+ return Optional.of(Boolean.TRUE);
+ }
}
}
-
+
return Optional.absent();
}
- public Optional<Boolean> makeWritable(URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, 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 f035f201423..11ff14694ca 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
@@ -10,12 +10,14 @@
* Contributors:
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IFile;
@@ -26,25 +28,30 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.swt.widgets.Display;
import com.google.common.base.Optional;
+/**
+ * The filesystem read-only handler is permission-based.
+ */
public class FSReadOnlyHandler extends AbstractReadOnlyHandler {
public FSReadOnlyHandler(EditingDomain editingDomain) {
super(editingDomain);
}
- public Optional<Boolean> anyReadOnly(URI[] uris) {
- for(URI uri : uris) {
-
- IFile file = getFile(uri);
- if(file != null && file.isReadOnly()) {
- return Optional.of(Boolean.TRUE);
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
+ if (axes.contains(ReadOnlyAxis.PERMISSION)) {
+ for(URI uri : uris) {
+ IFile file = getFile(uri);
+ if(file != null && file.isReadOnly()) {
+ return Optional.of(Boolean.TRUE);
+ }
}
}
-
+
return Optional.absent();
}
@@ -55,7 +62,11 @@ public class FSReadOnlyHandler extends AbstractReadOnlyHandler {
return null;
}
- public Optional<Boolean> makeWritable(final URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, final URI[] uris) {
+ if (!axes.contains(ReadOnlyAxis.PERMISSION)) {
+ return Optional.absent();
+ }
+
final AtomicBoolean doEnableWrite = new AtomicBoolean();
// We can't make a file writable if it already is (there are read-only handlers that treat files that
@@ -105,18 +116,20 @@ public class FSReadOnlyHandler extends AbstractReadOnlyHandler {
* I can make workspace resources writable.
*/
@Override
- public Optional<Boolean> canMakeWritable(URI[] uris) {
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
Optional<Boolean> result = Optional.absent();
- for(int i = 0; (!result.isPresent() || result.get()) && (i < uris.length); i++) {
- if(uris[i].isPlatformResource()) {
- result = Optional.of(true);
- } else if(uris[i].isFile()) {
- // We don't make non-workspace (external but local) files writable
- result = Optional.of(false);
+ if(axes.contains(ReadOnlyAxis.PERMISSION)) {
+ for(int i = 0; (!result.isPresent() || result.get()) && (i < uris.length); i++) {
+ if(uris[i].isPlatformResource()) {
+ result = Optional.of(true);
+ } else if(uris[i].isFile()) {
+ // We don't make non-workspace (external but local) files writable
+ result = Optional.of(false);
+ }
}
}
-
+
return result;
}
}
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 0d178b8c6be..d5ee21d8470 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
@@ -11,6 +11,7 @@
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - Support object-level read/write controls (CDO)
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
@@ -37,9 +38,9 @@ import org.eclipse.emf.transaction.TransactionalCommandStack;
import org.eclipse.emf.transaction.impl.InternalTransaction;
import org.eclipse.emf.transaction.impl.TransactionChangeRecorder;
import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
import org.eclipse.papyrus.infra.core.resource.IRollbackStatus;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.papyrus.infra.core.resource.RollbackStatus;
import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
import org.eclipse.papyrus.infra.onefile.model.PapyrusModelHelper;
@@ -54,14 +55,14 @@ public class PapyrusROTransactionalEditingDomain extends TransactionalEditingDom
@Override
public boolean isReadOnly(Resource resource) {
- if(resource != null && resource.getURI() != null) {
- return ReadOnlyManager.getReadOnlyHandler(this).anyReadOnly(new URI[]{ resource.getURI() }).get();
+ if((resource != null) && (resource.getURI() != null)) {
+ return ReadOnlyManager.getReadOnlyHandler(this).anyReadOnly(ReadOnlyAxis.anyAxis(), new URI[]{ resource.getURI() }).get();
}
return false;
}
public boolean isReadOnly(EObject eObject) {
- return ReadOnlyManager.getReadOnlyHandler(this).isReadOnly(eObject).get();
+ return ReadOnlyManager.getReadOnlyHandler(this).isReadOnly(ReadOnlyAxis.anyAxis(), eObject).get();
}
@Override
@@ -131,15 +132,13 @@ public class PapyrusROTransactionalEditingDomain extends TransactionalEditingDom
protected boolean makeWritable(Resource resource) {
URI[] uris = getCompositeModelURIs(resource.getURI());
- IReadOnlyHandler handler = ReadOnlyManager.getReadOnlyHandler(this);
+ IReadOnlyHandler2 handler = ReadOnlyManager.getReadOnlyHandler(this);
- if(handler instanceof IReadOnlyHandler2) {
- if(!((IReadOnlyHandler2)handler).canMakeWritable(uris).or(false)) {
- return false;
- }
+ if(!handler.canMakeWritable(ReadOnlyAxis.anyAxis(), uris).or(false)) {
+ return false;
}
- return handler.makeWritable(uris).get();
+ return handler.makeWritable(ReadOnlyAxis.anyAxis(), uris).get();
}
protected boolean makeWritable(EObject object) {
@@ -151,12 +150,12 @@ public class PapyrusROTransactionalEditingDomain extends TransactionalEditingDom
if(uri.isPlatformResource()) {
result = makeWritable(object.eResource());
} else {
- IReadOnlyHandler handler = ReadOnlyManager.getReadOnlyHandler(this);
+ IReadOnlyHandler2 handler = ReadOnlyManager.getReadOnlyHandler(this);
- if((handler instanceof IReadOnlyHandler2) && !((IReadOnlyHandler2)handler).canMakeWritable(object).or(false)) {
+ if(!handler.canMakeWritable(ReadOnlyAxis.anyAxis(), object).or(false)) {
result = false;
} else {
- result = handler.makeWritable(object).get();
+ result = handler.makeWritable(ReadOnlyAxis.anyAxis(), object).get();
}
}
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 f09bd0e39df..0b3c5330ccd 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
@@ -11,10 +11,13 @@
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - support non-IFile resources and object-level permissions (CDO)
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import static org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis.permissionAxes;
+
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
@@ -22,6 +25,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
@@ -30,11 +34,11 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import com.google.common.base.Optional;
-@SuppressWarnings("deprecation")
public class ReadOnlyManager implements IReadOnlyHandler2 {
//Using a WeakHashMap leads to a Memory Leak, because only the Key is weak.
@@ -42,10 +46,10 @@ public class ReadOnlyManager implements IReadOnlyHandler2 {
//which prevents garbage collection of the EditingDomain
//Workaround: when the (Papyrus) editing domain is disposed, it removes itself from this map
//This won't work for non-papyrus editing domains, which are still leaked (But we do not use non-papyrus editing domains which this ReadOnlyManager)
- protected static Map<EditingDomain, IReadOnlyHandler> roHandlers = new HashMap<EditingDomain, IReadOnlyHandler>();
+ protected static Map<EditingDomain, IReadOnlyHandler2> roHandlers = new HashMap<EditingDomain, IReadOnlyHandler2>();
- public static IReadOnlyHandler getReadOnlyHandler(EditingDomain editingDomain) {
- IReadOnlyHandler roHandler = roHandlers.get(editingDomain);
+ public static IReadOnlyHandler2 getReadOnlyHandler(EditingDomain editingDomain) {
+ IReadOnlyHandler2 roHandler = roHandlers.get(editingDomain);
if(roHandler == null) {
roHandler = new ReadOnlyManager(editingDomain);
roHandlers.put(editingDomain, roHandler);
@@ -121,7 +125,8 @@ public class ReadOnlyManager implements IReadOnlyHandler2 {
}
- protected static IReadOnlyHandler create(final Class<?> handlerClass, EditingDomain editingDomain) {
+ @SuppressWarnings("deprecation")
+ protected static IReadOnlyHandler2 create(final Class<?> handlerClass, EditingDomain editingDomain) {
boolean isEditingDomainConstructor = true;
Constructor<?> constructor = null;
try {
@@ -131,14 +136,20 @@ public class ReadOnlyManager implements IReadOnlyHandler2 {
constructor = handlerClass.getConstructor();
}
- if(IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) {
+ if(IReadOnlyHandler2.class.isAssignableFrom(constructor.getDeclaringClass())) {
+ if(isEditingDomainConstructor) {
+ return (IReadOnlyHandler2)constructor.newInstance(editingDomain);
+ } else {
+ return (IReadOnlyHandler2)constructor.newInstance();
+ }
+ } else if(IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) {
if(isEditingDomainConstructor) {
- return (IReadOnlyHandler)constructor.newInstance(editingDomain);
+ return new NewStyleHandlerAdapter((IReadOnlyHandler)constructor.newInstance(editingDomain), editingDomain);
} else {
- return (IReadOnlyHandler)constructor.newInstance();
+ return new NewStyleHandlerAdapter((IReadOnlyHandler)constructor.newInstance(), editingDomain);
}
} 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);
+ return new OldStyleHandlerAdapter((org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler)constructor.newInstance(), editingDomain);
}
} catch (Exception e) {
}
@@ -146,49 +157,49 @@ public class ReadOnlyManager implements IReadOnlyHandler2 {
return null;
}
- protected IReadOnlyHandler[] orderedHandlersArray;
+ protected IReadOnlyHandler2[] orderedHandlersArray;
public ReadOnlyManager(EditingDomain editingDomain) {
- ArrayList<IReadOnlyHandler> handlers = new ArrayList<IReadOnlyHandler>();
+ ArrayList<IReadOnlyHandler2> handlers = new ArrayList<IReadOnlyHandler2>();
for(Class<?> roClass : orderedHandlerClassesArray) {
- IReadOnlyHandler h = create(roClass, editingDomain);
+ IReadOnlyHandler2 h = create(roClass, editingDomain);
if(h != null) {
handlers.add(h);
}
}
- orderedHandlersArray = handlers.toArray(new IReadOnlyHandler[handlers.size()]);
+ orderedHandlersArray = handlers.toArray(new IReadOnlyHandler2[handlers.size()]);
}
- public Optional<Boolean> anyReadOnly(URI[] uris) {
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
Optional<Boolean> result = Optional.absent();
for(int i = 0; (i < orderedHandlersArray.length) && !result.isPresent(); i++) {
- result = orderedHandlersArray[i].anyReadOnly(uris);
+ result = orderedHandlersArray[i].anyReadOnly(axes, uris);
}
return result.isPresent() ? result : Optional.of(Boolean.FALSE);
}
- public Optional<Boolean> isReadOnly(EObject eObject) {
+ public Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject) {
Optional<Boolean> result = Optional.absent();
for(int i = 0; (i < orderedHandlersArray.length) && !result.isPresent(); i++) {
- result = orderedHandlersArray[i].isReadOnly(eObject);
+ result = orderedHandlersArray[i].isReadOnly(axes, eObject);
}
return result.isPresent() ? result : Optional.of(Boolean.FALSE);
}
- public Optional<Boolean> makeWritable(URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
Boolean finalResult = true;
for(int i = 0; (i < orderedHandlersArray.length); i++) {
- Optional<Boolean> isRO = orderedHandlersArray[i].anyReadOnly(uris);
- if(isRO.isPresent() && isRO.get()) {
- Optional<Boolean> result = orderedHandlersArray[i].makeWritable(uris);
+ Optional<Boolean> isRO = orderedHandlersArray[i].anyReadOnly(axes, uris);
+ if(isRO.or(Boolean.FALSE)) {
+ Optional<Boolean> result = orderedHandlersArray[i].makeWritable(axes, uris);
// makeWritable should provide an answer since anyReadOnly returned a positive value.
// If no answer consider it a failure
- if(!result.isPresent() || !result.get()) {
+ if(!result.or(Boolean.FALSE)) {
finalResult = false;
break;
}
@@ -198,91 +209,147 @@ public class ReadOnlyManager implements IReadOnlyHandler2 {
return Optional.of(finalResult);
}
- public Optional<Boolean> makeWritable(EObject eObject) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject) {
Boolean finalResult = true;
for(int i = 0; (i < orderedHandlersArray.length); i++) {
- Optional<Boolean> isRO = orderedHandlersArray[i].isReadOnly(eObject);
- if(isRO.isPresent() && isRO.get()) {
- Optional<Boolean> result = orderedHandlersArray[i].makeWritable(eObject);
+ Optional<Boolean> isRO = orderedHandlersArray[i].isReadOnly(axes, eObject);
+ if(isRO.or(Boolean.FALSE)) {
+ Optional<Boolean> result = orderedHandlersArray[i].makeWritable(axes, eObject);
// makeWritable should provide an answer since anyReadOnly returned a positive value
- // if no answer consider it fails
- if(result.isPresent() && !result.get()) {
+ // if no answer consider it a failure
+ if(!result.or(Boolean.FALSE)) {
finalResult = false;
+ break;
}
}
}
return Optional.of(finalResult);
}
-
- public Optional<Boolean> canMakeWritable(URI[] uris) {
+
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
Boolean result = false;
for(int i = 0; (i < orderedHandlersArray.length); i++) {
- if(orderedHandlersArray[i] instanceof IReadOnlyHandler2) {
- IReadOnlyHandler2 h2 = (IReadOnlyHandler2)orderedHandlersArray[i];
- if (h2.anyReadOnly(uris).or(false)) {
- // Only ask a handler about making writable what it considers to be read-only
- Optional<Boolean> canMakeWritable = h2.canMakeWritable(uris);
- if(canMakeWritable.isPresent()) {
- result = canMakeWritable.get();
- break;
- }
+ if(orderedHandlersArray[i].anyReadOnly(axes, uris).or(false)) {
+ // Only ask a handler about making writable what it considers to be read-only
+ Optional<Boolean> canMakeWritable = orderedHandlersArray[i].canMakeWritable(axes, uris);
+ if(canMakeWritable.isPresent()) {
+ result = canMakeWritable.get();
+ break;
}
}
}
return Optional.of(result);
}
-
- public Optional<Boolean> canMakeWritable(EObject object) {
+
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, EObject object) {
Boolean result = false;
for(int i = 0; (i < orderedHandlersArray.length); i++) {
- if(orderedHandlersArray[i] instanceof IReadOnlyHandler2) {
- IReadOnlyHandler2 h2 = (IReadOnlyHandler2)orderedHandlersArray[i];
- if (h2.isReadOnly(object).or(false)) {
- // Only ask a handler about making writable what it considers to be read-only
- Optional<Boolean> canMakeWritable = h2.canMakeWritable(object);
- if(canMakeWritable.isPresent()) {
- result = canMakeWritable.get();
- break;
- }
+ if(orderedHandlersArray[i].isReadOnly(axes, object).or(false)) {
+ // Only ask a handler about making writable what it considers to be read-only
+ Optional<Boolean> canMakeWritable = orderedHandlersArray[i].canMakeWritable(axes, object);
+ if(canMakeWritable.isPresent()) {
+ result = canMakeWritable.get();
+ break;
}
}
}
return Optional.of(result);
}
+
+ //
+ // Deprecated API
+ //
+
+ @Deprecated
+ public Optional<Boolean> anyReadOnly(URI[] uris) {
+ return anyReadOnly(permissionAxes(), uris);
+ }
+
+ @Deprecated
+ public Optional<Boolean> isReadOnly(EObject eObject) {
+ return isReadOnly(permissionAxes(), eObject);
+ }
+
+ @Deprecated
+ public Optional<Boolean> makeWritable(URI[] uris) {
+ return makeWritable(permissionAxes(), uris);
+ }
+
+ @Deprecated
+ public Optional<Boolean> makeWritable(EObject eObject) {
+ return makeWritable(permissionAxes(), eObject);
+ }
+
+ //
+ // Legacy adapters
+ //
- private static final class HandlerAdapter extends AbstractReadOnlyHandler {
+ @SuppressWarnings("deprecation")
+ private static final class OldStyleHandlerAdapter extends AbstractReadOnlyHandler {
private final org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler delegate;
- HandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler, EditingDomain editingDomain) {
+ OldStyleHandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler, EditingDomain editingDomain) {
super(editingDomain);
this.delegate = handler;
}
- public Optional<Boolean> anyReadOnly(URI[] uris) {
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, 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
- boolean delegateResult = delegate.isReadOnly(uris, getEditingDomain());
+ // answer. Moreover, they only dealt with permission-based read-only-ness
+ boolean delegateResult = axes.contains(ReadOnlyAxis.PERMISSION) && delegate.isReadOnly(uris, getEditingDomain());
return delegateResult ? Optional.of(Boolean.TRUE) : Optional.<Boolean> absent();
}
- public Optional<Boolean> makeWritable(URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, 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)
- boolean delegateResult = delegate.enableWrite(uris, getEditingDomain());
+ // isReadOnly logic). Moreover, they only dealt with permission-based
+ // read-only-ness
+ boolean delegateResult = axes.contains(ReadOnlyAxis.PERMISSION) && delegate.enableWrite(uris, getEditingDomain());
return delegateResult ? Optional.<Boolean> absent() : Optional.of(Boolean.FALSE);
}
}
-} \ No newline at end of file
+
+ private static final class NewStyleHandlerAdapter extends AbstractReadOnlyHandler {
+
+ private final IReadOnlyHandler delegate;
+
+ NewStyleHandlerAdapter(IReadOnlyHandler handler, EditingDomain editingDomain) {
+ super(editingDomain);
+
+ this.delegate = handler;
+ }
+
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
+ // these handlers implicitly only deal with permission-based read-only-ness
+ return !axes.contains(ReadOnlyAxis.PERMISSION) ? Optional.<Boolean> absent() : delegate.anyReadOnly(uris);
+ }
+
+ @Override
+ public Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject) {
+ return !axes.contains(ReadOnlyAxis.PERMISSION) ? Optional.<Boolean> absent() : delegate.isReadOnly(eObject);
+ }
+
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
+ // these handlers implicitly only deal with permission-based read-only-ness
+ return !axes.contains(ReadOnlyAxis.PERMISSION) ? Optional.<Boolean> absent() : delegate.makeWritable(uris);
+ }
+
+ @Override
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject) {
+ return !axes.contains(ReadOnlyAxis.PERMISSION) ? Optional.<Boolean> absent() : delegate.makeWritable(eObject);
+ }
+ }
+}
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 eaef7d7c325..a680d8df1eb 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
@@ -11,6 +11,7 @@
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - Support read-only state at object level (CDO)
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
@@ -19,12 +20,12 @@ import java.util.Iterator;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory;
+import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.papyrus.infra.emf.utils.BusinessModelResolver;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
import com.google.common.base.Objects;
@@ -59,9 +60,9 @@ public class ReadOnlyTester extends PropertyTester {
if(businessObject instanceof EObject) {
EObject eObject = (EObject)businessObject;
- Resource resource = eObject.eResource();
- if((resource != null) && (resource.getResourceSet() != null)) {
- return Objects.equal(ReadOnlyManager.getReadOnlyHandler(WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(resource.getResourceSet())).isReadOnly(eObject).get(), expectedValue);
+ EditingDomain domain = EMFHelper.resolveEditingDomain(eObject);
+ if(domain != null) {
+ return Objects.equal(ReadOnlyManager.getReadOnlyHandler(domain).isReadOnly(ReadOnlyAxis.anyAxis(), eObject).or(false), expectedValue);
}
}
}
@@ -75,11 +76,13 @@ public class ReadOnlyTester extends PropertyTester {
if(businessObject instanceof EObject) {
EObject eObject = (EObject)businessObject;
- Resource resource = eObject.eResource();
- if((resource != null) && (resource.getResourceSet() != null)) {
- IReadOnlyHandler handler = ReadOnlyManager.getReadOnlyHandler(WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(resource.getResourceSet()));
- boolean isAlreadyOrCanMakeWritable = !handler.isReadOnly(eObject).or(false) //
- || ((handler instanceof IReadOnlyHandler2) && ((IReadOnlyHandler2)handler).canMakeWritable(eObject).or(false));
+ EditingDomain domain = EMFHelper.resolveEditingDomain(eObject);
+ if(domain != null) {
+ IReadOnlyHandler2 handler = ReadOnlyManager.getReadOnlyHandler(domain);
+
+ boolean isAlreadyOrCanMakeWritable = handler.isReadOnly(ReadOnlyAxis.anyAxis(), eObject).or(false) //
+ || handler.canMakeWritable(ReadOnlyAxis.anyAxis(), eObject).or(false);
+
return Objects.equal(isAlreadyOrCanMakeWritable, expectedValue);
}
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReferencedModelReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReferencedModelReadOnlyHandler.java
index 6d909461712..77a54e9e939 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReferencedModelReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReferencedModelReadOnlyHandler.java
@@ -22,8 +22,9 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
+import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.papyrus.infra.emf.readonly.internal.messages.Messages;
import org.eclipse.swt.widgets.Display;
@@ -32,8 +33,8 @@ import com.google.common.base.Optional;
/**
- * A {@linkplain IReadOnlyHandler read-only handler} for objects in referenced models, which by default shouldn't be editable in the context of the
- * model referencing them.
+ * A {@linkplain IReadOnlyHandler2 read-only handler} for objects in referenced models, which by default shouldn't be editable in the context of the
+ * model referencing them. This is a discretion-based handler.
*/
public class ReferencedModelReadOnlyHandler extends AbstractReadOnlyHandler {
@@ -68,95 +69,101 @@ public class ReferencedModelReadOnlyHandler extends AbstractReadOnlyHandler {
this.interactive = interactive;
}
- public Optional<Boolean> anyReadOnly(URI[] uris) {
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
Optional<Boolean> result = Optional.absent();
- final URIConverter converter = getEditingDomain().getResourceSet().getURIConverter();
-
- for(int i = 0; i < uris.length; i++) {
- // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
- URI next = uris[i].trimFragment();
+ if(axes.contains(ReadOnlyAxis.DISCRETION)) {
+ final URIConverter converter = getEditingDomain().getResourceSet().getURIConverter();
- // If the resource doesn't exist, then it can't be opened in some other editor, so
- // we needn't be concerned about editing it in the context of a referencing model
- if(!readableReferencedModels.contains(next.trimFileExtension()) && isNotModelSetMainModel(next) && converter.exists(next, null)) {
- result = Optional.of(true);
- break;
+ for(int i = 0; i < uris.length; i++) {
+ // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
+ URI next = uris[i].trimFragment();
+
+ // If the resource doesn't exist, then it can't be opened in some other editor, so
+ // we needn't be concerned about editing it in the context of a referencing model
+ if(!readableReferencedModels.contains(next.trimFileExtension()) && isNotModelSetMainModel(next) && converter.exists(next, null)) {
+ result = Optional.of(true);
+ break;
+ }
}
}
-
+
return result;
}
@Override
- public Optional<Boolean> canMakeWritable(URI[] uris) {
+ public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
Optional<Boolean> result = Optional.absent();
- for(int i = 0; i < uris.length; i++) {
- // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
- URI next = uris[i].trimFragment();
-
- if(isNotModelSetMainModel(next)) {
- result = Optional.of(true);
- } else {
- // If it's not something I handle, then bomb
- result = Optional.of(false);
- break;
+ if(axes.contains(ReadOnlyAxis.DISCRETION)) {
+ for(int i = 0; i < uris.length; i++) {
+ // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
+ URI next = uris[i].trimFragment();
+
+ if(isNotModelSetMainModel(next)) {
+ result = Optional.of(true);
+ } else {
+ // If it's not something I handle, then bomb
+ result = Optional.of(false);
+ break;
+ }
}
}
-
+
return result;
}
- public Optional<Boolean> makeWritable(URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
Optional<Boolean> result = Optional.absent();
- final List<URI> toMakeWritable = new ArrayList<URI>(uris.length);
-
- for(int i = 0; i < uris.length; i++) {
- // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
- URI next = uris[i].trimFragment();
-
- if(isNotModelSetMainModel(next)) {
- toMakeWritable.add(next);
+ if(axes.contains(ReadOnlyAxis.DISCRETION)) {
+ final List<URI> toMakeWritable = new ArrayList<URI>(uris.length);
+
+ for(int i = 0; i < uris.length; i++) {
+ // Clients may pass object URIs (including fragments), so trim to a resource URI because we operate on the resource level
+ URI next = uris[i].trimFragment();
+
+ if(isNotModelSetMainModel(next)) {
+ toMakeWritable.add(next);
+ }
}
- }
-
- if(!toMakeWritable.isEmpty()) {
- final boolean[] enableWrite = { !isInteractive() };
-
- if(isInteractive()) {
- Display.getCurrent().syncExec(new Runnable() {
-
- public void run() {
- StringBuilder message = new StringBuilder(Messages.ReferencedModelReadOnlyHandler_promptMsg);
- for(URI uri : toMakeWritable) {
- String path;
- if(uri.isPlatformResource()) {
- path = uri.toPlatformString(true);
- } else if(uri.isFile()) {
- path = uri.toFileString();
- } else {
- path = uri.toString();
+
+ if(!toMakeWritable.isEmpty()) {
+ final boolean[] enableWrite = { !isInteractive() };
+
+ if(isInteractive()) {
+ Display.getCurrent().syncExec(new Runnable() {
+
+ public void run() {
+ StringBuilder message = new StringBuilder(Messages.ReferencedModelReadOnlyHandler_promptMsg);
+ for(URI uri : toMakeWritable) {
+ String path;
+ if(uri.isPlatformResource()) {
+ path = uri.toPlatformString(true);
+ } else if(uri.isFile()) {
+ path = uri.toFileString();
+ } else {
+ path = uri.toString();
+ }
+
+ message.append(path);
+ message.append("\n"); //$NON-NLS-1$
}
-
- message.append(path);
- message.append("\n"); //$NON-NLS-1$
+ enableWrite[0] = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), Messages.ReferencedModelReadOnlyHandler_promptTitle, message.toString());
}
- enableWrite[0] = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), Messages.ReferencedModelReadOnlyHandler_promptTitle, message.toString());
+ });
+ }
+
+ if(enableWrite[0]) {
+ for(URI next : toMakeWritable) {
+ readableReferencedModels.add(next.trimFileExtension());
}
- });
- }
-
- if(enableWrite[0]) {
- for(URI next : toMakeWritable) {
- readableReferencedModels.add(next.trimFileExtension());
}
+
+ result = Optional.of(enableWrite[0]);
}
-
- result = Optional.of(enableWrite[0]);
}
-
+
return result;
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/SashModelReadOnlyHandler.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/SashModelReadOnlyHandler.java
index bf0a1a1a086..fad1819d6e8 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/SashModelReadOnlyHandler.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/SashModelReadOnlyHandler.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * Copyright (c) 2014 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,12 +8,17 @@
*
* Contributors:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 429826
+ *
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import java.util.Set;
+
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel;
@@ -25,7 +30,9 @@ import com.google.common.base.Optional;
* If the model is located in the user preferences space, it may be considered
* read-only by other read-only handlers, whereas it shouldn't.
*
- * Its priority should be greater than EMFReadOnlyHandler, FSReadOnlyHandler and
+ * Its priority should be greater than EMFReadOnlyHandler, FSReadOnlyHandler and ...
+ *
+ * This handler is discretion-based.
*
* @author Camille Letavernier
*
@@ -45,8 +52,8 @@ public class SashModelReadOnlyHandler extends AbstractReadOnlyHandler {
/**
* {@inheritDoc}
*/
- public Optional<Boolean> anyReadOnly(URI[] uris) {
- if(modelSet == null) {
+ public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
+ if((modelSet == null) || !axes.contains(ReadOnlyAxis.DISCRETION)) {
return Optional.absent();
}
@@ -66,7 +73,7 @@ public class SashModelReadOnlyHandler extends AbstractReadOnlyHandler {
/**
* {@inheritDoc}
*/
- public Optional<Boolean> makeWritable(URI[] uris) {
+ public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
return Optional.absent(); //If the file is read-only, it can probably made writable by other read-only handlers (e.g. FSReadOnlyHandler).
}
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 3abfeb91979..e522cff9c02 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
@@ -11,6 +11,7 @@
* Christian W. Damus (CEA) - filter out EObjects that are Resources (CDO)
* Christian W. Damus (CEA) - Support read-only state at object level (CDO)
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus (CEA) - bug 429826
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.utils;
@@ -49,6 +50,7 @@ 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.IReadOnlyHandler2;
+import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
import org.eclipse.papyrus.infra.emf.Activator;
@@ -431,33 +433,66 @@ public class EMFHelper {
}
/**
- * Tests if an EObject is read only
+ * Tests if an EObject is read only on any {@linkplain ReadOnlyAxis axis}.
* Delegates to the EObject's editing domain if it can be found
*
* @param eObject
* @return
- * True if the EObject is read only
+ * True if the EObject is read only on any axis
+ * @see #isReadOnly(Set, EObject, EditingDomain)
*/
public static boolean isReadOnly(final EObject eObject) {
+ return isReadOnly(ReadOnlyAxis.anyAxis(), eObject);
+ }
+
+ /**
+ * Tests if an EObject is read only on any of the specified {@code axes}.
+ * Delegates to the EObject's editing domain if it can be found
+ *
+ * @param axes
+ * a set if orthogonal axes of read-only-ness to consider. May be empty, but that would not be especially useful
+ * @param eObject
+ * @return
+ * True if the EObject is read only on any of the given {@code axes}
+ */
+ public static boolean isReadOnly(Set<ReadOnlyAxis> axes, final EObject eObject) {
EditingDomain domain = resolveEditingDomain(eObject);
- return isReadOnly(eObject, domain);
+ return isReadOnly(axes, eObject, domain);
}
/**
- * Tests if an EObject is read only
+ * Tests if an EObject is read only on any {@linkplain ReadOnlyAxis axis}.
* Delegates to the given editing domain if it isn't null
*
* @param eObject
+ * @param domain
+ * @return
+ * True if the EObject is read only on any axis
+ */
+ public static boolean isReadOnly(final EObject eObject, final EditingDomain domain) {
+ return isReadOnly(ReadOnlyAxis.anyAxis(), eObject, domain);
+ }
+
+ /**
+ * Tests if an EObject is read only on any of the specified {@code axes}.
+ * Delegates to the given editing domain if it isn't null
+ *
+ * @param axes
+ * a set if orthogonal axes of read-only-ness to consider. May be empty, but that would not be especially useful
+ * @param eObject
*
* @param domain
* @return
* True if the EObject is read only
*/
- public static boolean isReadOnly(final EObject eObject, final EditingDomain domain) {
+ public static boolean isReadOnly(Set<ReadOnlyAxis> axes, final EObject eObject, final EditingDomain domain) {
if(domain != null) {
Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
- if(handler instanceof IReadOnlyHandler) {
- return ((IReadOnlyHandler)handler).isReadOnly(eObject).get();
+ if(handler instanceof IReadOnlyHandler2) {
+ return ((IReadOnlyHandler2)handler).isReadOnly(axes, eObject).get();
+ }else if(handler instanceof IReadOnlyHandler) {
+ // these handlers only deal with permission-based read-only-ness
+ return axes.contains(ReadOnlyAxis.PERMISSION) && ((IReadOnlyHandler)handler).isReadOnly(eObject).get();
}
if(eObject.eResource() != null) {
@@ -468,23 +503,41 @@ public class EMFHelper {
}
/**
- * Tests if the Resource is read only
+ * Tests if the Resource is read only on any {@linkplain ReadOnlyAxis axis}.
* Delegates to the given editing domain if it isn't null
*
* @param resource
* @param domain
* @return
- * True if the Resource is read only
+ * True if the Resource is read only on any axis
*/
public static boolean isReadOnly(final Resource resource, final EditingDomain domain) {
+ return isReadOnly(ReadOnlyAxis.anyAxis(), resource, domain);
+ }
+
+ /**
+ * Tests if the Resource is read only on any of the given {@code axes}.
+ * Delegates to the given editing domain if it isn't null
+ *
+ * @param axes
+ * a set if orthogonal axes of read-only-ness to consider. May be empty, but that would not be especially useful
+ * @param resource
+ * @param domain
+ * @return
+ * True if the Resource is read only on any of the given {@code axes}
+ */
+ public static boolean isReadOnly(Set<ReadOnlyAxis> axes, final Resource resource, final EditingDomain domain) {
if(resource == null) {
return false;
}
if(domain != null && resource.getURI() != null) {
Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
- if(handler instanceof IReadOnlyHandler) {
- return ((IReadOnlyHandler)handler).anyReadOnly(new URI[]{ resource.getURI() }).get();
+ if(handler instanceof IReadOnlyHandler2) {
+ return ((IReadOnlyHandler2)handler).anyReadOnly(axes, new URI[]{ resource.getURI() }).get();
+ } else if(handler instanceof IReadOnlyHandler) {
+ // these handlers only deal with permission-based read-only-ness
+ return axes.contains(ReadOnlyAxis.PERMISSION) && ((IReadOnlyHandler)handler).anyReadOnly(new URI[]{ resource.getURI() }).get();
}
return domain.isReadOnly(resource);
}
@@ -514,10 +567,27 @@ public class EMFHelper {
* whether the {@code eObject} could be made writable
*/
public static boolean canMakeWritable(final EObject eObject, final EditingDomain domain) {
+ return canMakeWritable(ReadOnlyAxis.anyAxis(), eObject, domain);
+ }
+
+ /**
+ * Tests if an object that is read only could possibly be made writable according to any of
+ * the specified {@code axes} of read-only-ness.
+ *
+ * @param axes
+ * a set if orthogonal axes of read-only-ness to consider. May be empty, but that would not be especially useful
+ * @param eObject
+ * an object that is assumed to be read-only
+ * @param domain
+ * the editing domain context of the {@link eObject}
+ * @return
+ * whether the {@code eObject} could be made writable
+ */
+ public static boolean canMakeWritable(Set<ReadOnlyAxis> axes, final EObject eObject, final EditingDomain domain) {
if(domain != null) {
Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
if(handler instanceof IReadOnlyHandler2) {
- return ((IReadOnlyHandler2)handler).canMakeWritable(eObject).or(false);
+ return ((IReadOnlyHandler2)handler).canMakeWritable(axes, eObject).or(false);
}
}
return false;
@@ -535,10 +605,27 @@ public class EMFHelper {
* whether the {@code resource} could be made writable
*/
public static boolean canMakeWritable(final Resource resource, final EditingDomain domain) {
+ return canMakeWritable(ReadOnlyAxis.anyAxis(), resource, domain);
+ }
+
+ /**
+ * Tests if a resource that is read only could possibly be made writable according to any of
+ * the specified {@code axes} of read-only-ness.
+ *
+ * @param axes
+ * a set if orthogonal axes of read-only-ness to consider. May be empty, but that would not be especially useful
+ * @param resource
+ * a resource that is assumed to be read-only
+ * @param domain
+ * the editing domain context of the {@link resource}
+ * @return
+ * whether the {@code resource} could be made writable
+ */
+ public static boolean canMakeWritable(Set<ReadOnlyAxis> axes, final Resource resource, final EditingDomain domain) {
if(domain != null) {
Object handler = PlatformHelper.getAdapter(domain, IReadOnlyHandler.class);
if(handler instanceof IReadOnlyHandler2) {
- return ((IReadOnlyHandler2)handler).canMakeWritable(new URI[] { resource.getURI() }).or(false);
+ return ((IReadOnlyHandler2)handler).canMakeWritable(axes, new URI[] { resource.getURI() }).or(false);
}
}
return false;

Back to the top