User: ara_e_w Date: 02/06/10 12:56:58 Added: core/src/xdoclet/ant/modulesbuilder Module.java ModulesGrandBuilderTask.java ModuleXmlParser.java Log: modules grand builder implemented and used. It builds all modules based on each module's dependency to other modules. Revision Changes Path 1.1 xdoclet/core/src/xdoclet/ant/modulesbuilder/Module.java Index: Module.java =================================================================== /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.ant.modulesbuilder; import java.io.File; import java.util.Enumeration; import java.util.Vector; /** * Holds information related to a module. * * @author Ara Abrahamian ([EMAIL PROTECTED]) * @created Jun 9, 2002 * @version $Revision: 1.1 $ */ final class Module { private Vector dependencies = new Vector(); private String name; private boolean executed; private File baseDir; /** * Returns an enumeration of the dependencies of this target. * * @return an enumeration of the dependencies of this target */ public Enumeration getDependencies() { return dependencies.elements(); } /** * Returns the name of this module. * * @return the name of this module, or <code>null</code> if the name has not been set yet. */ public String getName() { return name; } public boolean isExecuted() { return executed; } public File getBaseDir() { return baseDir; } /** * Sets the name of this module. * * @param name The name of this module. Should not be <code>null</code>. */ public void setName(String name) { this.name = name; } public void setExecuted(boolean executed) { this.executed = executed; } public void setBaseDir(File baseDir) { this.baseDir = baseDir; } /** * Adds a dependency to this target. * * @param dependency The name of a target this target is dependent on. Must not be <code>null</code>. */ public void addDependency(String dependency) { dependencies.addElement(dependency); } } 1.1 xdoclet/core/src/xdoclet/ant/modulesbuilder/ModulesGrandBuilderTask.java Index: ModulesGrandBuilderTask.java =================================================================== /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.ant.modulesbuilder; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.*; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.Ant; import xdoclet.ant.modulesbuilder.Module; /** * Loops over all modules and builds each one. It builds modules the module depends on first. The module dependency is * specified in a module.xml file in the root of each module. It's based on Ant's dependency checking code. Refer to * that code for more details. * * @author Ara Abrahamian ([EMAIL PROTECTED]) * @created Jun 9, 2002 * @version $Revision: 1.1 $ */ public class ModulesGrandBuilderTask extends Task { /** * Constant for the "visiting" state, used when traversing a DFS of target dependencies. */ private final static String VISITING = "VISITING"; /** * Constant for the "visited" state, used when traversing a DFS of target dependencies. */ private final static String VISITED = "VISITED"; private static ModuleXmlParser parser = new ModuleXmlParser(); private static BuildException makeCircularException(String end, Stack stk) { StringBuffer sb = new StringBuffer("Circular dependency: "); sb.append(end); String c; do { c = (String) stk.pop(); sb.append(" <- "); sb.append(c); } while (!c.equals(end)); return new BuildException(new String(sb)); } public final Vector topoSort(String root, Hashtable modules) throws BuildException { Vector ret = new Vector(); Hashtable state = new Hashtable(); Stack visiting = new Stack(); // We first run a DFS based sort using the root as the starting node. // This creates the minimum sequence of Modules to the root node. // We then do a sort on any remaining unVISITED modules. // This is unnecessary for doing our build, but it catches // circular dependencies or missing Modules on the entire // dependency tree, not just on the Modules that depend on the // build Module. tsort(root, modules, state, visiting, ret); for (Enumeration en = modules.keys(); en.hasMoreElements(); ) { String cur_module = (String) en.nextElement(); String st = (String) state.get(cur_module); if (st == null) { tsort(cur_module, modules, state, visiting, ret); } else if (st == VISITING) { throw new RuntimeException("Unexpected node in visiting state: " + cur_module); } } return ret; } public void execute() throws BuildException { File base_dir = this.getProject().getBaseDir(); File[] files = base_dir.listFiles(); Hashtable modules = new Hashtable(); for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isDirectory() && isModule(file)) { Module module = createModule(file); modules.put(module.getName(), module); } } //for all modules, one by one, execute each one, but first sort the list based on dependency path of each module for (Enumeration enum = modules.elements(); enum.hasMoreElements(); ) { Module module = (Module) enum.nextElement(); Vector sorted_modules = topoSort(module.getName(), modules); int curidx = 0; Module cur_module; do { cur_module = (Module) sorted_modules.elementAt(curidx++); if (cur_module.isExecuted() == false) { executeModule(cur_module); cur_module.setExecuted(true); } } while (!cur_module.getName().equals(module.getName())); } } private boolean isModule(File file) { return (!file.getName().equalsIgnoreCase("build")) && (!file.getName().equalsIgnoreCase("cvs")); } private final void tsort(String root, Hashtable targets, Hashtable state, Stack visiting, Vector ret) throws BuildException { state.put(root, VISITING); visiting.push(root); Module module = (Module) targets.get(root); // Make sure we exist if (module == null) { StringBuffer sb = new StringBuffer("Module `"); sb.append(root); sb.append("' does not exist. "); visiting.pop(); if (!visiting.empty()) { String parent = (String) visiting.peek(); sb.append("It is used from module `"); sb.append(parent); sb.append("'."); } throw new BuildException(new String(sb)); } for (Enumeration en = module.getDependencies(); en.hasMoreElements(); ) { String cur = (String) en.nextElement(); String m = (String) state.get(cur); if (m == null) { // Not been visited tsort(cur, targets, state, visiting, ret); } else if (m == VISITING) { // Currently visiting this node, so have a cycle throw makeCircularException(cur, visiting); } } String p = (String) visiting.pop(); if (root != p) { throw new RuntimeException("Unexpected internal error: expected to " + "pop " + root + " but got " + p); } state.put(root, VISITED); ret.addElement(module); } private void executeModule(Module module) { Ant ant = (Ant) getProject().createTask("ant"); ant.setDir(module.getBaseDir()); ant.init(); ant.execute(); } private Module createModule(File file) { //load dependency info File module_xml = new File(file, "module.xml"); Module module = null; if (module_xml.exists()) { try { FileInputStream module_xml_in = new FileInputStream(module_xml); module = parser.parse(module_xml_in); } catch (FileNotFoundException e) { e.printStackTrace(); } } else { module = new Module(); } module.setName(file.getName()); module.setBaseDir(file); return module; } } 1.1 xdoclet/core/src/xdoclet/ant/modulesbuilder/ModuleXmlParser.java Index: ModuleXmlParser.java =================================================================== /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.ant.modulesbuilder; import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * Parses module.xml module descriptor file. * * @author Ara Abrahamian ([EMAIL PROTECTED]) * @created Jun 10, 2002 * @version $Revision: 1.1 $ */ class ModuleXmlParser extends DefaultHandler { private final SAXParserFactory _factory; private Module module; public ModuleXmlParser() { _factory = SAXParserFactory.newInstance(); _factory.setValidating(false); } public Module parse(InputStream in) { try { SAXParser parser = _factory.newSAXParser(); parser.parse(in, this); } catch (IOException e) { module = null; e.printStackTrace(); } catch (IllegalArgumentException e) { module = null; e.printStackTrace(); } catch (ParserConfigurationException e) { module = null; e.printStackTrace(); } catch (SAXException e) { module = null; e.printStackTrace(); } return module; } public void startDocument() { module = new Module(); } public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) { if (qName.equals("module-dependency")) { module.addDependency(attributes.getValue("module-name")); } } }
_______________________________________________________________ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas - http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink _______________________________________________ Xdoclet-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/xdoclet-devel