/*******************************************************************************
* 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.actions.create.rule;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.henshin.model.HenshinFactory;
import org.eclipse.emf.henshin.model.IndependentUnit;
import org.eclipse.emf.henshin.model.Mapping;
import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
import de.tub.tfs.henshin.tgg.TEdge;
import de.tub.tfs.henshin.tgg.TGG;
import de.tub.tfs.henshin.tgg.TGGRule;
import de.tub.tfs.henshin.tgg.TNode;
import de.tub.tfs.henshin.tgg.TggFactory;
import de.tub.tfs.henshin.tgg.TripleComponent;
import de.tub.tfs.henshin.tgg.TripleGraph;
import de.tub.tfs.henshin.tgg.interpreter.impl.NodeTypes;
import de.tub.tfs.henshin.tgg.interpreter.util.ExceptionUtil;
import de.tub.tfs.henshin.tgg.interpreter.util.RuleUtil;
import de.tub.tfs.henshin.tggeditor.editparts.tree.TransformationSystemTreeEditPart;
import de.tub.tfs.henshin.tggeditor.editparts.tree.rule.RuleFolderTreeEditPart;
import de.tub.tfs.henshin.tggeditor.util.GraphicalNodeUtil;
import de.tub.tfs.henshin.tggeditor.util.dialogs.SingleElementListSelectionDialog;
public class CreatePrototypeRulesAction extends SelectionAction {
public static final String ID = "tggeditor.actions.create.CreatePrototypeRuleAction";
private Module transSys;
private IndependentUnit unit = null;
public CreatePrototypeRulesAction(IWorkbenchPart part) {
super(part);
setId(ID);
setText("Create Prototype Rules");
setToolTipText("Create prototype rules for a class");
}
@Override
protected boolean calculateEnabled() {
List<?> selectedObjects = getSelectedObjects();
if (selectedObjects.size() != 1) {
return false;
}
Object selecObject = selectedObjects.get(0);
if ((selecObject instanceof EditPart)) {
EditPart editpart = (EditPart) selecObject;
if ((editpart instanceof RuleFolderTreeEditPart)) {
unit = (IndependentUnit) editpart.getModel();
while (editpart != editpart.getRoot() && !(editpart instanceof TransformationSystemTreeEditPart))
editpart = editpart.getParent();
transSys = (Module) editpart.getModel();
return true;
}
}
return false;
}
@Override
public void run() {
Shell shell = new Shell();
List<EClass> nodeTypes = new LinkedList<EClass>();
TGG system = GraphicalNodeUtil.getLayoutSystem(transSys);
List<EPackage> epackages = getPackages(system, TripleComponent.SOURCE);
nodeTypes = NodeTypes.getNodeTypesOfEPackages(epackages,false);
EClass eClass = new SingleElementListSelectionDialog<EClass>(shell,
new LabelProvider() {
@Override
public String getText(Object element) {
return ((EClass) element).getName();
}
// @Override
// public Image getImage(Object element) {
// return IconUtil.getIcon("node18.png");
// }
}, nodeTypes.toArray(new EClass[nodeTypes.size()]),
"Node Type Selection",
"Select a EClass for the prototype rules:").run();
shell.close();
List<Rule> rules = buildPrototype(eClass);
transSys.getUnits().addAll(rules);
super.run();
}
private List<Rule> buildPrototype(EClass eClass){
List<Rule> rules = new LinkedList<Rule>();
rules.add(buildRule(eClass));
for (EReference ref : eClass.getEReferences()) {
rules.add(buildRule(eClass, ref));
if (ref.isContainment()){
//if (ref.getEType() instanceof EClass)
// rules.addAll(buildPrototype((EClass) ref.getEType()));
}
}
return rules;
}
private Rule buildRule(EClass eClass,EStructuralFeature feat){
Rule rule = createEmptyRule(eClass, feat);
TNode sourceNode = addSourceNode(eClass, rule, false);
TNode targetNode = addSourceNode((EClass) feat.getEType(), rule, true);
addFeature(sourceNode, targetNode, feat);
return rule;
}
private Rule buildRule(EClass root){
Rule rule = createEmptyRule(root);
addSourceNode(root, rule, true);
return rule;
}
private Rule createEmptyRule(EClass eClass,EStructuralFeature feat){
TGGRule r = TggFactory.eINSTANCE.createTGGRule();
r.setMarkerType(RuleUtil.TGG_RULE);
r.setName("Proto" + eClass.getName() + "_" + feat.getName() + "2SPELL");
TripleGraph lhs = TggFactory.eINSTANCE.createTripleGraph();
TripleGraph rhs = TggFactory.eINSTANCE.createTripleGraph();
lhs.setName("lhs");
rhs.setName("rhs");
r.setLhs(lhs);
r.setRhs(rhs);
return r;
}
private Rule createEmptyRule(EClass eClass){
TGGRule r = TggFactory.eINSTANCE.createTGGRule();
r.setMarkerType(RuleUtil.TGG_RULE);
r.setName("Proto" + eClass.getName() + "2SPELL");
TripleGraph lhs = TggFactory.eINSTANCE.createTripleGraph();
TripleGraph rhs = TggFactory.eINSTANCE.createTripleGraph();
lhs.setName("lhs");
rhs.setName("rhs");
r.setLhs(lhs);
r.setRhs(rhs);
return r;
}
private TNode addSourceNode(EClass eClass,Rule rule,boolean create){
TNode tNode = TggFactory.eINSTANCE.createTNode();
tNode.setType(eClass);
if (create){
rule.getRhs().getNodes().add(tNode);
tNode.setMarkerType(RuleUtil.NEW);
} else {
rule.getRhs().getNodes().add(tNode);
TNode lhsNode = TggFactory.eINSTANCE.createTNode();
lhsNode.setType(eClass);
rule.getLhs().getNodes().add(lhsNode);
Mapping mapping = HenshinFactory.eINSTANCE.createMapping(lhsNode, tNode);
rule.getMappings().add(mapping);
tNode.setMarkerType(null);
}
return tNode;
}
private TEdge addFeature(TNode source,TNode target,EStructuralFeature feat){
TEdge tEdge = TggFactory.eINSTANCE.createTEdge();
tEdge.setType((EReference) feat);
tEdge.setMarkerType(RuleUtil.NEW);
tEdge.setSource(source);
tEdge.setTarget(target);
source.getGraph().getEdges().add(tEdge);
return tEdge;
}
public static List<EPackage> getPackages(TGG layoutModel, TripleComponent type) {
if (layoutModel == null) {ExceptionUtil.error("Layout model is missing"); return null;}
return NodeTypes.getEPackagesOfComponent(layoutModel.getImportedPkgs(),type);
}
}