Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2017-11-22 21:31:40 +0000
committerChristian W. Damus2017-11-30 14:04:44 +0000
commit2270c96ad19452908d6c122bfd12a47fec32ae7f (patch)
tree381a075f2a94598ff0c790aeeecef1cfce3f3b31 /plugins
parent8418b7f1e115d78cc6ab6b9099425a77bbaa0ed6 (diff)
downloadorg.eclipse.papyrus-collaborativemodeling-2270c96ad19452908d6c122bfd12a47fec32ae7f.tar.gz
org.eclipse.papyrus-collaborativemodeling-2270c96ad19452908d6c122bfd12a47fec32ae7f.tar.xz
org.eclipse.papyrus-collaborativemodeling-2270c96ad19452908d6c122bfd12a47fec32ae7f.zip
Bug 527638 - Support diagram migration for Papyrus models
Solves the problem when you try to compare a model from a previous version of Papyrus. Solved by using the reconcile mechanism of Papyrus. Ported from EMF Compare project change https://git.eclipse.org/r/#/c/84294 with changes: - ensure that migration of multiple sides causes no spurious conflicts (detected by numerous failures in Git tests) - remove Mars compatibility no longer needed - add JUnit tests - other minor touches - support maven build on Mac platform Change-Id: I2925d9ac70a6cc421be9ba9ba7f5d6906b1aa1af Signed-off-by: Simon Delisle <simon.delisle@ericsson.com> Also-by: Christian W. Damus <give.a.damus@gmail.com>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/plugin.xml4
-rw-r--r--plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java334
-rw-r--r--plugins/compare/bundles/org.eclipse.papyrus.compare.diagram/META-INF/MANIFEST.MF3
-rwxr-xr-xplugins/compare/pom.xml7
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests.git/pom.xml2
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/META-INF/MANIFEST.MF3
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookIntegrationTest.java143
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookTest.java229
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.di2
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.notation33
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.uml8
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/saveparameter/SaveParameterHookIntegrationTest.java88
-rw-r--r--plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/suite/AllTests.java5
-rw-r--r--plugins/compare/tests/pom.xml18
14 files changed, 861 insertions, 18 deletions
diff --git a/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/plugin.xml b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/plugin.xml
index fbae7965..b4e20078 100644
--- a/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/plugin.xml
+++ b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/plugin.xml
@@ -13,6 +13,7 @@
Stefan Dirix - Bugs 456699, 474723
Camille Letavernier - Bug 515373
Christian W. Damus - bug 512529
+ Simon Delisle - bug 217638
-->
<plugin>
@@ -36,6 +37,9 @@
<resourceSetHook
class="org.eclipse.papyrus.compare.diagram.ide.ui.internal.ServicesRegistryInitializingHook">
</resourceSetHook>
+ <resourceSetHook
+ class="org.eclipse.papyrus.compare.diagram.ide.ui.internal.DiagramMigrationHook">
+ </resourceSetHook>
</extension>
<extension
point="org.eclipse.emf.compare.ide.ui.logicalModelViewHandlers">
diff --git a/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java
new file mode 100644
index 00000000..551401e2
--- /dev/null
+++ b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Ericsson 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:
+ * Simon Delisle - initial API and implementation
+ * Christian W. Damus - bug 527638
+ *******************************************************************************/
+package org.eclipse.papyrus.compare.diagram.ide.ui.internal;
+
+import static java.lang.String.format;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
+import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
+import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramReconciler;
+import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramReconcilersReader;
+import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramVersioningUtils;
+
+/**
+ * Hook in the EMF Compare {@link ResourceSet} in order to make it able to handle papyrus diagram migration
+ * features.
+ *
+ * @author <a href="mailto:simon.delisle@ericsson.com">Simon Delisle</a>
+ */
+public class DiagramMigrationHook extends AbstractPapyrusResourceSetHook {
+
+ @Override
+ public void preLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) {
+ // Pass
+ }
+
+ @Override
+ public void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) {
+ for (Resource resource : resourceSet.getResources()) {
+ if (NotationModel.NOTATION_FILE_EXTENSION.equals(resource.getURI().fileExtension())) {
+ EList<EObject> contents = resource.getContents();
+ for (EObject object : contents) {
+ if (object instanceof Diagram) {
+ Diagram diagram = (Diagram)object;
+
+ IDGenerator idgen = new IDGenerator(diagram);
+ try {
+ migrateDiagram(getEditingDomain(resourceSet), diagram);
+ } finally {
+ idgen.dispose();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the editing domain for this resourceSet or create it.
+ *
+ * @param resourceSet
+ * The resource set
+ * @return TransactionalEditingDomain
+ */
+ private TransactionalEditingDomain getEditingDomain(ResourceSet resourceSet) {
+ TransactionalEditingDomain existingDomain = TransactionalEditingDomain.Factory.INSTANCE
+ .getEditingDomain(resourceSet);
+ if (existingDomain == null) {
+ return TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resourceSet);
+ } else {
+ return existingDomain;
+ }
+ }
+
+ /**
+ * Build the migration command.
+ *
+ * @param diagram
+ * Diagram you want to migrate
+ * @return CompositeCommand
+ */
+ private CompositeCommand buildCommand(Diagram diagram) {
+ CompositeCommand reconcileCommand = null;
+
+ if (!DiagramVersioningUtils.isOfCurrentPapyrusVersion(diagram)) {
+ reconcileCommand = new CompositeCommand("Reconciling"); //$NON-NLS-1$
+
+ String sourceVersion = DiagramVersioningUtils.getCompatibilityVersion(diagram);
+ Map<String, Collection<DiagramReconciler>> diagramReconcilers = DiagramReconcilersReader
+ .getInstance().load();
+ String diagramType = diagram.getType();
+ Collection<DiagramReconciler> reconcilers = new LinkedList<DiagramReconciler>();
+ if (diagramReconcilers.containsKey(diagramType)) {
+ reconcilers.addAll(diagramReconcilers.get(diagramType));
+ }
+
+ boolean someFailed = false;
+ Iterator<DiagramReconciler> reconciler = reconcilers.iterator();
+ while (reconciler.hasNext() && !someFailed) {
+ DiagramReconciler next = reconciler.next();
+
+ if (!next.canReconcileFrom(diagram, sourceVersion)) {
+ // asked for ignore it for this instance, all fine
+ continue;
+ }
+ ICommand nextCommand = next.getReconcileCommand(diagram);
+ if (nextCommand == null) {
+ // legitimate no-op response, all fine
+ continue;
+ }
+
+ if (nextCommand.canExecute()) {
+ reconcileCommand.add(nextCommand);
+ } else {
+ CompareDiagramIDEUIPapyrusPlugin.getDefault().getLog().log(new Status(IStatus.ERROR,
+ CompareDiagramIDEUIPapyrusPlugin.PLUGIN_ID,
+ "Diagram reconciler " + next + " failed to reconcile diagram: " + diagram)); //$NON-NLS-1$ //$NON-NLS-2$
+ someFailed = true;
+ }
+ }
+ if (someFailed) {
+ reconcileCommand = null;
+ }
+ }
+ return reconcileCommand;
+ }
+
+ /**
+ * Migrate the diagram to the current version of Papyrus.
+ *
+ * @param domain
+ * The editing domain for this diagram.
+ * @param diagram
+ * The diagram.
+ */
+ private void migrateDiagram(TransactionalEditingDomain domain, Diagram diagram) {
+ CompositeCommand migrationCommand = buildCommand(diagram);
+ if (migrationCommand == null) {
+ domain.dispose();
+ return;
+ }
+
+ migrationCommand.add(DiagramVersioningUtils.createStampCurrentVersionCommand(diagram));
+ // TODO: Handle reconcile exception
+ try {
+ // The migration command requires a transactional editing domain, but we don't
+ // want to record anything for undo/redo etc.
+ GMFUnsafe.write(domain, migrationCommand);
+ } catch (Exception e) {
+ logException(e);
+ } finally {
+ domain.dispose();
+ }
+ }
+
+ /**
+ * Logs the specified exception.
+ *
+ * @param t
+ * The exception to be logged.
+ */
+ private static void logException(Throwable t) {
+ CompareDiagramIDEUIPapyrusPlugin.getDefault().getLog()
+ .log(new Status(IStatus.WARNING, CompareDiagramIDEUIPapyrusPlugin.PLUGIN_ID,
+ "Could not migrate the diagram before comparison", t)); //$NON-NLS-1$
+ }
+
+ //
+ // Nested types
+ //
+
+ /**
+ * An adapter that generates new unique IDs, using a stable algorithm, for all new objects created by
+ * diagram migration. This helps to ensure that when the same diagram on multiple sides of a comparison is
+ * migrated on each side, that new elements created by migration are matched to avoid spurious add-add
+ * conflicts.
+ *
+ * @author Christian W. Damus
+ */
+ protected static class IDGenerator extends EContentAdapter {
+ private static final Pattern NOT_NCNAME = Pattern.compile("[^-a-zA-Z0-9_.]"); //$NON-NLS-1$
+
+ private static final String CHILDREN_PAT = "%s.%d"; //$NON-NLS-1$
+
+ private static final String STYLES_PAT = "%s._%s"; //$NON-NLS-1$
+
+ private static final String OTHER_PAT = "%s.%s%d"; //$NON-NLS-1$
+
+ private final Matcher notNCName = NOT_NCNAME.matcher(""); //$NON-NLS-1$
+
+ private final EObject root;
+
+ // Papyrus diagrams do not support cross-resource containment
+ private XMLResource resource;
+
+ private boolean enabled;
+
+ /**
+ * Initializes me for generation of predictable, matchable unique identifiers in the tree under the
+ * given {@code root}.
+ *
+ * @param root
+ * the root of a tree in which to generate unique identifiers
+ */
+ public IDGenerator(EObject root) {
+ super();
+
+ this.root = root;
+ this.resource = (XMLResource)root.eResource();
+
+ root.eAdapters().add(this);
+ this.enabled = true;
+ }
+
+ public void dispose() {
+ this.enabled = false;
+ root.eAdapters().remove(this);
+ }
+
+ @Override
+ protected void setTarget(EObject target) {
+ if (enabled) {
+ generateID(target);
+ }
+
+ super.setTarget(target);
+ }
+
+ /**
+ * Generate a new unique ID for an {@code object} based on its containment in its parent object.
+ *
+ * @param object
+ * a new object for which to generate a predictable, matchable ID
+ */
+ protected void generateID(EObject object) {
+ // Everything has a container because we can never attempt to generate
+ // the ID of the diagram, itself
+ EObject parent = object.eContainer();
+ String parentID = resource.getID(parent);
+ String newID;
+
+ EReference containment = object.eContainmentFeature();
+ int index = indexOf(parent, containment, object);
+ if (containment == NotationPackage.Literals.VIEW__PERSISTED_CHILDREN) {
+ // For the most common case, the most compact scheme
+ newID = format(CHILDREN_PAT, parentID, Integer.valueOf(index));
+ } else if (containment == NotationPackage.Literals.VIEW__STYLES) {
+ // Identify styles by EClass to avoid ordering issues
+ newID = format(STYLES_PAT, parentID, asID(object.eClass().getName()));
+ } else {
+ newID = format(OTHER_PAT, parentID, asID(containment.getName()), Integer.valueOf(index));
+ }
+
+ resource.setID(object, unique(newID));
+ }
+
+ /**
+ * Compures the index of an object {@code contained} in some {@code containment} reference of a
+ * {@code container}.
+ *
+ * @param container
+ * the containing object
+ * @param containment
+ * the reference in which the {@code contained} object is stored
+ * @param contained
+ * the contained object
+ * @return its index
+ */
+ protected int indexOf(EObject container, EReference containment, EObject contained) {
+ if (containment.isMany()) {
+ return ((InternalEList<?>)container.eGet(containment, false)).basicIndexOf(contained);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Transforms a {@link name} from the Ecore model by removing characters that are not valid in an XMI
+ * ID.
+ *
+ * @param name
+ * an Ecore name
+ * @return a munged variant that is suitable for concatenation in an XMI ID (usually unchanged)
+ */
+ protected String asID(String name) {
+ notNCName.reset(name);
+ return notNCName.replaceAll(""); //$NON-NLS-1$
+ }
+
+ /**
+ * Munge an object identifier, if necessary, to make it unique in the resource.
+ *
+ * @param id
+ * an object identifier
+ * @return an unique variant of the identifier (usually unchanged)
+ */
+ protected String unique(String id) {
+ String base = id;
+ String result = base;
+ int suffix = -1;
+
+ while (resource.getEObject(result) != null) {
+ if (suffix < 0) {
+ base = base + '_';
+ }
+ suffix++;
+ result = base + suffix;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram/META-INF/MANIFEST.MF b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram/META-INF/MANIFEST.MF
index f1e12348..035eca27 100644
--- a/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram/META-INF/MANIFEST.MF
+++ b/plugins/compare/bundles/org.eclipse.papyrus.compare.diagram/META-INF/MANIFEST.MF
@@ -9,7 +9,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.10.0",
org.eclipse.emf.compare;bundle-version="3.2.0",
org.eclipse.uml2.uml;bundle-version="5.0.0",
org.eclipse.gmf.runtime.notation;bundle-version="1.8.0",
- org.eclipse.papyrus.infra.core;bundle-version="0.9.1"
+ org.eclipse.papyrus.infra.core;bundle-version="0.9.1",
+ org.eclipse.papyrus.infra.gmfdiag.style;bundle-version="[1.0.0,2.0.0)"
Bundle-ActivationPolicy: lazy
Import-Package: com.google.common.base;version="[15.0.0,22.0.0)",
com.google.common.collect;version="[15.0.0,22.0.0)"
diff --git a/plugins/compare/pom.xml b/plugins/compare/pom.xml
index 80ca27c0..e861274a 100755
--- a/plugins/compare/pom.xml
+++ b/plugins/compare/pom.xml
@@ -236,8 +236,11 @@
<ws>gtk</ws>
<arch>x86_64</arch>
</environment>
- <!-- <environment> <os>macosx</os> <ws>cocoa</ws> <arch>x86_64</arch>
- </environment> -->
+ <environment>
+ <os>macosx</os>
+ <ws>cocoa</ws>
+ <arch>x86_64</arch>
+ </environment>
</environments>
<target>
<artifact>
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests.git/pom.xml b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests.git/pom.xml
index 7ea91380..f8761c6f 100644
--- a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests.git/pom.xml
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests.git/pom.xml
@@ -26,7 +26,7 @@
<include>org/eclipse/papyrus/compare/diagram/tests/suite/PapyrusGitTests.class</include>
</includes>
<useUIHarness>true</useUIHarness>
- <argLine>-Xmx2048m</argLine>
+ <argLine>${test-vmargs} -Xmx2048m</argLine>
</configuration>
</plugin>
</plugins>
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/META-INF/MANIFEST.MF b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/META-INF/MANIFEST.MF
index 59cdde65..d0e4f48b 100644
--- a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/META-INF/MANIFEST.MF
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/META-INF/MANIFEST.MF
@@ -41,7 +41,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.compare.uml2.ide.tests,
org.eclipse.emf.compare.ide.ui.tests.framework,
org.eclipse.papyrus.sysml14;bundle-version="1.0.0",
- org.eclipse.papyrus.sysml14.architecture;bundle-version="1.0.0"
+ org.eclipse.papyrus.sysml14.architecture;bundle-version="1.0.0",
+ org.eclipse.papyrus.uml.diagram.component;bundle-version="3.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Vendor: %providerName
Import-Package: com.google.common.base;version="[15.0.0,22.0.0)",
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookIntegrationTest.java b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookIntegrationTest.java
new file mode 100644
index 00000000..1e43cd95
--- /dev/null
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookIntegrationTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.compare.diagram.tests.migration;
+
+import static org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookTest.collectAll;
+import static org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookTest.getTestInput;
+import static org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookTest.hasVisualID;
+import static org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookTest.isCurrentVersion;
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder;
+import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
+import org.eclipse.emf.compare.ide.ui.tests.workspace.TestProject;
+import org.eclipse.emf.compare.ide.utils.StorageTraversal;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.EMFCompareBuilderConfigurator;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.uml2.ide.tests.util.ProfileTestUtil;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.compare.diagram.ide.ui.internal.DiagramMigrationHook;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Integration tests for the {@link DiagramMigrationHook} class.
+ *
+ * @author Christian W. Damus
+ */
+@SuppressWarnings({"restriction", "nls" })
+public class DiagramMigrationHookIntegrationTest {
+
+ static final List<String> FILE_NAMES = ImmutableList.of("model.di", "model.uml", "model.notation");
+
+ private TestProject project;
+
+ private Map<String, IFile> files;
+
+ /**
+ * Initializes me.
+ */
+ public DiagramMigrationHookIntegrationTest() {
+ super();
+ }
+
+ @Test
+ public void hook() {
+ IComparisonScope scope = getComparisonScope(false);
+
+ // Views no longer have numeric "visual ID" types
+ Iterable<View> views = collectAll((ResourceSet)scope.getLeft(), View.class);
+ assumeThat(views, hasItem(any(View.class)));
+ assertThat(views, everyItem(not(hasVisualID())));
+
+ // Diagrams are up-to-date
+ Iterable<Diagram> diagrams = Iterables.filter(views, Diagram.class);
+ assumeThat(diagrams, hasItem(any(Diagram.class)));
+ assertThat(diagrams, everyItem(isCurrentVersion()));
+ }
+
+ @Test
+ public void noConflicts() {
+ IComparisonScope scope = getComparisonScope(true);
+ Comparison comparison = compare(scope);
+
+ assertThat("Migration introduced different objects on each side that are in conflict",
+ comparison.getConflicts(), not(hasItem(any(Conflict.class))));
+ }
+
+ //
+ // Test framework
+ //
+
+ @Before
+ public void createProject() throws Exception {
+ files = new LinkedHashMap<>();
+ project = new TestProject();
+
+ for (String next : FILE_NAMES) {
+ files.put(next, project.createFile(next, getTestInput(next)));
+ }
+ }
+
+ @After
+ public void deleteProject() throws CoreException, IOException {
+ files = null;
+ project.dispose();
+ }
+
+ IComparisonScope getComparisonScope(boolean threeWay) {
+ List<String> uris = new ArrayList<>(3);
+ for (IFile next : files.values()) {
+ uris.add(URI.createPlatformResourceURI(next.getFullPath().toString(), true).toString());
+ }
+
+ // Let the comparison scope machinery load the resources with all available hooks
+ final StorageTraversal traversal = ProfileTestUtil
+ .createStorageTraversal(uris.toArray(new String[uris.size()]));
+
+ // Use the same resources for all sides (if we compare, it's to find spurious conflicts)
+ StorageTraversal origin = threeWay ? traversal : null;
+ final SynchronizationModel syncModel = new SynchronizationModel(traversal, traversal, origin);
+
+ return ComparisonScopeBuilder.create(syncModel, new NullProgressMonitor());
+ }
+
+ Comparison compare(IComparisonScope scope) {
+ EMFCompare.Builder builder = EMFCompare.builder();
+ EMFCompareBuilderConfigurator.createDefault().configure(builder);
+ return builder.build().compare(scope);
+ }
+}
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookTest.java b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookTest.java
new file mode 100644
index 00000000..98bb307d
--- /dev/null
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/DiagramMigrationHookTest.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.compare.diagram.tests.migration;
+
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeThat;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+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.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.compare.diagram.ide.ui.internal.DiagramMigrationHook;
+import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramVersioningUtils;
+import org.hamcrest.CustomTypeSafeMatcher;
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Unit tests for the {@link DiagramMigrationHook} class.
+ */
+@SuppressWarnings("nls")
+public class DiagramMigrationHookTest {
+
+ private final DiagramMigrationHook fixture = new DiagramMigrationHook();
+
+ private final ResourceSet resourceSet = new ResourceSetImpl();
+
+ /**
+ * Initializes me.
+ */
+ public DiagramMigrationHookTest() {
+ super();
+ }
+
+ @Test
+ public void postLoadingHook() {
+ Collection<URI> uris = uris("model.di", "model.uml", "model.notation");
+ load(resourceSet, uris);
+ fixture.postLoadingHook(resourceSet, uris);
+
+ // Views no longer have numeric "visual ID" types
+ Iterable<View> views = collectAll(resourceSet, View.class);
+ assumeThat(views, hasItem(any(View.class)));
+ assertThat(views, everyItem(not(hasVisualID())));
+
+ // Diagrams are up-to-date
+ Iterable<Diagram> diagrams = Iterables.filter(views, Diagram.class);
+ assumeThat(diagrams, hasItem(any(Diagram.class)));
+ assertThat(diagrams, everyItem(isCurrentVersion()));
+ }
+
+ //
+ // Test framework
+ //
+
+ /**
+ * Ensure that the UML {@code CacheAdapter} doesn't hold on to our resources.
+ */
+ @After
+ public void unloadResourceSet() {
+ for (Resource next : resourceSet.getResources()) {
+ next.unload();
+ next.eAdapters().clear();
+ }
+
+ resourceSet.getResources().clear();
+ resourceSet.eAdapters().clear();
+ }
+
+ /**
+ * Create URIs from a bunch of strings.
+ *
+ * @param uri
+ * URI strings
+ * @return the corresponding URIs
+ */
+ static List<URI> uris(String... uri) {
+ List<URI> result = new ArrayList<>(uri.length);
+ for (String next : uri) {
+ result.add(URI.createURI(next));
+ }
+ return result;
+ }
+
+ /**
+ * Obtains the contents of the test resource that is intended to be persisted at the given target URI.
+ *
+ * @param targetURI
+ * the URI of the resource as it would be persisted. The last segment of this URI is taken as
+ * the name to {@linkplain #getTestInput(String) get}
+ * @return the contents of the resource from the host bundle
+ * @throws IOException
+ * on failure to find/access the test resource
+ * @see #getTestInput(String)
+ */
+ static InputStream getTestInput(URI targetURI) throws IOException {
+ return getTestInput(targetURI.lastSegment());
+ }
+
+ /**
+ * Obtains the contents of the {@code name}d test resource.
+ *
+ * @param name
+ * the test resource name to get
+ * @return the contents of the resource from the host bundle
+ * @throws IOException
+ * on failure to find/access the test resource
+ */
+ static InputStream getTestInput(String name) throws IOException {
+ URL url = DiagramMigrationHookTest.class.getResource(String.format("data/a1/%s", name));
+ return url.openStream();
+ }
+
+ /**
+ * Loads the given resource URIs in a resource set from the corresponding {@linkplain #getTestInput(URI)
+ * test resources} in the host bundle.
+ *
+ * @param rset
+ * the resource set context in which to load the resources
+ * @param uris
+ * the resource URIs to load
+ * @return the loaded resources
+ */
+ static Collection<Resource> load(ResourceSet rset, Collection<URI> uris) {
+ List<Resource> result = new ArrayList<>(uris.size());
+
+ for (URI next : uris) {
+ Resource resource = rset.createResource(next);
+ try (InputStream input = getTestInput(next)) {
+ resource.load(input, null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Failed to load test resource: " + e.getMessage());
+ }
+ result.add(resource);
+ }
+
+ return result;
+ }
+
+ /**
+ * Collect all objects of some {@code type} in a resource set.
+ *
+ * @param rset
+ * a resource set
+ * @param type
+ * the type of objects to retrieve
+ * @return the objects of the given {@code type}
+ */
+ static <T> Iterable<T> collectAll(ResourceSet rset, Class<T> type) {
+ return Lists.newArrayList(Iterators.filter(rset.getAllContents(), type));
+ }
+
+ /**
+ * Hamcrest matcher for diagram views that have "visual ID" types.
+ *
+ * @return matches views that have numeric types
+ */
+ static Matcher<View> hasVisualID() {
+ return new FeatureMatcher<View, String>(matchesRegex("\\d+"), "is an integer", "type") {
+ @Override
+ protected String featureValueOf(View actual) {
+ return actual.getType();
+ }
+ };
+ }
+
+ /**
+ * Hamcrest matcher for regular expressions.
+ *
+ * @param regex
+ * a regular expression
+ * @return a matcher for strings matching the {@code regex} in their entirety
+ */
+ static Matcher<String> matchesRegex(String regex) {
+ final java.util.regex.Matcher matcher = Pattern.compile(regex).matcher("");
+ return new CustomTypeSafeMatcher<String>(String.format("matches regex '%s'", regex)) {
+ @Override
+ protected boolean matchesSafely(String item) {
+ matcher.reset(item);
+ return matcher.matches();
+ }
+ };
+ }
+
+ /**
+ * Hamcrest matcher for diagrams that are at the current version.
+ *
+ * @return matches diagrams that are up-to-date
+ */
+ static Matcher<Diagram> isCurrentVersion() {
+ return new CustomTypeSafeMatcher<Diagram>("is up-to-date") {
+ @Override
+ protected boolean matchesSafely(Diagram item) {
+ return DiagramVersioningUtils.isOfCurrentPapyrusVersion(item);
+ }
+ };
+ }
+}
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.di b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.di
new file mode 100644
index 00000000..bf9abab3
--- /dev/null
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.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/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.notation b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.notation
new file mode 100644
index 00000000..49a6e24f
--- /dev/null
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.notation
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_tvKQsMKAEeS3-futUG4ugQ" type="PapyrusUMLComponentDiagram" name="ComponentDiagram" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_1V700MKAEeS3-futUG4ugQ" type="2002">
+ <children xmi:type="notation:DecorationNode" xmi:id="_1WICEMKAEeS3-futUG4ugQ" type="5004"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_1WIpIMKAEeS3-futUG4ugQ" type="6030">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_1WIpIcKAEeS3-futUG4ugQ" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_1WM6kMKAEeS3-futUG4ugQ" type="7001">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_1WM6kcKAEeS3-futUG4ugQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_1WM6ksKAEeS3-futUG4ugQ"/>
+ </children>
+ <element xmi:type="uml:Component" href="model.uml#_1GdOYMKAEeS3-futUG4ugQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_1V700cKAEeS3-futUG4ugQ" x="59" y="55" width="116"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_QL7KYMKCEeS3-futUG4ugQ" type="2002">
+ <children xmi:type="notation:DecorationNode" xmi:id="_QL7xcMKCEeS3-futUG4ugQ" type="5004"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_QL8YgMKCEeS3-futUG4ugQ" type="6030">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_QL8YgcKCEeS3-futUG4ugQ" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_QL8YgsKCEeS3-futUG4ugQ" type="7001">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_QL8Yg8KCEeS3-futUG4ugQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QL8YhMKCEeS3-futUG4ugQ"/>
+ </children>
+ <element xmi:type="uml:Component" href="model.uml#_QLtH8MKCEeS3-futUG4ugQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QL7KYcKCEeS3-futUG4ugQ" x="208" y="57" width="116"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_tvKQscKAEeS3-futUG4ugQ" name="diagram_compatibility_version" stringValue="1.0.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_tvKQssKAEeS3-futUG4ugQ"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_tvKQs8KAEeS3-futUG4ugQ">
+ <owner xmi:type="uml:Model" href="model.uml#_tsn6EMKAEeS3-futUG4ugQ"/>
+ </styles>
+ <element xmi:type="uml:Model" href="model.uml#_tsn6EMKAEeS3-futUG4ugQ"/>
+</notation:Diagram>
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.uml b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.uml
new file mode 100644
index 00000000..8d76f14f
--- /dev/null
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/migration/data/a1/model.uml
@@ -0,0 +1,8 @@
+<?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="_tsn6EMKAEeS3-futUG4ugQ" name="Model">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_tsn6EcKAEeS3-futUG4ugQ">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Component" xmi:id="_1GdOYMKAEeS3-futUG4ugQ" name="C1"/>
+ <packagedElement xmi:type="uml:Component" xmi:id="_QLtH8MKCEeS3-futUG4ugQ" name="C2"/>
+</uml:Model>
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/saveparameter/SaveParameterHookIntegrationTest.java b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/saveparameter/SaveParameterHookIntegrationTest.java
index 7d46e36e..d5a180ed 100644
--- a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/saveparameter/SaveParameterHookIntegrationTest.java
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/saveparameter/SaveParameterHookIntegrationTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * Copyright (c) 2015, 2017 EclipseSource Muenchen GmbH 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
@@ -7,10 +7,13 @@
*
* Contributors:
* Stefan Dirix - initial API and implementation
+ * Christian W. Damus - bug 527638
*******************************************************************************/
package org.eclipse.papyrus.compare.diagram.tests.saveparameter;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
@@ -22,12 +25,15 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder;
@@ -40,6 +46,9 @@ import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.papyrus.compare.diagram.ide.ui.internal.DiagramMigrationHook;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +60,7 @@ import org.osgi.framework.Bundle;
*
* @author Stefan Dirix <sdirix@eclipsesource.com>
*/
-@SuppressWarnings("restriction")
+@SuppressWarnings({"restriction", "nls" })
public class SaveParameterHookIntegrationTest {
/**
@@ -120,22 +129,39 @@ public class SaveParameterHookIntegrationTest {
final List<IFile> originalFiles = new ArrayList<IFile>(fileNames.size());
final List<IFile> saveFiles = new ArrayList<IFile>(fileNames.size());
- final List<String> platformURIStrings = new ArrayList<String>(fileNames.size());
+ final List<URI> originalResourceURIs = new ArrayList<>(fileNames.size());
+ final List<String> saveResourceURIStrings = new ArrayList<>(fileNames.size());
+ final Map<IFile, IFile> originalToSaveMap = new HashMap<>();
- // copy files twice
+ // Create originals
for (String fileName : fileNames) {
final String path = BASE_PATH + localContainer + fileName;
final URI fileURI = getFileUri(bundle.getEntry(path));
final IFile originalFile = project.createFile("original/" + fileName, getInputStream(fileURI));
- final IFile saveFile = project.createFile("save/" + fileName, getInputStream(fileURI));
+ final IFile saveFile = project.getProject().getFile(new Path("save/" + fileName));
+ originalToSaveMap.put(originalFile, saveFile);
+
originalFiles.add(originalFile);
+ originalResourceURIs
+ .add(URI.createPlatformResourceURI(originalFile.getFullPath().toString(), true));
+ }
+
+ // Run diagram migrations as needed, to avoid those introducing changes
+ migrateDiagrams(originalResourceURIs);
+
+ // Copy the migrated files. Be careful to maintain ordering
+ project.createFolder("save");
+ for (IFile originalFile : originalFiles) {
+ IFile saveFile = originalToSaveMap.get(originalFile);
+ saveFile.create(originalFile.getContents(true), true, null);
saveFiles.add(saveFile);
- platformURIStrings.add("platform:/resource/" + TEST_PROJECT_NAME + "/save/" + fileName);
+ saveResourceURIStrings
+ .add(URI.createPlatformResourceURI(saveFile.getFullPath().toString(), true).toString());
}
// build comparison scope which uses the internal resource sets of EMF Compare
final StorageTraversal traversal = ProfileTestUtil
- .createStorageTraversal(platformURIStrings.toArray(new String[0]));
+ .createStorageTraversal(saveResourceURIStrings.toArray(new String[0]));
final SynchronizationModel syncModel = new SynchronizationModel(traversal, traversal, null);
final IComparisonScope scope = ComparisonScopeBuilder.create(syncModel, new NullProgressMonitor());
@@ -149,7 +175,7 @@ public class SaveParameterHookIntegrationTest {
for (int i = 0; i < fileNames.size(); i++) {
final IFile originalFile = originalFiles.get(i);
final IFile saveFile = saveFiles.get(i);
- assertTrue(compareTextContent(originalFile, saveFile));
+ compareTextContent(originalFile, saveFile, true);
}
}
@@ -165,11 +191,15 @@ public class SaveParameterHookIntegrationTest {
* @throws IOException
* When there is an error reading one of the files.
*/
- private boolean compareTextContent(IFile fileA, IFile fileB) throws IOException {
+ private void compareTextContent(IFile fileA, IFile fileB, boolean expectedEqual) throws IOException {
final String textFileA = removeCRCharacters(getText(fileA));
final String textFileB = removeCRCharacters(getText(fileB));
- return textFileA.equals(textFileB);
+ if (expectedEqual) {
+ assertEquals(textFileB, textFileA);
+ } else {
+ assertNotEquals(textFileB, textFileA);
+ }
}
/**
@@ -248,4 +278,40 @@ public class SaveParameterHookIntegrationTest {
public void disposeProject() throws CoreException, IOException {
project.dispose();
}
+
+ /**
+ * Migrate the diagrams in a bunch of resources and save them.
+ *
+ * @param resourceURIs
+ * the resources in which to migrate diagrams
+ */
+ void migrateDiagrams(Collection<URI> resourceURIs) {
+ ResourceSet rset = new ResourceSetImpl();
+
+ DiagramMigrationHook hook = new DiagramMigrationHook();
+ for (URI next : resourceURIs) {
+ rset.getResource(next, true);
+ }
+
+ hook.postLoadingHook(rset, resourceURIs);
+
+ // Save the migrations. Note that the original test resources have the
+ // redundant XMI types, so preserve those
+ Map<Object, Object> saveOptions = new HashMap<>();
+ saveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, Boolean.TRUE);
+ saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Boolean.TRUE);
+ for (Resource next : rset.getResources()) {
+ try {
+ next.save(saveOptions);
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("Failed to save migrated diagram(s): " + e.getMessage());
+ }
+ }
+
+ for (Resource next : rset.getResources()) {
+ next.unload();
+ }
+ rset.getResources().clear();
+ }
}
diff --git a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/suite/AllTests.java b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/suite/AllTests.java
index 73a628b6..d2789ce6 100644
--- a/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/suite/AllTests.java
+++ b/plugins/compare/tests/org.eclipse.papyrus.compare.diagram.tests/src/org/eclipse/papyrus/compare/diagram/tests/suite/AllTests.java
@@ -10,7 +10,7 @@
* Stefan Dirix - add ModelExtensionUtil, SaveParameterHook and URIAttachment tests
* Philip Langer - add IngoreDiFileModelElementsTest
* Martin Fleck - add MergeNonConflictingCascadingDifferencesFilterTest
- * Christian W. Damus - bug 512529
+ * Christian W. Damus - bugs 512529, 527638
*******************************************************************************/
package org.eclipse.papyrus.compare.diagram.tests.suite;
@@ -29,6 +29,8 @@ import org.eclipse.papyrus.compare.diagram.tests.merge.AssocMergeTest;
import org.eclipse.papyrus.compare.diagram.tests.merge.EdgeMergeTest;
import org.eclipse.papyrus.compare.diagram.tests.merge.NodeMergeTest;
import org.eclipse.papyrus.compare.diagram.tests.merge.sysml.MergeDiffInvolvingRefineDiffTest;
+import org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookIntegrationTest;
+import org.eclipse.papyrus.compare.diagram.tests.migration.DiagramMigrationHookTest;
import org.eclipse.papyrus.compare.diagram.tests.modelextension.ModelExtensionUtilTest;
import org.eclipse.papyrus.compare.diagram.tests.saveparameter.SaveParameterHookIntegrationTest;
import org.eclipse.papyrus.compare.diagram.tests.saveparameter.SaveParameterHookTest;
@@ -56,6 +58,7 @@ import org.junit.runners.Suite.SuiteClasses;
IgnoreDiFilePostProcessorTest.class, PapyrusContextUtilTest.class,
MergeNonConflictingCascadingFilterTest.class, MergeDiffInvolvingRefineDiffTest.class, //
CSSTest.class, //
+ DiagramMigrationHookTest.class, DiagramMigrationHookIntegrationTest.class, //
})
public class AllTests {
diff --git a/plugins/compare/tests/pom.xml b/plugins/compare/tests/pom.xml
index 51eb4354..9fc00c89 100644
--- a/plugins/compare/tests/pom.xml
+++ b/plugins/compare/tests/pom.xml
@@ -12,8 +12,24 @@
<properties>
<target.file>${target.folder}/compare.tests-${target.stream}</target.file>
+ <test-vmargs></test-vmargs>
</properties>
+ <profiles>
+ <profile>
+ <id>mac-test</id>
+ <activation>
+ <os>
+ <family>mac</family>
+ </os>
+ </activation>
+ <properties>
+ <target.file>${target.folder}/compare.tests-${target.stream}</target.file>
+ <test-vmargs>-XstartOnFirstThread</test-vmargs>
+ </properties>
+ </profile>
+ </profiles>
+
<build>
<plugins>
<plugin>
@@ -21,10 +37,10 @@
<artifactId>tycho-surefire-plugin</artifactId>
<configuration>
<useUIHarness>true</useUIHarness>
+ <argLine>${test-vmargs}</argLine>
</configuration>
</plugin>
</plugins>
-
</build>
<modules>
<module>org.eclipse.papyrus.compare.uml2.tests</module>

Back to the top