/*******************************************************************************
* 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.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.henshin.model.IndependentUnit;
import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.model.Unit;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.ui.IWorkbenchPart;
import de.tub.tfs.henshin.tgg.TGG;
import de.tub.tfs.henshin.tgg.TGGRule;
import de.tub.tfs.henshin.tgg.interpreter.util.RuleUtil;
import de.tub.tfs.henshin.tggeditor.commands.create.rule.GenerateOpRuleCommand;
import de.tub.tfs.henshin.tggeditor.commands.create.rule.ProcessRuleCommand;
import de.tub.tfs.henshin.tggeditor.commands.delete.DeleteFoldercommand;
import de.tub.tfs.henshin.tggeditor.commands.delete.rule.DeleteOpRuleCommand;
import de.tub.tfs.henshin.tggeditor.editparts.tree.rule.RuleFolderTreeEditPart;
/**
* The class GenerateOpRuleAction generates the operational rule from a TGG rule. The action
* is registered in the Contextmenu of the tree editor.
* @see GenerateOpRuleToolBarAction
* @see ProcessRuleCommand
*/
public abstract class GenerateOpRulesAction extends SelectionAction {
public static boolean calcInProgress = false;
/** The Constant DESC for the description. */
protected String DESC = "Generate All Op_Rules";
/** The Constant TOOLTIP for the tooltip. */
protected String TOOLTIP = "Generates operational rules for all TGG Rules";
/**
* The command which is used to execute the generation of a Transformation-rule from a rule
*/
protected GenerateOpRuleCommand command;
/**
* The rules which are used as base for the Transformation-Rules.
*/
private List<Unit> rules;
/**
* The layout System
*/
private TGG layoutSystem;
protected IndependentUnit ruleFolder;
protected String opRuleTypeUpperCase = "";
protected String opRuleType = "";
/**
* the constructor
* @param part
*/
public GenerateOpRulesAction(IWorkbenchPart part) {
super(part);
}
private void getAllUnits(List<Unit> units,IndependentUnit folder){
for (Unit unit : folder.getSubUnits()) {
if (unit instanceof IndependentUnit){
units.add( unit);
getAllUnits(units, (IndependentUnit) unit);
} else {
units.add( unit);
}
}
}
/** Is only enabled for the context menu of a rule.
* @see org.eclipse.gef.ui.actions.WorkbenchPartAction#calculateEnabled()
*/
@Override
protected boolean calculateEnabled() {
List<?> selectedObjects = getSelectedObjects();
if (selectedObjects.size() != 1) {
return false;
}
Object selectedObject = selectedObjects.get(0);
if ((selectedObject instanceof EditPart)) {
EditPart editpart = (EditPart) selectedObject;
if (editpart instanceof RuleFolderTreeEditPart) {
ruleFolder = (IndependentUnit) editpart.getModel();
rules = new LinkedList<Unit>();
getAllUnits(rules, ruleFolder);
if (!rules.isEmpty()) {
if (!calcInProgress) {
for (Unit unit : rules) {
if (unit == null)
return false;
if (unit instanceof TGGRule &&
!RuleUtil.TGG_RULE.equals(((TGGRule) unit)
.getMarkerType()))
return false;
}
return true;
}
}
}
}
return false;
}
//NEW comment changed: generalized from FT to OP
/**
* Executes the GenerateOPRuleCommand.
* @see ProcessRuleCommand
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
if (rules != null) {
CompoundCommand cmd = new CompoundCommand();
calcInProgress = true;
IndependentUnit folder = getOpRuleFolder();
// delete current operational rules
cleanUpOldContainer(folder, cmd);
cmd.execute();
// generate the new operational rules
Iterator<Unit> iterator = rules.iterator();
Unit unit=null;
Rule rule=null;
for (int idx = 0 ; idx < rules.size();idx++){
unit = iterator.next();
if (unit instanceof IndependentUnit){
continue;
}
if (unit instanceof Rule)
rule = (Rule) unit;
if (idx % 10 == 0)
System.out.println("generate " + opRuleTypeUpperCase + "-Rule #" + idx + "-" + Math.min(idx + 10,rules.size()) + " of " + rules.size());
IndependentUnit container = findContainer((IndependentUnit) ((Module)EcoreUtil.getRootContainer(rule)).getUnit("RuleFolder") ,rule);
setCommand(rule, container);
super.execute(command);
}
calcInProgress = false;
}
}
protected abstract void setCommand(Rule rule, IndependentUnit container);
protected IndependentUnit getOpRuleFolder() {
IndependentUnit folder = (IndependentUnit) ((Module) EcoreUtil
.getRootContainer(ruleFolder)).getUnit(opRuleTypeUpperCase
+ "_" + ruleFolder.getName());
if (folder == null && ruleFolder.getName().equals("RuleFolder"))
folder = (IndependentUnit) ((Module) EcoreUtil
.getRootContainer(ruleFolder)).getUnit(opRuleTypeUpperCase
+ "RuleFolder");
return folder;
}
private void cleanUpOldContainer(IndependentUnit opRuleFolder,CompoundCommand cmd) {
if (opRuleFolder == null)
return;
for (Unit unit : opRuleFolder.getSubUnits()) {
if (unit instanceof IndependentUnit) {
cleanUpOldContainer((IndependentUnit) unit,cmd);
cmd.add(new DeleteFoldercommand((IndependentUnit) unit));
} else if (unit instanceof Rule)
cmd.add(new DeleteOpRuleCommand((Rule) unit, opRuleType));
}
}
private IndependentUnit findContainer(IndependentUnit opRuleFolder, Object obj) {
for (Unit unit : opRuleFolder.getSubUnits()) {
if (unit instanceof IndependentUnit) {
IndependentUnit u = findContainer((IndependentUnit) unit, obj);
if (u != null)
return u;
} else if (unit.equals(obj))
return opRuleFolder;
}
return null;
}
}