diff options
Diffstat (limited to 'plugins/infra/emf')
27 files changed, 2159 insertions, 2016 deletions
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.project index 8c0d3ad1182..5990bca3999 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.project @@ -1,28 +1,52 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.papyrus.infra.emf.appearance</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrus.infra.emf.appearance</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> + </natures> +</projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.settings/.api_filters b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.settings/.api_filters new file mode 100644 index 00000000000..ec19a254b99 --- /dev/null +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.settings/.api_filters @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.papyrus.infra.emf.appearance" version="2"> + <resource path="src/org/eclipse/papyrus/infra/emf/appearance/helper/AppearanceHelper.java" type="org.eclipse.papyrus.infra.emf.appearance.helper.AppearanceHelper"> + <filter comment="No developer would reasonably have modified this field" id="388100214"> + <message_arguments> + <message_argument value="org.eclipse.papyrus.infra.emf.appearance.helper.AppearanceHelper"/> + <message_argument value="EXTENSION_ID"/> + </message_arguments> + </filter> + </resource> +</component> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/META-INF/MANIFEST.MF index 76bf4d94668..036070fdca5 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/META-INF/MANIFEST.MF @@ -1,20 +1,16 @@ -Manifest-Version: 1.0
-Export-Package: org.eclipse.papyrus.infra.emf.appearance,
- org.eclipse.papyrus.infra.emf.appearance.commands,
- org.eclipse.papyrus.infra.emf.appearance.helper,
- org.eclipse.papyrus.infra.emf.appearance.style
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.emf.ecore;bundle-version="2.8.0",
- org.eclipse.emf.transaction;bundle-version="1.4.0",
- org.eclipse.papyrus.infra.emf;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0"
-Bundle-Vendor: %Bundle-Vendor
-Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.2.0.qualifier
-Bundle-Localization: plugin
-Bundle-Name: %Bundle-Name
-Bundle-Activator: org.eclipse.papyrus.infra.emf.appearance.Activator
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.appearance;singleton:=true
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Manifest-Version: 1.0 +Export-Package: org.eclipse.papyrus.infra.emf.appearance, + org.eclipse.papyrus.infra.emf.appearance.commands, + org.eclipse.papyrus.infra.emf.appearance.helper, + org.eclipse.papyrus.infra.emf.appearance.style +Require-Bundle: org.eclipse.ui;bundle-version="[3.107.0,4.0.0)", + org.eclipse.papyrus.infra.emf;bundle-version="[2.0.0,3.0.0)";visibility:=reexport +Bundle-Vendor: %Bundle-Vendor +Bundle-ActivationPolicy: lazy +Bundle-Version: 1.2.0.qualifier +Bundle-Localization: plugin +Bundle-Name: %Bundle-Name +Bundle-Activator: org.eclipse.papyrus.infra.emf.appearance.Activator +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.appearance;singleton:=true +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/.project index 3e7b2dd7dcf..12dd7756c1e 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/.project @@ -1,28 +1,52 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.papyrus.infra.emf.diagram.common</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrus.infra.emf.diagram.common</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> + </natures> +</projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/META-INF/MANIFEST.MF index f1bffdb6c75..c0809d5521b 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/META-INF/MANIFEST.MF @@ -1,17 +1,12 @@ Manifest-Version: 1.0 Export-Package: org.eclipse.papyrus.infra.emf.diagram.common, org.eclipse.papyrus.infra.emf.diagram.common.handler -Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="1.2.0", - org.eclipse.gmf.runtime.notation;bundle-version="1.5.0", - org.eclipse.emf.transaction;bundle-version="1.4.0", - org.eclipse.papyrus.infra.core.sasheditor;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0", - org.eclipse.core.commands;bundle-version="3.6.1", - org.eclipse.ui, - org.eclipse.papyrus.infra.emf.gmf;bundle-version="1.2.0", - org.eclipse.papyrus.infra.emf;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0", - org.eclipse.papyrus.infra.ui;bundle-version="1.2.0" +Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.gmf.runtime.notation;bundle-version="[1.8.0,2.0.0)", + org.eclipse.core.commands;bundle-version="[3.8.0,4.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.emf.gmf;bundle-version="[1.2.0,2.0.0)", + org.eclipse.papyrus.infra.emf;bundle-version="[2.0.0,3.0.0)", + org.eclipse.papyrus.infra.ui;bundle-version="[1.2.0,2.0.0)" Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy Bundle-Version: 1.2.0.qualifier diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/.project index d198355a356..66de7666aa5 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/.project @@ -20,9 +20,33 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> </natures> </projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/META-INF/MANIFEST.MF index 55ed840f623..f44ee9b426e 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/META-INF/MANIFEST.MF @@ -2,14 +2,11 @@ Manifest-Version: 1.0 Export-Package: org.eclipse.papyrus.infra.emf.gmf.command, org.eclipse.papyrus.infra.emf.gmf.util, org.eclipse.papyrus.infra.emf.internal.gmf;x-internal:=true -Require-Bundle: org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0", - org.eclipse.papyrus.infra.tools;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core;bundle-version="1.2.0", - org.eclipse.core.expressions;bundle-version="3.4.400", - org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.7.0", - com.google.guava;bundle-version="11.0.0", - org.eclipse.papyrus.emf.facet.custom.core;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0" +Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="[2.0.0,3.0.0)", + org.eclipse.gmf.runtime.emf.type.core;bundle-version="[1.9.0,2.0.0)", + org.eclipse.papyrus.emf.facet.custom.core;bundle-version="[1.2.0,2.0.0)", + org.eclipse.gmf.runtime.common.core;bundle-version="[1.7.0,2.0.0)";visibility:=reexport, + org.eclipse.emf.workspace;bundle-version="[1.5.0,2.0.0)";visibility:=reexport Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy Bundle-Version: 1.2.0.qualifier diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/.project index ebfa82252ba..0d1f05526ae 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/.project @@ -1,28 +1,52 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.papyrus.infra.emf.readonly</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrus.infra.emf.readonly</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> + </natures> +</projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/META-INF/MANIFEST.MF index 09cd9998ca9..9845b1cdb2b 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/META-INF/MANIFEST.MF @@ -2,19 +2,14 @@ Manifest-Version: 1.0 Export-Package: org.eclipse.papyrus.infra.emf.readonly, org.eclipse.papyrus.infra.emf.readonly.internal;x-friends:="org.eclipse.papyrus.infra.ui.emf", org.eclipse.papyrus.infra.emf.readonly.spi -Require-Bundle: org.eclipse.papyrus.infra.onefile;bundle-version="1.2.0", - org.eclipse.core.expressions;bundle-version="3.4.300", - org.eclipse.emf.workspace;bundle-version="1.4.0", - org.eclipse.gmf.runtime.common.core;bundle-version="1.4.1", - org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0", - org.eclipse.papyrus.infra.emf.gmf;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core;bundle-version="1.2.0", - org.eclipse.papyrus.infra.emf;bundle-version="1.2.0", - com.google.guava;bundle-version="11.0.0", - org.eclipse.papyrus.infra.tools;bundle-version="1.2.0" +Require-Bundle: org.eclipse.papyrus.infra.onefile;bundle-version="[2.0.0,3.0.0)", + org.eclipse.gmf.runtime.common.core;bundle-version="[1.7.0,2.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.emf.gmf;bundle-version="[1.2.0,2.0.0)", + org.eclipse.papyrus.infra.core;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.emf;bundle-version="[2.0.0,3.0.0)";visibility:=reexport Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-Name: %pluginName Bundle-Localization: plugin Bundle-ManifestVersion: 2 diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/pom.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/pom.xml index ead630febec..c801f2cf18f 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/pom.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/pom.xml @@ -7,6 +7,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.emf.readonly</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> -</project> +</project>
\ No newline at end of file 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 83d35ab9af5..45ca48d7724 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 @@ -1,589 +1,590 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2016 Atos Origin, CEA, Christian W. Damus, 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:
- * 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) - bugs 323802, 429826, 422257, 437217
- * Christian W. Damus - bugs 457560, 463564, 485220
- *
- *****************************************************************************/
-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.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.edit.domain.EditingDomain;
-import org.eclipse.papyrus.infra.core.resource.AbstractReadOnlyHandler;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2;
-import org.eclipse.papyrus.infra.core.resource.IReadOnlyListener;
-import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis;
-import org.eclipse.papyrus.infra.core.resource.ReadOnlyEvent;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-
-
-public class ReadOnlyManager implements IReadOnlyHandler2 {
-
- // Use weak values because the values otherwise retain the keys (indirectly)
- protected static final ConcurrentMap<EditingDomain, IReadOnlyHandler2> roHandlers = new MapMaker().weakKeys().weakValues().makeMap();
-
- private final CopyOnWriteArrayList<IReadOnlyListener> listeners = new CopyOnWriteArrayList<IReadOnlyListener>();
-
- private final ReadOnlyCache cache;
-
- private IReadOnlyListener forwardingListener;
-
- public static IReadOnlyHandler2 getReadOnlyHandler(EditingDomain editingDomain) {
- IReadOnlyHandler2 roHandler = IReadOnlyHandler2.NULL;
-
- if (editingDomain != null) {
- roHandler = roHandlers.get(editingDomain);
- if (roHandler == null) {
- roHandler = new ReadOnlyManager(editingDomain);
- process((ReadOnlyManager) roHandler, editingDomain);
- IReadOnlyHandler2 existing = roHandlers.putIfAbsent(editingDomain, roHandler);
- if (existing != null) {
- // Another thread beat us to it since we checked for an existing instance
- ((ReadOnlyManager) roHandler).cache.dispose();
- roHandler = existing;
- }
- }
- }
-
- return roHandler;
- }
-
- private static void process(ReadOnlyManager manager, EditingDomain domain) {
- Activator.getDefault().getReadOnlyManagerProcessors().forEach(p -> p.processReadOnlyManager(manager, domain));
- }
-
- protected static class HandlerPriorityPair implements Comparable<HandlerPriorityPair> {
-
- public Class<?> handlerClass;
-
- public int priority;
-
- public Set<ReadOnlyAxis> axes;
-
- @Override
- public int compareTo(HandlerPriorityPair o) {
- if (o.priority > priority) {
- return 1;
- } else if (o.priority < priority) {
- return -1;
- } else {
- return 0;
- }
- }
- }
-
- protected static final Map<Class<?>, Set<ReadOnlyAxis>> orderedHandlerClasses;
-
- static {
- IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.emf.readonly", "readOnlyHandler");
-
- List<HandlerPriorityPair> handlerPriorityPairs = new LinkedList<HandlerPriorityPair>();
- Map<String, HandlerPriorityPair> idMap = new HashMap<String, HandlerPriorityPair>();
-
- for (IConfigurationElement elem : configElements) {
- if ("readOnlyHandler".equals(elem.getName())) {
- try {
- HandlerPriorityPair handlerPriorityPair = new HandlerPriorityPair();
- String className = elem.getAttribute("class");
- handlerPriorityPair.handlerClass = Platform.getBundle(elem.getContributor().getName()).loadClass(className);
-
- handlerPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority"));
-
- IConfigurationElement[] affinities = elem.getChildren("affinity");
- if ((affinities == null) || (affinities.length == 0)) {
- // implicit affinity is with any axis
- handlerPriorityPair.axes = ReadOnlyAxis.anyAxis();
- } else {
- handlerPriorityPair.axes = EnumSet.noneOf(ReadOnlyAxis.class);
- for (IConfigurationElement next : affinities) {
- handlerPriorityPair.axes.add(ReadOnlyAxis.valueOf(next.getAttribute("axis").toUpperCase()));
- }
- }
-
- String id = elem.getAttribute("id");
- if (id != null) {
- // if any then the handler could be overrided by another registration
- HandlerPriorityPair oldHandler = idMap.get(id);
- if (oldHandler == null) {
- idMap.put(id, handlerPriorityPair);
- handlerPriorityPairs.add(handlerPriorityPair);
- } else {
- if (oldHandler.priority < handlerPriorityPair.priority) {
- handlerPriorityPairs.remove(oldHandler);
- handlerPriorityPairs.add(handlerPriorityPair);
- }
- }
- } else {
- // If none the handler can not be overrided
- handlerPriorityPairs.add(handlerPriorityPair);
- }
- } catch (Throwable t) {
- // FIXME: We need to catch Throwables because we rely on external contributions. It is required to also catch Errors (such as compilation errors).
- // Move this code to an initialization method, because if a throwable is not caught, this will prevent the whole class initialization
- Activator.log.error(t);
- }
- }
- }
-
- Collections.sort(handlerPriorityPairs);
-
- orderedHandlerClasses = new LinkedHashMap<Class<?>, Set<ReadOnlyAxis>>();
-
- for (HandlerPriorityPair next : handlerPriorityPairs) {
- orderedHandlerClasses.put(next.handlerClass, next.axes);
- }
- }
-
-
- @SuppressWarnings("deprecation")
- protected static IReadOnlyHandler2 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 (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 AbstractReadOnlyHandler.adapt((IReadOnlyHandler) constructor.newInstance(editingDomain), editingDomain);
- } else {
- return AbstractReadOnlyHandler.adapt((IReadOnlyHandler) constructor.newInstance(), editingDomain);
- }
- } else if (org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) {
- return new OldStyleHandlerAdapter((org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler) constructor.newInstance(), editingDomain);
- }
- } catch (Exception e) {
- }
-
- return null;
- }
-
- protected Map<ReadOnlyAxis, IReadOnlyHandler2[]> orderedHandlersByAxis;
-
- public ReadOnlyManager(final EditingDomain editingDomain) {
- // Create our transaction cache
- cache = ReadOnlyCache.create(this, Activator.getDefault().getReadOnlyCacheExecutor());
-
- final Map<ReadOnlyAxis, List<IReadOnlyHandler2>> handlers = new EnumMap<ReadOnlyAxis, List<IReadOnlyHandler2>>(ReadOnlyAxis.class);
- cache.run(new Runnable() {
-
- @Override
- public void run() {
- for (Map.Entry<Class<?>, Set<ReadOnlyAxis>> roClass : orderedHandlerClasses.entrySet()) {
- IReadOnlyHandler2 h = create(roClass.getKey(), editingDomain);
- if (h != null) {
- h.addReadOnlyListener(getForwardingListener());
-
- for (ReadOnlyAxis axis : roClass.getValue()) {
- List<IReadOnlyHandler2> list = handlers.get(axis);
- if (list == null) {
- list = new ArrayList<IReadOnlyHandler2>();
- handlers.put(axis, list);
- }
- list.add(h);
- }
- }
- }
- }
- });
-
- // Iterate the enumeration to make sure all axes are represented (even if only by an empty array)
- orderedHandlersByAxis = new EnumMap<ReadOnlyAxis, IReadOnlyHandler2[]>(ReadOnlyAxis.class);
- for (ReadOnlyAxis axis : ReadOnlyAxis.values()) {
- List<IReadOnlyHandler2> list = handlers.get(axis);
- if (list == null) {
- orderedHandlersByAxis.put(axis, new IReadOnlyHandler2[0]);
- } else {
- orderedHandlersByAxis.put(axis, list.toArray(new IReadOnlyHandler2[list.size()]));
- }
- }
- }
-
- @Override
- public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) {
- final Set<URI> uriSet = ImmutableSet.copyOf(uris);
- Optional<Boolean> result = cache.getResources(axes, uriSet);
- if (result == null) {
- result = Optional.absent();
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && !result.or(Boolean.FALSE); i++) {
- if (axes.contains(all[i])) {
- result = anyReadOnly(all[i], uris);
- }
- }
-
- cache.putResources(axes, uriSet, result);
- }
-
- return result.isPresent() ? result : Optional.of(Boolean.FALSE);
- }
-
- private Optional<Boolean> anyReadOnly(ReadOnlyAxis axis, URI[] uris) {
- final Set<URI> uriSet = ImmutableSet.copyOf(uris);
- Set<ReadOnlyAxis> axes = axis.singleton();
- Optional<Boolean> result = cache.getResources(axes, uriSet);
- if (result == null) {
- result = Optional.absent();
-
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length) && !result.isPresent(); i++) {
- result = orderedHandlers[i].anyReadOnly(axes, uris);
- }
-
- cache.putResources(axes, uriSet, result);
- }
-
- return result.isPresent() ? result : Optional.of(Boolean.FALSE);
- }
-
- @Override
- public Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject) {
- Optional<Boolean> result = cache.getObject(axes, eObject);
- if (result == null) {
- result = Optional.absent();
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && !result.or(Boolean.FALSE); i++) {
- if (axes.contains(all[i])) {
- result = isReadOnly(all[i], eObject);
- }
- }
-
- cache.putObject(axes, eObject, result);
- }
-
- return result.isPresent() ? result : Optional.of(Boolean.FALSE);
- }
-
- private Optional<Boolean> isReadOnly(ReadOnlyAxis axis, EObject eObject) {
- Set<ReadOnlyAxis> axes = axis.singleton();
- Optional<Boolean> result = cache.getObject(axes, eObject);
- if (result == null) {
- result = Optional.absent();
-
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length) && !result.isPresent(); i++) {
- result = orderedHandlers[i].isReadOnly(axes, eObject);
- }
-
- cache.putObject(axes, eObject, result);
- }
-
- return result.isPresent() ? result : Optional.of(Boolean.FALSE);
- }
-
- @Override
- public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
- Boolean finalResult = true;
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && finalResult; i++) {
- if (axes.contains(all[i])) {
- finalResult = makeWritable(all[i], uris);
- }
- }
-
- return Optional.of(finalResult);
- }
-
- private Boolean makeWritable(ReadOnlyAxis axis, URI[] uris) {
- Set<ReadOnlyAxis> axes = axis.singleton();
- Boolean finalResult = true;
-
- try {
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length); i++) {
- Optional<Boolean> isRO = orderedHandlers[i].anyReadOnly(axes, uris);
- if (isRO.or(Boolean.FALSE)) {
- Optional<Boolean> result = orderedHandlers[i].makeWritable(axes, uris);
- // makeWritable should provide an answer since anyReadOnly returned a positive value.
- // If no answer consider it a failure
- if (!result.or(Boolean.FALSE)) {
- finalResult = false;
- break;
- }
- }
- }
- } finally {
- cache.clear();
- }
-
- return finalResult;
- }
-
- @Override
- public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject) {
- Boolean finalResult = true;
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && finalResult; i++) {
- if (axes.contains(all[i])) {
- finalResult = makeWritable(all[i], eObject);
- }
- }
-
- return Optional.of(finalResult);
- }
-
- private Boolean makeWritable(ReadOnlyAxis axis, EObject eObject) {
- Set<ReadOnlyAxis> axes = axis.singleton();
- Boolean finalResult = true;
-
- try {
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length); i++) {
- Optional<Boolean> isRO = orderedHandlers[i].isReadOnly(axes, eObject);
- if (isRO.or(Boolean.FALSE)) {
- Optional<Boolean> result = orderedHandlers[i].makeWritable(axes, eObject);
- // makeWritable should provide an answer since anyReadOnly returned a positive value
- // if no answer consider it a failure
- if (!result.or(Boolean.FALSE)) {
- finalResult = false;
- break;
- }
- }
- }
- } finally {
- cache.clear();
- }
-
- return finalResult;
- }
-
- @Override
- public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) {
- Boolean result = false;
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && !result; i++) {
- if (axes.contains(all[i])) {
- result = canMakeWritable(all[i], uris);
- }
- }
-
- return Optional.of(result);
- }
-
- private Boolean canMakeWritable(ReadOnlyAxis axis, URI[] uris) {
- Set<ReadOnlyAxis> axes = axis.singleton();
- Boolean result = false;
-
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length); i++) {
- if (orderedHandlers[i].anyReadOnly(axes, uris).or(false)) {
- // Only ask a handler about making writable what it considers to be read-only
- Optional<Boolean> canMakeWritable = orderedHandlers[i].canMakeWritable(axes, uris);
- if (canMakeWritable.isPresent()) {
- result = canMakeWritable.get();
- break;
- }
- }
- }
-
- return result;
- }
-
- @Override
- public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, EObject object) {
- Boolean result = false;
-
- ReadOnlyAxis[] all = ReadOnlyAxis.values();
- for (int i = 0; (i < all.length) && !result; i++) {
- if (axes.contains(all[i])) {
- result = canMakeWritable(all[i], object);
- }
- }
-
- return Optional.of(result);
- }
-
- private Boolean canMakeWritable(ReadOnlyAxis axis, EObject object) {
- Set<ReadOnlyAxis> axes = axis.singleton();
- Boolean result = false;
-
- IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis);
- for (int i = 0; (i < orderedHandlers.length); i++) {
- if (orderedHandlers[i].isReadOnly(axes, object).or(false)) {
- // Only ask a handler about making writable what it considers to be read-only
- Optional<Boolean> canMakeWritable = orderedHandlers[i].canMakeWritable(axes, object);
- if (canMakeWritable.isPresent()) {
- result = canMakeWritable.get();
- break;
- }
- }
- }
-
- return result;
- }
-
- @Override
- public void addReadOnlyListener(IReadOnlyListener listener) {
- listeners.addIfAbsent(listener);
- }
-
- @Override
- public void removeReadOnlyListener(IReadOnlyListener listener) {
- listeners.remove(listener);
- }
-
- private IReadOnlyListener getForwardingListener() {
- if (forwardingListener == null) {
- forwardingListener = new IReadOnlyListener() {
-
- @Override
- public void readOnlyStateChanged(ReadOnlyEvent event) {
- ReadOnlyEvent myEvent;
-
- switch (event.getEventType()) {
- case ReadOnlyEvent.OBJECT_READ_ONLY_STATE_CHANGED:
- myEvent = new ReadOnlyEvent(ReadOnlyManager.this, event.getAxis(), event.getObject(), event.isReadOnly());
- break;
- default:
- myEvent = new ReadOnlyEvent(ReadOnlyManager.this, event.getAxis(), event.getResourceURI(), event.isReadOnly());
- break;
- }
-
- notifyReadOnlyStateChanged(myEvent);
- }
- };
- }
-
- return forwardingListener;
- }
-
- protected void notifyReadOnlyStateChanged(ReadOnlyEvent event) {
- if (!listeners.isEmpty()) {
- for (IReadOnlyListener next : listeners) {
- try {
- next.readOnlyStateChanged(event);
- } catch (Exception e) {
- Activator.log.error("Uncaught exception in read-only state change listener.", e); //$NON-NLS-1$
- }
- }
- }
- }
-
- /**
- * Obtains a snapshot of the read-only handlers currently registered with me.
- *
- * @return my read-only handlers, by axis of affiliation. Changes to this collection
- * do not affect my registered handlers
- */
- public final Map<ReadOnlyAxis, Collection<IReadOnlyHandler2>> getReadOnlyHandlers() {
- Map<ReadOnlyAxis, Collection<IReadOnlyHandler2>> result = new HashMap<>();
-
- // Be sure not to provide lists that are actually backed by the arrays!
- orderedHandlersByAxis.forEach((axis, handlers) -> result.put(axis, Lists.newArrayList(handlers)));
-
- return result;
- }
-
- //
- // Deprecated API
- //
-
- @Override
- @Deprecated
- public Optional<Boolean> anyReadOnly(URI[] uris) {
- return anyReadOnly(permissionAxes(), uris);
- }
-
- @Override
- @Deprecated
- public Optional<Boolean> isReadOnly(EObject eObject) {
- return isReadOnly(permissionAxes(), eObject);
- }
-
- @Override
- @Deprecated
- public Optional<Boolean> makeWritable(URI[] uris) {
- return makeWritable(permissionAxes(), uris);
- }
-
- @Override
- @Deprecated
- public Optional<Boolean> makeWritable(EObject eObject) {
- return makeWritable(permissionAxes(), eObject);
- }
-
- //
- // Legacy adapters
- //
-
- @SuppressWarnings("deprecation")
- private static final class OldStyleHandlerAdapter extends AbstractReadOnlyHandler {
-
- private final org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler delegate;
-
- OldStyleHandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler, EditingDomain editingDomain) {
- super(editingDomain);
-
- this.delegate = handler;
- }
-
- @Override
- 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. 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();
- }
-
- @Override
- 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). 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);
- }
- }
-}
+/***************************************************************************** + * Copyright (c) 2011, 2016 Atos Origin, CEA, Christian W. Damus, 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: + * 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) - bugs 323802, 429826, 422257, 437217 + * Christian W. Damus - bugs 457560, 463564, 485220 + * + *****************************************************************************/ +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.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.papyrus.infra.core.resource.AbstractReadOnlyHandler; +import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler; +import org.eclipse.papyrus.infra.core.resource.IReadOnlyHandler2; +import org.eclipse.papyrus.infra.core.resource.IReadOnlyListener; +import org.eclipse.papyrus.infra.core.resource.ReadOnlyAxis; +import org.eclipse.papyrus.infra.core.resource.ReadOnlyEvent; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.MapMaker; + + +public class ReadOnlyManager implements IReadOnlyHandler2 { + + // Use weak values because the values otherwise retain the keys (indirectly) + protected static final ConcurrentMap<EditingDomain, IReadOnlyHandler2> roHandlers = new MapMaker().weakKeys().weakValues().makeMap(); + + private final CopyOnWriteArrayList<IReadOnlyListener> listeners = new CopyOnWriteArrayList<IReadOnlyListener>(); + + private final ReadOnlyCache cache; + + private IReadOnlyListener forwardingListener; + + public static IReadOnlyHandler2 getReadOnlyHandler(EditingDomain editingDomain) { + IReadOnlyHandler2 roHandler = IReadOnlyHandler2.NULL; + + if (editingDomain != null) { + roHandler = roHandlers.get(editingDomain); + if (roHandler == null) { + roHandler = new ReadOnlyManager(editingDomain); + process((ReadOnlyManager) roHandler, editingDomain); + IReadOnlyHandler2 existing = roHandlers.putIfAbsent(editingDomain, roHandler); + if (existing != null) { + // Another thread beat us to it since we checked for an existing instance + ((ReadOnlyManager) roHandler).cache.dispose(); + roHandler = existing; + } + } + } + + return roHandler; + } + + private static void process(ReadOnlyManager manager, EditingDomain domain) { + Activator.getDefault().getReadOnlyManagerProcessors().forEach(p -> p.processReadOnlyManager(manager, domain)); + } + + protected static class HandlerPriorityPair implements Comparable<HandlerPriorityPair> { + + public Class<?> handlerClass; + + public int priority; + + public Set<ReadOnlyAxis> axes; + + @Override + public int compareTo(HandlerPriorityPair o) { + if (o.priority > priority) { + return 1; + } else if (o.priority < priority) { + return -1; + } else { + return 0; + } + } + } + + protected static final Map<Class<?>, Set<ReadOnlyAxis>> orderedHandlerClasses; + + static { + IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.emf.readonly", "readOnlyHandler"); + + List<HandlerPriorityPair> handlerPriorityPairs = new LinkedList<HandlerPriorityPair>(); + Map<String, HandlerPriorityPair> idMap = new HashMap<String, HandlerPriorityPair>(); + + for (IConfigurationElement elem : configElements) { + if ("readOnlyHandler".equals(elem.getName())) { + try { + HandlerPriorityPair handlerPriorityPair = new HandlerPriorityPair(); + String className = elem.getAttribute("class"); + handlerPriorityPair.handlerClass = Platform.getBundle(elem.getContributor().getName()).loadClass(className); + + handlerPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority")); + + IConfigurationElement[] affinities = elem.getChildren("affinity"); + if ((affinities == null) || (affinities.length == 0)) { + // implicit affinity is with any axis + handlerPriorityPair.axes = ReadOnlyAxis.anyAxis(); + } else { + handlerPriorityPair.axes = EnumSet.noneOf(ReadOnlyAxis.class); + for (IConfigurationElement next : affinities) { + handlerPriorityPair.axes.add(ReadOnlyAxis.valueOf(next.getAttribute("axis").toUpperCase())); + } + } + + String id = elem.getAttribute("id"); + if (id != null) { + // if any then the handler could be overrided by another registration + HandlerPriorityPair oldHandler = idMap.get(id); + if (oldHandler == null) { + idMap.put(id, handlerPriorityPair); + handlerPriorityPairs.add(handlerPriorityPair); + } else { + if (oldHandler.priority < handlerPriorityPair.priority) { + handlerPriorityPairs.remove(oldHandler); + handlerPriorityPairs.add(handlerPriorityPair); + } + } + } else { + // If none the handler can not be overrided + handlerPriorityPairs.add(handlerPriorityPair); + } + } catch (Throwable t) { + // FIXME: We need to catch Throwables because we rely on external contributions. It is required to also catch Errors (such as compilation errors). + // Move this code to an initialization method, because if a throwable is not caught, this will prevent the whole class initialization + Activator.log.error(t); + } + } + } + + Collections.sort(handlerPriorityPairs); + + orderedHandlerClasses = new LinkedHashMap<Class<?>, Set<ReadOnlyAxis>>(); + + for (HandlerPriorityPair next : handlerPriorityPairs) { + orderedHandlerClasses.put(next.handlerClass, next.axes); + } + } + + + @SuppressWarnings("deprecation") + protected static IReadOnlyHandler2 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 (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 AbstractReadOnlyHandler.adapt((IReadOnlyHandler) constructor.newInstance(editingDomain), editingDomain); + } else { + return AbstractReadOnlyHandler.adapt((IReadOnlyHandler) constructor.newInstance(), editingDomain); + } + } else if (org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler.class.isAssignableFrom(constructor.getDeclaringClass())) { + return new OldStyleHandlerAdapter((org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler) constructor.newInstance(), editingDomain); + } + } catch (Exception e) { + } + + return null; + } + + protected Map<ReadOnlyAxis, IReadOnlyHandler2[]> orderedHandlersByAxis; + + public ReadOnlyManager(final EditingDomain editingDomain) { + // Create our transaction cache + cache = ReadOnlyCache.create(this, Activator.getDefault().getReadOnlyCacheExecutor()); + + final Map<ReadOnlyAxis, List<IReadOnlyHandler2>> handlers = new EnumMap<ReadOnlyAxis, List<IReadOnlyHandler2>>(ReadOnlyAxis.class); + cache.run(new Runnable() { + + @Override + public void run() { + for (Map.Entry<Class<?>, Set<ReadOnlyAxis>> roClass : orderedHandlerClasses.entrySet()) { + IReadOnlyHandler2 h = create(roClass.getKey(), editingDomain); + if (h != null) { + h.addReadOnlyListener(getForwardingListener()); + + for (ReadOnlyAxis axis : roClass.getValue()) { + List<IReadOnlyHandler2> list = handlers.get(axis); + if (list == null) { + list = new ArrayList<IReadOnlyHandler2>(); + handlers.put(axis, list); + } + list.add(h); + } + } + } + } + }); + + // Iterate the enumeration to make sure all axes are represented (even if only by an empty array) + orderedHandlersByAxis = new EnumMap<ReadOnlyAxis, IReadOnlyHandler2[]>(ReadOnlyAxis.class); + for (ReadOnlyAxis axis : ReadOnlyAxis.values()) { + List<IReadOnlyHandler2> list = handlers.get(axis); + if (list == null) { + orderedHandlersByAxis.put(axis, new IReadOnlyHandler2[0]); + } else { + orderedHandlersByAxis.put(axis, list.toArray(new IReadOnlyHandler2[list.size()])); + } + } + } + + @Override + public Optional<Boolean> anyReadOnly(Set<ReadOnlyAxis> axes, URI[] uris) { + final Set<URI> uriSet = ImmutableSet.copyOf(uris); + Optional<Boolean> result = cache.getResources(axes, uriSet); + if (result == null) { + result = Optional.absent(); + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && !result.or(Boolean.FALSE); i++) { + if (axes.contains(all[i])) { + result = anyReadOnly(all[i], uris); + } + } + + cache.putResources(axes, uriSet, result); + } + + return result.isPresent() ? result : Optional.of(Boolean.FALSE); + } + + private Optional<Boolean> anyReadOnly(ReadOnlyAxis axis, URI[] uris) { + final Set<URI> uriSet = ImmutableSet.copyOf(uris); + Set<ReadOnlyAxis> axes = axis.singleton(); + Optional<Boolean> result = cache.getResources(axes, uriSet); + if (result == null) { + result = Optional.absent(); + + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length) && !result.isPresent(); i++) { + result = orderedHandlers[i].anyReadOnly(axes, uris); + } + + cache.putResources(axes, uriSet, result); + } + + return result.isPresent() ? result : Optional.of(Boolean.FALSE); + } + + @Override + public Optional<Boolean> isReadOnly(Set<ReadOnlyAxis> axes, EObject eObject) { + Optional<Boolean> result = cache.getObject(axes, eObject); + if (result == null) { + result = Optional.absent(); + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && !result.or(Boolean.FALSE); i++) { + if (axes.contains(all[i])) { + result = isReadOnly(all[i], eObject); + } + } + + cache.putObject(axes, eObject, result); + } + + return result.isPresent() ? result : Optional.of(Boolean.FALSE); + } + + private Optional<Boolean> isReadOnly(ReadOnlyAxis axis, EObject eObject) { + Set<ReadOnlyAxis> axes = axis.singleton(); + Optional<Boolean> result = cache.getObject(axes, eObject); + if (result == null) { + result = Optional.absent(); + + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length) && !result.isPresent(); i++) { + result = orderedHandlers[i].isReadOnly(axes, eObject); + } + + cache.putObject(axes, eObject, result); + } + + return result.isPresent() ? result : Optional.of(Boolean.FALSE); + } + + @Override + public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, URI[] uris) { + Boolean finalResult = true; + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && finalResult; i++) { + if (axes.contains(all[i])) { + finalResult = makeWritable(all[i], uris); + } + } + + return Optional.of(finalResult); + } + + private Boolean makeWritable(ReadOnlyAxis axis, URI[] uris) { + Set<ReadOnlyAxis> axes = axis.singleton(); + Boolean finalResult = true; + + try { + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length); i++) { + Optional<Boolean> isRO = orderedHandlers[i].anyReadOnly(axes, uris); + if (isRO.or(Boolean.FALSE)) { + Optional<Boolean> result = orderedHandlers[i].makeWritable(axes, uris); + // makeWritable should provide an answer since anyReadOnly returned a positive value. + // If no answer consider it a failure + if (!result.or(Boolean.FALSE)) { + finalResult = false; + break; + } + } + } + } finally { + cache.clear(); + } + + return finalResult; + } + + @Override + public Optional<Boolean> makeWritable(Set<ReadOnlyAxis> axes, EObject eObject) { + Boolean finalResult = true; + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && finalResult; i++) { + if (axes.contains(all[i])) { + finalResult = makeWritable(all[i], eObject); + } + } + + return Optional.of(finalResult); + } + + private Boolean makeWritable(ReadOnlyAxis axis, EObject eObject) { + Set<ReadOnlyAxis> axes = axis.singleton(); + Boolean finalResult = true; + + try { + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length); i++) { + Optional<Boolean> isRO = orderedHandlers[i].isReadOnly(axes, eObject); + if (isRO.or(Boolean.FALSE)) { + Optional<Boolean> result = orderedHandlers[i].makeWritable(axes, eObject); + // makeWritable should provide an answer since anyReadOnly returned a positive value + // if no answer consider it a failure + if (!result.or(Boolean.FALSE)) { + finalResult = false; + break; + } + } + } + } finally { + cache.clear(); + } + + return finalResult; + } + + @Override + public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, URI[] uris) { + Boolean result = false; + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && !result; i++) { + if (axes.contains(all[i])) { + result = canMakeWritable(all[i], uris); + } + } + + return Optional.of(result); + } + + private Boolean canMakeWritable(ReadOnlyAxis axis, URI[] uris) { + Set<ReadOnlyAxis> axes = axis.singleton(); + Boolean result = false; + + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length); i++) { + if (orderedHandlers[i].anyReadOnly(axes, uris).or(false)) { + // Only ask a handler about making writable what it considers to be read-only + Optional<Boolean> canMakeWritable = orderedHandlers[i].canMakeWritable(axes, uris); + if (canMakeWritable.isPresent()) { + result = canMakeWritable.get(); + break; + } + } + } + + return result; + } + + @Override + public Optional<Boolean> canMakeWritable(Set<ReadOnlyAxis> axes, EObject object) { + Boolean result = false; + + ReadOnlyAxis[] all = ReadOnlyAxis.values(); + for (int i = 0; (i < all.length) && !result; i++) { + if (axes.contains(all[i])) { + result = canMakeWritable(all[i], object); + } + } + + return Optional.of(result); + } + + private Boolean canMakeWritable(ReadOnlyAxis axis, EObject object) { + Set<ReadOnlyAxis> axes = axis.singleton(); + Boolean result = false; + + IReadOnlyHandler2[] orderedHandlers = orderedHandlersByAxis.get(axis); + for (int i = 0; (i < orderedHandlers.length); i++) { + if (orderedHandlers[i].isReadOnly(axes, object).or(false)) { + // Only ask a handler about making writable what it considers to be read-only + Optional<Boolean> canMakeWritable = orderedHandlers[i].canMakeWritable(axes, object); + if (canMakeWritable.isPresent()) { + result = canMakeWritable.get(); + break; + } + } + } + + return result; + } + + @Override + public void addReadOnlyListener(IReadOnlyListener listener) { + listeners.addIfAbsent(listener); + } + + @Override + public void removeReadOnlyListener(IReadOnlyListener listener) { + listeners.remove(listener); + } + + private IReadOnlyListener getForwardingListener() { + if (forwardingListener == null) { + forwardingListener = new IReadOnlyListener() { + + @Override + public void readOnlyStateChanged(ReadOnlyEvent event) { + ReadOnlyEvent myEvent; + + switch (event.getEventType()) { + case ReadOnlyEvent.OBJECT_READ_ONLY_STATE_CHANGED: + myEvent = new ReadOnlyEvent(ReadOnlyManager.this, event.getAxis(), event.getObject(), event.isReadOnly()); + break; + default: + myEvent = new ReadOnlyEvent(ReadOnlyManager.this, event.getAxis(), event.getResourceURI(), event.isReadOnly()); + break; + } + + notifyReadOnlyStateChanged(myEvent); + } + }; + } + + return forwardingListener; + } + + protected void notifyReadOnlyStateChanged(ReadOnlyEvent event) { + if (!listeners.isEmpty()) { + for (IReadOnlyListener next : listeners) { + try { + next.readOnlyStateChanged(event); + } catch (Exception e) { + Activator.log.error("Uncaught exception in read-only state change listener.", e); //$NON-NLS-1$ + } + } + } + } + + /** + * Obtains a snapshot of the read-only handlers currently registered with me. + * + * @return my read-only handlers, by axis of affiliation. Changes to this collection + * do not affect my registered handlers + * @since 2.0 + */ + public final Map<ReadOnlyAxis, Collection<IReadOnlyHandler2>> getReadOnlyHandlers() { + Map<ReadOnlyAxis, Collection<IReadOnlyHandler2>> result = new HashMap<>(); + + // Be sure not to provide lists that are actually backed by the arrays! + orderedHandlersByAxis.forEach((axis, handlers) -> result.put(axis, Lists.newArrayList(handlers))); + + return result; + } + + // + // Deprecated API + // + + @Override + @Deprecated + public Optional<Boolean> anyReadOnly(URI[] uris) { + return anyReadOnly(permissionAxes(), uris); + } + + @Override + @Deprecated + public Optional<Boolean> isReadOnly(EObject eObject) { + return isReadOnly(permissionAxes(), eObject); + } + + @Override + @Deprecated + public Optional<Boolean> makeWritable(URI[] uris) { + return makeWritable(permissionAxes(), uris); + } + + @Override + @Deprecated + public Optional<Boolean> makeWritable(EObject eObject) { + return makeWritable(permissionAxes(), eObject); + } + + // + // Legacy adapters + // + + @SuppressWarnings("deprecation") + private static final class OldStyleHandlerAdapter extends AbstractReadOnlyHandler { + + private final org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler delegate; + + OldStyleHandlerAdapter(org.eclipse.papyrus.infra.emf.readonly.IReadOnlyHandler handler, EditingDomain editingDomain) { + super(editingDomain); + + this.delegate = handler; + } + + @Override + 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. 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(); + } + + @Override + 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). 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); + } + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/spi/IReadOnlyManagerProcessor.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/spi/IReadOnlyManagerProcessor.java index e56620c8fec..9fa0c779ada 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/spi/IReadOnlyManagerProcessor.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/spi/IReadOnlyManagerProcessor.java @@ -18,7 +18,7 @@ import org.eclipse.papyrus.infra.emf.readonly.ReadOnlyManager; /** * <p> - * An OSGi service interface for hooks to process the a new {@link ReadOnlyManager} + * An OSGi service interface for hooks to process a new {@link ReadOnlyManager} * upon its creation. There is no special provision for notification of when the * manager is no longer being used. * </p> @@ -26,6 +26,8 @@ import org.eclipse.papyrus.infra.emf.readonly.ReadOnlyManager; * Any number of of implementations of this service may be registered; all will be * invoked for each read-only manager. * </p> + * + * @since 2.0 */ @FunctionalInterface public interface IReadOnlyManagerProcessor { diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/.project index 739a883bc87..6d2edc9f146 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/.project @@ -20,9 +20,27 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> </natures> </projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/META-INF/MANIFEST.MF index f1b58b7d9dd..eb196ce4666 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/META-INF/MANIFEST.MF @@ -2,25 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.types.ui;singleton:=true -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.papyrus.infra.emf.types.ui.advices.values.provider.RuntimeValuesAdviceEditPlugin$Implementation -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.emf.ecore;visibility:=reexport, - org.eclipse.emf.ecore.xmi;visibility:=reexport, - org.eclipse.papyrus.infra.constraints;visibility:=reexport, - org.eclipse.papyrus.infra.types;visibility:=reexport, - org.eclipse.papyrus.infra.types.core;bundle-version="1.2.0";visibility:=reexport, - org.eclipse.papyrus.infra.properties;visibility:=reexport, - org.eclipse.emf.edit;visibility:=reexport, - org.eclipse.papyrus.infra.constraints.edit;visibility:=reexport, - org.eclipse.emf.ecore.edit;visibility:=reexport, - org.eclipse.papyrus.infra.types.edit;visibility:=reexport, - org.eclipse.papyrus.infra.properties.edit;visibility:=reexport, - org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.9.0", - org.eclipse.papyrus.views.properties;bundle-version="1.2.0", - org.eclipse.papyrus.infra.services.edit;bundle-version="1.2.0" +Require-Bundle: org.eclipse.papyrus.infra.types.core;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.types.edit;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.properties.edit;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, + org.eclipse.papyrus.views.properties;bundle-version="[1.2.0,2.0.0)", + org.eclipse.papyrus.infra.services.edit;bundle-version="[1.2.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/pom.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/pom.xml index d7e09280b23..4debef138e1 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/pom.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/pom.xml @@ -7,6 +7,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.emf.types.ui</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/.project index 6c62ecfe762..2270d511be4 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/.project @@ -1,28 +1,46 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.papyrus.infra.emf.types</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.eclipse.pde.PluginNature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrus.infra.emf.types</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> + </natures> +</projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/META-INF/MANIFEST.MF index d56fcb5df95..76a601a2ec2 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/META-INF/MANIFEST.MF @@ -1,43 +1,27 @@ -Manifest-Version: 1.0
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
- org.eclipse.emf.ecore;visibility:=reexport,
- org.eclipse.emf.ecore.xmi;visibility:=reexport,
- org.eclipse.papyrus.infra.types;visibility:=reexport,
- org.eclipse.papyrus.infra.types.rulebased;visibility:=reexport,
- org.eclipse.papyrus.infra.constraints;visibility:=reexport,
- org.eclipse.papyrus.infra.types;visibility:=reexport,
- org.eclipse.uml2.uml;visibility:=reexport,
- org.eclipse.uml2.types;visibility:=reexport,
- org.eclipse.papyrus.infra.properties;visibility:=reexport,
- org.eclipse.papyrus.infra.types.rulebased;bundle-version="1.2.0";visibility:=reexport,
- org.eclipse.emf.edit;visibility:=reexport,
- org.eclipse.papyrus.infra.constraints.edit;visibility:=reexport,
- org.eclipse.emf.ecore.edit;visibility:=reexport,
- org.eclipse.papyrus.infra.types.edit;visibility:=reexport,
- org.eclipse.papyrus.infra.properties.edit;bundle-version="1.2.0";visibility:=reexport,
- org.eclipse.uml2.uml.edit;visibility:=reexport,
- org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.services.edit;bundle-version="1.2.0",
- org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.4.0",
- org.eclipse.core.databinding;bundle-version="1.4.1",
- org.eclipse.papyrus.infra.core;bundle-version="1.2.0"
-Export-Package: org.eclipse.papyrus.infra.emf.types,
- org.eclipse.papyrus.infra.emf.types.advices.values,
- org.eclipse.papyrus.infra.emf.types.advices.values.impl,
- org.eclipse.papyrus.infra.emf.types.advices.values.provider,
- org.eclipse.papyrus.infra.emf.types.advices.values.util,
- org.eclipse.papyrus.infra.emf.types.converter,
- org.eclipse.papyrus.infra.emf.types.rules.container,
- org.eclipse.papyrus.infra.emf.types.rules.container.impl,
- org.eclipse.papyrus.infra.emf.types.rules.container.provider,
- org.eclipse.papyrus.infra.emf.types.rules.container.util
-Bundle-Vendor: %providerName
-Bundle-ActivationPolicy: lazy
-Bundle-ClassPath: .
-Bundle-Version: 1.2.0.qualifier
-Bundle-Name: %pluginName
-Bundle-Localization: plugin
-Bundle-ManifestVersion: 2
-Bundle-Activator: org.eclipse.papyrus.infra.emf.types.rules.container.provider.InvariantContainerRuleEditPlugin$Implementation
-Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.types;singleton:=true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Manifest-Version: 1.0 +Require-Bundle: org.eclipse.papyrus.infra.types.rulebased;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.types.rulebased;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.properties.edit;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, + org.eclipse.uml2.uml.edit;bundle-version="[5.1.0,6.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.services.edit;bundle-version="[1.2.0,2.0.0)", + org.eclipse.core.databinding;bundle-version="[1.6.0,2.0.0)";visibility:=reexport +Export-Package: org.eclipse.papyrus.infra.emf.types, + org.eclipse.papyrus.infra.emf.types.advices.values, + org.eclipse.papyrus.infra.emf.types.advices.values.impl, + org.eclipse.papyrus.infra.emf.types.advices.values.provider, + org.eclipse.papyrus.infra.emf.types.advices.values.util, + org.eclipse.papyrus.infra.emf.types.converter, + org.eclipse.papyrus.infra.emf.types.rules.container, + org.eclipse.papyrus.infra.emf.types.rules.container.impl, + org.eclipse.papyrus.infra.emf.types.rules.container.provider, + org.eclipse.papyrus.infra.emf.types.rules.container.util +Bundle-Vendor: %providerName +Bundle-ActivationPolicy: lazy +Bundle-ClassPath: . +Bundle-Version: 2.0.0.qualifier +Bundle-Name: %pluginName +Bundle-Localization: plugin +Bundle-ManifestVersion: 2 +Bundle-Activator: org.eclipse.papyrus.infra.emf.types.rules.container.provider.InvariantContainerRuleEditPlugin$Implementation +Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.types;singleton:=true +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/pom.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/pom.xml index a3299c0e10a..ea2d92d93e0 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/pom.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/pom.xml @@ -7,6 +7,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.emf.types</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/.project index 2e261c7b71c..a79b6ba3e7f 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/.project @@ -1,28 +1,52 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.papyrus.infra.emf</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrus.infra.emf</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> + </natures> +</projectDescription> 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 f79d3178a14..ea5faf931d5 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 @@ -1,28 +1,24 @@ -Manifest-Version: 1.0
-Export-Package: org.eclipse.papyrus.infra.emf,
- org.eclipse.papyrus.infra.emf.adapters,
- org.eclipse.papyrus.infra.emf.advice,
- org.eclipse.papyrus.infra.emf.commands,
- org.eclipse.papyrus.infra.emf.edit.domain,
- org.eclipse.papyrus.infra.emf.requests,
- org.eclipse.papyrus.infra.emf.resource,
- org.eclipse.papyrus.infra.emf.resource.index,
- org.eclipse.papyrus.infra.emf.spi.resolver,
- org.eclipse.papyrus.infra.emf.utils
-Require-Bundle: org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.tools;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
- org.eclipse.core.expressions;bundle-version="3.4.400",
- org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.7.0",
- com.google.guava;bundle-version="11.0.0",
- org.eclipse.papyrus.emf.facet.custom.core;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0"
-Bundle-Vendor: Eclipse Modeling Project
-Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.2.0.qualifier
-Bundle-Name: EMF Tools
-Bundle-Activator: org.eclipse.papyrus.infra.emf.Activator
-Bundle-ManifestVersion: 2
-Bundle-Description: %pluginDescription
-Bundle-SymbolicName: org.eclipse.papyrus.infra.emf;singleton:=true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Manifest-Version: 1.0 +Export-Package: org.eclipse.papyrus.infra.emf, + org.eclipse.papyrus.infra.emf.adapters, + org.eclipse.papyrus.infra.emf.advice, + org.eclipse.papyrus.infra.emf.commands, + org.eclipse.papyrus.infra.emf.edit.domain, + org.eclipse.papyrus.infra.emf.requests, + org.eclipse.papyrus.infra.emf.resource, + org.eclipse.papyrus.infra.emf.resource.index, + org.eclipse.papyrus.infra.emf.spi.resolver, + org.eclipse.papyrus.infra.emf.utils +Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.core.expressions;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, + org.eclipse.gmf.runtime.emf.type.core;bundle-version="[1.9.0,2.0.0)";visibility:=reexport, + org.eclipse.papyrus.emf.facet.custom.core;bundle-version="[1.2.0,2.0.0)";visibility:=reexport +Bundle-Vendor: Eclipse Modeling Project +Bundle-ActivationPolicy: lazy +Bundle-Version: 2.0.0.qualifier +Bundle-Name: EMF Tools +Bundle-Activator: org.eclipse.papyrus.infra.emf.Activator +Bundle-ManifestVersion: 2 +Bundle-Description: %pluginDescription +Bundle-SymbolicName: org.eclipse.papyrus.infra.emf;singleton:=true +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/pom.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/pom.xml index cc4360ddd2d..afbd61aedc8 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/pom.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/pom.xml @@ -7,6 +7,6 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.emf</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> -</project> +</project>
\ No newline at end of file diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/Activator.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/Activator.java index a3c0e69cc06..0698bdea266 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/Activator.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/Activator.java @@ -121,6 +121,7 @@ public class Activator extends Plugin { * Obtain the instance of the {@link EObject} resolver service, if any. * * @return the object resolver service (never {@code null} while this bundle is active) + * @since 2.0 */ public IEObjectResolver getEObjectResolver() { return resolverService; diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/EObjectResolverService.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/EObjectResolverService.java index dd9f1e67d95..1892e863144 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/EObjectResolverService.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/EObjectResolverService.java @@ -19,6 +19,8 @@ import org.osgi.framework.BundleContext; /** * A resolver that delegates to registered OSGi services in a <em>Chain of Command</em> * pattern to provide the first available service result. + * + * @since 2.0 */ public class EObjectResolverService implements IEObjectResolver { private final CompositeServiceTracker<IEObjectResolver> tracker; diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/IEObjectResolver.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/IEObjectResolver.java index 8f968d2db5e..82bf50aacb0 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/IEObjectResolver.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/IEObjectResolver.java @@ -20,6 +20,8 @@ import org.eclipse.emf.ecore.EObject; * A service interface for resolution of the {@linkplain EObject EMF object} wrapped * in an EMF Facet content-provider node or anything else that doesn't implement * the usual {@link IAdaptable} protocol with respect to provision of an {@link EObject}. + * + * @since 2.0 */ @FunctionalInterface public interface IEObjectResolver { 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 feef59d314d..bd806fec1c2 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 @@ -1,1122 +1,1124 @@ -/*****************************************************************************
- * Copyright (c) 2010, 2016 CEA LIST, Christian W. Damus, 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:
- * 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)
- * Christian W. Damus (CEA) - bugs 323802, 429826, 408491, 432813, 422257
- * Christian W. Damus - bugs 469188, 485220
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.emf.utils;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-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.common.util.WrappedException;
-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.EcoreUtil;
-import org.eclipse.emf.ecore.xmi.XMIResource;
-import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
-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 org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
-import org.eclipse.papyrus.infra.emf.Activator;
-import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-/**
- * A Helper class for manipulating EMF Objects
- *
- * @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) {
- String message = String.format("Class %s not found in metamodel: %s (%s)", className, metamodel.getName(), metamodel.getNsURI());//$NON-NLS-1$
- Activator.log.warn(message);
- return false;
- }
-
- return theClass.isInstance(element);
- }
-
-
- /**
- * 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 URI of 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(EObject selectedItem, String className, String nsUri) {
- EClass actualEClass = selectedItem.eClass();
-
- // Exact match
- if (isExactMatch(actualEClass, className, nsUri)) {
- return true;
- }
-
- List<EClass> allSuperTypes = actualEClass.getEAllSuperTypes();
- for (EClass eClass : allSuperTypes) {
- if (isExactMatch(eClass, className, nsUri)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Tests whether the given EClass has the given className and belongs to the EPackage represented by nsUri
- *
- * @param eClass
- * The EClass to test
- * @param className
- *
- * @param nsUri
- * @return
- * True if the EClass' name is className and the EClass' EPackage's nsURI is nsUri
- */
- private static boolean isExactMatch(EClass eClass, String className, String nsUri) {
- return className.equals(eClass.getName()) && nsUri.equals(eClass.getEPackage().getNsURI());
- }
-
- /**
- * 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;
- }
-
- /**
- * Returns the EObject corresponding to the input object
- * Tests if the input is an EObject, or if it is Adaptable
- * to an EObject
- *
- * @param source
- * @return An EObject corresponding to the input source, or null
- * if the EObject could not be resolved
- */
- public static EObject getEObject(final Object source) {
-
- // Support for EMF 0.2 CustomizedTree: The TreeElements are IAdaptable, but the
- // EObject adapter for some of them (e.g. reference node) is not what we need
- Object resolved = Activator.getDefault().getEObjectResolver().resolve(source);
- if ((resolved != source) && isEMFModelElement(resolved)) {
- return (EObject) resolved;
- }
-
- // General case
- if (isEMFModelElement(source)) {
- return (EObject) source;
- }
-
- // Try to get an intrinsic adapter
- if (source instanceof IAdaptable) {
- EObject eObject = ((IAdaptable) source).getAdapter(EObject.class);
- if (eObject == null) { // EMF Facet 0.1
- eObject = ((IAdaptable) source).getAdapter(EReference.class);
- }
-
- if (eObject != null) {
- return asEMFModelElement(eObject); // in case the adapter is a CDOResource
- }
- }
-
- // External adapter (last ditch case)
- if (source != null) {
- return asEMFModelElement(Platform.getAdapterManager().getAdapter(source, EObject.class));
- }
-
- return null;
- }
-
- /**
- * 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.
- *
- * @param source
- * @return
- * The source object's editing domain, or null if it couldn't be found
- */
- public static EditingDomain resolveEditingDomain(final Object source) {
- return resolveEditingDomain(getEObject(source));
- }
-
- /**
- * Retrieve the EditingDomain for the given source EObject
- *
- * @param source
- * @return
- * The source eObject's editing domain, or null if it couldn't be found
- */
- public static EditingDomain resolveEditingDomain(final EObject source) {
- EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(source);
- if (domain == null) {
- try {
- domain = ServiceUtils.getInstance().getTransactionalEditingDomain(null);
- } catch (ServiceException e) {
- // Ignore: We cannot find the domain
- }
- }
- return domain;
- }
-
- /**
- * 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 {
- assert resourceSet != null : "null resourceSet"; //$NON-NLS-1$
- if (resourceSet == null) {
- Activator.log.warn("Created a new resourceSet to load an EMF model in " + Activator.log.getCallerMethod()); //$NON-NLS-1$
- 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;
- }
-
- /**
- * Completely unloads a resource set so that it and all the models it contained may be reclaimed by the
- * Java garbage collector. This includes, at least:
- * <ul>
- * <li>unloading all resources in the set, which converts all model elements to proxies and removes all adapters from them</li>
- * <li>removing all resources from the set</li>
- * <li>removing all adapters from all resources</li>
- * <li>removing all adapters from the resource set</li>
- * </ul>
- *
- * @param resourceSet
- * the resource set to purge
- */
- public static void unload(ResourceSet resourceSet) {
- List<Resource> resources = ImmutableList.copyOf(resourceSet.getResources());
- resourceSet.getResources().clear();
- for (Resource next : resources) {
- next.unload();
- next.eAdapters().clear();
- }
- resourceSet.eAdapters().clear();
-
- // Clear the package registry (it may contain dynamic profile EPackages that we don't
- // want to leak in BasicExtendedMetaData instances attached to static EPackages)
- // Works around EMF bug 433108
- EPackage.Registry packageRegistry = resourceSet.getPackageRegistry();
- if (packageRegistry != null) {
- packageRegistry.clear();
- }
- }
-
- /**
- * 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());
- }
-
- /**
- * Gets the object of a given {@code type} containing an {@code object}, or the
- * {@code object} itself if it is of that {@code type}.
- *
- * @param object
- * the object for which to search for a container
- * @param type
- * the type of container to find
- *
- * @return the container of the requested {@code type}, or {@code null} if none
- */
- public static <T extends EObject> T getContainer(EObject object, EClass type) {
- T result = null;
-
- for (EObject next = object; (next != null) && (result == null); next = next.eContainer()) {
- if (type.isInstance(next)) {
- @SuppressWarnings("unchecked")
- T nextAsT = (T) next;
- result = nextAsT;
- }
- }
-
- return result;
- }
-
- /**
- * Gets the object of a given {@code type} containing an {@code object}, or the
- * {@code object} itself if it is of that {@code type}.
- *
- * @param object
- * the object for which to search for a container
- * @param type
- * the type of container to find
- *
- * @return the container of the requested {@code type}, or {@code null} if none
- */
- public static <T extends EObject> T getContainer(EObject object, Class<T> type) {
- T result = null;
-
- for (EObject next = object; (next != null) && (result == null); next = next.eContainer()) {
- if (type.isInstance(next)) {
- result = type.cast(next);
- }
- }
-
- return result;
- }
-
- /**
- * 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 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 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(axes, eObject, domain);
- }
-
- /**
- * 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(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).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) {
- return domain.isReadOnly(eObject.eResource());
- }
- }
- return false;
- }
-
- /**
- * 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 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 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);
- }
-
- // no editing domain : use file system attribute
- ResourceSet resourceSet = resource.getResourceSet();
-
- if (resourceSet == null) {
- return false;
- }
-
- Map<String, ?> attributes = resourceSet.getURIConverter().getAttributes(resource.getURI(), null);
- Boolean readOnly = (Boolean) attributes.get(URIConverter.ATTRIBUTE_READ_ONLY);
-
- return readOnly == null ? false : readOnly;
- }
-
- /**
- * Tests if an object that is read only could possibly be made writable by some means (file system attributes, team provider hook, database
- * permissions, etc.)
- *
- * @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(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(axes, eObject).or(false);
- }
- }
- return false;
- }
-
- /**
- * Tests if a resource that is read only could possibly be made writable by some means (file system attributes, team provider hook, database
- * permissions, etc.)
- *
- * @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(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(axes, new URI[] { resource.getURI() }).or(false);
- }
- }
- return false;
- }
-
- /**
- * 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) {
- EClassifier eType = feature.getEType();
- if (eType == null) {
- return false;
- }
-
- // EEnums are always required, as an EEnum always has a default value
- if (eType 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 (eType.getInstanceClass() != null && eType.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 org.eclipse.papyrus.infra.core.utils.EMFHelper.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;
- }
-
- /**
- * Computes the path from the root EObject to the given element, as a List of EObjects
- *
- * @param element
- * @return
- */
- public static List<EObject> getContainmentPath(EObject element) {
- List<EObject> result;
- if (element.eContainer() == null) {
- result = new LinkedList<EObject>();
- result.add(element);
- return result;
- } else {
- result = getContainmentPath(element.eContainer());
- result.add(element);
- }
- return result;
- }
-
- /**
- * Returns the given element, reloaded into the resource set of the context element,
- * or the source element itself if not possible.
- *
- * Use this method for e.g. loading an element from a shared resource set into another resource set
- * (Apply a registered profile/library, drop an element from the project explorer, ...)
- *
- * @param element
- * @param contextElement
- * @return
- */
- public static <T extends EObject> T reloadIntoContext(T element, EObject contextElement) {
- ResourceSet sourceResourceSet = getResourceSet(element);
- ResourceSet loadingContext = getResourceSet(contextElement);
-
- if (sourceResourceSet == loadingContext || loadingContext == null) {
- return element;
- }
-
- URI sourceURI = EcoreUtil.getURI(element);
- EObject result = loadingContext.getEObject(sourceURI, true);
-
- return (T) result;
- }
-
- /**
- * Returns the resourceSet owning this eObject, or null if it is detached
- *
- * @param eObject
- */
- public static ResourceSet getResourceSet(EObject eObject) {
- Resource resource = (eObject == null) ? null : eObject.eResource();
- return (resource == null) ? null : resource.getResourceSet();
- }
-
- /**
- * Best-effort loads a resource, returning the first root element of the requested {@code type}. Unlike the {@link #loadChecked(ResourceSet, URI, Class) loadChecked} method, this will never throw an exception.
- *
- * @param rset
- * a resource set in which to load the resource
- * @param uri
- * the URI of the resource to load
- * @param type
- * the type of root element to retrieve
- *
- * @return the requested root element, or {@code null} if the resource does not contain such an element or could not be loaded
- *
- * @see #loadChecked(ResourceSet, URI, Class)
- */
- public static <T extends EObject> T load(ResourceSet rset, URI uri, Class<T> type) {
- T result = null;
-
- try {
- result = loadChecked(rset, uri, type);
- } catch (Exception e) {
- Activator.log.error("Exception in loading resource " + uri, e); //$NON-NLS-1$
-
- // Maybe it was partially loaded? If so, try again
- Resource res = rset.getResource(uri, false);
- if ((res != null) && res.isLoaded()) {
- result = Iterables.getFirst(Iterables.filter(res.getContents(), type), null);
- }
- }
-
- return result;
- }
-
- /**
- * Best-effort loads a resource, returning the first root element of the requested {@code type}.
- *
- * @param rset
- * a resource set in which to load the resource
- * @param uri
- * the URI of the resource to load
- * @param type
- * the type of root element to retrieve
- *
- * @return the requested root element, or {@code null} if the resource does not contain such an element or could not be loaded
- * @throws IOException
- * on an I/O problem in loading the resource
- * @throw RuntimeException on any other unforeseen (usually programming error) problem
- *
- * @see #load(ResourceSet, URI, Class)
- */
- public static <T extends EObject> T loadChecked(ResourceSet rset, URI uri, Class<T> type) throws IOException {
- try {
- return Iterables.getFirst(Iterables.filter(rset.getResource(uri, true).getContents(), type), null);
- } catch (WrappedException e) {
- if (e.exception() instanceof IOException) {
- throw (IOException) e.exception();
- } else if (e.exception() instanceof RuntimeException) {
- throw (RuntimeException) e.exception();
- } else {
- throw e;
- }
- }
- }
-}
+/***************************************************************************** + * Copyright (c) 2010, 2016 CEA LIST, Christian W. Damus, 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: + * 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) + * Christian W. Damus (CEA) - bugs 323802, 429826, 408491, 432813, 422257 + * Christian W. Damus - bugs 469188, 485220 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.emf.utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +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.common.util.WrappedException; +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.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMIResource; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +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 org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.utils.ServiceUtils; +import org.eclipse.papyrus.infra.emf.Activator; +import org.eclipse.papyrus.infra.tools.util.PlatformHelper; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +/** + * A Helper class for manipulating EMF Objects + * + * @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) { + String message = String.format("Class %s not found in metamodel: %s (%s)", className, metamodel.getName(), metamodel.getNsURI());//$NON-NLS-1$ + Activator.log.warn(message); + return false; + } + + return theClass.isInstance(element); + } + + + /** + * 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 URI of 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(EObject selectedItem, String className, String nsUri) { + EClass actualEClass = selectedItem.eClass(); + + // Exact match + if (isExactMatch(actualEClass, className, nsUri)) { + return true; + } + + List<EClass> allSuperTypes = actualEClass.getEAllSuperTypes(); + for (EClass eClass : allSuperTypes) { + if (isExactMatch(eClass, className, nsUri)) { + return true; + } + } + + return false; + } + + /** + * Tests whether the given EClass has the given className and belongs to the EPackage represented by nsUri + * + * @param eClass + * The EClass to test + * @param className + * + * @param nsUri + * @return + * True if the EClass' name is className and the EClass' EPackage's nsURI is nsUri + */ + private static boolean isExactMatch(EClass eClass, String className, String nsUri) { + return className.equals(eClass.getName()) && nsUri.equals(eClass.getEPackage().getNsURI()); + } + + /** + * 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; + } + + /** + * Returns the EObject corresponding to the input object + * Tests if the input is an EObject, or if it is Adaptable + * to an EObject + * + * @param source + * @return An EObject corresponding to the input source, or null + * if the EObject could not be resolved + */ + public static EObject getEObject(final Object source) { + + // Support for EMF 0.2 CustomizedTree: The TreeElements are IAdaptable, but the + // EObject adapter for some of them (e.g. reference node) is not what we need + Object resolved = Activator.getDefault().getEObjectResolver().resolve(source); + if ((resolved != source) && isEMFModelElement(resolved)) { + return (EObject) resolved; + } + + // General case + if (isEMFModelElement(source)) { + return (EObject) source; + } + + // Try to get an intrinsic adapter + if (source instanceof IAdaptable) { + EObject eObject = ((IAdaptable) source).getAdapter(EObject.class); + if (eObject == null) { // EMF Facet 0.1 + eObject = ((IAdaptable) source).getAdapter(EReference.class); + } + + if (eObject != null) { + return asEMFModelElement(eObject); // in case the adapter is a CDOResource + } + } + + // External adapter (last ditch case) + if (source != null) { + return asEMFModelElement(Platform.getAdapterManager().getAdapter(source, EObject.class)); + } + + return null; + } + + /** + * 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. + * + * @param source + * @return + * The source object's editing domain, or null if it couldn't be found + */ + public static EditingDomain resolveEditingDomain(final Object source) { + return resolveEditingDomain(getEObject(source)); + } + + /** + * Retrieve the EditingDomain for the given source EObject + * + * @param source + * @return + * The source eObject's editing domain, or null if it couldn't be found + */ + public static EditingDomain resolveEditingDomain(final EObject source) { + EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(source); + if (domain == null) { + try { + domain = ServiceUtils.getInstance().getTransactionalEditingDomain(null); + } catch (ServiceException e) { + // Ignore: We cannot find the domain + } + } + return domain; + } + + /** + * 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 { + assert resourceSet != null : "null resourceSet"; //$NON-NLS-1$ + if (resourceSet == null) { + Activator.log.warn("Created a new resourceSet to load an EMF model in " + Activator.log.getCallerMethod()); //$NON-NLS-1$ + 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; + } + + /** + * Completely unloads a resource set so that it and all the models it contained may be reclaimed by the + * Java garbage collector. This includes, at least: + * <ul> + * <li>unloading all resources in the set, which converts all model elements to proxies and removes all adapters from them</li> + * <li>removing all resources from the set</li> + * <li>removing all adapters from all resources</li> + * <li>removing all adapters from the resource set</li> + * </ul> + * + * @param resourceSet + * the resource set to purge + */ + public static void unload(ResourceSet resourceSet) { + List<Resource> resources = ImmutableList.copyOf(resourceSet.getResources()); + resourceSet.getResources().clear(); + for (Resource next : resources) { + next.unload(); + next.eAdapters().clear(); + } + resourceSet.eAdapters().clear(); + + // Clear the package registry (it may contain dynamic profile EPackages that we don't + // want to leak in BasicExtendedMetaData instances attached to static EPackages) + // Works around EMF bug 433108 + EPackage.Registry packageRegistry = resourceSet.getPackageRegistry(); + if (packageRegistry != null) { + packageRegistry.clear(); + } + } + + /** + * 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()); + } + + /** + * Gets the object of a given {@code type} containing an {@code object}, or the + * {@code object} itself if it is of that {@code type}. + * + * @param object + * the object for which to search for a container + * @param type + * the type of container to find + * + * @return the container of the requested {@code type}, or {@code null} if none + * @since 2.0 + */ + public static <T extends EObject> T getContainer(EObject object, EClass type) { + T result = null; + + for (EObject next = object; (next != null) && (result == null); next = next.eContainer()) { + if (type.isInstance(next)) { + @SuppressWarnings("unchecked") + T nextAsT = (T) next; + result = nextAsT; + } + } + + return result; + } + + /** + * Gets the object of a given {@code type} containing an {@code object}, or the + * {@code object} itself if it is of that {@code type}. + * + * @param object + * the object for which to search for a container + * @param type + * the type of container to find + * + * @return the container of the requested {@code type}, or {@code null} if none + * @since 2.0 + */ + public static <T extends EObject> T getContainer(EObject object, Class<T> type) { + T result = null; + + for (EObject next = object; (next != null) && (result == null); next = next.eContainer()) { + if (type.isInstance(next)) { + result = type.cast(next); + } + } + + return result; + } + + /** + * 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 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 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(axes, eObject, domain); + } + + /** + * 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(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).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) { + return domain.isReadOnly(eObject.eResource()); + } + } + return false; + } + + /** + * 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 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 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); + } + + // no editing domain : use file system attribute + ResourceSet resourceSet = resource.getResourceSet(); + + if (resourceSet == null) { + return false; + } + + Map<String, ?> attributes = resourceSet.getURIConverter().getAttributes(resource.getURI(), null); + Boolean readOnly = (Boolean) attributes.get(URIConverter.ATTRIBUTE_READ_ONLY); + + return readOnly == null ? false : readOnly; + } + + /** + * Tests if an object that is read only could possibly be made writable by some means (file system attributes, team provider hook, database + * permissions, etc.) + * + * @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(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(axes, eObject).or(false); + } + } + return false; + } + + /** + * Tests if a resource that is read only could possibly be made writable by some means (file system attributes, team provider hook, database + * permissions, etc.) + * + * @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(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(axes, new URI[] { resource.getURI() }).or(false); + } + } + return false; + } + + /** + * 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) { + EClassifier eType = feature.getEType(); + if (eType == null) { + return false; + } + + // EEnums are always required, as an EEnum always has a default value + if (eType 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 (eType.getInstanceClass() != null && eType.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 org.eclipse.papyrus.infra.core.utils.EMFHelper.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; + } + + /** + * Computes the path from the root EObject to the given element, as a List of EObjects + * + * @param element + * @return + */ + public static List<EObject> getContainmentPath(EObject element) { + List<EObject> result; + if (element.eContainer() == null) { + result = new LinkedList<EObject>(); + result.add(element); + return result; + } else { + result = getContainmentPath(element.eContainer()); + result.add(element); + } + return result; + } + + /** + * Returns the given element, reloaded into the resource set of the context element, + * or the source element itself if not possible. + * + * Use this method for e.g. loading an element from a shared resource set into another resource set + * (Apply a registered profile/library, drop an element from the project explorer, ...) + * + * @param element + * @param contextElement + * @return + */ + public static <T extends EObject> T reloadIntoContext(T element, EObject contextElement) { + ResourceSet sourceResourceSet = getResourceSet(element); + ResourceSet loadingContext = getResourceSet(contextElement); + + if (sourceResourceSet == loadingContext || loadingContext == null) { + return element; + } + + URI sourceURI = EcoreUtil.getURI(element); + EObject result = loadingContext.getEObject(sourceURI, true); + + return (T) result; + } + + /** + * Returns the resourceSet owning this eObject, or null if it is detached + * + * @param eObject + */ + public static ResourceSet getResourceSet(EObject eObject) { + Resource resource = (eObject == null) ? null : eObject.eResource(); + return (resource == null) ? null : resource.getResourceSet(); + } + + /** + * Best-effort loads a resource, returning the first root element of the requested {@code type}. Unlike the {@link #loadChecked(ResourceSet, URI, Class) loadChecked} method, this will never throw an exception. + * + * @param rset + * a resource set in which to load the resource + * @param uri + * the URI of the resource to load + * @param type + * the type of root element to retrieve + * + * @return the requested root element, or {@code null} if the resource does not contain such an element or could not be loaded + * + * @see #loadChecked(ResourceSet, URI, Class) + */ + public static <T extends EObject> T load(ResourceSet rset, URI uri, Class<T> type) { + T result = null; + + try { + result = loadChecked(rset, uri, type); + } catch (Exception e) { + Activator.log.error("Exception in loading resource " + uri, e); //$NON-NLS-1$ + + // Maybe it was partially loaded? If so, try again + Resource res = rset.getResource(uri, false); + if ((res != null) && res.isLoaded()) { + result = Iterables.getFirst(Iterables.filter(res.getContents(), type), null); + } + } + + return result; + } + + /** + * Best-effort loads a resource, returning the first root element of the requested {@code type}. + * + * @param rset + * a resource set in which to load the resource + * @param uri + * the URI of the resource to load + * @param type + * the type of root element to retrieve + * + * @return the requested root element, or {@code null} if the resource does not contain such an element or could not be loaded + * @throws IOException + * on an I/O problem in loading the resource + * @throw RuntimeException on any other unforeseen (usually programming error) problem + * + * @see #load(ResourceSet, URI, Class) + */ + public static <T extends EObject> T loadChecked(ResourceSet rset, URI uri, Class<T> type) throws IOException { + try { + return Iterables.getFirst(Iterables.filter(rset.getResource(uri, true).getContents(), type), null); + } catch (WrappedException e) { + if (e.exception() instanceof IOException) { + throw (IOException) e.exception(); + } else if (e.exception() instanceof RuntimeException) { + throw (RuntimeException) e.exception(); + } else { + throw e; + } + } + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/.project b/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/.project index 16fd397042a..8368019aeaa 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/.project +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/.project @@ -20,9 +20,33 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.oomph.version.VersionBuilder</name> + <arguments> + <dictionary> + <key>check.maven.pom</key> + <value>true</value> + </dictionary> + <dictionary> + <key>ignore.lower.bound.dependency.ranges</key> + <value>true</value> + </dictionary> + <dictionary> + <key>release.path</key> + <value>/org.eclipse.papyrus.releng.main.release/release.xml</value> + </dictionary> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>org.eclipse.oomph.version.VersionNature</nature> </natures> </projectDescription> diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/META-INF/MANIFEST.MF index cddde77a32d..4ed317ef7fd 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/META-INF/MANIFEST.MF @@ -7,26 +7,16 @@ Export-Package: org.eclipse.papyrus.infra.ui.emf.adapters, org.eclipse.papyrus.infra.ui.emf.utils, org.eclipse.papyrus.infra.ui.internal.emf;x-internal:=true, org.eclipse.papyrus.infra.ui.internal.emf.expressions;x-internal:=true, - org.eclipse.papyrus.infra.ui.internal.emf.readonly.handlers -Require-Bundle: org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0", - org.eclipse.papyrus.infra.widgets;bundle-version="1.2.0", - org.eclipse.emf.edit.ui;bundle-version="2.8.0", - org.eclipse.emf.databinding;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core;bundle-version="1.2.0", - org.eclipse.papyrus.infra.services.labelprovider;bundle-version="1.2.0", - org.eclipse.gmf.runtime.notation;bundle-version="1.5.0", - org.eclipse.core.expressions;bundle-version="3.4.400", - org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.7.0", - com.google.guava;bundle-version="11.0.0", - org.eclipse.papyrus.emf.facet.custom.ui;bundle-version="1.2.0", - org.eclipse.papyrus.emf.facet.custom.core;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core.sasheditor.di;bundle-version="1.2.0", - org.eclipse.papyrus.infra.emf;bundle-version="1.2.0", - org.eclipse.papyrus.infra.emf.readonly;bundle-version="1.2.0", - org.eclipse.papyrus.infra.onefile;bundle-version="1.2.0", - org.eclipse.papyrus.infra.ui;bundle-version="1.2.0", - org.eclipse.papyrus.infra.tools;bundle-version="1.2.0", - org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0" + org.eclipse.papyrus.infra.ui.internal.emf.readonly.handlers;x-internal:=true +Require-Bundle: org.eclipse.emf.edit.ui;bundle-version="[2.12.0,3.0.0)";visibility:=reexport, + org.eclipse.emf.databinding;bundle-version="[1.3.0,2.0.0)";visibility:=reexport, + org.eclipse.core.databinding.property;bundle-version="[1.6.0,2.0.0)";visibility:=reexport, + org.eclipse.gmf.runtime.notation;bundle-version="[1.8.0,2.0.0)", + org.eclipse.papyrus.emf.facet.custom.ui;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, + org.eclipse.papyrus.emf.facet.custom.core;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, + org.eclipse.papyrus.infra.emf.readonly;bundle-version="[2.0.0,3.0.0)", + org.eclipse.papyrus.infra.onefile;bundle-version="[2.0.0,3.0.0)", + org.eclipse.papyrus.infra.ui;bundle-version="[1.2.0,2.0.0)";visibility:=reexport Bundle-Vendor: %pluginProvider Bundle-ActivationPolicy: lazy Bundle-Version: 1.2.0.qualifier |