Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-02-11 21:38:52 +0000
committerChristian W. Damus2016-02-24 22:26:27 +0000
commit09fde7a4087685b065b7f1e40375686fb9f19f2a (patch)
tree36668c0515a08586179a74cefcf1dc6197311d70 /plugins/infra/emf
parent2f0dd86c51f8543f56a99cd4371965a01287fcaa (diff)
downloadorg.eclipse.papyrus-09fde7a4087685b065b7f1e40375686fb9f19f2a.tar.gz
org.eclipse.papyrus-09fde7a4087685b065b7f1e40375686fb9f19f2a.tar.xz
org.eclipse.papyrus-09fde7a4087685b065b7f1e40375686fb9f19f2a.zip
Bug 485220: [Architecture] Provide a more modular architecture
https://bugs.eclipse.org/bugs/show_bug.cgi?id=485220 Implement version management: PDE API Tooling and Oomph Version Management. Introduce two new plug-in projects to manage versioning using Oomph: * org.eclipse.papyrus.releng.main.release for the Main bundles and features * org.eclipse.papyrus.releng.dev.release for the Dev Tools Add new menu actions to the Dev Tools: * main menu bar: * synchronize POM and manifest versions * "Configure" context menu on bundle projects and MANIFEST.MF * optimize bundle dependencies and re-exports * update dependency version ranges to match current workspace and PDE target Remove obsolete menu actions from the Dev Tools: * main menu bar: * Set all Papyrus feature versions * Set all Papyrus plug-in versions * Set versions of all Papyrus dependencies in Papyrus plug-ins Fix versioning errors reported by PDE and Oomph. Ensure proper version ranges consistent with latest build target. Optimize the dependencies of all Papyrus Main bundles and Dev Tools. Remove version- and reexport-checking tests in the BundlesTests that are now not needed because, on the one hand, we now implement discrete bundle versioning (managed by PDE/Oomph) and on the other, we now use re-exports properly to ensure classpath consistency in clients of a bundle's API. Thorough overhaul of the "project editors" API, including: * rationalize the API interfaces * refactor the all-in-one PluginEditor class from the customization bundle to the project-editors bundle * update clients in the Customization and DSML Validation components * fix a bunch of operations that didn't work * add missing operations required by the new Dev Tools actions * complete some unimplemented APIs * add a comprehensive JUnit test suite covering all of the project-editors API Change-Id: I6a699d93909f61099226ceb994140f03ea99a70f
Diffstat (limited to 'plugins/infra/emf')
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.project80
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/.settings/.api_filters11
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.appearance/META-INF/MANIFEST.MF36
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/.project80
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.diagram.common/META-INF/MANIFEST.MF17
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/.project24
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/META-INF/MANIFEST.MF13
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/.project80
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/META-INF/MANIFEST.MF17
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/pom.xml4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/ReadOnlyManager.java1179
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/spi/IReadOnlyManagerProcessor.java4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/.project18
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/META-INF/MANIFEST.MF23
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types.ui/pom.xml2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/.project74
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/META-INF/MANIFEST.MF70
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.types/pom.xml2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/.project80
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF52
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/pom.xml4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/Activator.java1
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/EObjectResolverService.java2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/spi/resolver/IEObjectResolver.java2
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java2246
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/.project24
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.ui.emf/META-INF/MANIFEST.MF30
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

Back to the top