/*
* Copyright (c) 2006, 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:
* Alexander Shatalin (Borland) - initial API and implementation
*/
package org.eclipse.gmf.tests.rt;
import java.util.Collection;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.codegen.gmfgen.FeatureLinkModelFacet;
import org.eclipse.gmf.codegen.gmfgen.GenCommonBase;
import org.eclipse.gmf.codegen.gmfgen.GenLink;
import org.eclipse.gmf.codegen.gmfgen.GenNode;
import org.eclipse.gmf.codegen.gmfgen.TypeLinkModelFacet;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.tests.setup.RuntimeBasedGeneratorConfiguration;
public class LinkCreationTest extends GeneratedCanvasTest {
private Node myNodeA;
private Node myNodeB;
public LinkCreationTest(String name) {
this(name, new RuntimeBasedGeneratorConfiguration());
}
public LinkCreationTest(String name, RuntimeBasedGeneratorConfiguration genConfig) {
super(name, genConfig);
}
protected void setUp() throws Exception {
super.setUp();
myNodeA = getNotation(getNodeEditPartA());
myNodeB = getNotation(getNodeEditPartB());
}
/**
* TypeLink can be created only in straight direction
*/
public void testTypeLinkOutOnly() {
GenLink genLink = getSetup().getGenModel().getLinkC();
assertTrue("Incorrect session setup: outgoing creation should be allowed", genLink.isOutgoingCreationAllowed());
assertFalse("Incorrect session setup: incoming creation should not be allowed", genLink.isIncomingCreationAllowed());
checkLink(genLink);
}
/**
* Multiple TypeLinks can be created between choosen source and target
*/
public void testCreateMultipleTypeLinks() {
GenLink genLink = getSetup().getGenModel().getLinkC();
checkLinkCreation(genLink, false);
checkLinkCreation(genLink, false);
checkLinkCreation(genLink, false);
}
/**
* TypeLink can be created only in reversed direction
*/
public void testTypeLinkInOnly() {
GenLink genLink = getLink(true, 1);
assertFalse("Incorrect session setup: outgoing creation should not be allowed", genLink.isOutgoingCreationAllowed());
assertTrue("Incorrect session setup: incoming creation should be allowed", genLink.isIncomingCreationAllowed());
checkLink(genLink);
}
/**
* Only one TypeLink can be created between choosen source and target
*/
public void testCreateOneTypeLink() {
GenLink genLink = getLink(true, 1);
checkLinkCreation(genLink, true);
checkLinkCreationNotAllowed(genLink);
}
/**
* TypeLink can be created in streight or reversed direction
*/
public void testTypeLinkInOut() {
GenLink genLink = getLink(true, 2);
assertTrue("Incorrect session setup: outgoing creation should be allowed", genLink.isOutgoingCreationAllowed());
assertTrue("Incorrect session setup: incoming creation should be allowed", genLink.isIncomingCreationAllowed());
checkLink(genLink);
}
/**
* Only two TypeLinks can be created between choosen source and target
*/
public void testCreateTwoTypeLinks() {
GenLink genLink = getLink(true, 2);
checkLinkCreation(genLink, false);
checkLinkCreation(genLink, true);
checkLinkCreationNotAllowed(genLink);
}
/**
* ReferenceLink can be created only in straight direction
*/
public void testRefLinkOutOnly() {
Node nodeB = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB);
checkLink(getSetup().getGenModel().getLinkD(), myNodeA, nodeB, true, false);
}
/**
* Multiple ReferenceLinks can be created between choosen source and target
* NOTE: in EMF reference links are always unique.
*/
public void testCreateMultipleReferenceLinks() {
Node nodeB1 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB1);
Node nodeB2 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB2);
Node nodeB3 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB3);
GenLink genLink = getSetup().getGenModel().getLinkD();
checkLinkCreation(genLink, myNodeA, nodeB3, false);
checkLinkCreation(genLink, myNodeA, nodeB1, false);
checkLinkCreation(genLink, myNodeA, nodeB2, false);
}
/**
* ReferenceLink can be created only in reversed direction
*/
public void testRefLinkInOnly() {
GenLink genLink = getLink(false, 1);
assertFalse("Incorrect session setup: outgoing creation should not be allowed", genLink.isOutgoingCreationAllowed());
assertTrue("Incorrect session setup: incoming creation should be allowed", genLink.isIncomingCreationAllowed());
checkLink(genLink);
}
/**
* Only one ReferenceLink can be created between choosen source and target
*/
public void testCreateOneReferenceLink() {
Node nodeB1 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB1);
GenLink genLink = getLink(false, 1);
checkLinkCreation(genLink, nodeB1, myNodeA, true);
checkLinkCreationNotAllowed(genLink);
}
/**
* ReferenceLink can be created in streight or reversed direction
*/
public void testRefLinkInOut() {
GenLink genLink = getLink(false, 2);
assertTrue("Incorrect session setup: outgoing creation should be allowed", genLink.isOutgoingCreationAllowed());
assertTrue("Incorrect session setup: incoming creation should be allowed", genLink.isIncomingCreationAllowed());
checkLink(genLink);
}
/**
* Only two ReferenceLinks can be created between choosen source and target
* NOTE: in EMF reference links are always unique.
*/
public void testCreateTwoReferenceLinks() {
Node nodeB1 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB1);
Node nodeB2 = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create another nodeB", nodeB2);
GenLink genLink = getLink(false, 2);
checkLinkCreation(genLink, myNodeA, nodeB1, false);
checkLinkCreation(genLink, nodeB2, myNodeA, true);
checkLinkCreationNotAllowed(genLink);
}
/**
* In EMF reference links are always unique.
*/
public void testCreateReferenceLinkUniqueness() {
GenLink genLink = getLink(false, 2);
assertTrue("Incorrect genLink found", genLink.getModelFacet() instanceof FeatureLinkModelFacet && ((FeatureLinkModelFacet) genLink.getModelFacet()).getMetaFeature().isUnique());
checkLinkCreation(genLink, false);
checkLinkCreationNotAllowed(genLink);
}
/**
* TypeLink: SelfLink should becreated in straight direction if both
* outgoing and incomming creations allowed
*/
public void testSelfTypeLinkOut() {
Node nodeA1 = createNode(getSetup().getGenModel().getNodeA(), getDiagram());
assertNotNull("Unable to create another nodeA", nodeA1);
checkLinkCreation(getSelfLink(true), myNodeA, nodeA1, false);
}
/**
* ReferenceLink: SelfLink should becreated in straight direction if both
* outgoing and incomming creations allowed
*/
public void testSelfRefLinkOut() {
Node nodeA1 = createNode(getSetup().getGenModel().getNodeA(), getDiagram());
assertNotNull("Unable to create another nodeA", nodeA1);
checkLinkCreation(getSelfLink(false), myNodeA, nodeA1, false);
}
public void testLink2Link() {
Edge link = createSourceTargetLink();
Node node = createNode(getNodeD(), getDiagram());
GenLink link2Link = getLink(true, 3);
assertNotNull(link2Link);
checkLinkCreation(link2Link, node, link, false);
}
public void testLinkFromLink() {
Edge link = createSourceTargetLink();
Node node = createNode(getNodeD(), getDiagram());
GenLink link2Link = getLink(true, 4);
assertNotNull(link2Link);
checkLinkCreation(link2Link, link, node, false);
}
public void testLinkCrossLink() {
Edge link = createSourceTargetLink();
GenLink link2Link = getLink(true, 5);
assertNotNull(link2Link);
checkLinkCreation(link2Link, link, link, false);
}
public void testLink2LinkRef() {
Edge link = createSourceTargetLink();
Node node = createNode(getNodeD(), getDiagram());
GenLink link2Link = getLink(false, 3);
assertNotNull(link2Link);
checkLinkCreation(link2Link, node, link, false);
}
public void testLinkFromLinkRef() {
Edge link = createSourceTargetLink();
Node node = createNode(getNodeD(), getDiagram());
GenLink link2Link = getLink(false, 4);
assertNotNull(link2Link);
checkLinkCreation(link2Link, link, node, false);
}
public void testLinkCrossLinkRef() {
Edge link = createSourceTargetLink();
GenLink link2Link = getLink(false, 5);
assertNotNull(link2Link);
checkLinkCreation(link2Link, link, link, false);
}
private GenCommonBase getNodeD() {
for (GenNode nextGenNode : getSetup().getGenModel().getGenDiagram().getTopLevelNodes()) {
if ("NodeTargetD".equals(nextGenNode.getDomainMetaClass().getName())) {
return nextGenNode;
}
}
fail("No NodeTargetD found");
return null;
}
private Edge createSourceTargetLink() {
Node nodeA = createNode(getSetup().getGenModel().getNodeA(), getDiagram());
assertNotNull("Unable to create nodeA", nodeA);
Node nodeB = createNode(getSetup().getGenModel().getNodeB(), getDiagram());
assertNotNull("Unable to create nodeB", nodeB);
Edge link = createLink(getSetup().getGenModel().getLinkC(), nodeA, nodeB);
assertNotNull("Unable to create link from nodeA to nodeB", link);
return link;
}
private void checkLinkCreationNotAllowed(GenLink genLink) {
checkLink(genLink, myNodeA, myNodeB, false, false);
}
private void checkLink(GenLink genLink) {
checkLink(genLink, myNodeA, myNodeB, genLink.isOutgoingCreationAllowed(), genLink.isIncomingCreationAllowed());
}
private void checkLink(GenLink genLink, View sourceNode, View targetNode, boolean directCreation, boolean reversedCreation) {
Command directCommand = getViewerConfiguration().getCreateLinkCommand(sourceNode, targetNode, genLink);
assertTrue("Dirrect link creation command should " + (directCreation ? "" : "not ") + "be allowed", (directCommand != null && directCommand.canExecute()) == directCreation);
Command reversedCommand = getViewerConfiguration().getCreateLinkCommand(targetNode, sourceNode, genLink);
assertTrue("Reversed link creation command should " + (reversedCreation ? "" : "not ") + "be allowed", (reversedCommand != null && reversedCommand.canExecute()) == reversedCreation);
}
private GenLink getSelfLink(boolean typeLink) {
for (GenLink nextLink : getSetup().getGenModel().getGenDiagram().getLinks()) {
if (typeLink && nextLink.getModelFacet() instanceof TypeLinkModelFacet) {
TypeLinkModelFacet modelFacet = (TypeLinkModelFacet) nextLink.getModelFacet();
if (modelFacet.getTargetMetaFeature().getTypeGenClass() == modelFacet.getContainmentMetaFeature().getGenClass()) {
return nextLink;
}
} else if (!typeLink && nextLink.getModelFacet() instanceof FeatureLinkModelFacet) {
FeatureLinkModelFacet modelFacet = (FeatureLinkModelFacet) nextLink.getModelFacet();
if (modelFacet.getMetaFeature().getTypeGenClass() == modelFacet.getMetaFeature().getGenClass()) {
return nextLink;
}
}
}
fail("Self gen link was not found. Probably incorrect session setup used. isTypeLink = " + typeLink);
return null;
}
private GenLink getLink(boolean typeLink, int cardinality) {
for (GenLink nextLink : getSetup().getGenModel().getGenDiagram().getLinks()) {
if (typeLink && nextLink.getModelFacet() instanceof TypeLinkModelFacet) {
TypeLinkModelFacet modelFacet = (TypeLinkModelFacet) nextLink.getModelFacet();
if (modelFacet.getContainmentMetaFeature().getEcoreFeature().getUpperBound() == cardinality) {
return nextLink;
}
} else if (!typeLink && nextLink.getModelFacet() instanceof FeatureLinkModelFacet) {
FeatureLinkModelFacet modelFacet = (FeatureLinkModelFacet) nextLink.getModelFacet();
if (modelFacet.getMetaFeature().getEcoreFeature().getUpperBound() == cardinality) {
return nextLink;
}
}
}
fail("Gen link was not found. Probably incorrect session setup used. type = " + typeLink + ", cardinality = " + cardinality);
return null;
}
private void checkLinkCreation(GenLink link, boolean reversed) {
checkLinkCreation(link, reversed ? myNodeB : myNodeA, reversed ? myNodeA : myNodeB, reversed);
}
private void checkLinkCreation(GenLink genLink, View source, View target, boolean reversed) {
Edge link = createLink(genLink, source, target);
assertNotNull(link);
View srcView = reversed ? target : source;
View dstView = reversed ? source : target;
assertEquals(srcView, link.getSource());
assertEquals(dstView, link.getTarget());
if (genLink.getModelFacet() instanceof TypeLinkModelFacet) {
checkSemanticTypeLink(link, srcView, dstView, (TypeLinkModelFacet) genLink.getModelFacet());
} else if (genLink.getModelFacet() instanceof FeatureLinkModelFacet) {
checkSemanticReferenceLink(link, srcView, dstView, (FeatureLinkModelFacet) genLink.getModelFacet());
} else {
fail("Link with unsupported model facet passed");
}
}
private void checkSemanticReferenceLink(Edge link, View source, View target, FeatureLinkModelFacet facet) {
EObject linkSource = source.getElement();
EObject linkTarget = target.getElement();
assertNull(link.getElement());
EStructuralFeature linkFeature = linkSource.eClass().getEStructuralFeature(facet.getMetaFeature().getName());
assertNotNull(linkFeature);
Object linked = linkSource.eGet(linkFeature);
if (linked instanceof Collection<?>) {
assertTrue("Link element was not added to the container", ((Collection<?>) linked).contains(linkTarget));
} else {
assertEquals("Link element was not added to the container", linkTarget, linked);
}
}
private void checkSemanticTypeLink(Edge link, View source, View target, TypeLinkModelFacet facet) {
EObject linkSource = source.getElement();
EObject linkElement = link.getElement();
EObject linkTarget = target.getElement();
assertNotNull(linkElement);
if (facet.getSourceMetaFeature() == null) {
EStructuralFeature containmentFeature = linkSource.eClass().getEStructuralFeature(facet.getContainmentMetaFeature().getName());
assertNotNull(containmentFeature);
Object contained = linkSource.eGet(containmentFeature);
if (contained instanceof Collection<?>) {
assertTrue("Link element was not added to the container", ((Collection<?>) contained).contains(linkElement));
} else {
assertEquals("Link element was not added to the container", linkElement, contained);
}
} else {
EStructuralFeature sourceFeature = linkElement.eClass().getEStructuralFeature(facet.getSourceMetaFeature().getName());
assertNotNull(sourceFeature);
Object sources = linkElement.eGet(sourceFeature);
if (sources instanceof Collection<?>) {
assertTrue("Link source was not set correctly", ((Collection<?>) sources).contains(linkSource));
} else {
assertEquals("Link source was not set correctly", linkSource, sources);
}
}
EStructuralFeature targetFeature = linkElement.eClass().getEStructuralFeature(facet.getTargetMetaFeature().getName());
assertNotNull(targetFeature);
Object targets = linkElement.eGet(targetFeature);
if (targets instanceof Collection<?>) {
assertTrue("Link target was not set correctly", ((Collection<?>) targets).contains(linkTarget));
} else {
assertEquals("Link target was not set correctly", linkTarget, targets);
}
}
}