Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStéphane Thibaudeau2020-05-29 13:59:05 +0000
committerPierre-Charles David2020-06-24 06:57:33 +0000
commit9cf25ac4dc47cae0076ee32a9cb6deb0b059f18c (patch)
treeaab6d22ae4d35579b699b09e895bc62e4e684f1a
parent520d13a052c01ac69a936aa8878a334b134e87a9 (diff)
downloadorg.eclipse.sirius-9cf25ac4dc47cae0076ee32a9cb6deb0b059f18c.tar.gz
org.eclipse.sirius-9cf25ac4dc47cae0076ee32a9cb6deb0b059f18c.tar.xz
org.eclipse.sirius-9cf25ac4dc47cae0076ee32a9cb6deb0b059f18c.zip
[563730] Modify extension point to declare EClasses as DocumentRoots
Reuse the package_meta_data extension point to add an element to specify EClasses in the metamodel which should be considered as a Document Roots. This is useful for metamodel generated from a XSD. To help Sirius consider some containment references as not transient even though the metamodel declares them as transient. Change-Id: If744a9ab7bb214b665de452982711c947087bfef Signed-off-by: Stéphane Thibaudeau <stephane.thibaudeau@obeo.fr> Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common/schema/package_meta_data.exsd15
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/ecore/EPackageMetaData.java21
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java30
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/ecore/EPackageMetaDataRegistryReader.java15
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.html18
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile4
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java2
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/query/NotificationQueryTests.java214
8 files changed, 304 insertions, 15 deletions
diff --git a/plugins/org.eclipse.sirius.common/schema/package_meta_data.exsd b/plugins/org.eclipse.sirius.common/schema/package_meta_data.exsd
index e44c06f4e1..665365a6b8 100644
--- a/plugins/org.eclipse.sirius.common/schema/package_meta_data.exsd
+++ b/plugins/org.eclipse.sirius.common/schema/package_meta_data.exsd
@@ -47,7 +47,8 @@
<element name="ePackageMetaData">
<complexType>
<sequence minOccurs="0" maxOccurs="unbounded">
- <element ref="suggestedRoot"/>
+ <element ref="suggestedRoot" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="documentRoot" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="nsURI" type="string" use="required">
<annotation>
@@ -85,6 +86,18 @@
</complexType>
</element>
+ <element name="documentRoot">
+ <complexType>
+ <attribute name="className" type="string">
+ <annotation>
+ <documentation>
+ The name of the EClass which is to be considered as a potential DocumentRoot class. This is particularly useful when working with an EPackage generated from XSD. The named class must be contained directly in the EPackage.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
<annotation>
<appInfo>
<meta.section type="since"/>
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/ecore/EPackageMetaData.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/ecore/EPackageMetaData.java
index 8191211f89..48466ff787 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/ecore/EPackageMetaData.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/ecore/EPackageMetaData.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 Obeo.
+ * Copyright (c) 2017, 2020 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -38,6 +38,15 @@ public class EPackageMetaData {
private String documentation;
/**
+ * Names of the EClass which are possible DocumentRoot classes for this EPackage.
+ * This is useful when working with EPackages generated from XSD.
+ * Checking if an EClass is the DocumentRoot can not always be done using
+ * ExtendedMetaData.INSTANCE.isDocumentRoot(eClass) depending on how
+ * the EPackage was generated from XSD
+ */
+ private List<String> documentRootClassNames = new ArrayList<>();
+
+ /**
* Names of EClasses from the EPackage that are good candidates as root model elements.
*/
private List<String> suggestedRoots = new ArrayList<>();
@@ -98,6 +107,16 @@ public class EPackageMetaData {
public void setDocumentation(String documentation) {
this.documentation = documentation;
}
+
+ /**
+ * Returns the name of the EClasses to be considered as the DocumentRoot.
+ *
+ * @return the documentRootClassNames
+ * @since 6.3.2
+ */
+ public List<String> getDocumentRootClassNames() {
+ return documentRootClassNames;
+ }
/**
* Returns the names of EClasses from the EPackage that are good candidates as root model elements.
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java
index 6348ecebdb..149d9766e4 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/query/NotificationQuery.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 THALES GLOBAL SERVICES.
+ * Copyright (c) 2011, 2015, 2020 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -13,9 +13,12 @@
package org.eclipse.sirius.common.tools.api.query;
import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
+import org.eclipse.sirius.common.tools.api.ecore.EPackageMetaData;
import com.google.common.base.Preconditions;
@@ -38,11 +41,10 @@ public class NotificationQuery {
}
/**
- * Check if the feature of the notification is a transient
- * EStructuralFeature.
+ * Check if the feature of the notification is a transient EStructuralFeature.
*
- * @return true if this notification does not need to be consider as a
- * resource modification (because it is transient), false otherwise.
+ * @return true if this notification does not need to be consider as a resource modification (because it is
+ * transient), false otherwise.
*/
public boolean isTransientNotification() {
if (isNotificationOnTransientFeature()) {
@@ -73,11 +75,27 @@ public class NotificationQuery {
// Do not consider transient containing feature when the container
// is a DocumentRoot. See section 1.5 of
// https://www.eclipse.org/modeling/emf/docs/overviews/XMLSchemaToEcoreMapping.pdf
- if (current.eContainingFeature().isTransient() && !ExtendedMetaData.INSTANCE.isDocumentRoot(container.eClass())) {
+ if (current.eContainingFeature().isTransient() && !isDocumentRoot(container.eClass())) {
return true;
}
current = container;
}
return false;
}
+
+ private boolean isDocumentRoot(EClass eClass) {
+ return ExtendedMetaData.INSTANCE.isDocumentRoot(eClass) || isDeclaredAsDocumentRoot(eClass);
+ }
+
+ private boolean isDeclaredAsDocumentRoot(EClass eClass) {
+ if (eClass != null && eClass.getEPackage() != null) {
+ String nsURI = eClass.getEPackage().getNsURI();
+ EPackageMetaData metaData = DslCommonPlugin.INSTANCE.getEPackageMetaData(nsURI);
+
+ if (metaData != null && metaData.getDocumentRootClassNames() != null) {
+ return metaData.getDocumentRootClassNames().contains(eClass.getName());
+ }
+ }
+ return false;
+ }
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/ecore/EPackageMetaDataRegistryReader.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/ecore/EPackageMetaDataRegistryReader.java
index d000f1336c..5f57a04118 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/ecore/EPackageMetaDataRegistryReader.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/ecore/EPackageMetaDataRegistryReader.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2017 Obeo
+ * Copyright (c) 2017, 2020 Obeo
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -42,6 +42,11 @@ public class EPackageMetaDataRegistryReader {
/** Documentation attribute. */
private static final String DOCUMENTATION_ATTRIBUTE = "documentation"; //$NON-NLS-1$
+ /** DocumentRoot class names. */
+ private static final String DOCUMENT_ROOT_ELEMENT = "documentRoot"; //$NON-NLS-1$
+
+ private static final String DOCUMENT_ROOT_CLASS_NAME_ATTRIBUTE = "className"; //$NON-NLS-1$
+
/** Preferred root element attribute. */
private static final String SUGGESTED_ROOT_ELEMENT = "suggestedRoot"; //$NON-NLS-1$
@@ -67,7 +72,7 @@ public class EPackageMetaDataRegistryReader {
}
/**
- * Initialize the regsitry and start listening for dynamic changes.
+ * Initialize the registry and start listening for dynamic changes.
*/
public synchronized void start() {
for (IConfigurationElement cfg : extensionRegistry.getConfigurationElementsFor(EPACKAGE_META_DATA_EXTENSION_POINT)) {
@@ -98,6 +103,12 @@ public class EPackageMetaDataRegistryReader {
result.getSuggestedRoots().add(className.trim());
}
}
+ for (IConfigurationElement child : cfg.getChildren(DOCUMENT_ROOT_ELEMENT)) {
+ String className = child.getAttribute(DOCUMENT_ROOT_CLASS_NAME_ATTRIBUTE);
+ if (!StringUtil.isEmpty(className)) {
+ result.getDocumentRootClassNames().add(className.trim());
+ }
+ }
return result;
} else {
return null;
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
index fd2ebbd65e..caafb82f5d 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
@@ -140,6 +140,14 @@
<img border="0" src="images/combined_fragment_label_before.png"/> With Sirius 6.3.2, the label is now on the top of execution:
<img border="0" src="images/combined_fragment_label_after.png"/>
<h3 id="DeveloperVisibleChanges">Developer-Visible Changes</h3>
+ <h4 id="Changesinorg.eclipse.sirius.common">Changes in
+ <code>org.eclipse.sirius.common</code>
+ </h4>
+ <ul>
+ <li><span class="label label-success">Added</span> In the
+ <code>org.eclipse.sirius.common.package_meta_data</code> extension point, it is now possible for a given metamodel (nsURI) to declare some EClasses as potential DocumentRoots. This is needed with some XSD-derived metamodels which normally declare some of their containment references as transient to make sure Sirius will properly consider these classes (and their contents) as needing to be serialized.
+ </li>
+ </ul>
<h4 id="Changesinorg.eclipse.sirius.diagram.ui">Changes in
<code>org.eclipse.sirius.diagram.ui</code>
</h4>
@@ -333,7 +341,7 @@
<code>DREPRESENTATION_DESCRIPTOR</code> has been removed because they are not available anymore in custom data.
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common2">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -479,7 +487,7 @@
</li>
</ul>
<h3 id="DeveloperVisibleChanges5">Developer-Visible Changes</h3>
- <h4 id="Changesinorg.eclipse.sirius.common2">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common3">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -900,7 +908,7 @@
<code>org.eclipse.sirius.diagram.ui.tools.api.decoration.DecorationDescriptor.isPrintable</code>. This attribute is used to know if the decoration should be hidden when printing or exporting the diagram. The behavior is applied only if there is no printable decoration in its diagram element location (South, West, South-West etc).
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common3">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common4">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -1225,7 +1233,7 @@
<code>org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures</code> package.
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common4">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common5">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
@@ -1362,7 +1370,7 @@
<code>SemanticBasedDecoration</code>.
</li>
</ul>
- <h4 id="Changesinorg.eclipse.sirius.common5">Changes in
+ <h4 id="Changesinorg.eclipse.sirius.common6">Changes in
<code>org.eclipse.sirius.common</code>
</h4>
<ul>
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
index c69d3f1933..009bdfd3f6 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
@@ -20,6 +20,10 @@ A consequence is that the display of existing compartments in diagrams may be ch
h3. Developer-Visible Changes
+h4. Changes in @org.eclipse.sirius.common@
+
+* <span class="label label-success">Added</span> In the @org.eclipse.sirius.common.package_meta_data@ extension point, it is now possible for a given metamodel (nsURI) to declare some EClasses as potential DocumentRoots. This is needed with some XSD-derived metamodels which normally declare some of their containment references as transient to make sure Sirius will properly consider these classes (and their contents) as needing to be serialized.
+
h4. Changes in @org.eclipse.sirius.diagram.ui@
* <span class="label label-success">Added</span>The class @org.eclipse.sirius.diagram.ui.graphical.figures.OverlayLabelsDrawerFigure@ is a "virtual" figure that should be added to the @DDiagramRootEditPart#OVERLAY_LAYER@ and which paints all the overlay labels (instance of @OverlayLabel@) on top of the rest of the diagram to make sure they are always readable. This figure is currently only used by sequence diagrams for operand labels(@org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.OperandEditPart@) and combined fragment labels (@org.eclipse.sirius.diagram.sequence.ui.tool.internal.edit.part.CombinedFragmentEditPart@).
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
index 9058c4b78f..29d8342d0c 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java
@@ -39,6 +39,7 @@ import org.eclipse.sirius.tests.unit.api.modelingproject.SaveWhenNoEditorsTests;
import org.eclipse.sirius.tests.unit.api.modelingproject.SemanticResourcesManagementTests;
import org.eclipse.sirius.tests.unit.api.navigator.GroupingContentProviderByContainingTest;
import org.eclipse.sirius.tests.unit.api.navigator.GroupingContentProviderTest;
+import org.eclipse.sirius.tests.unit.api.query.NotificationQueryTests;
import org.eclipse.sirius.tests.unit.api.refresh.ModifyHeaderLabelExpressionTest;
import org.eclipse.sirius.tests.unit.api.representation.DRepresentationLocationManagerTest;
import org.eclipse.sirius.tests.unit.api.representation.InvalidRepresentationTest;
@@ -355,6 +356,7 @@ public class AllCommonPluginTests extends TestCase {
suite.addTestSuite(PageOrdererTest.class);
suite.addTestSuite(ModelingProjectDetectionTest.class);
+ suite.addTestSuite(NotificationQueryTests.class);
}
/**
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/query/NotificationQueryTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/query/NotificationQueryTests.java
new file mode 100644
index 0000000000..fc9c58d5b4
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/query/NotificationQueryTests.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2020 THALES GLOBAL SERVICES.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tests.unit.api.query;
+
+import java.io.ByteArrayInputStream;
+
+import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.runtime.ContributorFactoryOSGi;
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryEventListener;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.ETypedElement;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.sirius.common.tools.api.query.NotificationQuery;
+import org.eclipse.sirius.tests.SiriusTestsPlugin;
+import org.eclipse.sirius.tests.support.api.SiriusDiagramTestCase;
+
+/**
+ * Test class for {@link NotificationQuery}.
+ * This test was created for bug 563730
+ *
+ * @author <a href="mailto:stephane.thibaudeau@obeo.fr">Stéphane Thibaudeau</a>
+ */
+@SuppressWarnings("restriction")
+public class NotificationQueryTests extends SiriusDiagramTestCase {
+
+ private static final String EXTENSION_ID = "NotificationQueryTests";
+
+ private static final String EPACKAGE_META_DATA_EXTENSION_POINT = "org.eclipse.sirius.common.package_meta_data";
+
+ /** Dynamic metamodel */
+ private EPackage mm_pkg;
+ private EClass mm_rootEClass;
+ private EReference mm_childrenERef;
+ private EClass mm_childEClass;
+ private EAttribute mm_nameAtt;
+
+ /** model */
+ private EObject model_rootObject;
+ private EObject model_childObject;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ initDynamicMetamodel();
+ initModel();
+ }
+
+ /**
+ * Test the case of a EPackage with a EClass with null as name.
+ */
+ public void testNotificationQuery() {
+ Notification notification = new ENotificationImpl((InternalEObject)model_childObject, Notification.SET, mm_nameAtt, "ChildObject", "newName");
+
+ NotificationQuery query = new NotificationQuery(notification);
+
+ // initial state
+ assertEquals("Notification should not be transient", false, query.isTransientNotification());
+
+ // Set the containment reference to be transient
+ mm_childrenERef.setTransient(true);
+ assertEquals("Notification should be transient", true, query.isTransientNotification());
+
+ // Register the extension, this extension indicates that rootEClass corresponds to a document root
+ // now our Root class should be seen as a DocumentRoot
+ registerExtensionAndExecute(() -> assertEquals("Notification should not be transient", false, query.isTransientNotification()));
+
+ // Remove the extension
+ removeExtensionAndExecute(() -> assertEquals("Notification should be transient", true, query.isTransientNotification()));
+ }
+
+ @SuppressWarnings("unchecked")
+ private void initModel() {
+ EFactory factory = mm_pkg.getEFactoryInstance();
+
+ model_childObject = factory.create(mm_childEClass);
+ model_childObject.eSet(mm_nameAtt, "ChildObject");
+
+ model_rootObject = factory.create(mm_rootEClass);
+ ((EList<EObject>)model_rootObject.eGet(mm_childrenERef)).add(model_childObject);
+ }
+
+ private void initDynamicMetamodel() {
+ EcoreFactory factory = EcoreFactory.eINSTANCE;
+
+ mm_childEClass = factory.createEClass();
+ mm_childEClass.setName("Child");
+
+ mm_nameAtt = factory.createEAttribute();
+ mm_nameAtt.setName("name");
+ mm_nameAtt.setEType(EcorePackage.Literals.ESTRING);
+ mm_childEClass.getEStructuralFeatures().add(mm_nameAtt);
+
+ mm_rootEClass = factory.createEClass();
+ mm_rootEClass.setName("Root");
+
+ mm_childrenERef = factory.createEReference();
+ mm_childrenERef.setName("children");
+ mm_childrenERef.setEType(mm_childEClass);
+ mm_childrenERef.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
+ mm_childrenERef.setContainment(true);
+ mm_rootEClass.getEStructuralFeatures().add(mm_childrenERef);
+
+ mm_pkg = factory.createEPackage();
+ mm_pkg.setName("testMM");
+ mm_pkg.setNsPrefix("testMM");
+ mm_pkg.setNsURI("http://www.example.com/testMM");
+
+ mm_pkg.getEClassifiers().add(mm_rootEClass);
+ mm_pkg.getEClassifiers().add(mm_childEClass);
+
+ }
+
+ /**
+ * Installs dynamically an extension that adds "custom" at the end of the value of the "name" field CellEditor.
+ */
+ private void registerExtensionAndExecute(Runnable executeAfterModification) {
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+
+ // Add a listener to execute runnable after modification has been done
+ IRegistryEventListener listener = new IRegistryEventListener() {
+
+ @Override
+ public void removed(IExtensionPoint[] extensionPoints) {
+ }
+
+ @Override
+ public void removed(IExtension[] extensions) {
+ }
+
+ @Override
+ public void added(IExtensionPoint[] extensionPoints) {
+ }
+
+ @Override
+ public void added(IExtension[] extensions) {
+ executeAfterModification.run();
+ extensionRegistry.removeListener(this);
+ }
+ };
+ extensionRegistry.addListener(listener, EPACKAGE_META_DATA_EXTENSION_POINT);
+
+ IContributor contributor = ContributorFactoryOSGi.createContributor(SiriusTestsPlugin.getDefault().getBundle());
+ extensionRegistry.addContribution(new ByteArrayInputStream(getPluginXml().getBytes()), contributor, false, null, null, ((ExtensionRegistry) extensionRegistry).getTemporaryUserToken());
+ }
+
+ private String getPluginXml() {
+ return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<?eclipse version=\"3.4\"?>" +
+ "<plugin>" +
+ "<extension id=\"" + EXTENSION_ID + "\" point=\"org.eclipse.sirius.common.package_meta_data\">" +
+ "<ePackageMetaData nsURI=\"" + mm_pkg.getNsURI() + "\"><documentRoot className=\"" + mm_rootEClass.getName() + "\"/></ePackageMetaData>" +
+ "</extension>" +
+ "</plugin>";
+ }
+
+ /**
+ * Remove the installed extension.
+ */
+ private void removeExtensionAndExecute(Runnable executeAfterModification) {
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+
+ // Add a listener to execute runnable after modification has been done
+ IRegistryEventListener listener = new IRegistryEventListener() {
+
+ @Override
+ public void removed(IExtensionPoint[] extensionPoints) {
+ }
+
+ @Override
+ public void removed(IExtension[] extensions) {
+ executeAfterModification.run();
+ extensionRegistry.removeListener(this);
+ }
+
+ @Override
+ public void added(IExtensionPoint[] extensionPoints) {
+ }
+
+ @Override
+ public void added(IExtension[] extensions) {
+ }
+ };
+ extensionRegistry.addListener(listener, EPACKAGE_META_DATA_EXTENSION_POINT);
+
+ IExtension extension = extensionRegistry.getExtension(EPACKAGE_META_DATA_EXTENSION_POINT, SiriusTestsPlugin.PLUGIN_ID + "." + EXTENSION_ID);
+ extensionRegistry.removeExtension(extension, ((ExtensionRegistry) extensionRegistry).getTemporaryUserToken());
+ }
+
+}

Back to the top