1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.LinkedList ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.TreeMap ; 31 import org.apache.tools.ant.BuildException; 32 import org.apache.tools.ant.Task; 33 import org.apache.tools.ant.types.Path; 34 import org.w3c.dom.Document ; 35 import org.w3c.dom.Element ; 36 import org.xml.sax.InputSource ; 37 import org.xml.sax.SAXException ; 38 39 43 public class SortSuiteModules extends Task { 44 private boolean sortTests; 45 private Path unsortedModules; 46 50 public void setUnsortedModules(Path unsortedModules) { 51 this.unsortedModules = unsortedModules; 52 } 53 54 private String sortedModulesProperty; 55 58 public void setSortedModulesProperty(String sortedModulesProperty) { 59 this.sortedModulesProperty = sortedModulesProperty; 60 } 61 62 64 public boolean isSortTests() { 65 return sortTests; 66 } 67 68 70 public void setSortTests(boolean sortTests) { 71 this.sortTests = sortTests; 72 } 73 74 public SortSuiteModules() {} 75 76 public void execute() throws BuildException { 77 if (unsortedModules == null) { 78 throw new BuildException("Must set unsortedModules"); 79 } 80 if (sortedModulesProperty == null) { 81 throw new BuildException("Must set sortedModulesProperty"); 82 } 83 Map <String ,File > basedirsByCNB = new TreeMap <String ,File >(); 84 Map <String ,List <String >> buildDeps = new HashMap <String ,List <String >>(); 85 String [] pieces = unsortedModules.list(); 86 for (int i = 0; i < pieces.length; i++) { 87 File d = new File (pieces[i]); 88 File projectXml = new File (d, "nbproject" + File.separatorChar + "project.xml"); 89 if (!projectXml.isFile()) { 90 throw new BuildException("Cannot open " + projectXml, getLocation()); 91 } 92 Document doc; 93 try { 94 doc = XMLUtil.parse(new InputSource (projectXml.toURI().toString()), false, true, null, null); 95 } catch (IOException e) { 96 throw new BuildException("Error parsing " + projectXml + ": " + e, e, getLocation()); 97 } catch (SAXException e) { 98 throw new BuildException("Error parsing " + projectXml + ": " + e, e, getLocation()); 99 } 100 Element config = XMLUtil.findElement(doc.getDocumentElement(), "configuration", ParseProjectXml.PROJECT_NS); 101 if (config == null) { 102 throw new BuildException("Malformed project file " + projectXml, getLocation()); 103 } 104 Element data = ParseProjectXml.findNBMElement(config, "data"); 105 if (data == null) { 106 throw new BuildException("Malformed project file " + projectXml, getLocation()); 107 } 108 Element cnbEl = ParseProjectXml.findNBMElement(data, "code-name-base"); 109 if (cnbEl == null) { 110 throw new BuildException("Malformed project file " + projectXml, getLocation()); 111 } 112 String cnb = XMLUtil.findText(cnbEl); 113 basedirsByCNB.put(cnb, d); 114 List <String > deps = new LinkedList <String >(); 115 Element depsEl = ParseProjectXml.findNBMElement(data, "module-dependencies"); 116 if (depsEl == null) { 117 throw new BuildException("Malformed project file " + projectXml, getLocation()); 118 } 119 Iterator it = XMLUtil.findSubElements(depsEl).iterator(); 120 while (it.hasNext()) { 121 Element dep = (Element ) it.next(); 122 if (ParseProjectXml.findNBMElement(dep, "build-prerequisite") == null) { 123 continue; 124 } 125 Element cnbEl2 = ParseProjectXml.findNBMElement(dep, "code-name-base"); 126 if (cnbEl2 == null) { 127 throw new BuildException("Malformed project file " + projectXml, getLocation()); 128 } 129 String cnb2 = XMLUtil.findText(cnbEl2); 130 deps.add(cnb2); 131 } 132 buildDeps.put(cnb, deps); 133 134 if (isSortTests()) { 136 Element testDepsEl = ParseProjectXml.findNBMElement(data,"test-dependencies"); 137 if (testDepsEl != null) { 138 Iterator itTType = XMLUtil.findSubElements(testDepsEl).iterator(); 140 while (itTType.hasNext()) { 141 Iterator itt = XMLUtil.findSubElements((Element )itTType.next()).iterator(); 142 while (itt.hasNext()) { 143 Element dep = (Element ) itt.next(); 144 if (ParseProjectXml.findNBMElement(dep, "test") == null) { 145 continue; 146 } 147 Element cnbEl2 = ParseProjectXml.findNBMElement(dep, "code-name-base"); 148 if (cnbEl2 == null) { 149 throw new BuildException("No cobase found for test-dependency"); 150 } 151 String cnb2 = XMLUtil.findText(cnbEl2); 152 deps.add(cnb2); 153 } 154 } 155 } 156 } 157 } 158 for (List <String > deps: buildDeps.values()) { 159 deps.retainAll(basedirsByCNB.keySet()); 160 } 161 List <String > cnbs = new ArrayList <String >(); 163 List <String > cRev = new ArrayList <String >(basedirsByCNB.keySet()); 164 Map <String ,Boolean > finished = new HashMap <String ,Boolean >(); 165 for (String s: cRev) { 166 if (!visit(s, buildDeps, finished, cnbs)) { 167 throw new BuildException("Cycles detected in dependency graph, cannot sort", getLocation()); 168 } 169 } 170 StringBuffer path = new StringBuffer (); 171 for (String cnb: cnbs) { 172 assert basedirsByCNB.containsKey(cnb); 173 if (path.length() > 0) { 174 path.append(File.pathSeparatorChar); 175 } 176 path.append(basedirsByCNB.get(cnb).getAbsolutePath()); 177 } 178 getProject().setNewProperty(sortedModulesProperty, path.toString()); 179 } 180 181 private static <String> boolean visit(String node, Map <String ,List <String >> edges, Map <String ,Boolean > finished, List <String > r) { 182 Boolean b = finished.get(node); 183 if (b != null) { 184 return b.booleanValue(); 185 } 186 List <String > e = edges.get(node); 187 if (e != null) { 188 finished.put(node, Boolean.FALSE); 189 for (String s: e) { 190 if (!visit(s, edges, finished, r)) { 191 return false; 192 } 193 } 194 } 195 finished.put(node, Boolean.TRUE); 196 r.add(node); 197 return true; 198 } 199 200 } 201 | Popular Tags |