/******************************************************************************* * 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.tggeditor.commands.create.rule; import org.eclipse.emf.henshin.model.Attribute; import org.eclipse.emf.henshin.model.Edge; import org.eclipse.emf.henshin.model.Graph; import org.eclipse.emf.henshin.model.HenshinFactory; import org.eclipse.emf.henshin.model.Mapping; import org.eclipse.emf.henshin.model.Node; import org.eclipse.emf.henshin.model.Rule; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import de.tub.tfs.henshin.tgg.TAttribute; import de.tub.tfs.henshin.tgg.TEdge; import de.tub.tfs.henshin.tgg.TNode; import de.tub.tfs.henshin.tgg.TggFactory; import de.tub.tfs.henshin.tgg.interpreter.util.NodeUtil; import de.tub.tfs.henshin.tgg.interpreter.util.RuleUtil; import de.tub.tfs.henshin.tggeditor.util.GraphicalNodeUtil; import de.tub.tfs.muvitor.commands.SimpleDeleteEObjectCommand; /** * The class MarkCommand can mark a node in a rule as new or not new. It makes * all the needed changes in the model of the rule and in the tgg layouts. * When executed it either deletes the lhs node plus its mapping or it creates * a new lhs node plus its mapping. Also the edges are handled. */ public class MarkCommand extends CompoundCommand { /** * the rhs node */ private Node rhsNode; /** * the mapping between the rhs and lhs node */ private Mapping mapping; /** * the lhs node */ private Node lhsNode; /** * the rule containing lhs and rhs node */ private Rule rule; /** * the lhs graph */ private Graph lhsGraph; /** * The constructor * @param newMapping the mapping between the rhs and lhs node * @param rhsNode the rhs node */ public MarkCommand(Mapping newMapping, Node rhsNode) { this.mapping = newMapping; this.rhsNode = rhsNode; } public MarkCommand(Node rhsNode) { this.rhsNode = rhsNode; this.mapping = RuleUtil.getRHSNodeMapping(rhsNode); } /* (non-Javadoc) * @see org.eclipse.gef.commands.CompoundCommand#execute() */ @Override public void execute() { getCommands().clear(); // case: node is currently preserved and shall be marked as new // and the node marker ++ is not present if (!RuleUtil.NEW.equals(((TNode) rhsNode).getMarkerType())) { // - if the rule is consistent, then the first check for the // mapping is valid already, otherwise, the inconsistency will // be removed mark(); // case: node is currently created by the rule, thus demark it and // create a node in the lhs of the rule } else { demark(); } super.execute(); } /* (non-Javadoc) * @see org.eclipse.gef.commands.CompoundCommand#undo() */ @Override public void undo() { execute(); } /* (non-Javadoc) * @see org.eclipse.gef.commands.CompoundCommand#redo() */ @Override public void redo() { execute(); } /* (non-Javadoc) * @see org.eclipse.gef.commands.CompoundCommand#canExecute() */ @Override public boolean canExecute() { if (mapping != null) { // mapping is invalid if (mapping.getOrigin() == null) return true; else // case: node is used for a NAC, then marking is not possible if (NodeUtil.hasNodeNacMapping(mapping.getOrigin())) { Shell shell = new Shell(); MessageDialog.openError(shell, "Node has NAC mapping", "A 'new' Marker could not be created, because the node " + rhsNode.getName() + " has a NAC mapping."); shell.dispose(); return false; } } return true; } /** * marks a rule node as new and changes the model accordingly */ private void mark() { lhsNode = RuleUtil.getLHSNode(rhsNode); mapping = RuleUtil.getRHSNodeMapping(rhsNode); // mark all contained attributes as new for (Attribute attr : rhsNode.getAttributes()) { if (((TAttribute) attr).getMarkerType() != null){ // attribute is already marked as created } else { // mark attribute as created add(new MarkAttributeCommand(attr)); } } for(Edge e:rhsNode.getIncoming()){ // if edge is not marked, then mark it if(((TEdge) e).getMarkerType() == null) add(new MarkEdgeCommand(e)); } for(Edge e:rhsNode.getOutgoing()){ // if edge is not marked, then mark it if(((TEdge) e).getMarkerType() == null) add(new MarkEdgeCommand(e)); } ((TNode) rhsNode).setMarkerType(RuleUtil.NEW); if(lhsNode!=null){ add(new SimpleDeleteEObjectCommand(lhsNode)); } else System.out.println("!WARNING: marking rhs node -> lhs node does not exist and will not be deleted."); if(mapping!=null){ add(new SimpleDeleteEObjectCommand(mapping)); } else System.out.println("!WARNING: marking rhs node -> mapping does not exist and will not be deleted."); mapping=null; //super.execute(); } /** * marks a node as not new and changes the model accordingly */ private void demark() { // check and restore consistency if necessary for corrupted models lhsNode = RuleUtil.getLHSNode(rhsNode); mapping = RuleUtil.getRHSNodeMapping(rhsNode); if(lhsNode!=null){ add(new SimpleDeleteEObjectCommand(lhsNode)); System.out.println("!WARNING: demarking rhs node -> lhs node already exists and will not be replaced."); } if(mapping!=null){ add(new SimpleDeleteEObjectCommand(mapping)); System.out.println("!WARNING: demarking rhs node -> mapping does already exist and will be replaced."); } // remove marker and create the corresponding node in the LHS lhsNode = TggFactory.eINSTANCE.createTNode(); rule = rhsNode.getGraph().getRule(); lhsGraph = rhsNode.getGraph().getRule().getLhs(); lhsGraph.getNodes().add(lhsNode); lhsNode.setName(rhsNode.getName()); lhsNode.setType(rhsNode.getType()); ((TNode) rhsNode).setMarkerType(null); mapping = HenshinFactory.eINSTANCE.createMapping(); mapping.setImage(rhsNode); mapping.setOrigin(lhsNode); rule.getMappings().add(mapping); } }