package agg.xt_basis; import java.util.List; import java.util.Random; import java.util.Vector; import java.util.Date; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.File; import agg.cons.AtomConstraint; import agg.util.Pair; import agg.xt_basis.agt.RuleScheme; public class DefaultGraTraImpl extends GraTra { @SuppressWarnings("unused") private int doneSteps; // only for test private int counterMax; Random ran = new Random(); private boolean appliedOnce; private boolean applyContinue = false; private boolean allRulesEnabled = false; File f; FileOutputStream os; String protocolFileName = ""; private boolean grammarChecked; public DefaultGraTraImpl() { } public void dispose() { super.dispose(); } /** * not yet implemented! */ public Pair<Morphism, Morphism> derivation(Match m) { return (null); } public boolean apply() { if (!this.allRulesEnabled) { // remove disabled rules from currentRuleSet for (int j = 0; j < this.currentRuleSet.size(); j++) { if (!this.currentRuleSet.elementAt(j).isEnabled()) { this.currentRuleSet.removeElementAt(j); j--; } } this.allRulesEnabled = true; } boolean applied = false; while (!this.stopping && (this.currentRuleSet.size() > 0) && !applied) { this.pauseRule = false; this.stoppingRule = false; if (!this.applyContinue) { int i = this.ran.nextInt(this.currentRuleSet.size()); this.currentRule = this.currentRuleSet.elementAt(i); } else this.applyContinue = false; if(!this.stoppingRule) { if (this.currentRule instanceof RuleScheme) { applied = apply((RuleScheme) this.currentRule); } else { applied = this.currentRule.canMatch(this.hostgraph, this.strategy) && apply(this.currentRule); } } else this.stoppingRule = false; if (this.pauseRule) return false; // System.out.println(currentRule.getName() + " \t applied: " // + applied); if (this.os != null) writeTransformProtocol(this.currentRule.getName() + " \t applied: " + applied); if (!applied) { if (this.os != null) writeTransformProtocol(getErrorMsg()); this.currentRuleSet.remove(this.currentRule); if (this.os != null) writeTransformProtocol(getRuleNames(this.currentRuleSet)); } else { System.out.println(this.currentRule.getName() + " \t applied"); this.doneSteps++; this.appliedOnce = true; if (!isGraphConsistent()) this.stopping = true; } } return applied; } public void transform(List<Rule> ruleSet) { this.allRulesEnabled = true; boolean applicable = true; while (!this.stopping && applicable) { if (this.os != null) { String ss = getRuleNames(ruleSet); writeTransformProtocol(ss); } this.currentRuleSet = new Vector<Rule>(ruleSet); applicable = apply(); if(this.pauseRule) return; if(this.waitAfterStep) return; } } public void setMaxOfCounter(int nb) { this.counterMax = nb; } public void transformByCounter(List<Rule> ruleSet) { this.allRulesEnabled = true; boolean applicable = true; for (int i = 1; i<=this.counterMax && applicable; i++) { if (this.os != null) { String ss = getRuleNames(ruleSet); writeTransformProtocol(ss); } this.currentRuleSet = new Vector<Rule>(ruleSet); long t0 = System.currentTimeMillis(); applicable = apply(); System.out.println(i+") Time: " +(System.currentTimeMillis()-t0) + "ms " +Runtime.getRuntime().freeMemory() + "b" +" nodes ("+this.hostgraph.getNodesCount()+")" +" edges ("+this.hostgraph.getArcsCount()+")" ); // if(pauseRule) return; // // if(waitAfterStep) return; } } public void transformContinue() { this.applyContinue = true; this.pauseRule = false; transform(this.currentRuleSet); // if(pauseRule) return; // if(!stopping && waitAfterStep) return; } public void transformContinueWithNextStep() { this.pauseRule = false; transform(this.currentRuleSet); // if(pauseRule) return; // if(!stopping && waitAfterStep) return; // writeTransformProtocol("\nGraph transformation is finished"); // fireGraTra(new GraTraEvent(this,GraTraEvent.TRANSFORM_FINISHED)); // closeTransformProtocol(); } public void transform() { this.stopping = false; if(!this.grammar.getListOfRules().isEmpty() && this.currentRuleSet.isEmpty()) setRuleSet(); if (this.writeLogFile) { String dirName = this.grammar.getDirName(); String fileName = this.grammar.getFileName(); if ((fileName == null) || fileName.equals("")) fileName = this.grammar.getName(); openTransformProtocol(dirName, fileName); String version = "Version: AGG " + Version.getID() + "\n"; writeTransformProtocol(version); String s0 = "Graph transformation of : " + this.grammar.getName(); String s1 = "on graph : " + this.grammar.getGraph().getName(); String s2 = getRuleNames(this.currentRuleSet); writeTransformProtocol(s0); writeTransformProtocol(s1); writeTransformProtocol(s2); writeTransformProtocol("\n"); } // first check the rules, the graph if (!this.grammarChecked) { Pair<Object, String> pair = this.grammar.isReadyToTransform(true); if (pair != null) { Object test = pair.first; if (test != null) { String s0 = pair.second + "\nTransformation is stopped."; if (test instanceof Type) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.ATTR_TYPE_FAILED, s0)); else if (test instanceof Rule) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.RULE_FAILED, s0)); else if (test instanceof AtomConstraint) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.ATOMIC_GC_FAILED, s0)); transformFailed(s0); return; } } else if (!this.grammar.isGraphReadyForTransform()) { String s0 = "Graph of the grammar isn't fine." + "\nPlease check attribute settings of the objects. \nTransformation is stopped."; ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.GRAPH_FAILED, s0)); transformFailed(s0); return; } else if (!this.checkGraphConsistency()) { String s = "Graph consistency failed." + "\nPlease check the host graph against the graph constraints." + "\nTransformation is stopped."; ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.GRAPH_FAILED, s)); transformFailed(s); return; } this.grammarChecked = true; } Vector<Rule> ruleSet = getEnabledRules(this.currentRuleSet); // set start time long startTime = System.currentTimeMillis(); if (this.counterMax == 0) transform(ruleSet); else this.transformByCounter(ruleSet); // stop end time System.out.println("Used time for graph transformation: " + (System.currentTimeMillis()-startTime) + "ms"); if (this.options.hasOption(GraTraOptions.CONSISTENCY_CHECK_AFTER_GRAPH_TRAFO)) { this.checkGraphConsistency(); } if (this.writeLogFile) { writeTransformProtocol("\nUsed time for graph transformation: " + (System.currentTimeMillis()-startTime) + "ms"); writeTransformProtocol("\nGraph transformation finished"); closeTransformProtocol(); } fireGraTra(new GraTraEvent(this, GraTraEvent.TRANSFORM_FINISHED, this.errorMsg)); } private Vector<Rule> getEnabledRules(Vector<Rule> ruleSet) { Vector<Rule> vec = new Vector<Rule>(ruleSet.size()); for (int j = 0; j < ruleSet.size(); j++) { if (ruleSet.elementAt(j).isEnabled()) vec.add(ruleSet.elementAt(j)); } return vec; } private void transformFailed(String text) { System.out.println(text); writeTransformProtocol(text); writeTransformProtocol("\nGraph transformation failed"); // fireGraTra(new GraTraEvent(this,GraTraEvent.TRANSFORM_FAILED, // errorMsg)); fireGraTra(new GraTraEvent(this, GraTraEvent.TRANSFORM_FINISHED, this.errorMsg)); closeTransformProtocol(); } public boolean transformationDone() { return this.appliedOnce; } public String getProtocolName() { return this.protocolFileName; } private String getRuleNames(List<Rule> rules) { String names = "[ "; for (int j = 0; j < rules.size(); j++) { Rule r = rules.get(j); names = names + r.getName() + " "; } names = names + "]"; return names; } private void openTransformProtocol(String dirName, String fileName) { String dName = dirName; String fName = "DefaultGraTra.log"; // System.out.println("DefaultGraTraImpl.openTransformProtocol: dirName: // "+dirName); // System.out.println("DefaultGraTraImpl.openTransformProtocol: // fileName: "+fileName); if ((fileName != null) && !fileName.equals("")) { if (fileName.endsWith(".ggx")) fName = fileName.substring(0, fileName.length() - 4) + "_GraTra.log"; else fName = fileName + "_GraTra.log"; } // System.out.println(fName); if ((dName != null) && !dName.equals("")) { this.f = new File(dName); if (this.f.exists()) { if (this.f.isFile()) { if (this.f.getParent() != null) dName = this.f.getParent() + File.separator; else dName = "." + File.separator; } else if (this.f.isDirectory()) { // System.out.println(dirName); dName = this.f.getPath() + File.separator; } else dName = "." + File.separator; } else dName = "." + File.separator; this.f = new File(dirName + fName); } else this.f = new File(fName); try { this.os = new FileOutputStream(this.f); this.protocolFileName = this.f.getName(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } writeTransformProtocol((new Date()).toString()); } private void writeTransformProtocol(String s) { if (this.os == null) return; try { if (!s.equals("\n")) this.os.write(s.getBytes()); this.os.write('\n'); } catch (IOException ex) { ex.printStackTrace(); } } private void closeTransformProtocol() { if (this.os == null) return; try { this.os.close(); } catch (IOException ex) { ex.printStackTrace(); } } }