1 5 package xdoclet.ant.modulesbuilder; 6 7 import java.io.File ; 8 import java.io.FileInputStream ; 9 import java.io.FileNotFoundException ; 10 import java.io.IOException ; 11 import java.util.*; 12 13 import org.apache.tools.ant.BuildException; 14 import org.apache.tools.ant.Project; 15 import org.apache.tools.ant.Task; 16 import org.apache.tools.ant.taskdefs.Execute; 17 import org.apache.tools.ant.taskdefs.LogStreamHandler; 18 import org.apache.tools.ant.types.CommandlineJava; 19 import org.apache.tools.ant.types.DTDLocation; 20 import org.apache.tools.ant.types.Environment; 21 import org.apache.tools.ant.types.Path; 22 import org.apache.tools.ant.types.XMLCatalog; 23 24 33 public class ModulesGrandBuilderTask extends Task 34 { 35 38 private final static String VISITING = "VISITING"; 39 42 private final static String VISITED = "VISITED"; 43 44 private static ModuleXmlParser parser = new ModuleXmlParser(); 45 46 private String target = null; 47 48 51 private XMLCatalog xmlCatalog = new XMLCatalog(); 52 53 private static boolean isModule(File file) 54 { 55 File module_build_xml = new File (file, "build.xml"); 56 57 return (!file.getName().equalsIgnoreCase("build")) && (!file.getName().equalsIgnoreCase("cvs")) && module_build_xml.exists(); 58 } 59 60 private static BuildException makeCircularException(String end, Stack stk) 61 { 62 StringBuffer sb = new StringBuffer ("Circular dependency: "); 63 64 sb.append(end); 65 66 String c; 67 68 do { 69 c = (String ) stk.pop(); 70 sb.append(" <- "); 71 sb.append(c); 72 } while (!c.equals(end)); 73 74 return new BuildException(new String (sb)); 75 } 76 77 82 public void setTarget(String target) 83 { 84 this.target = target; 85 } 86 87 public final Vector topoSort(String root, Hashtable modules) throws BuildException 88 { 89 Vector ret = new Vector(); 90 Hashtable state = new Hashtable(); 91 Stack visiting = new Stack(); 92 93 tsort(root, modules, state, visiting, ret); 101 102 for (Enumeration en = modules.keys(); en.hasMoreElements(); ) { 103 String cur_module = (String ) en.nextElement(); 104 String st = (String ) state.get(cur_module); 105 106 if (st == null) { 107 tsort(cur_module, modules, state, visiting, ret); 108 } 109 else if (st.equals(VISITING)) { 110 throw new RuntimeException ("Unexpected node in visiting state: " + cur_module); 111 } 112 } 113 114 return ret; 115 } 116 117 122 public void addConfiguredXMLCatalog(XMLCatalog catalog) 123 { 124 xmlCatalog.addConfiguredXMLCatalog(catalog); 125 } 126 127 133 public DTDLocation createDTD() 134 { 135 DTDLocation dtdLocation = new DTDLocation(); 136 137 xmlCatalog.addDTD(dtdLocation); 138 return dtdLocation; 139 } 140 141 146 public void init() throws BuildException 147 { 148 super.init(); 149 xmlCatalog.setProject(project); 150 } 151 152 public void execute() throws BuildException 153 { 154 File base_dir = this.getProject().getBaseDir(); 155 File [] files = base_dir.listFiles(); 156 Hashtable modules = new Hashtable(); 157 158 parser.setEntityResolver(xmlCatalog); 159 160 for (int i = 0; i < files.length; i++) { 161 File file = files[i]; 162 163 if (file.isDirectory() && isModule(file)) { 164 Module module = createModule(file); 165 166 modules.put(module.getName(), module); 167 } 168 } 169 170 for (Enumeration en = modules.elements(); en.hasMoreElements(); ) { 172 Module module = (Module) en.nextElement(); 173 Vector sorted_modules = topoSort(module.getName(), modules); 174 175 int curidx = 0; 176 Module cur_module; 177 178 do { 179 cur_module = (Module) sorted_modules.elementAt(curidx++); 180 181 if (cur_module.isExecuted() == false) { 182 executeModule(cur_module); 183 cur_module.setExecuted(true); 184 } 185 } while (!cur_module.getName().equals(module.getName())); 186 } 187 } 188 189 198 private final void tsort(String root, Hashtable targets, Hashtable state, Stack visiting, Vector ret) throws BuildException 199 { 200 state.put(root, VISITING); 201 visiting.push(root); 202 203 Module module = (Module) targets.get(root); 204 205 if (module == null) { 207 StringBuffer sb = new StringBuffer ("Module `"); 208 209 sb.append(root); 210 sb.append("' does not exist. "); 211 212 visiting.pop(); 213 if (!visiting.empty()) { 214 String parent = (String ) visiting.peek(); 215 216 sb.append("It is used from module `"); 217 sb.append(parent); 218 sb.append("'."); 219 } 220 221 throw new BuildException(new String (sb)); 222 } 223 224 for (Enumeration en = module.getDependencies(); en.hasMoreElements(); ) { 225 String cur = (String ) en.nextElement(); 226 String m = (String ) state.get(cur); 227 228 if (m == null) { 229 tsort(cur, targets, state, visiting, ret); 231 } 232 else if (m.equals(VISITING)) { 233 throw makeCircularException(cur, visiting); 235 } 236 } 237 238 String p = (String ) visiting.pop(); 239 240 if (!root.equals(p)) { 241 throw new RuntimeException ("Unexpected internal error: expected to " + "pop " + root + " but got " + p); 242 } 243 244 state.put(root, VISITED); 245 ret.addElement(module); 246 } 247 248 private void executeModule(Module module) 249 { 250 Execute exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), null); 251 252 exe.setAntRun(project); 253 exe.setWorkingDirectory(module.getBaseDir()); 254 255 CommandlineJava cmdl = new CommandlineJava(); 256 257 Environment.Variable ant_home = new Environment.Variable(); 258 259 String env_ant_home = project.getProperty("env.ANT_HOME"); 261 262 if (env_ant_home != null) { 263 ant_home.setKey("ant.home"); 264 ant_home.setValue(env_ant_home); 265 cmdl.addSysproperty(ant_home); 266 } 267 268 Path classpath = cmdl.createClasspath(project); 269 270 classpath.setPath(System.getProperty("java.class.path")); 271 272 cmdl.setClassname("org.apache.tools.ant.Main"); 274 275 if (target != null) { 277 cmdl.createArgument().setValue(target); 278 } 279 280 Hashtable props = getProject().getProperties(); 282 Enumeration prop_keys = props.keys(); 283 284 while (prop_keys.hasMoreElements()) { 285 String arg = prop_keys.nextElement().toString(); 286 287 if (argumentShouldntBePassedOn(arg)) 288 continue; 289 290 String value = props.get(arg).toString(); 291 292 if (value == null || value.indexOf(" ") == -1) { 295 cmdl.createArgument().setValue("-D" + arg + "=" + value); 296 } 297 299 } 300 301 exe.setCommandline(cmdl.getCommandline()); 302 303 try { 304 int exit = exe.execute(); 305 306 if (exe.killedProcess()) { 307 log("Timeout: killed the sub-process", Project.MSG_WARN); 308 } 309 if (exit != 0) { 310 throw new BuildException("" + exit, location); 311 } 312 } 313 catch (IOException e) { 314 e.printStackTrace(); 315 throw new BuildException(e, location); 316 } 317 } 318 319 private boolean argumentShouldntBePassedOn(String arg) 320 { 321 return "basedir".equals(arg) || "ant.file".equals(arg) || arg.startsWith("java.") || arg.startsWith("sun."); 322 } 323 324 private Module createModule(File file) 325 { 326 File module_xml = new File (file, "module.xml"); 328 Module module = null; 329 330 if (module_xml.exists()) { 331 try { 332 FileInputStream module_xml_in = new FileInputStream (module_xml); 333 334 module = parser.parse(module_xml_in); 335 } 336 catch (FileNotFoundException e) { 337 e.printStackTrace(); 338 } 339 } 340 else { 341 module = new Module(); 342 } 343 344 module.setName(file.getName()); 345 module.setBaseDir(file); 346 347 return module; 348 } 349 350 } 351 | Popular Tags |