001: package org.ztemplates.render.script;
002:
003: import java.io.Serializable;
004: import java.util.ArrayList;
005: import java.util.List;
006: import java.util.Set;
007:
008: import org.jgrapht.alg.CycleDetector;
009: import org.jgrapht.graph.DefaultDirectedGraph;
010: import org.jgrapht.graph.DefaultEdge;
011: import org.jgrapht.traverse.TopologicalOrderIterator;
012: import org.ztemplates.render.ZCss;
013: import org.ztemplates.render.ZJavaScript;
014: import org.ztemplates.render.ZScript;
015:
016: public class ZScriptRepository implements Serializable {
017: private List<String> javaScriptSorted = new ArrayList<String>();
018:
019: private List<String> cssSorted = new ArrayList<String>();
020:
021: public ZScriptRepository(List<ZScript> scripts) throws Exception {
022: initJavaScript(scripts);
023: initCss(scripts);
024: }
025:
026: private void initJavaScript(List<ZScript> scripts) throws Exception {
027: DefaultDirectedGraph<String, DefaultEdge> jsGraph = new DefaultDirectedGraph<String, DefaultEdge>(
028: DefaultEdge.class);
029:
030: for (ZScript zs : scripts) {
031: for (ZJavaScript js : zs.javaScript()) {
032: jsGraph.addVertex(js.value());
033: }
034: }
035:
036: for (ZScript zs : scripts) {
037: String v1 = null;
038: for (ZJavaScript js : zs.javaScript()) {
039: if (v1 == null) {
040: v1 = js.value();
041: } else {
042: String v2 = js.value();
043: jsGraph.addEdge(v1, v2);
044: v1 = v2;
045: }
046: }
047: }
048:
049: CycleDetector<String, DefaultEdge> cycleDetector = new CycleDetector<String, DefaultEdge>(
050: jsGraph);
051: if (cycleDetector.detectCycles()) {
052: StringBuffer sb = new StringBuffer(
053: "@ZScript.javascript have cyclic dependencies: ");
054: Set<String> javaScriptCycles = cycleDetector.findCycles();
055: for (String js : javaScriptCycles) {
056: sb.append(js);
057: sb.append(" --- ");
058: }
059: throw new Exception(sb.toString());
060: }
061:
062: TopologicalOrderIterator<String, DefaultEdge> sortedIterator = new TopologicalOrderIterator<String, DefaultEdge>(
063: jsGraph);
064: while (sortedIterator.hasNext()) {
065: String js = sortedIterator.next();
066: javaScriptSorted.add(js);
067: }
068: }
069:
070: private void initCss(List<ZScript> scripts) throws Exception {
071: DefaultDirectedGraph<String, DefaultEdge> g = new DefaultDirectedGraph<String, DefaultEdge>(
072: DefaultEdge.class);
073:
074: for (ZScript zs : scripts) {
075: for (ZCss js : zs.css()) {
076: g.addVertex(js.value());
077: }
078: }
079:
080: for (ZScript zs : scripts) {
081: String v1 = null;
082: for (ZCss js : zs.css()) {
083: if (v1 == null) {
084: v1 = js.value();
085: } else {
086: String v2 = js.value();
087: g.addEdge(v1, v2);
088: v1 = v2;
089: }
090: }
091: }
092:
093: CycleDetector<String, DefaultEdge> cycleDetector = new CycleDetector<String, DefaultEdge>(
094: g);
095: if (cycleDetector.detectCycles()) {
096: StringBuffer sb = new StringBuffer(
097: "@ZScript.css have cyclic dependencies: ");
098: Set<String> javaScriptCycles = cycleDetector.findCycles();
099: for (String js : javaScriptCycles) {
100: sb.append(js);
101: sb.append(" --- ");
102: }
103: throw new Exception(sb.toString());
104: }
105:
106: TopologicalOrderIterator<String, DefaultEdge> sortedIterator = new TopologicalOrderIterator<String, DefaultEdge>(
107: g);
108: while (sortedIterator.hasNext()) {
109: String js = sortedIterator.next();
110: cssSorted.add(js);
111: }
112: }
113:
114: public List<String> getJavaScriptSorted() {
115: return javaScriptSorted;
116: }
117:
118: public List<String> getCssSorted() {
119: return cssSorted;
120: }
121: }
|