Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-07-13 19:05:54 +0000
committerChristian W. Damus2016-07-13 19:51:04 +0000
commitddfb7b0caefdd1be212db31bde24b8a9feb225de (patch)
tree5c350c81ea1a9fb2985bb62195c06ff50a7a5174 /tests/junit/plugins/infra
parentf68c766e5c5df1bb5c08fd65bc6f5464d3a58208 (diff)
downloadorg.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.tar.gz
org.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.tar.xz
org.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.zip
Bug 496299: Controlled Units as Integral Fragments
https://bugs.eclipse.org/bugs/show_bug.cgi?id=496299 Implement a new mode of controlled unit in Papyrus dubbed "shards". A shard is like any other sub-unit created up to and including the Neon release, except that it cannot be opened independently in the editor. The Papyrus editor, when asked to open a "shard", will instead open the root resource of the model. Likewise, the editor matcher normalizes editor inputs to the root resource of any shard. The graph of shard dependencies is inferred from a new workspace- wide index of cross-resource containment references, when it is available. Otherwise, the linkage of shards to their parent references is parsed on-the-fly from the shard annotation's reference (with a relatively efficient XML parsing that terminates after reading only a few lines of the XMI text). A new ResourceLocator is implemented to provide a pluggable hook for resource loading (including proxy resolution), to ensure when loading a shard resource that its parent resource chain is first loaded from the top down to ensure that all context of profile applications is available before loading the shard, itself, which may have stereotype applications that depend on those profile applications. The CoreMultiDiagramEditor installs this resource locator on the ModelSet; other applications (including in a non-Eclipse context) can make similar use of it. Some additional fixes are required in other core components to make the loading of referenced sharded models as in bug 458837 work: * the SemanticUMLContentProvider did not detect the final resolution of containment proxies that changes what looks look a model root object into just another intermediate element in the content tree. Besides that it would schedule a large number of redundant UI refreshes asynchronously (deferred) on the UI thread * the DiModel and NotationModel would load their adjuncts to the *.uml resource when that resource is created, not after it has been loaded. This is much too early and ends up causing the transactional editing domain to detect the attachment of a resource's contents at the end of loading as an attempt to edit the model during a read-only transaction, which logs an exception and bombs the UI action. Instead, these models now have snippets that load the *.di and *.notation resources after the semantic resource has been loaded. * the new model snippets required an additional fix in the loading of IModels to handle contributions of snippets and dependencies to models that are overridden by other IModels registered under the same ID, such as is the case with the NotationModel and the CSSNotationModel, which latter needs the snippet declared by the former * the IModels additionally need to ensure that they start snippets on loading of an existing model even when it is already found to be loaded in the ModelSet (as happens often in JUnit tests) * the AbstractModelFixture in the JUnit test framework is updated to ensure that the ModelSet is properly initialized, with its own snippets started and its IModels loaded and their snippets started * the basic uncontrol command now removes the shard annotation from the uncontrolled element/resource, if there was one. Because this bundle now supports a new feature (that being shards), it seems appropriate to bump its minor version number General-purpose changes in the core workspace model index framework that improve overall performance, of particular significance in large and highly fragmented models: Implement persistent storage of the workspace model index at workspace save to support quick start-up without parsing the entire workspace. Consolidation of indices: * run a single pool of indexing jobs and a single resource change listener to trigger (re)-indexing of files * all indices matching any given file process it * includes a new extension point from which all indices are loaded into the shared index manager to initialize them and do the work (cherry-picked from streams/2.0-maintenance) Change-Id: Ifd65a71c57134b69d873f17139f3cedbf11c5ba5
Diffstat (limited to 'tests/junit/plugins/infra')
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.classpath8
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/META-INF/MANIFEST.MF9
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/pom.xml2
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1.uml10
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA.uml10
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA/foo.uml9
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2.uml10
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB.uml10
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB/bar.uml9
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/referencing.uml21
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.di2
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.notation2
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.uml11
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/AbstractCrossReferenceIndexTest.java182
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/CrossReferenceIndexTest.java150
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceHelperTest.java241
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceLocatorTest.java93
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/index/WorkspaceModelIndexTest.java225
-rw-r--r--tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/tests/AllTests.java9
-rw-r--r--tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.classpath14
-rw-r--r--tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/META-INF/MANIFEST.MF8
-rw-r--r--tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/pom.xml2
-rw-r--r--tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/src/org/eclipse/papyrus/infra/services/controlmode/tests/uncontrol/UncontrolModelTest.java45
25 files changed, 1027 insertions, 67 deletions
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.classpath b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.classpath
index 4ff9e9735c7..293e77968b0 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.classpath
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.classpath
@@ -1,7 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/papyrus/infra/emf/internal/**"/>
+ </accessrules>
+ </classpathentry>
<classpathentry kind="src" path="tests"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.settings/org.eclipse.jdt.core.prefs b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.settings/org.eclipse.jdt.core.prefs
index 9ec8d31b26b..43d10874e2c 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/.settings/org.eclipse.jdt.core.prefs
@@ -1,14 +1,14 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/META-INF/MANIFEST.MF b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/META-INF/MANIFEST.MF
index 3f619512f80..5762bedc61a 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/META-INF/MANIFEST.MF
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/META-INF/MANIFEST.MF
@@ -1,19 +1,20 @@
Manifest-Version: 1.0
Export-Package: org.eclipse.papyrus.infra.emf.advice,
+ org.eclipse.papyrus.infra.emf.resource,
org.eclipse.papyrus.infra.emf.resource.index,
org.eclipse.papyrus.infra.emf.tests,
org.eclipse.papyrus.infra.emf.utils
Require-Bundle: org.eclipse.emf.ecore.xmi;bundle-version="2.8.0",
org.junit;bundle-version="4.10.0",
org.eclipse.uml2.uml;bundle-version="5.0.0",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.3.0",
org.eclipse.papyrus.junit.framework;bundle-version="1.2.0",
org.eclipse.papyrus.junit.utils;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.types.core;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.emf;bundle-version="1.2.0"
+ org.eclipse.papyrus.infra.types.core;bundle-version="1.2.0"
Bundle-Vendor: %providerName
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.4.0.qualifier
Bundle-Name: %pluginName
Bundle-Localization: fragment
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.papyrus.infra.emf.tests;singleton:=true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/pom.xml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/pom.xml
index 779f465b911..84adf7aa7c5 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/pom.xml
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/pom.xml
@@ -10,6 +10,6 @@
</parent>
<groupId>org.eclipse.papyrus</groupId>
<artifactId>org.eclipse.papyrus.infra.emf.tests</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
</project>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1.uml
new file mode 100644
index 00000000000..c6669a567a2
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Package xmi:id="_M6uS4EYCEeagQvw0AruCcg" name="package1">
+ <eAnnotations xmi:id="_0iFCIEYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Model" href="root.uml#_-T-r8EYBEeagQvw0AruCcg"/>
+ </eAnnotations>
+ <packagedElement xmi:type="uml:Package" href="package1/packageA.uml#_R5WJAEYCEeagQvw0AruCcg"/>
+ </uml:Package>
+ <Ecore:EPackage xmi:id="_esXvkEYCEeagQvw0AruCcg" base_Package="_M6uS4EYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA.uml
new file mode 100644
index 00000000000..5e245519bcd
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Package xmi:id="_R5WJAEYCEeagQvw0AruCcg" name="packageA">
+ <eAnnotations xmi:id="_axVn8EYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Package" href="../package1.uml#_M6uS4EYCEeagQvw0AruCcg"/>
+ </eAnnotations>
+ <packagedElement xmi:type="uml:Class" href="packageA/foo.uml#_VYUxUEYCEeagQvw0AruCcg"/>
+ </uml:Package>
+ <Ecore:EPackage xmi:id="_dxA6kEYCEeagQvw0AruCcg" base_Package="_R5WJAEYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA/foo.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA/foo.uml
new file mode 100644
index 00000000000..d538aa7d82a
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package1/packageA/foo.uml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Class xmi:id="_VYUxUEYCEeagQvw0AruCcg" name="Foo">
+ <eAnnotations xmi:id="_anqukEYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Package" href="../packageA.uml#_R5WJAEYCEeagQvw0AruCcg"/>
+ </eAnnotations>
+ </uml:Class>
+ <Ecore:EClass xmi:id="_anRicEYCEeagQvw0AruCcg" base_Class="_VYUxUEYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2.uml
new file mode 100644
index 00000000000..0d530b1d276
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Package xmi:id="_Qdf2EEYCEeagQvw0AruCcg" name="package2">
+ <eAnnotations xmi:id="_bGexgEYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Model" href="root.uml#_-T-r8EYBEeagQvw0AruCcg"/>
+ </eAnnotations>
+ <packagedElement xmi:type="uml:Package" href="package2/packageB.uml#_THKnAEYCEeagQvw0AruCcg"/>
+ </uml:Package>
+ <Ecore:EPackage xmi:id="_fsK_sEYCEeagQvw0AruCcg" base_Package="_Qdf2EEYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB.uml
new file mode 100644
index 00000000000..e8b1a5838ba
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Package xmi:id="_THKnAEYCEeagQvw0AruCcg" name="packageB">
+ <eAnnotations xmi:id="_accWAEYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Package" href="../package2.uml#_Qdf2EEYCEeagQvw0AruCcg"/>
+ </eAnnotations>
+ <packagedElement xmi:type="uml:Class" href="packageB/bar.uml#_Yg658EYCEeagQvw0AruCcg"/>
+ </uml:Package>
+ <Ecore:EPackage xmi:id="_gopPAEYCEeagQvw0AruCcg" base_Package="_THKnAEYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB/bar.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB/bar.uml
new file mode 100644
index 00000000000..db8808c46dd
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/package2/packageB/bar.uml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA">
+ <uml:Class xmi:id="_Yg658EYCEeagQvw0AruCcg" name="Bar">
+ <eAnnotations xmi:id="_P_TowEYDEeagQvw0AruCcg" source="http://www.eclipse.org/papyrus/2016/resource/shard">
+ <references xmi:type="uml:Package" href="../packageB.uml#_THKnAEYCEeagQvw0AruCcg"/>
+ </eAnnotations>
+ </uml:Class>
+ <Ecore:EClass xmi:id="_cfH04EYCEeagQvw0AruCcg" base_Class="_Yg658EYCEeagQvw0AruCcg"/>
+</xmi:XMI>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/referencing.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/referencing.uml
new file mode 100644
index 00000000000..4d575d4e308
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/referencing.uml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_0S-gEEYMEeagQvw0AruCcg" name="referencing">
+ <packagedElement xmi:type="uml:Package" xmi:id="_wTjjMEd3Eeayp81rgar4Qw" name="package1">
+ <packagedElement xmi:type="uml:Package" xmi:id="_y4j2kEd3Eeayp81rgar4Qw" name="packageA">
+ <packagedElement xmi:type="uml:Class" xmi:id="_3QKC4EYMEeagQvw0AruCcg" name="Subclass">
+ <generalization xmi:id="_9sFkgEYMEeagQvw0AruCcg">
+ <general xmi:type="uml:Class" href="package2/packageB/bar.uml#_Yg658EYCEeagQvw0AruCcg"/>
+ </generalization>
+ </packagedElement>
+ </packagedElement>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Package" xmi:id="_yLgjUEd3Eeayp81rgar4Qw" name="package2">
+ <packagedElement xmi:type="uml:Package" xmi:id="_0ZwjkEd3Eeayp81rgar4Qw" name="packageB">
+ <packagedElement xmi:type="uml:Class" xmi:id="_2f4ikEd3Eeayp81rgar4Qw" name="Quux">
+ <generalization xmi:id="_2f4ikUd3Eeayp81rgar4Qw">
+ <general xmi:type="uml:Class" href="package2/packageB/bar.uml#_Yg658EYCEeagQvw0AruCcg"/>
+ </generalization>
+ </packagedElement>
+ </packagedElement>
+ </packagedElement>
+</uml:Model>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.di b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.di
new file mode 100644
index 00000000000..bf9abab340f
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.notation b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.notation
new file mode 100644
index 00000000000..bf9abab340f
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.notation
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.uml b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.uml
new file mode 100644
index 00000000000..5427fd15867
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/resources/shards/root.uml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_-T-r8EYBEeagQvw0AruCcg" name="root">
+ <packagedElement xmi:type="uml:Package" href="package1.uml#_M6uS4EYCEeagQvw0AruCcg"/>
+ <packagedElement xmi:type="uml:Package" href="package2.uml#_Qdf2EEYCEeagQvw0AruCcg"/>
+ <profileApplication xmi:id="_-mL2QEYBEeagQvw0AruCcg">
+ <eAnnotations xmi:id="_-mNrcEYBEeagQvw0AruCcg" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA"/>
+ </eAnnotations>
+ <appliedProfile href="pathmap://UML_PROFILES/Ecore.profile.uml#_0"/>
+ </profileApplication>
+</uml:Model>
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/AbstractCrossReferenceIndexTest.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/AbstractCrossReferenceIndexTest.java
new file mode 100644
index 00000000000..3c251e5010a
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/AbstractCrossReferenceIndexTest.java
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.papyrus.infra.emf.internal.resource.CrossReferenceIndex;
+import org.eclipse.papyrus.infra.emf.internal.resource.OnDemandCrossReferenceIndex;
+import org.eclipse.papyrus.junit.utils.rules.AbstractHouseKeeperRule.CleanUp;
+import org.eclipse.papyrus.junit.utils.rules.AnnotationRule;
+import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
+import org.eclipse.papyrus.junit.utils.rules.ProjectFixture;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Stereotype;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Test framework for cross-reference index and shards-related tests.
+ */
+public abstract class AbstractCrossReferenceIndexTest {
+
+ @ClassRule
+ public static final ProjectFixture project = new ProjectFixture();
+
+ @Rule
+ public final HouseKeeper housekeeper = new HouseKeeper();
+
+ @Rule
+ public final AnnotationRule<String[]> resourcePaths = AnnotationRule.create(ProjectResource.class);
+
+ protected ResourceSet fixture;
+
+ @CleanUp
+ protected List<Resource> initialResources;
+
+ private final Function<? super ResourceSet, ? extends ICrossReferenceIndex> indexFunction;
+
+ /**
+ * Initializes me.
+ */
+ public AbstractCrossReferenceIndexTest() {
+ this(null);
+ }
+
+ /**
+ * Initializes me.
+ *
+ * @param onDemand
+ * {@code true} to force the on-demand index, {@code false} to force the
+ * full index, or {@code null} to let the framework decide the best
+ * available index
+ */
+ public AbstractCrossReferenceIndexTest(Boolean onDemand) {
+ super();
+
+ if (onDemand == null) {
+ // Best available
+ indexFunction = ICrossReferenceIndex::getInstance;
+ } else if (onDemand) {
+ // Force the on-demand index
+ indexFunction = OnDemandCrossReferenceIndex::new;
+ } else {
+ // Force the full index
+ indexFunction = __ -> CrossReferenceIndex.getInstance();
+ }
+ }
+
+ @BeforeClass
+ public static void createProjectContents() {
+ List<String> resources = ImmutableList.of(
+ "root.uml",
+ "package1.uml",
+ "package1/packageA.uml",
+ "package1/packageA/foo.uml",
+ "package2.uml",
+ "package2/packageB.uml",
+ "package2/packageB/bar.uml",
+ "referencing.uml");
+
+ resources.forEach(res -> {
+ try {
+ project.createFile(res, AbstractCrossReferenceIndexTest.class, "resources/shards/" + res);
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("Failed to create test resource: " + e.getMessage());
+ }
+ });
+ }
+
+ @Before
+ public void createFixture() {
+ fixture = housekeeper.createResourceSet();
+
+ new ShardResourceLocator((ResourceSetImpl) fixture, index());
+
+ // Load resources
+ if (resourcePaths.get() != null) {
+ URI base = baseURI();
+ initialResources = Stream.of(resourcePaths.get())
+ .map(URI::createURI)
+ .map(uri -> uri.resolve(base))
+ .map(uri -> fixture.getResource(uri, true))
+ .collect(Collectors.toList());
+ }
+ }
+
+ protected final ICrossReferenceIndex index() {
+ return indexFunction.apply(fixture);
+ }
+
+ URI baseURI() {
+ return URI.createPlatformResourceURI(project.getProject().getName() + "/", true);
+ }
+
+ protected URI uri(String path) {
+ URI result = URI.createURI(path, true);
+ return result.resolve(baseURI());
+ }
+
+ protected Resource requireLoaded(String path) {
+ Resource result = fixture.getResource(uri(path), false);
+ assertThat("resource not created: " + path, result, notNullValue());
+ assertThat("resource not loaded: " + path, result.isLoaded(), is(true));
+ return result;
+ }
+
+ protected Stereotype requireStereotype(Element element, String qualifiedName) {
+ Stereotype result = element.getApplicableStereotype(qualifiedName);
+ assertThat("stereotype not applicable: " + qualifiedName, result, notNullValue());
+ assertThat("stereotype not applied: " + qualifiedName, element.isStereotypeApplied(result), is(true));
+ return result;
+ }
+
+ protected Stereotype requireEClass(Classifier classifier) {
+ return requireStereotype(classifier, "Ecore::EClass");
+ }
+
+ protected Stereotype requireEPackage(Package package_) {
+ return requireStereotype(package_, "Ecore::EPackage");
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ProjectResource {
+ String[] value();
+ }
+}
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/CrossReferenceIndexTest.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/CrossReferenceIndexTest.java
new file mode 100644
index 00000000000..d3fcca35732
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/CrossReferenceIndexTest.java
@@ -0,0 +1,150 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singleton;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.infra.emf.internal.resource.CrossReferenceIndex;
+import org.eclipse.uml2.uml.resource.UMLResource;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+
+/**
+ * Tests for the {@link CrossReferenceIndex} class, the full indexer.
+ */
+public class CrossReferenceIndexTest extends AbstractCrossReferenceIndexTest {
+
+ /**
+ * Initializes me.
+ */
+ public CrossReferenceIndexTest() {
+ super(false); // Always the full indexer
+ }
+
+ //
+ // Don't need to load any resources for these tests
+ //
+
+ @Test
+ public void isShard() throws Exception {
+ assertThat(index().isShard(uri("package1/packageA/foo.uml")), is(true));
+ assertThat(index().isShard(uri("package1/packageA.uml")), is(true));
+ assertThat(index().isShard(uri("package1.uml")), is(true));
+ assertThat(index().isShard(uri("root.uml")), is(false));
+ }
+
+ @Test
+ public void shards() throws Exception {
+ assertThat(index().getShards(uri("package1/packageA/foo.uml")), is(emptySet()));
+ assertThat(index().getShards(uri("package1/packageA.uml")), is(singleton(uri("package1/packageA/foo.uml"))));
+ assertThat(index().getShards(uri("package1.uml")), is(singleton(uri("package1/packageA.uml"))));
+ assertThat(index().getShards(uri("root.uml")), // This one has two shards
+ is(ImmutableSet.of(uri("package1.uml"), uri("package2.uml"))));
+ }
+
+ @Test
+ public void parentShards() throws Exception {
+ assertThat(index().getParents(uri("package1/packageA/foo.uml")), is(singleton(uri("package1/packageA.uml"))));
+ assertThat(index().getParents(uri("package1/packageA.uml")), is(singleton(uri("package1.uml"))));
+ assertThat(index().getParents(uri("package1.uml")), is(singleton(uri("root.uml"))));
+ assertThat(index().getParents(uri("root.uml")), is(emptySet()));
+ }
+
+ @Test
+ public void roots() throws Exception {
+ assertThat(index().getRoots(uri("package1/packageA/foo.uml")), is(singleton(uri("root.uml"))));
+ assertThat(index().getRoots(uri("package1/packageA.uml")), is(singleton(uri("root.uml"))));
+ assertThat(index().getRoots(uri("package1.uml")), is(singleton(uri("root.uml"))));
+
+ // A root has no parents and, therefore, no root
+ assertThat(index().getRoots(uri("root.uml")), is(emptySet()));
+
+ // And this one has nothing to do with shards
+ assertThat(index().getRoots(uri("referencing.uml")), is(emptySet()));
+ }
+
+ @Test
+ public void outgoingReferences_givenURI() throws Exception {
+ // Shard relationship (cross-resource containment) is not a cross-reference
+ assertThat(index().getOutgoingCrossReferences(uri("package1.uml")), is(emptySet()));
+
+ // We find cross-references to non-workspace resources, though those aren't indexed
+ assertThat(index().getOutgoingCrossReferences(uri("root.uml")),
+ is(singleton(URI.createURI(UMLResource.ECORE_PROFILE_URI))));
+
+ // This has a cross-reference in the class generalization
+ assertThat(index().getOutgoingCrossReferences(uri("referencing.uml")),
+ is(singleton(uri("package2/packageB/bar.uml"))));
+
+ // This API is generalized for the Papyrus one-file
+ assertThat(index().getOutgoingCrossReferences(uri("referencing.di")),
+ is(singleton(uri("package2/packageB/bar.di"))));
+ }
+
+ @Test
+ public void incomingReferences_givenURI() throws Exception {
+ // Parent pointer in shard annotation is not a cross-reference
+ assertThat(index().getIncomingCrossReferences(uri("root.uml")), is(emptySet()));
+ assertThat(index().getIncomingCrossReferences(uri("package1.uml")), is(emptySet()));
+
+ // This has a cross-reference in the class generalization
+ assertThat(index().getIncomingCrossReferences(uri("package2/packageB/bar.uml")),
+ is(singleton(uri("referencing.uml"))));
+
+ // This API is generalized for the Papyrus one-file
+ assertThat(index().getIncomingCrossReferences(uri("package2/packageB/bar.di")),
+ is(singleton(uri("referencing.di"))));
+ }
+
+ @Test
+ public void outgoingReferences() throws Exception {
+ SetMultimap<URI, URI> xrefs = index().getOutgoingCrossReferences();
+
+ // Shard relationship (cross-resource containment) is not a cross-reference
+ assertThat(xrefs.get(uri("package1.uml")), is(emptySet()));
+
+ // We find cross-references to non-workspace resources, though those aren't indexed
+ assertThat(xrefs.get(uri("root.uml")),
+ is(singleton(URI.createURI(UMLResource.ECORE_PROFILE_URI))));
+
+ // This has a cross-reference in the class generalization
+ assertThat(xrefs.get(uri("referencing.uml")),
+ is(singleton(uri("package2/packageB/bar.uml"))));
+
+ // This API is *not* generalized for the Papyrus one-file
+ assertThat(xrefs.get(uri("referencing.di")), is(emptySet()));
+ }
+
+ @Test
+ public void incomingReferences() throws Exception {
+ SetMultimap<URI, URI> xrefs = index().getIncomingCrossReferences();
+
+ // Parent pointer in shard annotation is not a cross-reference
+ assertThat(xrefs.get(uri("root.uml")), is(emptySet()));
+ assertThat(xrefs.get(uri("package1.uml")), is(emptySet()));
+
+ // This has a cross-reference in the class generalization
+ assertThat(xrefs.get(uri("package2/packageB/bar.uml")),
+ is(singleton(uri("referencing.uml"))));
+
+ // This API is *not* generalized for the Papyrus one-file
+ assertThat(xrefs.get(uri("package2/packageB/bar.di")), is(emptySet()));
+ }
+}
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceHelperTest.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceHelperTest.java
new file mode 100644
index 00000000000..d2a8ef84841
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceHelperTest.java
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Optional;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.infra.emf.internal.resource.AbstractCrossReferenceIndex;
+import org.eclipse.papyrus.junit.utils.rules.AnnotationRule;
+import org.eclipse.uml2.uml.util.UMLUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests for the {@link ShardResourceHelper} class.
+ */
+@RunWith(Parameterized.class)
+public class ShardResourceHelperTest extends AbstractCrossReferenceIndexTest {
+
+ @Rule
+ public final AnnotationRule<String> shardElementQualifiedName = AnnotationRule.create(ShardElement.class);
+
+ private final boolean useCommands;
+ private EditingDomain domain; // In case we are using commands
+
+ private ShardResourceHelper helper;
+ private EObject shardElement;
+ private Resource shardResource;
+
+ /**
+ * Initializes me.
+ *
+ * @param useCommands
+ * whether to use the shard helper's commands for resource manipulation
+ * (ensures test coverage)
+ */
+ public ShardResourceHelperTest(boolean useCommands) {
+ super();
+
+ this.useCommands = useCommands;
+ }
+
+ @Test
+ @ProjectResource("referencing.uml")
+ @ShardElement("referencing::package2::packageB")
+ public void makeShard() {
+ setShard(true);
+ assertAdapter();
+ assertAnnotation();
+
+ undo();
+ assertAdapter();
+ assertNoAnnotation();
+
+ redo();
+ assertAdapter();
+ assertAnnotation();
+ }
+
+ @Test
+ @ProjectResource("root.uml")
+ @ShardElement("root::package2::packageB")
+ public void makeNotShard() {
+ setShard(false);
+ assertAdapter();
+ assertNoAnnotation();
+
+ undo();
+ assertAdapter();
+ assertAnnotation();
+
+ redo();
+ assertAdapter();
+ assertNoAnnotation();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ @ProjectResource("referencing.uml")
+ @ShardElement("referencing::package2::packageB")
+ public void attemptToUseClosedHelper() {
+ helper.close();
+
+ setShard(true);
+ }
+
+ //
+ // Test framework
+ //
+
+ @Parameters(name = "{index}: useCommands={0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ { false },
+ { true },
+ });
+ }
+
+ @Before
+ public void createShardHelper() {
+ if (useCommands) {
+ // Need an editing domain for command execution
+ domain = housekeeper.createSimpleEditingDomain(fixture);
+ }
+
+ // Find the shard element
+ shardElement = initialResources.stream()
+ .flatMap(res -> UMLUtil.findNamedElements(res, shardElementQualifiedName.get()).stream())
+ .findAny()
+ .orElseThrow(AssertionError::new);
+
+ // Create or find the shard resource
+ if (((InternalEObject) shardElement).eDirectResource() != null) {
+ shardResource = shardElement.eResource();
+ } else {
+ shardResource = fixture.createResource(project.getURI("the-shard.uml"));
+ if (useCommands) {
+ domain.getCommandStack().execute(new AddCommand(domain, shardResource.getContents(), shardElement));
+ } else {
+ shardResource.getContents().add(shardElement);
+ }
+ }
+ helper = new ShardResourceHelper(shardElement);
+ }
+
+ @After
+ public void destroyShardHelper() {
+ helper.close();
+ }
+
+ void setShard(boolean shard) {
+ if (useCommands) {
+ Command command = helper.getSetShardCommand(shard);
+ domain.getCommandStack().execute(command);
+ } else {
+ helper.setShard(shard);
+ }
+
+ assertThat("Changing shard status failed", helper.isShard(), is(shard));
+ }
+
+ void undo() {
+ if (useCommands) {
+ assertThat("Cannot undo", domain.getCommandStack().canUndo(), is(true));
+ domain.getCommandStack().undo();
+ } else {
+ helper.setShard(!helper.isShard());
+ }
+ }
+
+ void redo() {
+ if (useCommands) {
+ assertThat("Cannot redo", domain.getCommandStack().canRedo(), is(true));
+ domain.getCommandStack().redo();
+ } else {
+ helper.setShard(!helper.isShard());
+ }
+ }
+
+ /** Assert that our model element has the shard adapter attached. */
+ void assertAdapter() {
+ assertThat("Shard adapter not found", findAdapter().isPresent(), is(true));
+ }
+
+ /** Assert that our model element does not have the shard adapter attached. */
+ void assertNoAdapter() {
+ assertThat("Shard adapter found", findAdapter().isPresent(), is(false));
+ }
+
+ private Optional<Adapter> findAdapter() {
+ return shardElement.eAdapters().stream()
+ .filter(a -> a.getClass().getName().contains("ShardResourceHelper$"))
+ .findAny();
+ }
+
+ /** Assert that our model element has the shard annotation. */
+ void assertAnnotation() {
+ Optional<EAnnotation> annotation = findAnnotation();
+ assertThat("Shard annotation not found", annotation.isPresent(), is(true));
+ assertThat("Shard annotation missing back pointer",
+ annotation.map(EAnnotation::getReferences).get(),
+ hasItem(shardElement.eContainer()));
+ }
+
+ /** Assert that our model element does not have the shard annotation. */
+ void assertNoAnnotation() {
+ assertThat("Shard annotation found", findAnnotation().isPresent(), is(false));
+ }
+
+ private Optional<EAnnotation> findAnnotation() {
+ return Optional.of(shardElement)
+ .filter(EModelElement.class::isInstance).map(EModelElement.class::cast)
+ .map(EModelElement::getEAnnotations).map(Collection::stream)
+ .map(s -> s.filter(a -> AbstractCrossReferenceIndex.SHARD_ANNOTATION_SOURCE.equals(a.getSource())))
+ .flatMap(s -> s.findAny());
+ }
+
+ //
+ // Nested types
+ //
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ShardElement {
+ /** The qualified name of the element to make or unmake as a shard. */
+ String value();
+ }
+}
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceLocatorTest.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceLocatorTest.java
new file mode 100644
index 00000000000..6c602b90670
--- /dev/null
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/ShardResourceLocatorTest.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2016 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import java.util.Arrays;
+
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Package;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests for the {@link ShardResourceLocator} class. These tests are run both
+ * with the full cross-reference index and with the partial on-demand index that
+ * only looks for shard parent relationships.
+ */
+@RunWith(Parameterized.class)
+public class ShardResourceLocatorTest extends AbstractCrossReferenceIndexTest {
+
+ /**
+ * Initializes me.
+ *
+ * @param onDemand
+ * whether to force the on-demand cross-reference index
+ * @param description
+ * the description of the test conditions
+ */
+ public ShardResourceLocatorTest(boolean onDemand, String description) {
+ super(onDemand);
+ }
+
+ @Test
+ @ProjectResource("package1/packageA/foo.uml")
+ public void shardLoadsContainersAndDoesntLoseStereotypes() {
+ Class foo = (Class) initialResources.get(0).getContents().get(0);
+
+ // The parent chain of Foo is loaded
+ requireLoaded("root.uml");
+ requireLoaded("package1.uml");
+ requireLoaded("package1/packageA.uml");
+
+ // Stereotype applications were not lost
+ requireEClass(foo);
+ requireEPackage(foo.getNearestPackage());
+ requireEPackage(foo.getNearestPackage().getNestingPackage());
+ }
+
+ @Test
+ @ProjectResource("referencing.uml")
+ public void proxyResolutionLoadsShardFromTheTop() {
+ Package referencing = (Package) initialResources.get(0).getContents().get(0);
+ Class subclass = (Class) referencing.getNestedPackage("package1")
+ .getNestedPackage("packageA").getOwnedType("Subclass");
+
+ // Get its general
+ Class superclass = (Class) subclass.getGeneral("Bar");
+
+ // The parent chain of Bar is loaded
+ requireLoaded("root.uml");
+ requireLoaded("package2.uml");
+ requireLoaded("package2/packageB.uml");
+
+ // Stereotype applications were not lost
+ requireEClass(superclass);
+ requireEPackage(superclass.getNearestPackage());
+ requireEPackage(superclass.getNearestPackage().getNestingPackage());
+ }
+
+ //
+ // Test framework
+ //
+
+ @Parameters(name = "{index}: {1}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ { false, "full index" },
+ { true, "on-demand index" },
+ });
+ }
+}
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/index/WorkspaceModelIndexTest.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/index/WorkspaceModelIndexTest.java
index f94288ef453..1c31edb53d1 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/index/WorkspaceModelIndexTest.java
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/resource/index/WorkspaceModelIndexTest.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014, 2015 Christian W. Damus and others.
+ * Copyright (c) 2014, 2016 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
@@ -20,6 +20,7 @@ import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileNotFoundException;
@@ -31,7 +32,12 @@ import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Supplier;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -41,8 +47,11 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
@@ -51,6 +60,8 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.infra.emf.Activator;
+import org.eclipse.papyrus.infra.emf.internal.resource.index.IndexManager;
+import org.eclipse.papyrus.infra.emf.internal.resource.index.InternalModelIndex;
import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
import org.eclipse.papyrus.junit.utils.LogTracker;
@@ -66,16 +77,17 @@ import org.junit.Test;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
-import com.google.common.util.concurrent.Uninterruptibles;
/**
* Test suite for the {@link WorkspaceModelIndex} class.
*/
public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
- private static final CrossReferenceIndexer index = new CrossReferenceIndexer();
+ private static final SyncHolder syncHolder = new SyncHolder();
+ private static final CrossReferenceIndexer index = new CrossReferenceIndexer(syncHolder);
+
+ private static IndexManager manager;
private static WorkspaceModelIndex<CrossReferenceIndex> fixture;
- private static boolean delayIndexing;
@Rule
public final HouseKeeper houseKeeper = new HouseKeeper();
@@ -219,8 +231,8 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
// Initial build
Map<IFile, CrossReferenceIndex> index = fixture.getIndex().get();
- // Ensure that indexing will take a bit of time
- delayIndexing = true;
+ // Interlock with the indexing for timing purposes
+ Semaphore sync = syncHolder.createStandardSync();
final String newFileName = "the_referencing_model.uml";
@@ -231,8 +243,11 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
referencingFile = referencingProject.getFile(new Path(newFileName));
referencingURI = uri(referencingFile);
+ // Let the indexing start
+ sync.release();
+
// Cancel the index control job
- Job[] family = Job.getJobManager().find(fixture);
+ Job[] family = Job.getJobManager().find(manager);
Job controlJob = null;
for (Job job : family) {
if (job.getClass().getSimpleName().contains("JobWrangler")) {
@@ -241,16 +256,25 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
}
}
assertThat("Control job not found", controlJob, notNullValue());
+
+ long cancellingAt = System.currentTimeMillis();
+
controlJob.cancel();
- long requestIndex = System.currentTimeMillis();
+ // Let the indexing finish
+ sync.release();
- // Check the index
- index = fixture.getIndex().get();
+ JobWaiter controlJobWaiter = JobWaiter.waitForStart(controlJob);
- long gotIndex = System.currentTimeMillis();
+ controlJobWaiter.waitForJob();
+
+ long restartedAt = System.currentTimeMillis();
- assertThat("Didn't have to wait for the index to recover", (gotIndex - requestIndex), greaterThan(1000L));
+ assertThat("Didn't have to wait for the index to recover",
+ (restartedAt - cancellingAt), greaterThan(1000L));
+
+ // Check the index
+ index = fixture.getIndex().get();
assertIndex(index);
}
@@ -311,12 +335,21 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
@BeforeClass
public static void createFixture() {
- fixture = new WorkspaceModelIndex<CrossReferenceIndex>("test", UMLResource.UML_CONTENT_TYPE_IDENTIFIER, index, 2);
+ manager = new IndexManager() {
+ @Override
+ protected Map<QualifiedName, InternalModelIndex> loadIndices() {
+ fixture = new WorkspaceModelIndex<>("test", UMLResource.UML_CONTENT_TYPE_IDENTIFIER, index, 2);
+ return Collections.singletonMap(fixture.getIndexKey(), (InternalModelIndex) fixture);
+ }
+ };
+ manager.startManager();
}
@AfterClass
public static void destroyFixture() {
- fixture.dispose();
+ // This disposes the fixture, too
+ manager.dispose();
+ manager = null;
fixture = null;
}
@@ -346,7 +379,7 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
@After
public void reset() {
- delayIndexing = false;
+ syncHolder.clear();
}
static URI uri(IFile file) {
@@ -393,9 +426,45 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
// Nested types
//
+ static class SyncHolder implements Supplier<Semaphore> {
+ private volatile Semaphore sync;
+
+ @Override
+ public Semaphore get() {
+ return sync;
+ }
+
+ Semaphore createStandardSync() {
+ sync = new Semaphore(0);
+ return sync;
+ }
+
+ void clear() {
+ if (sync != null) {
+ // Make sure that any blocked threads are released to whatever fate
+ syncHolder.sync.release(100);
+ syncHolder.sync = null;
+ }
+ }
+ }
+
static class CrossReferenceIndexer implements WorkspaceModelIndex.IndexHandler<CrossReferenceIndex> {
private final Map<IFile, CrossReferenceIndex> index = Maps.newHashMap();
+ private final Supplier<? extends Semaphore> syncSupplier;
+
+ /**
+ * Initializes me.
+ *
+ * @param syncSupplier
+ * a supplier of an optional semaphore to acquire at start and end of indexing a file
+ */
+ public CrossReferenceIndexer(Supplier<? extends Semaphore> syncSupplier) {
+ super();
+
+ this.syncSupplier = syncSupplier;
+ }
+
private CrossReferenceIndex get(IFile file) {
CrossReferenceIndex result;
@@ -413,38 +482,48 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
@Override
public CrossReferenceIndex index(IFile file) {
final CrossReferenceIndex result = get(file);
+ final Semaphore sync = syncSupplier.get();
- Set<URI> imports = result.imports;
-
- ResourceSet resourceSet = new IndexingResourceSet();
+ if (sync != null) {
+ // Wait for the test to let us proceed
+ sync.acquireUninterruptibly();
+ }
try {
- URI uri = uri(file);
-
- Resource resource = resourceSet.getResource(uri, true);
- for (Map.Entry<EObject, Collection<EStructuralFeature.Setting>> next : EcoreUtil.ProxyCrossReferencer.find(resource).entrySet()) {
- for (EStructuralFeature.Setting setting : next.getValue()) {
- Object references = setting.get(false);
-
- if (references instanceof EObject) {
- EObject ref = (EObject) references;
- if (ref.eIsProxy()) {
- URI href = EcoreUtil.getURI(ref).trimFragment();
- if (href.isPlatformResource() && imports.add(href)) {
- // add the corresponding export
- IFile other = file.getWorkspace().getRoot().getFile(new Path(href.toPlatformString(true)));
- get(other).exports.add(uri);
+ Set<URI> imports = result.imports;
+ imports.clear();
+
+ ResourceSet resourceSet = new IndexingResourceSet();
+
+ try {
+ URI uri = uri(file);
+
+ Resource resource = resourceSet.getResource(uri, true);
+ for (Map.Entry<EObject, Collection<EStructuralFeature.Setting>> next : EcoreUtil.ProxyCrossReferencer.find(resource).entrySet()) {
+ for (EStructuralFeature.Setting setting : next.getValue()) {
+ Object references = setting.get(false);
+
+ if (references instanceof EObject) {
+ EObject ref = (EObject) references;
+ if (ref.eIsProxy()) {
+ URI href = EcoreUtil.getURI(ref).trimFragment();
+ if (href.isPlatformResource() && imports.add(href)) {
+ // add the corresponding export
+ IFile other = file.getWorkspace().getRoot().getFile(new Path(href.toPlatformString(true)));
+ get(other).exports.add(uri);
+ }
}
}
}
}
+ } finally {
+ EMFHelper.unload(resourceSet);
}
} finally {
- EMFHelper.unload(resourceSet);
- }
-
- if (delayIndexing) {
- Uninterruptibles.sleepUninterruptibly(1L, TimeUnit.SECONDS);
+ if (sync != null) {
+ // Wait for the test to let us finish
+ sync.acquireUninterruptibly();
+ }
}
return result;
@@ -552,4 +631,74 @@ public class WorkspaceModelIndexTest extends AbstractPapyrusTest {
file.delete(true, monitor);
}
}
+
+ static final class JobWaiter extends JobChangeAdapter {
+ private final Job job;
+ private final boolean waitForStart;
+
+ private final Lock lock = new ReentrantLock();
+ private final Condition cond = lock.newCondition();
+ private volatile boolean gotIt;
+
+ private JobWaiter(Job job, boolean waitForStart) {
+ super();
+
+ this.job = job;
+ this.waitForStart = waitForStart;
+
+ Job.getJobManager().addJobChangeListener(this);
+ }
+
+ public static JobWaiter waitForStart(Job job) {
+ return new JobWaiter(job, true);
+ }
+
+ public static JobWaiter waitForEnd(Job job) {
+ return new JobWaiter(job, false);
+ }
+
+ public void waitForJob() {
+ lock.lock();
+
+ try {
+ while (!gotIt) {
+ try {
+ cond.await();
+ } catch (InterruptedException e) {
+ fail("Test was interrupted");
+ }
+ }
+ } finally {
+ lock.unlock();
+ Job.getJobManager().removeJobChangeListener(this);
+ }
+ }
+
+ @Override
+ public void aboutToRun(IJobChangeEvent event) {
+ if (waitForStart && (event.getJob() == job)) {
+ lock.lock();
+ try {
+ gotIt = true;
+ cond.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void done(IJobChangeEvent event) {
+ if (!waitForStart && (event.getJob() == job)) {
+ lock.lock();
+ try {
+ gotIt = true;
+ cond.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ }
}
diff --git a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/tests/AllTests.java b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/tests/AllTests.java
index 158a001365e..46aa80c3609 100644
--- a/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/tests/AllTests.java
+++ b/tests/junit/plugins/infra/emf/org.eclipse.papyrus.infra.emf.tests/tests/org/eclipse/papyrus/infra/emf/tests/AllTests.java
@@ -8,13 +8,16 @@
*
* Contributors:
* Christian W. Damus (CEA) - Initial API and implementation
- * Christian W. Damus - bugs 399859, 465416, 485220
+ * Christian W. Damus - bugs 399859, 465416, 485220, 496299
*
*/
package org.eclipse.papyrus.infra.emf.tests;
import org.eclipse.papyrus.infra.emf.advice.ReadOnlyObjectEditAdviceTest;
import org.eclipse.papyrus.infra.emf.edit.domain.PapyrusTransactionalEditingDomainTest;
+import org.eclipse.papyrus.infra.emf.resource.CrossReferenceIndexTest;
+import org.eclipse.papyrus.infra.emf.resource.ShardResourceHelperTest;
+import org.eclipse.papyrus.infra.emf.resource.ShardResourceLocatorTest;
import org.eclipse.papyrus.infra.emf.resource.index.WorkspaceModelIndexTest;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForResourceTest;
import org.eclipse.papyrus.infra.types.core.registries.ElementTypeSetConfigurationRegistry;
@@ -37,8 +40,10 @@ import org.junit.runners.Suite.SuiteClasses;
PapyrusTransactionalEditingDomainTest.class,
// oep.infra.emf.utils
ServiceUtilsForResourceTest.class,
+ // oep.infra.emf.resource
+ ShardResourceHelperTest.class, ShardResourceLocatorTest.class, CrossReferenceIndexTest.class,
// oep.infra.emf.resource.index
- WorkspaceModelIndexTest.class
+ WorkspaceModelIndexTest.class,
})
public class AllTests {
diff --git a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.classpath b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.classpath
index 8a8f1668cdc..eca7bdba8f0 100644
--- a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.classpath
+++ b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.classpath
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.settings/org.eclipse.jdt.core.prefs b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.settings/org.eclipse.jdt.core.prefs
index 410244d65a6..62a08f4494d 100644
--- a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/.settings/org.eclipse.jdt.core.prefs
@@ -1,10 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/META-INF/MANIFEST.MF b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/META-INF/MANIFEST.MF
index be5e009ef29..bef0c0a73be 100644
--- a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/META-INF/MANIFEST.MF
+++ b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.106.0",
org.junit;bundle-version="4.11.0",
org.eclipse.papyrus.junit.framework;bundle-version="1.2.0",
org.eclipse.papyrus.infra.core.log;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.services.controlmode;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.services.controlmode;bundle-version="1.3.0",
org.eclipse.papyrus.infra.core;bundle-version="1.2.0",
org.eclipse.papyrus.views.modelexplorer;bundle-version="1.2.0",
org.eclipse.uml2.uml;bundle-version="5.0.0",
org.eclipse.emf.transaction,
org.eclipse.papyrus.infra.services.resourceloading;bundle-version="1.2.0",
org.eclipse.papyrus.junit.utils;bundle-version="1.2.0",
- org.eclipse.papyrus.infra.emf;bundle-version="1.2.0",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.3.0",
org.eclipse.papyrus.infra.widgets;bundle-version="1.2.0",
org.eclipse.ui.navigator;bundle-version="3.5.500",
com.google.guava;bundle-version="11.0.0",
@@ -21,9 +21,9 @@ Export-Package: org.eclipse.papyrus.infra.services.controlmode.tests,
org.eclipse.papyrus.infra.services.controlmode.tests.uncontrol
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.4.0.qualifier
Bundle-Name: %Bundle-Name
Bundle-ManifestVersion: 2
Bundle-Activator: org.eclipse.papyrus.infra.services.controlmode.tests.control.Activator
Bundle-SymbolicName: org.eclipse.papyrus.infra.services.controlmode.tests
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/pom.xml b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/pom.xml
index 5341ea1e2be..ac0785e925e 100644
--- a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/pom.xml
+++ b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/pom.xml
@@ -10,6 +10,6 @@
</parent>
<groupId>org.eclipse.papyrus</groupId>
<artifactId>org.eclipse.papyrus.infra.services.controlmode.tests</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
</project>
diff --git a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/src/org/eclipse/papyrus/infra/services/controlmode/tests/uncontrol/UncontrolModelTest.java b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/src/org/eclipse/papyrus/infra/services/controlmode/tests/uncontrol/UncontrolModelTest.java
index 47316c7bdc3..dac0bb79c44 100644
--- a/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/src/org/eclipse/papyrus/infra/services/controlmode/tests/uncontrol/UncontrolModelTest.java
+++ b/tests/junit/plugins/infra/services/org.eclipse.papyrus.infra.services.controlmode.tests/src/org/eclipse/papyrus/infra/services/controlmode/tests/uncontrol/UncontrolModelTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2015 CEA LIST, Christian W. Damus, and others.
+ * Copyright (c) 2014, 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
@@ -8,27 +8,34 @@
* Contributors:
* Juan Cadavid (CEA) juan.cadavid@cea.fr - Implementation initial and API
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 459427
- * Christian W. Damus - bug 480209
+ * Christian W. Damus - bugs 480209, 496299
******************************************************************************/
package org.eclipse.papyrus.infra.services.controlmode.tests.uncontrol;
+import static org.hamcrest.CoreMatchers.anything;
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeThat;
import java.util.Collections;
import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.resource.ShardResourceHelper;
import org.eclipse.papyrus.infra.services.controlmode.tests.Messages;
import org.eclipse.papyrus.junit.utils.rules.PluginResource;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.PackageableElement;
+import org.hamcrest.CoreMatchers;
import org.junit.Test;
/**
@@ -392,4 +399,38 @@ public class UncontrolModelTest extends AbstractUncontrolModelTest {
};
uncontrolAssertion.assertUncontrol();
}
+
+ /**
+ * Test uncontrol of a "shard" resource sub-unit.
+ */
+ @Test
+ public void testUncontrolShardSubunit() throws ServiceException {
+ ShardResourceHelper[] helper = { null };
+ EModelElement[] element = { null };
+
+ UncontrolModeAssertion uncontrolAssertion = new UncontrolModeAssertion(Messages.UncontrolModelTest_4) {
+ @Override
+ protected void assertBeforeUncontrol() {
+ super.assertBeforeUncontrol();
+
+ element[0] = getElementToUnControl();
+ helper[0] = new ShardResourceHelper(element[0]);
+ houseKeeper.cleanUpLater(helper[0], ShardResourceHelper::close);
+
+ editorFixture.execute(helper[0].getSetShardCommand(true));
+ assumeThat("Element does not appear to be a shard", helper[0].isShard(), is(true));
+ }
+ };
+ uncontrolAssertion.assertUncontrol();
+
+ assertThat("Element still appears to be a shard", helper[0].isShard(), is(false));
+ assertThat("Element still has an annotation", element[0].getEAnnotations(),
+ not(CoreMatchers.<EAnnotation> hasItem(anything())));
+
+ undo();
+ assertNotSame(model.eResource(), selectedElements.get(0).eResource());
+ assertThat("Element does not appear to be a shard", helper[0].isShard(), is(true));
+ assertThat("Element does not have any annotation", element[0].getEAnnotations(),
+ CoreMatchers.<EAnnotation> hasItem(anything()));
+ }
}

Back to the top