diff options
| author | Laurent Redor | 2016-08-09 08:02:30 +0000 |
|---|---|---|
| committer | Laurent Redor | 2016-08-23 13:09:51 +0000 |
| commit | 67285def977561511f2e1714275dfb1d1671a9c1 (patch) | |
| tree | fc34f2c3f214fbd22454fb70cfd68f0585d8bc77 | |
| parent | 70732e47a4ea7fd774852162ce8b921f2284a2d8 (diff) | |
| download | org.eclipse.sirius-67285def977561511f2e1714275dfb1d1671a9c1.tar.gz org.eclipse.sirius-67285def977561511f2e1714275dfb1d1671a9c1.tar.xz org.eclipse.sirius-67285def977561511f2e1714275dfb1d1671a9c1.zip | |
[499805] Delete note attachment with corresponding Note or Text
* The test RemoveNoteTextTest has been completed to cover this cases.
* Add migration participant to remove note attachment without source or
target, and add the corresponding test.
Bug: 499805
Cherry-picked-from: 499414
Change-Id: I8b3285a4184bf6ca128faadcaafaea24e09bbd77
Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
8 files changed, 369 insertions, 19 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/ViewDeleteCommand.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/ViewDeleteCommand.java index 0c16bf3723..87ea1d3970 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/ViewDeleteCommand.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/internal/command/ViewDeleteCommand.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Obeo. + * Copyright (c) 2015, 2016 Obeo. * 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 @@ -17,8 +17,12 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand; +import org.eclipse.gmf.runtime.diagram.core.util.ViewType; +import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; +import com.google.common.collect.Iterables; + /** * Extends the GMF {@link DeleteCommand} to avoid creating * {@link org.eclipse.gmf.runtime.emf.core.util.CrossReferenceAdapter}. @@ -54,6 +58,13 @@ public class ViewDeleteCommand extends DeleteCommand { protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { // Prevents GMF to install its CrossReferencerAdapter by not calling // ViewUtil.destroy(View) + + // Remove incoming or outgoing NoteAttachment links + for (Edge edge : Iterables.filter(Iterables.concat(getView().getSourceEdges(), getView().getTargetEdges()), Edge.class)) { + if (ViewType.NOTEATTACHMENT.equals(edge.getType())) { + EcoreUtil.remove(edge); + } + } EcoreUtil.remove(getView()); return CommandResult.newOKCommandResult(); } diff --git a/plugins/org.eclipse.sirius.diagram/plugin.xml b/plugins/org.eclipse.sirius.diagram/plugin.xml index 6b7ade8c53..ca0bd12b2d 100644 --- a/plugins/org.eclipse.sirius.diagram/plugin.xml +++ b/plugins/org.eclipse.sirius.diagram/plugin.xml @@ -752,6 +752,10 @@ class="org.eclipse.sirius.diagram.business.internal.migration.VariableMigrationParticipant" kind="VSM"> </participant> + <participant + class="org.eclipse.sirius.diagram.business.internal.migration.NoteAttachmentWithoutSourceOrTargetMigrationParticipant" + kind="RepresentationsFile"> + </participant> </extension> <extension point="org.eclipse.sirius.mmdescriptor"> diff --git a/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/migration/NoteAttachmentWithoutSourceOrTargetMigrationParticipant.java b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/migration/NoteAttachmentWithoutSourceOrTargetMigrationParticipant.java new file mode 100644 index 0000000000..51dda2a471 --- /dev/null +++ b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/migration/NoteAttachmentWithoutSourceOrTargetMigrationParticipant.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2016 THALES GLOBAL SERVICES. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.diagram.business.internal.migration; + +import org.eclipse.gmf.runtime.diagram.core.util.ViewType; +import org.eclipse.gmf.runtime.notation.Connector; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.sirius.business.api.migration.AbstractRepresentationsFileMigrationParticipant; +import org.eclipse.sirius.diagram.DDiagram; +import org.eclipse.sirius.diagram.business.api.refresh.DiagramCreationUtil; +import org.eclipse.sirius.viewpoint.DAnalysis; +import org.eclipse.sirius.viewpoint.DView; +import org.osgi.framework.Version; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +/** + * A migration participant following the bug #499414 to remove all + * NoteAttachment without source or target.<br /> + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + * + */ +public class NoteAttachmentWithoutSourceOrTargetMigrationParticipant extends AbstractRepresentationsFileMigrationParticipant { + /** + * The VP version for which this migration is added. + */ + public static final Version MIGRATION_VERSION = new Version("11.0.1.201608181000"); //$NON-NLS-1$ + + @Override + public Version getMigrationVersion() { + return MIGRATION_VERSION; + } + + @Override + protected void postLoad(DAnalysis dAnalysis, Version loadedVersion) { + if (loadedVersion.compareTo(MIGRATION_VERSION) < 0) { + for (DView dView : dAnalysis.getOwnedViews()) { + for (DDiagram dDiagram : Iterables.filter(dView.getOwnedRepresentations(), DDiagram.class)) { + DiagramCreationUtil diagramCreationUtil = new DiagramCreationUtil(dDiagram); + if (diagramCreationUtil.findAssociatedGMFDiagram()) { + Diagram gmfDiagram = diagramCreationUtil.getAssociatedGMFDiagram(); + deleteNoteAttachmentWithoutSourceOrTarget(gmfDiagram); + } + } + } + super.postLoad(dAnalysis, loadedVersion); + } + } + + private void deleteNoteAttachmentWithoutSourceOrTarget(Diagram gmfDiagram) { + Iterable<Connector> noteAttachmentsToRemoveIter = Iterables.filter(Iterables.filter(gmfDiagram.getEdges(), Connector.class), new Predicate<Connector>() { + @Override + public boolean apply(Connector connector) { + if (ViewType.NOTEATTACHMENT.equals(connector.getType())) { + if (connector.getSource() == null || connector.getTarget() == null) { + return true; + } + } + return false; + } + }); + // Make a copy to avoid modification of edges list during the iteration + // on it. + Connector[] noteAttachmentsToRemove = Iterables.toArray(noteAttachmentsToRemoveIter, Connector.class); + // Remove each invalid note attachments + for (Connector connector : noteAttachmentsToRemove) { + gmfDiagram.removeEdge(connector); + } + } +} diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.aird b/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.aird new file mode 100644 index 0000000000..f422e9b720 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.aird @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="UTF-8"?> +<viewpoint:DAnalysis xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:diagram="http://www.eclipse.org/sirius/diagram/1.1.0" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/sirius/diagram/description/style/1.1.0" xmlns:viewpoint="http://www.eclipse.org/sirius/1.1.0" xsi:schemaLocation="http://www.eclipse.org/sirius/description/1.1.0 http://www.eclipse.org/sirius/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/style/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description/style" xmi:id="_WRqRgGUZEeaD08IjNDRpgg" selectedViews="_XjMK0GUZEeaD08IjNDRpgg" version="11.0.0.201604141600"> + <semanticResources>My.ecore</semanticResources> + <ownedViews xmi:type="viewpoint:DView" xmi:id="_XjMK0GUZEeaD08IjNDRpgg"> + <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']"/> + <ownedRepresentations xmi:type="diagram:DSemanticDiagram" xmi:id="_XqBLkGUZEeaD08IjNDRpgg" name="root package entities"> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_XqBLkWUZEeaD08IjNDRpgg" source="DANNOTATION_CUSTOMIZATION_KEY"> + <data xmi:type="diagram:ComputedStyleDescriptionRegistry" xmi:id="_XqBLkmUZEeaD08IjNDRpgg"/> + </ownedAnnotationEntries> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_XqIgUGUZEeaD08IjNDRpgg" source="GMF_DIAGRAMS"> + <data xmi:type="notation:Diagram" xmi:id="_XqIgUWUZEeaD08IjNDRpgg" type="Sirius" element="_XqBLkGUZEeaD08IjNDRpgg" measurementUnit="Pixel"> + <children xmi:type="notation:Node" xmi:id="_XqMKsGUZEeaD08IjNDRpgg" type="2003" element="_XqBLk2UZEeaD08IjNDRpgg"> + <children xmi:type="notation:Node" xmi:id="_XqRqQGUZEeaD08IjNDRpgg" type="5007"/> + <children xmi:type="notation:Node" xmi:id="_XqSRUGUZEeaD08IjNDRpgg" type="7004"> + <styles xmi:type="notation:SortingStyle" xmi:id="_XqSRUWUZEeaD08IjNDRpgg"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_XqSRUmUZEeaD08IjNDRpgg"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_XqMKsWUZEeaD08IjNDRpgg" fontName="Segoe UI" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XqMKsmUZEeaD08IjNDRpgg" x="115" y="76"/> + </children> + <children xmi:type="notation:Node" xmi:id="_XqS4YGUZEeaD08IjNDRpgg" type="2003" element="_XqBLlWUZEeaD08IjNDRpgg"> + <children xmi:type="notation:Node" xmi:id="_XqS4Y2UZEeaD08IjNDRpgg" type="5007"/> + <children xmi:type="notation:Node" xmi:id="_XqTfcGUZEeaD08IjNDRpgg" type="7004"> + <styles xmi:type="notation:SortingStyle" xmi:id="_XqTfcWUZEeaD08IjNDRpgg"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_XqTfcmUZEeaD08IjNDRpgg"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_XqS4YWUZEeaD08IjNDRpgg" fontName="Segoe UI" fontHeight="8"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XqS4YmUZEeaD08IjNDRpgg" x="315" y="175"/> + </children> + <styles xmi:type="notation:DiagramStyle" xmi:id="_XqIgUmUZEeaD08IjNDRpgg"/> + <edges xmi:type="notation:Edge" xmi:id="_XqVUoGUZEeaD08IjNDRpgg" type="4001" element="_XqBLl2UZEeaD08IjNDRpgg" source="_XqMKsGUZEeaD08IjNDRpgg" target="_XqS4YGUZEeaD08IjNDRpgg"> + <children xmi:type="notation:Node" xmi:id="_XqWiwGUZEeaD08IjNDRpgg" type="6001"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XqWiwWUZEeaD08IjNDRpgg" x="-5" y="3"/> + </children> + <children xmi:type="notation:Node" xmi:id="_XqXw4GUZEeaD08IjNDRpgg" type="6002"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XqXw4WUZEeaD08IjNDRpgg" x="2" y="-4"/> + </children> + <children xmi:type="notation:Node" xmi:id="_XqYX8GUZEeaD08IjNDRpgg" type="6003"> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XqYX8WUZEeaD08IjNDRpgg" x="3" y="-5"/> + </children> + <styles xmi:type="notation:ConnectorStyle" xmi:id="_XqVUoWUZEeaD08IjNDRpgg"/> + <styles xmi:type="notation:FontStyle" xmi:id="_XqVUomUZEeaD08IjNDRpgg" fontName="Segoe UI" fontHeight="8"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XqVUo2UZEeaD08IjNDRpgg" points="[41, 31, -159, -107]$[159, 123, -41, -15]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XqcpYGUZEeaD08IjNDRpgg" id="(0.5,0.0)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XqdQcGUZEeaD08IjNDRpgg" id="(0.5,1.0)"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_c2ROAGUZEeaD08IjNDRpgg" type="NoteAttachment" target="_XqMKsGUZEeaD08IjNDRpgg" lineWidth="1"> + <styles xmi:type="notation:ArrowStyle" xmi:id="_c2ROAWUZEeaD08IjNDRpgg"/> + <styles xmi:type="notation:LineTypeStyle" xmi:id="_c2ROAmUZEeaD08IjNDRpgg"/> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_c2ROA2UZEeaD08IjNDRpgg" points="[-3, -39, 2, 158]$[-3, -187, 2, 10]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_c2WtkGUZEeaD08IjNDRpgg" id="(0.85,0.6964285714285714)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_c2WtkWUZEeaD08IjNDRpgg" id="(0.5833333333333334,0.7560975609756098)"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_dbuEcGUZEeaD08IjNDRpgg" type="NoteAttachment" target="_XqS4YGUZEeaD08IjNDRpgg" lineWidth="1"> + <styles xmi:type="notation:ArrowStyle" xmi:id="_dburgGUZEeaD08IjNDRpgg"/> + <styles xmi:type="notation:LineTypeStyle" xmi:id="_dburgWUZEeaD08IjNDRpgg"/> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_dburgmUZEeaD08IjNDRpgg" points="[-3, -7, 27, 98]$[-28, -95, 2, 10]"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_dbxHwGUZEeaD08IjNDRpgg" id="(0.5833333333333334,0.7560975609756098)"/> + </edges> + </data> + </ownedAnnotationEntries> + <ownedDiagramElements xmi:type="diagram:DNodeList" xmi:id="_XqBLk2UZEeaD08IjNDRpgg" name="NewEClass1" tooltipText="root.NewEClass1" outgoingEdges="_XqBLl2UZEeaD08IjNDRpgg"> + <target xmi:type="ecore:EClass" href="My.ecore#//NewEClass1"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//NewEClass1"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_XqBLlGUZEeaD08IjNDRpgg" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="GradientTopToBottom"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DNodeList" xmi:id="_XqBLlWUZEeaD08IjNDRpgg" name="NewEClass2" tooltipText="root.NewEClass2" incomingEdges="_XqBLl2UZEeaD08IjNDRpgg"> + <target xmi:type="ecore:EClass" href="My.ecore#//NewEClass2"/> + <semanticElements xmi:type="ecore:EClass" href="My.ecore#//NewEClass2"/> + <arrangeConstraints>KEEP_LOCATION</arrangeConstraints> + <arrangeConstraints>KEEP_SIZE</arrangeConstraints> + <arrangeConstraints>KEEP_RATIO</arrangeConstraints> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_XqBLlmUZEeaD08IjNDRpgg" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="GradientTopToBottom"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/> + </ownedStyle> + <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/> + </ownedDiagramElements> + <ownedDiagramElements xmi:type="diagram:DEdge" xmi:id="_XqBLl2UZEeaD08IjNDRpgg" name="[0..1] newEReference1" sourceNode="_XqBLk2UZEeaD08IjNDRpgg" targetNode="_XqBLlWUZEeaD08IjNDRpgg"> + <target xmi:type="ecore:EReference" href="My.ecore#//NewEClass1/newEReference1"/> + <semanticElements xmi:type="ecore:EReference" href="My.ecore#//NewEClass1/newEReference1"/> + <ownedStyle xmi:type="diagram:EdgeStyle" xmi:id="_XqBLmGUZEeaD08IjNDRpgg"> + <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']/@style"/> + <centerLabelStyle xmi:type="diagram:CenterLabelStyle" xmi:id="_XqBLmWUZEeaD08IjNDRpgg" showIcon="false"/> + </ownedStyle> + <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/> + </ownedDiagramElements> + <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/> + <filterVariableHistory xmi:type="diagram:FilterVariableHistory" xmi:id="_XqBLmmUZEeaD08IjNDRpgg"/> + <activatedLayers xmi:type="description_1:Layer" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer"/> + <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']"/> + <target xmi:type="ecore:EPackage" href="My.ecore#/"/> + </ownedRepresentations> + </ownedViews> +</viewpoint:DAnalysis> diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.ecore b/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.ecore new file mode 100644 index 0000000000..64e2bc6510 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/migration/do_not_migrate/noteAttachment/My.ecore @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="root"> + <eClassifiers xsi:type="ecore:EClass" name="NewEClass1"> + <eStructuralFeatures xsi:type="ecore:EReference" name="newEReference1" eType="#//NewEClass2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NewEClass2"/> +</ecore:EPackage> 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 a79d4b50ce..35a55e99a4 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 @@ -105,6 +105,7 @@ import org.eclipse.sirius.tests.unit.common.migration.GeneralMigrationMechanismT import org.eclipse.sirius.tests.unit.common.migration.MigrationFromSirius0_9Test; import org.eclipse.sirius.tests.unit.common.migration.MigrationFromSirius1_0_0_M5Test; import org.eclipse.sirius.tests.unit.common.migration.ModelsToSemanticResourcesMigrationTest; +import org.eclipse.sirius.tests.unit.common.migration.NoteAttachmentMigrationTest; import org.eclipse.sirius.tests.unit.common.migration.VariableMigrationTest; import org.eclipse.sirius.tests.unit.diagram.filter.EObjectSelectionFilterTest; import org.eclipse.sirius.tests.unit.diagram.migration.BorderSizeMigrationTest; @@ -216,6 +217,7 @@ public class AllCommonPluginTests extends TestCase { suite.addTestSuite(BorderSizeMigrationTest.class); suite.addTestSuite(VariableMigrationTest.class); suite.addTestSuite(DRepresentationContainerRemovalMigrationTest.class); + suite.addTestSuite(NoteAttachmentMigrationTest.class); suite.addTest(new JUnit4TestAdapter(CommonPreferencesTest.class)); suite.addTest(new JUnit4TestAdapter(GroupingContentProviderTest.class)); diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/migration/NoteAttachmentMigrationTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/migration/NoteAttachmentMigrationTest.java new file mode 100644 index 0000000000..ca3b2d460f --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/migration/NoteAttachmentMigrationTest.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2016 THALES GLOBAL SERVICES. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.unit.common.migration; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.gmf.runtime.diagram.core.util.ViewType; +import org.eclipse.gmf.runtime.notation.Connector; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.sirius.business.internal.migration.RepresentationsFileMigrationService; +import org.eclipse.sirius.diagram.DDiagram; +import org.eclipse.sirius.diagram.business.api.refresh.DiagramCreationUtil; +import org.eclipse.sirius.diagram.business.internal.migration.NoteAttachmentWithoutSourceOrTargetMigrationParticipant; +import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactory; +import org.eclipse.sirius.ecore.extender.tool.api.ModelUtils; +import org.eclipse.sirius.tests.SiriusTestsPlugin; +import org.eclipse.sirius.tests.support.api.SiriusTestCase; +import org.eclipse.sirius.viewpoint.DAnalysis; +import org.eclipse.sirius.viewpoint.DView; +import org.osgi.framework.Version; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; + +/** + * Ensure that NoteAttachment without source or target has been removed.<br /> + * See {@link NoteAttachmentWithoutSourceOrTargetMigrationParticipant} for more + * details. + * + * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> + */ +public class NoteAttachmentMigrationTest extends SiriusTestCase { + + private static final String REPRESENTATIONS_FILE_PATH = "/data/unit/migration/do_not_migrate/noteAttachment/"; + + private static final String REPRESENTATIONS_FILE_NAME = "My.aird"; + + private static final String MODEL_FILE_NAME = "My.ecore"; + + @Override + protected IDiagramCommandFactory getCommandFactory() { + return null; + } + + /** + * Test that the data were not migrated on the repo. It allows to check the + * effect of the migration in the other test. + */ + public void testMigrationIsNeededOnData() { + Version loadedVersion = checkRepresentationFileMigrationStatus(URI.createPlatformPluginURI(SiriusTestsPlugin.PLUGIN_ID + REPRESENTATIONS_FILE_PATH + REPRESENTATIONS_FILE_NAME, true), true); + + // Check that the migration is needed. + Version migration = NoteAttachmentWithoutSourceOrTargetMigrationParticipant.MIGRATION_VERSION; + assertTrue("The migration must be required on test data.", loadedVersion == null || migration.compareTo(loadedVersion) > 0); + } + + /** + * Check that the NoteAttachment without source or target have been removed. + */ + public void testNoteAttachmentCorrectlyRemoved() { + copyFilesToTestProject(SiriusTestsPlugin.PLUGIN_ID, REPRESENTATIONS_FILE_PATH, REPRESENTATIONS_FILE_NAME, MODEL_FILE_NAME); + + ResourceSet set = new ResourceSetImpl(); + DAnalysis analysis = null; + try { + analysis = (DAnalysis) ModelUtils.load(URI.createPlatformResourceURI(TEMPORARY_PROJECT_NAME + "/" + REPRESENTATIONS_FILE_NAME, true), set); + } catch (IOException e) { + e.printStackTrace(); + } + + // Check that the migration was done. + assertNotNull("Analysis is not retrieved.", analysis); + + // The version will change on save, so migration service will still + // indicates that the migration is needed. + String version = analysis.getVersion(); + assertTrue("Before save, the migration framework will return true even if the migration has been done during load.", + RepresentationsFileMigrationService.getInstance().isMigrationNeeded(Version.parseVersion(version))); + + try { + analysis.eResource().save(Collections.emptyMap()); + } catch (IOException e) { + e.printStackTrace(); + } + // save should update the version. + version = analysis.getVersion(); + assertFalse("The version tag should now be set telling that the migration was done.", RepresentationsFileMigrationService.getInstance().isMigrationNeeded(Version.parseVersion(version))); + + // We can now check the migration effect to be sure that the migration + // is effective. + checkMigrationEffect(analysis); + } + + private void checkMigrationEffect(DAnalysis analysis) { + Iterator<EObject> noteAttachmentWithoutSourceOrTarget = null; + for (DView dView : analysis.getOwnedViews()) { + for (DDiagram dDiagram : Iterables.filter(dView.getOwnedRepresentations(), DDiagram.class)) { + DiagramCreationUtil diagramCreationUtil = new DiagramCreationUtil(dDiagram); + if (diagramCreationUtil.findAssociatedGMFDiagram()) { + Diagram gmfDiagram = diagramCreationUtil.getAssociatedGMFDiagram(); + noteAttachmentWithoutSourceOrTarget = Iterators.filter(gmfDiagram.eAllContents(), Predicates.and(Predicates.instanceOf(Connector.class), new Predicate<EObject>() { + @Override + public boolean apply(EObject input) { + Connector connector = (Connector) input; + if (ViewType.NOTEATTACHMENT.equals(connector.getType())) { + return connector.getSource() == null || connector.getTarget() == null; + } + return false; + } + })); + } + } + } + assertTrue("It should not have NoteAttachment without source or target in this representations file.", + noteAttachmentWithoutSourceOrTarget == null || !noteAttachmentWithoutSourceOrTarget.hasNext()); + } +} diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/RemoveNoteTextTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/RemoveNoteTextTest.java index fbd81ec7d0..16111ecab3 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/RemoveNoteTextTest.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/RemoveNoteTextTest.java @@ -13,17 +13,19 @@ package org.eclipse.sirius.tests.swtbot; import org.eclipse.gmf.runtime.diagram.ui.editparts.NoteEditPart; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.NoteAttachmentEditPart; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.TextEditPart; +import org.eclipse.gmf.runtime.notation.View; import org.eclipse.sirius.diagram.DDiagram; import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase; import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource; +import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor; import org.eclipse.swtbot.eclipse.gef.finder.matchers.IsInstanceOf; import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefConnectionEditPart; import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart; /** - * Checks that the "remove from diagram" action removes notes and texts. Also - * checks that is impossible to use "remove from model" action for notes and - * texts. + * Checks that the "remove from diagram" action removes notes and texts (and + * associated NoteAttachment). Also checks that is impossible to use + * "remove from model" action for notes and texts. * * @author jdupont */ @@ -63,7 +65,7 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { protected void onSetUpAfterOpeningDesignerPerspective() throws Exception { sessionAirdResource = new UIResource(designerProject, FILE_DIR, SESSION_FILE); localSession = designerPerspective.openSessionFromFile(sessionAirdResource); - editor = openDiagram(localSession.getOpenedSession(), REPRESENTATION_NAME, REPRESENTATION_INSTANCE_NAME, DDiagram.class); + editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(), REPRESENTATION_NAME, REPRESENTATION_INSTANCE_NAME, DDiagram.class); } /** @@ -73,9 +75,9 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveNoteFromContextualMenuAction() { // Select note editor.click(NOTE); - SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE); - SWTBotGefEditPart diagram = noteEditPart.parent().parent(); - assertEquals("The note " + NOTE + " should be present", noteEditPart.parent(), diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).get(0)); + SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE, NoteEditPart.class); + SWTBotGefEditPart diagram = noteEditPart.parent(); + assertEquals("The note " + NOTE + " should be present", noteEditPart, diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).get(0)); editor.clickContextMenu(DELETE_FROM_DIAGRAM); // Check that the note has been removed assertTrue("The note " + NOTE + " should be removed", diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).isEmpty()); @@ -88,7 +90,7 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveNoteAttachmentFromContextualMenuAction() { // Select note editor.click(NOTE); - SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE).parent(); + SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE, NoteEditPart.class); SWTBotGefConnectionEditPart noteAttachment = noteEditPart.sourceConnections().get(0); noteAttachment.select(); assertEquals("The note attachment should be present", noteAttachment, noteEditPart.sourceConnections().iterator().next()); @@ -105,9 +107,9 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveTextFromContextualMenuAction() { // Select text editor.click(TEXT); - SWTBotGefEditPart textEditPart = editor.getEditPart(TEXT); - SWTBotGefEditPart diagram = textEditPart.parent().parent(); - assertEquals("The Text " + TEXT + " should be present", textEditPart.parent(), diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).get(0)); + SWTBotGefEditPart textEditPart = editor.getEditPart(TEXT, TextEditPart.class); + SWTBotGefEditPart diagram = textEditPart.parent(); + assertEquals("The Text " + TEXT + " should be present", textEditPart, diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).get(0)); editor.clickContextMenu(DELETE_FROM_DIAGRAM); // Check that the text has been removed assertTrue("The Text " + TEXT + " should be removed", diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).isEmpty()); @@ -120,12 +122,16 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveNoteFromTabbarAction() { // Select note editor.click(NOTE); - SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE); - SWTBotGefEditPart diagram = noteEditPart.parent().parent(); - assertEquals("The note " + NOTE + " should be present", noteEditPart.parent(), diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).get(0)); + SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE, NoteEditPart.class); + SWTBotGefEditPart diagram = noteEditPart.parent(); + SWTBotGefConnectionEditPart noteAttachmentPart = noteEditPart.sourceConnections().get(0); + View noteAttachment = (View) noteAttachmentPart.part().getModel(); + assertEquals("The note " + NOTE + " should be present", noteEditPart, diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).get(0)); editor.bot().toolbarButtonWithTooltip(DELETE_FROM_DIAGRAM).click(); // Check that the note has been removed assertTrue("The note " + NOTE + " should be removed", diagram.descendants(IsInstanceOf.instanceOf(NoteEditPart.class)).isEmpty()); + // Check that the corresponding note attachment has also been removed + assertNull("The corresponding note attachment should be removed", noteAttachment.eContainer()); } /** @@ -135,7 +141,7 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveNoteAttachmentFromTabbarAction() { // Select note editor.click(NOTE); - SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE).parent(); + SWTBotGefEditPart noteEditPart = editor.getEditPart(NOTE, NoteEditPart.class); SWTBotGefConnectionEditPart noteAttachment = noteEditPart.sourceConnections().get(0); noteAttachment.select(); assertEquals("The note attachment should be present", noteAttachment, noteEditPart.sourceConnections().iterator().next()); @@ -152,11 +158,15 @@ public class RemoveNoteTextTest extends AbstractSiriusSwtBotGefTestCase { public void testRemoveTextFromTabbarAction() { // Select text editor.click(TEXT); - SWTBotGefEditPart noteEditPart = editor.getEditPart(TEXT); - SWTBotGefEditPart diagram = noteEditPart.parent().parent(); - assertEquals("The Text " + TEXT + " should be present", noteEditPart.parent(), diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).get(0)); + SWTBotGefEditPart textEditPart = editor.getEditPart(TEXT, TextEditPart.class); + SWTBotGefConnectionEditPart noteAttachmentPart = textEditPart.targetConnections().get(0); + View noteAttachment = (View) noteAttachmentPart.part().getModel(); + SWTBotGefEditPart diagram = textEditPart.parent(); + assertEquals("The Text " + TEXT + " should be present", textEditPart, diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).get(0)); editor.bot().toolbarButtonWithTooltip(DELETE_FROM_DIAGRAM).click(); // Check that the text has been removed assertTrue("The Text " + TEXT + " should be removed", diagram.descendants(IsInstanceOf.instanceOf(TextEditPart.class)).isEmpty()); + // Check that the corresponding note attachment has also been removed + assertNull("The corresponding note attachment should be removed", noteAttachment.eContainer()); } } |
