package agg.gui.trafo; import java.util.BitSet; import java.util.List; import java.util.Vector; import agg.editor.impl.EdGraGra; import agg.editor.impl.EdRule; import agg.gui.editor.GraGraEditor; import agg.gui.event.TransformEvent; import agg.gui.event.TransformEventListener; import agg.gui.options.GraTraMatchOptionGUI; import agg.gui.options.GraTraOptionGUI; import agg.xt_basis.CompletionStrategySelector; import agg.xt_basis.GraTraOptions; import agg.xt_basis.LayeredGraTraImpl; import agg.xt_basis.DefaultGraTraImpl; import agg.xt_basis.MorphCompletionStrategy; import agg.xt_basis.PriorityGraTraImpl; import agg.xt_basis.Rule; import agg.xt_basis.RuleSequencesGraTraImpl; import agg.xt_basis.csp.CompletionPropertyBits; import agg.ruleappl.RuleSequence; import agg.util.Pair; /** * The class GraGraTransform handles a step by step (debugger) and interpreting * (interpreter) transformation of a gragra. It uses the class TransformDebug * for the debugger and the class TransformInterpret for the interpreter. It * provides the procedures to the Transform menu. * * @author $Author: olga $ * @version $Id: GraGraTransform.java,v 1.12 2010/10/21 11:18:16 olga Exp $ */ public class GraGraTransform { /** Creates a new instance */ public GraGraTransform(GraGraEditor anEditor) { this.editor = anEditor; this.threadpriority = 7; /* create gratra options GUI */ this.generalOptionGUI = new GraTraMatchOptionGUI(this); this.optionGUI = new GraTraOptionGUI(this.editor.getParentFrame(), this); /* set strategy to default strategy */ this.strategy = this.generalOptionGUI.getMorphCompletionStrategy(); /* create a new step by step (debugger) transformation object */ this.debugger = new TransformDebug(this); this.debugger.setCompletionStrategy(this.strategy); this.editor.addEditEventListener(this.debugger); this.transformListeners = new Vector<TransformEventListener>(); } public GraGraEditor getEditor() { return this.editor; } public EdGraGra getGraGra() { return this.editor.getGraGra(); } public Vector<EdRule> getCurrentRuleSet() { if (this.editor.getGraGra() != null) { // return this.editor.getGraGra().getRules(); return this.editor.getGraGra().getEnabledRules(); } return new Vector<EdRule>(0); } /** * Returns GraTraOptionGUI instance which allows to set the possible graph * transformation options. */ public GraTraOptionGUI getOptionGUI() { return this.optionGUI; } /** Returns general options of the gragra transformation. */ public GraTraMatchOptionGUI getGeneralOptionGUI() { return this.generalOptionGUI; } /** Returns the current completion strategy */ public MorphCompletionStrategy getStrategy() { return this.strategy; } public void setEachRuleToApplyOfRuleSequence(boolean b) { if (this.ruleSequenceTransform != null) this.ruleSequenceTransform.setEachRuleToApplyOfRuleSequence(b); } public void setRuleSequences( final List<EdRule> rules, final List<Pair<List<Pair<String, String>>, String>> sequences) { this.optionGUI.setRulesOfRuleSequenceGUI(rules); this.optionGUI.setRuleSequences(sequences); this.optionGUI.enableRuleSequenceGUI(this.optionGUI.ruleSequenceEnabled()); } public void resetCurrentRuleSequences() { if (this.editor.getGraGra() != null) { this.optionGUI.setRulesOfRuleSequenceGUI(this.editor.getGraGra().getEnabledRules()); this.optionGUI.setRuleSequences(this.editor.getGraGra().getRuleSequenceList()); this.optionGUI.enableRuleSequenceGUI(this.optionGUI.ruleSequenceEnabled()); } } public void setRuleSequences( List<Pair<List<Pair<String, String>>, String>> sequences) { this.optionGUI.setRuleSequences(sequences); this.optionGUI.enableRuleSequenceGUI(this.optionGUI.ruleSequenceEnabled()); } public List<Pair<List<Pair<String, String>>, String>> getRuleSequences() { if (this.optionGUI.ruleSequenceEnabled()) return this.optionGUI.getRuleSequences(); return null; } public String getRuleSequencesAsText() { if (this.optionGUI.ruleSequenceEnabled()) return this.optionGUI.getRuleSequencesAsText(); return null; } /** * If return value is TRUE, the rule to be applied is choosen * non-deterministically. */ public boolean nondeterministicallyEnabled() { return this.optionGUI.nondeterministicallyEnabled(); } /** * If return value is TRUE, the user defined rule priorities are used for * graph transformation. */ public boolean priorityEnabled() { return this.optionGUI.priorityEnabled(); } /** * If return value is TRUE, the user defined rule layers are used for graph * transformation. */ public boolean layeredEnabled() { return this.optionGUI.layeredEnabled(); } /** * If return value is TRUE, the user defined rule sequences are used for * graph transformation. */ public boolean ruleSequenceEnabled() { return this.optionGUI.ruleSequenceEnabled(); } /** * In case of TRUE, the consistency check will be done after each * transformation step. If the consistency check fails, the next valid match * is taken for the graph transformation. */ public boolean consistencyEnabled() { return this.generalOptionGUI.consistencyEnabled(); } /** * In case of TRUE, the consistency check will be done after the graph * transformation finished. For layered graph transformation the consistency * check will be done at the end of a layer. */ public boolean consistencyCheckAfterGraphTrafoEnabled() { return this.generalOptionGUI.consistencyCheckAfterGraphTrafoEnabled(); } /** * If return value is TRUE, the layer's table is displayed before * transformation starts to give the user a possibility to change the * current rule-layer setting. */ public boolean showLayerEnabled() { return this.optionGUI.showLayerEnabled(); } /** * If return value is TRUE, the graph transformation will stop after each * layer and wait for a user action. */ public boolean stopLayerAndWaitEnabled() { return this.optionGUI.stopLayerAndWaitEnabled(); } /** * If return value is TRUE, the only current layer will break when the tool * button "Stop" transformation is pressed. */ public boolean breakLayerEnabled() { return this.optionGUI.breakLayerEnabled(); } /** * If return value is TRUE, the layered transformation will break when the * tool button "Stop" transformation is pressed. */ public boolean breakAllLayerEnabled() { return this.optionGUI.breakAllLayerEnabled(); } /** * If return value is TRUE, the modified host graph will be shown after each * transformation step. */ public boolean showGraphAfterStepEnabled() { return this.generalOptionGUI.showGraphAfterStepEnabled(); } /** * If return value is TRUE, the graph transformation will stop after each * step and wait for a user action. */ public boolean waitAfterStepEnabled() { return this.generalOptionGUI.waitAfterStepEnabled(); } /** * If return value is TRUE, the rule applicability check will be done after * each transformation step. */ public boolean checkRuleApplicabilityEnabled() { return this.generalOptionGUI.checkRuleApplicabilityEnabled(); } /** Returns TRUE if the option -apply parallel- is set. */ // public boolean applyParallelEnabled() { // return this.generalOptionGUI.applyParallelEnabled(); // } public boolean selectMatchObjectsEnabled() { return this.generalOptionGUI.selectMatchObjectsEnabled(); } /** * If return value is TRUE, all nodes and edges created during * transformation step are shown as selected objects. */ public boolean selectNewAfterStepEnabled() { return this.generalOptionGUI.selectNewAfterStepEnabled(); } /** * If return value is TRUE, the layered transformation starts with the first * layer again. */ public boolean layeredLoopEnabled() { return this.optionGUI.layeredLoopEnabled(); } /** Returns TRUE if the option - reset graph - is set * in this case the host graph will be reset for each loop over layers. */ public boolean resetGraphEnabled() { return this.optionGUI.resetGraphEnabled(); } public int getLayerToStop() { return this.optionGUI.getLayerToStop(); } /** * Sets the current completion strategy. The completion strategy of the * transform debugger will be set too. */ public void setCompletionStrategy(MorphCompletionStrategy strat) { this.strategy = strat; this.debugger.setCompletionStrategy(strat); if (this.debugger.getMatch() != null) { this.debugger.getMatch().setCompletionStrategy(strat); } this.editor.getGraGra().getBasisGraGra().setGraTraOptions(strat); } /** * The current transformation options, backed by a vector of option names. */ public Vector<String> getGraTraOptionsList() { GraTraOptions gratraOptions = getGraTraOptions(); return gratraOptions.getOptions(); } public GraTraOptions getGraTraOptions() { GraTraOptions gratraOptions = new GraTraOptions(); gratraOptions.addOption(CompletionStrategySelector.getName(this.strategy)); BitSet activebits = this.strategy.getProperties(); for (int i = 0; i < CompletionPropertyBits.BITNAME.length; i++) { if (activebits.get(i)) { String bitName = CompletionPropertyBits.BITNAME[i]; gratraOptions.addOption(bitName); } } if (!this.strategy.isRandomisedDomain()) gratraOptions.addOption(GraTraOptions.DETERMINED_CSP_DOMAIN); if (this.generalOptionGUI.consistencyEnabled()) gratraOptions.addOption(GraTraOptions.CONSISTENT_ONLY); if (this.generalOptionGUI.consistencyCheckAfterGraphTrafoEnabled()) gratraOptions.addOption(GraTraOptions.CONSISTENCY_CHECK_AFTER_GRAPH_TRAFO); if (this.optionGUI.priorityEnabled()) gratraOptions.addOption(GraTraOptions.PRIORITY); else if (this.optionGUI.layeredEnabled()) gratraOptions.addOption(GraTraOptions.LAYERED); else if (this.optionGUI.ruleSequenceEnabled()) { gratraOptions.addOption(GraTraOptions.RULE_SEQUENCE); if (this.optionGUI.eachRuleToApplyEnabled()) gratraOptions.addOption(GraTraOptions.EACH_RULE_TO_APPLY); } if (this.optionGUI.stopLayerAndWaitEnabled()) gratraOptions.addOption(GraTraOptions.STOP_LAYER_AND_WAIT); if (this.optionGUI.layeredLoopEnabled()) gratraOptions.addOption(GraTraOptions.LOOP_OVER_LAYER); if (this.optionGUI.resetGraphEnabled()) gratraOptions.addOption(GraTraOptions.RESET_GRAPH); if (this.optionGUI.breakLayerEnabled()) gratraOptions.addOption(GraTraOptions.BREAK_LAYER); if (this.optionGUI.breakAllLayerEnabled()) gratraOptions.addOption(GraTraOptions.BREAK_ALL_LAYER); if (this.generalOptionGUI.checkRuleApplicabilityEnabled()) gratraOptions.addOption(GraTraOptions.CHECK_RULE_APPLICABILITY); if (this.generalOptionGUI.applyParallelEnabled()) gratraOptions.addOption(GraTraOptions.PARALLEL_MATCHING); if (this.generalOptionGUI.showGraphAfterStepEnabled()) gratraOptions.addOption(GraTraOptions.SHOW_GRAPH_AFTER_STEP); if (this.generalOptionGUI.waitAfterStepEnabled()) gratraOptions.addOption(GraTraOptions.WAIT_AFTER_STEP); return gratraOptions; } public void updateGraTraOption(String opt, boolean b) { if (this.editor.getGraGra() == null) { return; } if (this.layeredTransform != null && this.layeredTransform.isAlive()) { if (opt.equals(GraTraOptions.LOOP_OVER_LAYER) && !b) { ((LayeredGraTraImpl) this.layeredTransform.getGraTra()).setLayeredLoop(false); } else if (opt.equals(GraTraOptions.BREAK_ALL_LAYER) && b) { ((LayeredGraTraImpl) this.layeredTransform.getGraTra()).setBreakAllLayer(true); this.layeredTransform.stopping(); } } else { if (b) this.editor.getGraGra().getBasisGraGra().addGraTraOption(opt); else this.editor.getGraGra().getBasisGraGra().removeGraTraOption(opt); } } public void updateGraTraOptionGUI(Vector<String> optionsList) { this.optionGUI.update(optionsList); this.optionGUI.updateLayerToStopIfNeeded(); this.generalOptionGUI.update(optionsList); } public void setRulesOfGraphRuleSequenceGUI(Vector<EdRule> rules) { this.optionGUI.setRulesOfRuleSequenceGUI(rules); } /** Sets priority of the interpreter thread. */ public void setTransformationThreadPriority(int prior) { this.threadpriority = prior; // if (this.interpreterTransform != null) // interpreterTransform.setPriority(prior); // else if (this.layeredTransform != null) // this.layeredTransform.setPriority(prior); // else if (this.ruleSequenceTransform != null) // this.ruleSequenceTransform.setPriority(prior); } /** Returns the transform debugger. */ public TransformDebug getTransformDebugger() { return this.debugger; } /** Returns a non-deterministically rule transform interpreter */ public TransformInterpret createInterpreterTransform() { this.interpreterTransform = new TransformInterpret(this); return this.interpreterTransform; } /** Returns the non-deterministically rule transform interpreter */ public TransformInterpret getInterpreterTransform() { return this.interpreterTransform; } /** Returns a rule priority transform interpreter. */ public TransformInterpret createRulePriorityTransform() { this.rulePriorityTransform = new TransformInterpret(this, true); return this.rulePriorityTransform; } /** Returns the rule priority transform interpreter. */ public TransformInterpret getRulePriorityTransform() { return this.rulePriorityTransform; } /** Returns a rule layer transform interpreter. */ public TransformLayered createRuleLayerTransform() { this.layeredTransform = new TransformLayered(this); return this.layeredTransform; } /** Returns the rule layer transform interpreter. */ public TransformLayered getRuleLayerTransform() { return this.layeredTransform; } /** Returns a rule sequence transform interpreter. */ public TransformRuleSequences createRuleSequenceTransform(boolean useApplRuleSequence) { this.ruleSequenceTransform = new TransformRuleSequences(this, useApplRuleSequence); return this.ruleSequenceTransform; } /** Returns the rule sequence transform interpreter. */ public TransformRuleSequences getRuleSequenceTransform() { return this.ruleSequenceTransform; } /** Starts the rule sequences transformation. */ public void startTransformByRuleSequence( final EdGraGra gragra, final RuleSequence ruleSequence) { this.editor.removeEditEventListener(this.debugger); this.editor.addEditEventListener(this.ruleSequenceTransform); this.editor.setInterpreting(false); this.editor.setLayering(false); this.editor.setTransformRuleSequences(true); if (gragra.getBasisGraGra().trafoByApplicableRuleSequence()) { gragra.getBasisGraGra().addGraTraOption(GraTraOptions.WAIT_AFTER_STEP); gragra.getBasisGraGra().addGraTraOption(GraTraOptions.SELECT_NEW_AFTER_STEP); } this.ruleSequenceTransform.setGraGra(gragra, ruleSequence); this.ruleSequenceTransform.setCompletionStrategy(this.strategy); this.ruleSequenceTransform.setPriority(this.threadpriority); this.ruleSequenceTransform .setShowGraphAfterStep(showGraphAfterStepEnabled()); ((RuleSequencesGraTraImpl) this.ruleSequenceTransform.getGraTra()) .setGraTraOptions(getGraTraOptions()); fireTransform(new TransformEvent(this.ruleSequenceTransform, TransformEvent.START)); this.ruleSequenceTransform.start(); } /** Stops the rule sequences transform. */ public void stopTransformRuleSequences() { this.ruleSequenceTransform.stopping(); if (this.ruleSequenceTransform.getGraTra().getGraGra().trafoByApplicableRuleSequence()) { this.ruleSequenceTransform.getGraTra().getGraGra().removeGraTraOption(GraTraOptions.WAIT_AFTER_STEP); this.ruleSequenceTransform.getGraTra().getGraGra().removeGraTraOption(GraTraOptions.SELECT_NEW_AFTER_STEP); } } /** Starts the transform interpreter. */ public void startTransformInterpreter(EdGraGra gragra) { this.editor.removeEditEventListener(this.debugger); this.editor.addEditEventListener(this.interpreterTransform); this.editor.setInterpreting(true); this.editor.setLayering(false); this.editor.setTransformRuleSequences(false); this.interpreterTransform.setGraGra(gragra); this.interpreterTransform.setCompletionStrategy(this.strategy); this.interpreterTransform.setPriority(this.threadpriority); this.interpreterTransform.setShowGraphAfterStep(showGraphAfterStepEnabled()); ((DefaultGraTraImpl) this.interpreterTransform.getGraTra()) .setGraTraOptions(getGraTraOptions()); fireTransform(new TransformEvent(this.interpreterTransform, TransformEvent.START)); this.interpreterTransform.start(); } /** Stops the transform interpreter. */ public void stopTransformInterpreter() { this.interpreterTransform.stopping(); } /** Starts the rule priority transformation. */ public void startRulePriorityTransformInterpreter(EdGraGra gragra) { this.editor.removeEditEventListener(this.debugger); this.editor.addEditEventListener(this.rulePriorityTransform); this.editor.setInterpreting(true); this.editor.setLayering(false); this.editor.setTransformRuleSequences(false); this.rulePriorityTransform.setGraGra(gragra); this.rulePriorityTransform.setCompletionStrategy(this.strategy); this.rulePriorityTransform.setPriority(this.threadpriority); this.rulePriorityTransform .setShowGraphAfterStep(showGraphAfterStepEnabled()); ((PriorityGraTraImpl) this.rulePriorityTransform.getGraTra()) .setGraTraOptions(getGraTraOptions()); fireTransform(new TransformEvent(this.rulePriorityTransform, TransformEvent.START)); this.rulePriorityTransform.start(); } /** Stops the rule priority transform interpreter. */ public void stopRulePriorityTransformInterpreter() { this.rulePriorityTransform.stopping(); } /** Starts the layered transformation. */ public void startTransformLayered(EdGraGra gragra) { this.editor.removeEditEventListener(this.debugger); this.editor.addEditEventListener(this.layeredTransform); this.editor.setInterpreting(false); this.editor.setLayering(true); this.editor.setTransformRuleSequences(false); this.layeredTransform.setGraGra(gragra); this.layeredTransform.setCompletionStrategy(this.strategy); this.layeredTransform.setPriority(this.threadpriority); this.layeredTransform.setShowGraphAfterStep(showGraphAfterStepEnabled()); ((LayeredGraTraImpl) this.layeredTransform.getGraTra()) .setStopLayerAndWait(stopLayerAndWaitEnabled()); ((LayeredGraTraImpl) this.layeredTransform.getGraTra()) .setLayeredLoop(layeredLoopEnabled()); ((LayeredGraTraImpl) this.layeredTransform.getGraTra()) .setResetGraphBeforeLoop(resetGraphEnabled()); ((LayeredGraTraImpl) this.layeredTransform.getGraTra()) .setBreakLayer(breakLayerEnabled()); ((LayeredGraTraImpl) this.layeredTransform.getGraTra()) .setBreakAllLayer(breakAllLayerEnabled()); fireTransform(new TransformEvent(this.layeredTransform, TransformEvent.START)); this.layeredTransform.start(); } /** Stops the layered transformation. */ public void stopTransformLayered() { this.layeredTransform.stopping(); } public void changeFromTransformLayeredToTransformInterpreter() { stopTransformLayered(); this.editor.startInterpreterTransform(); } public Vector<Rule> getApplicableRules(EdGraGra gragra) { return this.debugger.getApplicableRules(gragra); } public Vector<EdRule> getApplicableRules(EdGraGra gragra, boolean applicable) { return this.debugger.getApplicableRules(gragra, applicable); } /** Defines a new match of the transform debugger. */ public void matchDef(EdRule rule) { this.debugger.setRule(rule); this.debugger.matchDef(); } public void destroyMatch() { this.debugger.destroyMatch(); } /** Completes the match of the transform debugger. */ public void nextCompletion(EdRule rule) { this.debugger.setRule(rule); this.debugger.nextCompletion(); } /** Applies the match of the transform debugger. */ public void step(EdRule rule) { this.debugger.setRule(rule); this.debugger.step(); } public void unsetTransformDebug() { // this.debugger.setRule(null); this.debugger.dispose(); } /** Adds a new transform event listener. */ public synchronized void addTransformEventListener(TransformEventListener l) { if (!this.transformListeners.contains(l)) this.transformListeners.addElement(l); } /** Removes the transform event listener. */ public synchronized void removeTransformEventListener( TransformEventListener l) { if (this.transformListeners.contains(l)) this.transformListeners.removeElement(l); } /** Sends a transform event to the all my listeners. */ public void fireTransform(TransformEvent e) { for (int i = 0; i < this.transformListeners.size(); i++) this.transformListeners.get(i).transformEventOccurred(e); } private final GraTraOptionGUI optionGUI; private final GraTraMatchOptionGUI generalOptionGUI; private MorphCompletionStrategy strategy; private final TransformDebug debugger; private TransformInterpret interpreterTransform; private TransformInterpret rulePriorityTransform; private TransformLayered layeredTransform; private TransformRuleSequences ruleSequenceTransform; private final Vector<TransformEventListener> transformListeners; private GraGraEditor editor; private int threadpriority; }