/*******************************************************************************
* Copyright (c) 2010-2015 Henshin developers. 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:
* TU Berlin, University of Luxembourg, SES S.A.
*******************************************************************************/
/**
*
*/
package de.tub.tfs.henshin.editor.commands.rule;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.HenshinFactory;
import org.eclipse.emf.henshin.model.HenshinPackage;
import org.eclipse.emf.henshin.model.Mapping;
import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.NestedCondition;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import de.tub.tfs.henshin.editor.commands.SimpleAddEObjectCommand;
import de.tub.tfs.henshin.editor.commands.SimpleSetEFeatureCommand;
import de.tub.tfs.henshin.editor.util.HenshinLayoutUtil;
import de.tub.tfs.henshin.editor.util.HenshinUtil;
import de.tub.tfs.henshin.editor.util.JavaUtil;
import de.tub.tfs.henshin.editor.util.ModelUtil;
import de.tub.tfs.henshin.model.layout.NodeLayout;
import de.tub.tfs.muvitor.commands.SimpleDeleteEObjectCommand;
/**
* A {@link Command command} to create {@link Mapping mappings} between
* {@link Node nodes} contained by {@link Graph graphs} in a {@link Rule rule} .
* (e.g. LHS <-> RHS, LHS <-> NAC, NC <->NC, NC<->RHS...)
*
* @author Johann, nam
*/
public class CreateNodeMappingCommand extends CompoundCommand {
private Node origin;
private Node image;
private Mapping newMapping;
private EObject container;
private NodeLayout originLayout;
private NodeLayout imageLayout;
private EStructuralFeature mappingsFeature;
private Graph orgGraph;
private Graph imgGraph;
private boolean skipCheck = false;
/**
*
*/
private void init() {
if (JavaUtil.notNull(origin, image, newMapping, container,
originLayout, image, mappingsFeature, orgGraph, imgGraph)) {
int idx = -1;
getCommands().clear();
if (!origin.getType().isSuperTypeOf(image.getType())
|| orgGraph == imgGraph) {
return;
}
if (orgGraph.isLhs() && imgGraph.isRhs()) {
container = imgGraph.getRule();
}
if (imgGraph.isNestedCondition()) {
container = imgGraph.eContainer();
}
if (orgGraph.isRhs()) {
swapOrgImg();
}
if (!skipCheck && HenshinLayoutUtil.INSTANCE.isMultiNode(origin) ){
return;
}
newMapping.setOrigin(origin);
newMapping.setImage(image);
Module rootModel = HenshinUtil.INSTANCE
.getTransformationSystem(origin);
if (rootModel == null) {
rootModel = HenshinUtil.INSTANCE.getTransformationSystem(image);
}
//add(new CreateMappingColorCommand(originLayout, imageLayout,
// container));
//System.out.println("DEBUG:_idx=_" + idx);
add(new SimpleAddEObjectCommand<EObject, Mapping>(newMapping,
mappingsFeature, container,idx));
// refresh labels on origin and image nodes
Node originNode = newMapping.getOrigin();
Node imageNode = newMapping.getImage();
add(new SimpleSetEFeatureCommand<Node, String>(originNode, originNode.getName(),
HenshinPackage.Literals.NAMED_ELEMENT__NAME));
add(new SimpleSetEFeatureCommand<Node, String>(imageNode, imageNode.getName(),
HenshinPackage.Literals.NAMED_ELEMENT__NAME));
for (Rule multiRule : this.orgGraph.getRule().getMultiRules()) {
Node multiSource = multiRule.getMultiMappings().getImage(origin, multiRule.getLhs());
Node multiTarget = multiRule.getMultiMappings().getImage(image, multiRule.getRhs());
CreateNodeMappingCommand c = new CreateNodeMappingCommand(multiSource,multiTarget,multiRule);
c.skipCheck = true;
c.init();
add(c);
}
List<Mapping> currMappingsFromOrigin = ModelUtil.getReferences(
origin, Mapping.class, rootModel,
HenshinPackage.Literals.MAPPING__ORIGIN);
for (Mapping m : currMappingsFromOrigin) {
if (m.getImage() == image) {
return;
}
if (m.getImage() != null && m.getImage().getGraph() == imgGraph) {
add(new DeleteMappingCommand(m, false));
//add(new SimpleDeleteEObjectCommand(m));
if (m.getImage().getGraph().eContainer() instanceof Rule){
idx = m.getImage().getGraph().getRule().getMappings().indexOf(m);
} else {
idx = ((NestedCondition)m.getImage().getGraph().eContainer()).getMappings().indexOf(m);
}
}
}
List<Mapping> currMappingsToTarget = ModelUtil.getReferences(image,
Mapping.class, rootModel,
HenshinPackage.Literals.MAPPING__IMAGE);
for (Mapping m : currMappingsToTarget) {
if (m.getOrigin() != null && m.getOrigin().getGraph() == orgGraph) {
add(new DeleteMappingCommand(m, false));
//add(new SimpleDeleteEObjectCommand(m));
if (m.getOrigin().getGraph().eContainer() instanceof Rule){
idx = m.getOrigin().getGraph().getRule().getMappings().indexOf(m);
} else {
idx = ((NestedCondition)m.getOrigin().getGraph().eContainer()).getMappings().indexOf(m);
}
}
}
}
}
/**
* @param newMapping
* @param origin
* @param image
* @param container
*/
public CreateNodeMappingCommand(Mapping newMapping, Node origin,
Node image, EObject container) {
this(newMapping, origin);
setImage(image);
setContainer(container);
//init();
}
@Override
public boolean canExecute() {
if (this.getCommands().isEmpty())
return true;
if(!super.canExecute())
System.out.println("No.");
return super.canExecute();
}
/**
* Instantiates a new creates the node mapping command.
*
* @param origin
* the original
* @param mapping
* the mapping
*/
public CreateNodeMappingCommand(Mapping newMapping, Node origin) {
super("Creating Node Mapping");
this.newMapping = newMapping;
setOrigin(origin);
}
/**
* @param origin
* @param image
* @param container
*/
public CreateNodeMappingCommand(final Node origin, final Node image,
final EObject container) {
this(HenshinFactory.eINSTANCE.createMapping(), origin, image, container);
}
/**
* Gets the original.
*
* @return the original
*/
public Node getOrigin() {
return origin;
}
/**
* Sets the image {@link Node} for the new {@link Mapping}.
*
* @param image
* the new image {@link Node}.
*/
public void setImage(final Node image) {
this.image = image;
if (image != null) {
imageLayout = HenshinLayoutUtil.INSTANCE.getLayout(image);
imgGraph = image.getGraph();
}
//init();
}
/**
* @param imgGraph
* the imgGraph to set
*/
public void setImgGraph(Graph imgGraph) {
this.imgGraph = imgGraph;
init();
}
/**
* @param origin
* the origin to set
*/
public void setOrigin(Node origin) {
this.origin = origin;
if (origin != null) {
if (origin.eContainer() != null) {
originLayout = HenshinLayoutUtil.INSTANCE.getLayout(origin);
orgGraph = origin.getGraph();
}
}
//init();
}
/**
* @param container
*/
public void setContainer(final EObject container) {
this.container = container;
if (container != null) {
if (container instanceof Rule) {
mappingsFeature = HenshinPackage.Literals.RULE__MAPPINGS;
} else if (container instanceof NestedCondition) {
mappingsFeature = HenshinPackage.Literals.NESTED_CONDITION__MAPPINGS;
}
}
init();
}
/**
* @param imageLayout
* the imageLayout to set
*/
public void setImageLayout(NodeLayout imageLayout) {
this.imageLayout = imageLayout;
init();
}
/**
*
*/
private void swapOrgImg() {
Node tmp = origin;
origin = image;
image = tmp;
imgGraph = image.getGraph();
orgGraph = origin.getGraph();
imageLayout = HenshinLayoutUtil.INSTANCE.getLayout(image);
originLayout = HenshinLayoutUtil.INSTANCE.getLayout(origin);
}
}