diff options
| author | Laurent Fasani | 2016-09-27 13:19:46 +0000 |
|---|---|---|
| committer | Laurent Fasani | 2016-10-04 13:51:23 +0000 |
| commit | 83f70b06681b67b36fd4a2cb1c1ac7974249ae56 (patch) | |
| tree | 63e71b9d50b4472463a71a4ada1f037704c72c34 | |
| parent | 541388262b85783a538724be4d37f380e3b61a1e (diff) | |
| download | org.eclipse.sirius-83f70b06681b67b36fd4a2cb1c1ac7974249ae56.tar.gz org.eclipse.sirius-83f70b06681b67b36fd4a2cb1c1ac7974249ae56.tar.xz org.eclipse.sirius-83f70b06681b67b36fd4a2cb1c1ac7974249ae56.zip | |
[501515] Remove the Sirius ECrossRefAdapter from deleted representations
The ECrossReferenceAdapter is not removed from an object being deleted
if this object is a root object of the resource, which is now the case
for DRepresentations (since bug #494766).
This commit overloads the selfAdapt method in SessionLazyCrossReferencer
to remove the cross-referencer from DRepresentations (and only them)
when they are removed from the root of a Resource. The normal EMF
behavior is not changed for other cases.
Bug: 501515
Change-Id: Iaec65f86e17a6e67bff708ad4fb0ae0866b74361
Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
4 files changed, 234 insertions, 3 deletions
diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/RepresentationCRUD.ecore b/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/RepresentationCRUD.ecore new file mode 100644 index 0000000000..2a023284e9 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/RepresentationCRUD.ecore @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" + name="P0" nsURI=""> + <eSubpackages name="sub_package"/> +</ecore:EPackage> diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/representations.aird b/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/representations.aird new file mode 100644 index 0000000000..d7b1d65f39 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/representation/representations.aird @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI 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"> + <viewpoint:DAnalysis xmi:id="_hB_O8IPCEeaqF41KJF2NgA" selectedViews="_lza9oIPCEeaqF41KJF2NgA" version="11.1.0.201608251200"> + <semanticResources>RepresentationCRUD.ecore</semanticResources> + <ownedViews xmi:type="viewpoint:DView" xmi:id="_lza9oIPCEeaqF41KJF2NgA"> + <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']"/> + <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" xmi:id="_9ndcsISVEeaAb5DcH1QfOA" name="P0packageDiag" representation="_9neDwISVEeaAb5DcH1QfOA"> + <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/> + <target xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#/"/> + </ownedRepresentationDescriptors> + <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" xmi:id="_-pMmgISVEeaAb5DcH1QfOA" name="P0packageDiag2" representation="_-pMmgYSVEeaAb5DcH1QfOA"> + <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/> + <target xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#/"/> + </ownedRepresentationDescriptors> + </ownedViews> + </viewpoint:DAnalysis> + <diagram:DSemanticDiagram xmi:id="_9neDwISVEeaAb5DcH1QfOA" name="P0packageDiag"> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_9neDwYSVEeaAb5DcH1QfOA" source="DANNOTATION_CUSTOMIZATION_KEY"> + <data xmi:type="diagram:ComputedStyleDescriptionRegistry" xmi:id="_9neDwoSVEeaAb5DcH1QfOA"/> + </ownedAnnotationEntries> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_9neq0ISVEeaAb5DcH1QfOA" source="GMF_DIAGRAMS"> + <data xmi:type="notation:Diagram" xmi:id="_9neq0YSVEeaAb5DcH1QfOA" type="Sirius" element="_9neDwISVEeaAb5DcH1QfOA" measurementUnit="Pixel"> + <children xmi:type="notation:Node" xmi:id="_9nfR4ISVEeaAb5DcH1QfOA" type="2002" element="_9neDw4SVEeaAb5DcH1QfOA"> + <children xmi:type="notation:Node" xmi:id="_9nhHEISVEeaAb5DcH1QfOA" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_9nhuIISVEeaAb5DcH1QfOA" type="7001"> + <styles xmi:type="notation:SortingStyle" xmi:id="_9nhuIYSVEeaAb5DcH1QfOA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_9nhuIoSVEeaAb5DcH1QfOA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_9nfR4YSVEeaAb5DcH1QfOA" fontName="Segoe UI" fontHeight="10"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9nfR4oSVEeaAb5DcH1QfOA"/> + </children> + <styles xmi:type="notation:DiagramStyle" xmi:id="_9neq0oSVEeaAb5DcH1QfOA"/> + </data> + </ownedAnnotationEntries> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" xmi:id="_9neDw4SVEeaAb5DcH1QfOA" name="sub_package"> + <target xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#//sub_package"/> + <semanticElements xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#//sub_package"/> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_9neDxISVEeaAb5DcH1QfOA" labelSize="10" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="GradientTopToBottom" backgroundColor="255,245,181" foregroundColor="255,255,255"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']/@containerMappings[name='Design%20Package']/@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']/@additionalLayers[name='Package']/@containerMappings[name='Design%20Package']"/> + </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="_9neDxYSVEeaAb5DcH1QfOA"/> + <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="RepresentationCRUD.ecore#/"/> + </diagram:DSemanticDiagram> + <diagram:DSemanticDiagram xmi:id="_-pMmgYSVEeaAb5DcH1QfOA" name="P0packageDiag2"> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_-pMmgoSVEeaAb5DcH1QfOA" source="DANNOTATION_CUSTOMIZATION_KEY"> + <data xmi:type="diagram:ComputedStyleDescriptionRegistry" xmi:id="_-pMmg4SVEeaAb5DcH1QfOA"/> + </ownedAnnotationEntries> + <ownedAnnotationEntries xmi:type="description:AnnotationEntry" xmi:id="_-pPCwISVEeaAb5DcH1QfOA" source="GMF_DIAGRAMS"> + <data xmi:type="notation:Diagram" xmi:id="_-pPCwYSVEeaAb5DcH1QfOA" type="Sirius" element="_-pMmgYSVEeaAb5DcH1QfOA" measurementUnit="Pixel"> + <children xmi:type="notation:Node" xmi:id="_-pPCw4SVEeaAb5DcH1QfOA" type="2002" element="_-pMmhISVEeaAb5DcH1QfOA"> + <children xmi:type="notation:Node" xmi:id="_-pPp0oSVEeaAb5DcH1QfOA" type="5006"/> + <children xmi:type="notation:Node" xmi:id="_-pQQ4ISVEeaAb5DcH1QfOA" type="7001"> + <styles xmi:type="notation:SortingStyle" xmi:id="_-pQQ4YSVEeaAb5DcH1QfOA"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_-pQQ4oSVEeaAb5DcH1QfOA"/> + </children> + <styles xmi:type="notation:ShapeStyle" xmi:id="_-pPp0ISVEeaAb5DcH1QfOA" fontName="Segoe UI" fontHeight="10"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_-pPp0YSVEeaAb5DcH1QfOA"/> + </children> + <styles xmi:type="notation:DiagramStyle" xmi:id="_-pPCwoSVEeaAb5DcH1QfOA"/> + </data> + </ownedAnnotationEntries> + <ownedDiagramElements xmi:type="diagram:DNodeContainer" xmi:id="_-pMmhISVEeaAb5DcH1QfOA" name="sub_package"> + <target xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#//sub_package"/> + <semanticElements xmi:type="ecore:EPackage" href="RepresentationCRUD.ecore#//sub_package"/> + <ownedStyle xmi:type="diagram:FlatContainerStyle" xmi:id="_-pMmhYSVEeaAb5DcH1QfOA" labelSize="10" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="GradientTopToBottom" backgroundColor="255,245,181" foregroundColor="255,255,255"> + <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.sirius.sample.ecore.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']/@containerMappings[name='Design%20Package']/@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']/@additionalLayers[name='Package']/@containerMappings[name='Design%20Package']"/> + </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="_-pMmhoSVEeaAb5DcH1QfOA"/> + <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="RepresentationCRUD.ecore#/"/> + </diagram:DSemanticDiagram> +</xmi:XMI> diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/representation/RepresentationCRUDTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/representation/RepresentationCRUDTest.java new file mode 100644 index 0000000000..f94f3719ee --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/representation/RepresentationCRUDTest.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * 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.api.representation; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.sirius.business.api.dialect.DialectManager; +import org.eclipse.sirius.business.api.query.DRepresentationQuery; +import org.eclipse.sirius.business.api.query.DViewQuery; +import org.eclipse.sirius.tests.SiriusTestsPlugin; +import org.eclipse.sirius.tests.unit.common.command.RepresentationDeleterRecordingCommand; +import org.eclipse.sirius.tests.unit.diagram.GenericTestCase; +import org.eclipse.sirius.viewpoint.DRepresentation; +import org.eclipse.sirius.viewpoint.DRepresentationDescriptor; +import org.eclipse.sirius.viewpoint.DSemanticDecorator; +import org.eclipse.sirius.viewpoint.DView; +import org.eclipse.sirius.viewpoint.ViewpointPackage; + +import com.google.common.collect.Lists; + +/** + * @author lfasani + * + * Test Open representation menu. + */ +public class RepresentationCRUDTest extends GenericTestCase { + + private static final String PLUGIN = "/" + SiriusTestsPlugin.PLUGIN_ID; + + private static final String SEMANTIC_MODEL_PATH = PLUGIN + "/data/unit/representation/RepresentationCRUD.ecore"; + + private static final String REP_MODEL_PATH = PLUGIN + "/data/unit/representation/representations.aird"; + + private static final String DIAGRAM_NAME = "P0packageDiag2"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + genericSetUp(Collections.singleton(SEMANTIC_MODEL_PATH), Collections.<String> emptyList(), REP_MODEL_PATH); + } + + private DRepresentation getRepresentation(String name) { + for (final DView dView : session.getOwnedViews()) { + for (final Iterator<DRepresentation> iterator = new DViewQuery(dView).getLoadedRepresentations().iterator(); iterator.hasNext();) { + final DRepresentation rep = iterator.next(); + if (name.equals(rep.getName())) { + return rep; + } + } + } + return null; + } + + public void testDeleteRepresentation() throws Exception { + DRepresentation diagram = getRepresentation(DIAGRAM_NAME); + DRepresentationDescriptor repDesc = new DRepresentationQuery(diagram).getRepresentationDescriptor(); + assertNotNull("The diagram " + DIAGRAM_NAME + " does not exist.", diagram); + EObject rootPackage = ((DSemanticDecorator) diagram).getTarget(); + + // Check that the root package is the diagram target + checkRepresentation(rootPackage, diagram, true); + + // Delete Rep + session.getTransactionalEditingDomain().getCommandStack().execute(new RepresentationDeleterRecordingCommand(session.getTransactionalEditingDomain(), repDesc, session)); + checkRepresentation(rootPackage, diagram, false); + + // undo + undo(); + checkRepresentation(rootPackage, diagram, true); + } + + /** + * Check that the {@code representation} is correctly removed/present + * including removed/prevent from/in the Sirius CrossReferencer. + * + * @param target + * the semantic target + * @param representation + * the representation to check + * @param expected + * true if representation have to be found + */ + private void checkRepresentation(EObject target, DRepresentation representation, boolean expected) { + Collection<DRepresentation> representations = Lists.newArrayList(); + ECrossReferenceAdapter xref = session.getSemanticCrossReferencer(); + for (EStructuralFeature.Setting setting : xref.getInverseReferences(target)) { + if (ViewpointPackage.Literals.DREPRESENTATION.isInstance(setting.getEObject()) && setting.getEStructuralFeature() == ViewpointPackage.Literals.DSEMANTIC_DECORATOR__TARGET) { + representations.add((DRepresentation) setting.getEObject()); + } + } + assertEquals("Can " + (expected ? "not " : "") + "find " + DIAGRAM_NAME + " DRepresentation with sirius cross referencer", expected, representations.contains(representation)); + + representations = DialectManager.INSTANCE.getRepresentations(target, session); + assertEquals("Can " + (expected ? "not " : "") + "find " + DIAGRAM_NAME + " DRepresentation with DialectManager.INSTANCE.getRepresentations", expected, + representations.contains(representation)); + } +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionLazyCrossReferencer.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionLazyCrossReferencer.java index 10cd26cf50..b5b497d7f1 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionLazyCrossReferencer.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionLazyCrossReferencer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2015 THALES GLOBAL SERVICES. + * Copyright (c) 2014, 2016 THALES GLOBAL SERVICES 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 @@ -15,10 +15,13 @@ import java.util.List; import java.util.Set; import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.sirius.common.tools.api.util.LazyCrossReferencer; +import org.eclipse.sirius.viewpoint.DRepresentation; +import com.google.common.base.Predicates; import com.google.common.collect.Iterables; /** @@ -45,11 +48,11 @@ public class SessionLazyCrossReferencer extends LazyCrossReferencer { @Override protected void initialize() { super.initialize(); - + Collection<Resource> semanticResources = session.getSemanticResources(); EList<Resource> controlledResources = session.getControlledResources(); Set<Resource> allSessionResources = session.getAllSessionResources(); - + Iterable<Resource> resources = Iterables.concat(semanticResources, controlledResources, allSessionResources); for (Resource resource : resources) { List<Adapter> adapters = resource.eAdapters(); @@ -60,4 +63,36 @@ public class SessionLazyCrossReferencer extends LazyCrossReferencer { } } } + + @Override + protected void selfAdapt(Notification notification) { + if (isTopLevelRepresentationRemoval(notification)) { + if (!unloadedResources.contains(notification.getNotifier())) { + handleContainment(notification); + } + } + super.selfAdapt(notification); + } + + /** + * Say if a {@link DRepresentation} is being removed from the resource. + * + * @param notification + * the notification + * @return true is the DRepresentation is being removed. + */ + public static boolean isTopLevelRepresentationRemoval(Notification notification) { + Object notifier = notification.getNotifier(); + boolean isResourceContentChange = notifier instanceof Resource && notification.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS; + final boolean isRepresentationRemoval; + if (notification.getEventType() == Notification.REMOVE && notification.getOldValue() instanceof DRepresentation) { + isRepresentationRemoval = true; + } else if (notification.getEventType() == Notification.REMOVE_MANY) { + Collection<?> removed = (Collection<?>) notification.getOldValue(); + isRepresentationRemoval = Iterables.all(removed, Predicates.instanceOf(DRepresentation.class)); + } else { + isRepresentationRemoval = false; + } + return isResourceContentChange && isRepresentationRemoval; + } } |
