/* * Copyright (c) 2008, 2010 Borland Software Corporation 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: * Artem Tikhomirov (Borland) - initial API and implementation */ package org.eclipse.gmf.tests.rt; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.resource.impl.ResourceImpl; import org.eclipse.gmf.codegen.gmfgen.FigureViewmap; import org.eclipse.gmf.codegen.gmfgen.GMFGenFactory; import org.eclipse.gmf.codegen.gmfgen.GenDiagram; import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator; import org.eclipse.gmf.codegen.gmfgen.GenLink; import org.eclipse.gmf.codegen.gmfgen.GenNode; import org.eclipse.gmf.codegen.gmfgen.GenTopLevelNode; import org.eclipse.gmf.codegen.gmfgen.MetamodelType; import org.eclipse.gmf.codegen.gmfgen.TypeLinkModelFacet; import org.eclipse.gmf.codegen.gmfgen.TypeModelFacet; import org.eclipse.gmf.internal.bridge.genmodel.GenModelMatcher; import org.eclipse.gmf.internal.bridge.genmodel.RuntimeGenModelAccess; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.tests.Utils; import org.eclipse.gmf.tests.gef.AbstractDiagramEditorTest; import org.eclipse.gmf.tests.setup.DiaGenSource; import org.eclipse.gmf.tests.setup.GeneratedDiagramPlugin; import org.eclipse.gmf.tests.setup.RuntimeBasedGeneratorConfiguration; import org.eclipse.gmf.tests.setup.SessionSetup; /** * @see https://bugs.eclipse.org/226882 * @author artem */ public class LinkChildMetaFeatureNotFromContainerTest extends AbstractDiagramEditorTest { protected static final class DiaGenSourceImpl implements DiaGenSource { private final GenDiagram myDiagram; private final GenTopLevelNode myNodeA; private final GenTopLevelNode myNodeB; private final GenLink myLinkL; /* * C holds A, B and L, where L is a link between A and B, * such as A has outgoing EReference to L, B knows nothing * about L, while L does (it got an EReference to B) */ public DiaGenSourceImpl() { EcoreFactory f = EcoreFactory.eINSTANCE; EClass a = f.createEClass(); EClass b = f.createEClass(); EClass c = f.createEClass(); EClass l = f.createEClass(); a.setName("ElemA"); b.setName("ElemB"); l.setName("BindAtoB"); c.setName("Cont"); l.getESuperTypes().add(a); EReference rc1 = f.createEReference(); rc1.setName("containmA"); rc1.setUpperBound(-1); rc1.setEType(a); rc1.setContainment(true); EReference rc2 = f.createEReference(); rc2.setName("containmB"); rc2.setUpperBound(-1); rc2.setEType(b); rc2.setContainment(true); c.getEStructuralFeatures().add(rc1); c.getEStructuralFeatures().add(rc2); EReference rl = f.createEReference(); rl.setName("ls"); // link source rl.setEType(l); a.getEStructuralFeatures().add(rl); EReference rb = f.createEReference(); rb.setName("lt"); // link target rb.setEType(b); l.getEStructuralFeatures().add(rb); EPackage p = f.createEPackage(); p.setName("xxx"); p.setNsPrefix("xxx"); p.setNsURI("uri:/CreateLinkTest/"); p.getEClassifiers().add(a); p.getEClassifiers().add(b); p.getEClassifiers().add(c); p.getEClassifiers().add(l); final GenModelMatcher gmm = new GenModelMatcher(Utils.createGenModel(p)); RuntimeGenModelAccess runtimeAccess = new RuntimeGenModelAccess(); runtimeAccess.ensure(); final GenModel runtimeModel = runtimeAccess.model(); GMFGenFactory gf = GMFGenFactory.eINSTANCE; myDiagram = gf.createGenDiagram(); myDiagram.setDomainDiagramElement(gmm.findGenClass(c)); myDiagram.setDiagramRunTimeClass(Utils.findGenClass(runtimeModel, NotationPackage.eINSTANCE.getDiagram())); myDiagram.setViewmap(gf.createFigureViewmap()); myDiagram.setVisualID(99); MetamodelType dgmmType = gf.createMetamodelType(); myDiagram.setElementType(dgmmType); myNodeA = gf.createGenTopLevelNode(); myNodeA.setDiagramRunTimeClass(Utils.findGenClass(runtimeModel, NotationPackage.eINSTANCE.getNode())); myNodeA.setElementType(gf.createMetamodelType()); TypeModelFacet mf = gf.createTypeModelFacet(); mf.setMetaClass(gmm.findGenClass(a)); mf.setContainmentMetaFeature(gmm.findGenFeature(rc1)); myNodeA.setModelFacet(mf); FigureViewmap fv = gf.createFigureViewmap(); fv.setFigureQualifiedClassName("org.eclipse.draw2d.RoundedRectangle"); myNodeA.setViewmap(fv); myNodeA.setVisualID(1001); myNodeB = gf.createGenTopLevelNode(); myNodeB.setDiagramRunTimeClass(myNodeA.getDiagramRunTimeClass()); myNodeB.setElementType(gf.createMetamodelType()); mf = gf.createTypeModelFacet(); mf.setMetaClass(gmm.findGenClass(b)); mf.setContainmentMetaFeature(gmm.findGenFeature(rc2)); myNodeB.setModelFacet(mf); fv = gf.createFigureViewmap(); fv.setFigureQualifiedClassName("org.eclipse.draw2d.RoundedRectangle"); myNodeB.setViewmap(fv); myNodeB.setVisualID(1002); myLinkL = gf.createGenLink(); myLinkL.setDiagramRunTimeClass(Utils.findGenClass(runtimeModel, NotationPackage.eINSTANCE.getEdge())); TypeLinkModelFacet lmf = gf.createTypeLinkModelFacet(); lmf.setMetaClass(gmm.findGenClass(l)); lmf.setContainmentMetaFeature(gmm.findGenFeature(rc1)); // >>> lmf.setChildMetaFeature(gmm.findGenFeature(rl)); // HERE COMES INTERESTING PART // <<< lmf.setTargetMetaFeature(gmm.findGenFeature(rb)); myLinkL.setModelFacet(lmf); fv = gf.createFigureViewmap(); fv.setFigureQualifiedClassName("org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx"); myLinkL.setViewmap(fv); myLinkL.setVisualID(2001); myLinkL.setElementType(gf.createMetamodelType()); myDiagram.getTopLevelNodes().add(myNodeA); myDiagram.getTopLevelNodes().add(myNodeB); myDiagram.getLinks().add(myLinkL); GenEditorGenerator geg = gf.createGenEditorGenerator(); geg.setDiagram(myDiagram); geg.setDomainGenModel(myDiagram.getDomainDiagramElement().getGenModel()); geg.setEditor(gf.createGenEditorView()); geg.setPlugin(gf.createGenPlugin()); geg.setDiagramUpdater(gf.createGenDiagramUpdater()); geg.setLabelParsers(gf.createGenParsers()); geg.getLabelParsers().setExtensibleViaService(true); new ResourceImpl(URI.createURI("uri://org.eclipse.gmf/tests/CreateLinkTest")).getContents().add(geg); } public GenDiagram getGenDiagram() { return myDiagram; } public GenNode getNodeA() { return myNodeA; } public GenNode getNodeB() { return myNodeB; } public GenLink getLinkC() { return myLinkL; } public GenLink getLinkD() { return null; } } public static final class CustomSetup extends SessionSetup { public CustomSetup() { super(new RuntimeBasedGeneratorConfiguration()); } @Override protected DiaGenSource createGenModel() { return new DiaGenSourceImpl(); } }; public LinkChildMetaFeatureNotFromContainerTest(String name) { this(name, new RuntimeBasedGeneratorConfiguration()); } public LinkChildMetaFeatureNotFromContainerTest(String name, RuntimeBasedGeneratorConfiguration genConfig) { super(name, genConfig); } public void testCreateLink() { Node nodeA = createNode(getSetup().getGenModel().getNodeA(), getDiagram()); Node nodeB = createNode(getSetup().getGenModel().getNodeB(), getDiagram()); assertNotNull(nodeA); assertNotNull(nodeB); Edge link = createLink(getSetup().getGenModel().getLinkC(), nodeA, nodeB); assertNotNull(link); EObject a = nodeA.getElement(); EObject b = nodeB.getElement(); EObject c = nodeA.getDiagram().getElement(); EObject l = link.getElement(); assertEquals(a.eContainer(), c); assertEquals(b.eContainer(), c); assertNotSame("Sanity", a.eContainmentFeature(), b.eContainmentFeature()); assertEquals(l.eContainer(), c); // assert source feature (A to L) is set (A.ls == L), // and target feature (L to B) is also set (L.lt == B); // see session setup for more details EStructuralFeature ls = a.eClass().getEStructuralFeature("ls"); assertNotNull("Sanity", ls); // just in case metamodel definition was modified assertFalse("Sanity", ((EReference)ls).isContainment()); EStructuralFeature lt = l.eClass().getEStructuralFeature("lt"); assertNotNull("Sanity", lt); assertFalse("Sanity", ((EReference)lt).isContainment()); // assertEquals("Link target should be B, accessible from L.lt", l.eGet(lt), b); assertEquals("Link should originate at A element, from non-containment featyre A.lt", a.eGet(ls), l); } @Override protected Diagram createDiagramView(EObject domainElement, GeneratedDiagramPlugin genPlugin) { return RuntimeBasedGeneratorConfiguration.createDiagram(domainElement, genPlugin); } }