|
From: <tr...@us...> - 2003-06-27 00:15:10
|
Update of /cvsroot/babeldoc/babeldoc/support/src/com/babeldoc/bootstrap/ant
In directory sc8-pr-cvs1:/tmp/cvs-serv19206/support/src/com/babeldoc/bootstrap/ant
Modified Files:
ModuleFinder.java
Log Message:
Updated the build system using an explicit modular ant task. This is better than the method previously employed which added "hidden" tasks to the build and clean etc targets. Additionally using a more robust module sorting algorithm.
Index: ModuleFinder.java
===================================================================
RCS file: /cvsroot/babeldoc/babeldoc/support/src/com/babeldoc/bootstrap/ant/ModuleFinder.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** ModuleFinder.java 24 Jun 2003 03:27:13 -0000 1.5
--- ModuleFinder.java 27 Jun 2003 00:14:56 -0000 1.6
***************
*** 46,49 ****
--- 46,53 ----
public static final String DEPENDS = "Depends";
+ private static final String CORE = "core";
+ private static final String VISITING = "VISITING";
+ private static final String VISITED = "VISITED";
+
private String moduleSearchPath = "";
private String modulesProperty = "";
***************
*** 92,117 ****
public void execute() throws BuildException {
try {
! if(moduleSearchPath==null) {
throw new BuildException("Must provide 'moduleSearchPath'");
! } else if(modulesProperty==null) {
throw new BuildException("Must provide 'modulesProperty'");
} else {
Map moduleMap = new HashMap();
! for(StringTokenizer st = new StringTokenizer(moduleSearchPath);st.hasMoreTokens();) {
String part = st.nextToken();
- // System.out.println("doing module directory: "+part);
File file = new File(part);
discoverModulesInPath(moduleMap, file);
}
! if(moduleMap.size() == 0) {
throw new BuildException("No moduleMap found!");
} else {
! BabeldocBuildModule [] modules = getSortedModules(moduleMap);
StringBuffer buffer = new StringBuffer();
boolean first = true;
! for(int i = 0; i < modules.length; ++i) {
String part = modules[i].path;
! if(first) {
first = false;
} else {
--- 96,120 ----
public void execute() throws BuildException {
try {
! if (moduleSearchPath == null) {
throw new BuildException("Must provide 'moduleSearchPath'");
! } else if (modulesProperty == null) {
throw new BuildException("Must provide 'modulesProperty'");
} else {
Map moduleMap = new HashMap();
! for (StringTokenizer st = new StringTokenizer(moduleSearchPath); st.hasMoreTokens();) {
String part = st.nextToken();
File file = new File(part);
discoverModulesInPath(moduleMap, file);
}
! if (moduleMap.size() == 0) {
throw new BuildException("No moduleMap found!");
} else {
! BabeldocBuildModule[] modules = getSortedModules(moduleMap);
StringBuffer buffer = new StringBuffer();
boolean first = true;
! for (int i = 0; i < modules.length; ++i) {
String part = modules[i].path;
! if (first) {
first = false;
} else {
***************
*** 123,141 ****
// Now handle the subdirectories.
! if(subdirectories!=null) {
! for(StringTokenizer st2 = new StringTokenizer(subdirectories); st2.hasMoreTokens();) {
buffer = new StringBuffer();
String dir = st2.nextToken();
first = true;
! for(int i = 0; i < modules.length; ++i) {
String part = modules[i].path;
! if(first) {
first = false;
} else {
buffer.append(File.pathSeparator);
}
! buffer.append(part+File.separatorChar+dir);
}
! String property = modulesProperty+"_"+dir;
project.setNewProperty(property, buffer.toString());
}
--- 126,144 ----
// Now handle the subdirectories.
! if (subdirectories != null) {
! for (StringTokenizer st2 = new StringTokenizer(subdirectories); st2.hasMoreTokens();) {
buffer = new StringBuffer();
String dir = st2.nextToken();
first = true;
! for (int i = 0; i < modules.length; ++i) {
String part = modules[i].path;
! if (first) {
first = false;
} else {
buffer.append(File.pathSeparator);
}
! buffer.append(part + File.separatorChar + dir);
}
! String property = modulesProperty + "_" + dir;
project.setNewProperty(property, buffer.toString());
}
***************
*** 150,153 ****
--- 153,169 ----
}
+ 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));
+ }
+
/**
* Get an array of sorted modules. The first element in the array should be be
***************
*** 156,201 ****
* @return array of modules, sorted from least dependant to most.
*/
! private BabeldocBuildModule[] getSortedModules(Map moduleMap) {
! BabeldocBuildModule [] modules = new BabeldocBuildModule[moduleMap.size()];
! moduleMap.values().toArray(modules);
! for(int i = 0; i<modules.length; ++i ) {
! for(int j = 0; j<modules.length; ++j) {
! if(i==j) {
! continue;
! }
! BabeldocBuildModule mod1 = modules[i];
! BabeldocBuildModule mod2 = modules[j];
! if(!dependsOn(moduleMap, mod1, mod2)) {
! BabeldocBuildModule tmp = modules[i];
! modules[i] = modules[j];
! modules[j] = tmp;
! }
}
}
! return modules;
}
/**
! * Returns true if mod1 depends on mod2. This is a fairly expensive operation.
*
! * @param mod1 the lefthand argument
! * @param mod2 the righthand argument
! * @return wether left argument depends on the right argment
*/
! private boolean dependsOn(Map moduleMap, BabeldocBuildModule mod1, BabeldocBuildModule mod2) {
! if(mod1.depends!=null) {
! for(int i = 0; i < mod1.depends.length; ++i) {
! String depName = mod1.depends[i];
! if(depName.equals(mod2.name)) {
! return true;
! } else {
! BabeldocBuildModule depMod = (BabeldocBuildModule)moduleMap.get(depName);
! return dependsOn(moduleMap, depMod, mod2);
}
}
}
! return false;
}
--- 172,260 ----
* @return array of modules, sorted from least dependant to most.
*/
! private BabeldocBuildModule[] getSortedModules(Map moduleMap)
! throws BuildException {
! Collection ret = new ArrayList();
! Map state = new HashMap();
! Stack visiting = new Stack();
! /** Handle the core module - always first in list */
! state.put(CORE, VISITED);
! ret.add(moduleMap.get(CORE));
! /** Now iterate over each of the modules, sorting as we go */
! for (Iterator en = moduleMap.keySet().iterator(); en.hasNext();) {
! String currModuleName = (String)en.next();
! String currModuleState = (String) state.get(currModuleName);
!
! if (currModuleState == null) {
! treeSort(currModuleName, moduleMap, state, visiting, ret);
! } else if (currModuleState == VISITING) {
! throw new RuntimeException("Unexpected node in visiting state: " + currModuleName);
}
}
!
! return (BabeldocBuildModule[])ret.toArray(new BabeldocBuildModule[0]);
}
/**
! * Sort the nodes from the root node. This is a topographical sort
*
! * @param root
! * @param moduleMap
! * @param state
! * @param visiting
! * @param ret
! * @throws BuildException
*/
! private final void treeSort(String root, Map moduleMap, Map state, Stack visiting,
! Collection ret)
! throws BuildException {
! state.put(root, VISITING);
! visiting.push(root);
!
! BabeldocBuildModule module = (BabeldocBuildModule) moduleMap.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));
! }
!
! if(module.depends!=null) {
! for (int i = 0; i < module.depends.length; i++) {
! String currModuleName = module.depends[i];
! String currModuleState = (String) state.get(currModuleName);
!
! if (currModuleState == null) {
! // Not been visited
! treeSort(currModuleName, moduleMap, state, visiting, ret);
! } else if (currModuleState == VISITING) {
! // Currently visiting this node, so have a cycle
! throw makeCircularException(currModuleName, 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.add(module);
}
***************
*** 209,221 ****
*/
private void discoverModulesInPath(Map modules, File file)
! throws Exception{
! if(file.isDirectory()) {
File[] files = file.listFiles();
! for(int i = 0; i < files.length; ++i) {
discoverModulesInPath(modules, files[i]);
}
} else {
! if(BUILD_PROPERTIES.equals(file.getName())) {
// System.out.println("Analyzing file: "+file.toString());
Properties properties = new Properties();
--- 268,280 ----
*/
private void discoverModulesInPath(Map modules, File file)
! throws Exception {
! if (file.isDirectory()) {
File[] files = file.listFiles();
! for (int i = 0; i < files.length; ++i) {
discoverModulesInPath(modules, files[i]);
}
} else {
! if (BUILD_PROPERTIES.equals(file.getName())) {
// System.out.println("Analyzing file: "+file.toString());
Properties properties = new Properties();
***************
*** 224,233 ****
fis = new FileInputStream(file);
properties.load(fis);
! } catch(Exception e) {
throw e;
} finally {
fis.close();
}
! if(properties.containsKey(MODULE)) {
BabeldocBuildModule buildModule = makeBuildModule(properties, file);
modules.put(buildModule.name, buildModule);
--- 283,292 ----
fis = new FileInputStream(file);
properties.load(fis);
! } catch (Exception e) {
throw e;
} finally {
fis.close();
}
! if (properties.containsKey(MODULE)) {
BabeldocBuildModule buildModule = makeBuildModule(properties, file);
modules.put(buildModule.name, buildModule);
***************
*** 252,261 ****
String dependsList = properties.getProperty(DEPENDS);
! if(dependsList!=null) {
StringTokenizer st = new StringTokenizer(dependsList, " ,");
int numDepends = st.countTokens();
! if(numDepends>0) {
buildModule.depends = new String[numDepends];
! for(int i = 0; i < numDepends; ++i) {
buildModule.depends[i] = st.nextToken();
}
--- 311,320 ----
String dependsList = properties.getProperty(DEPENDS);
! if (dependsList != null) {
StringTokenizer st = new StringTokenizer(dependsList, " ,");
int numDepends = st.countTokens();
! if (numDepends > 0) {
buildModule.depends = new String[numDepends];
! for (int i = 0; i < numDepends; ++i) {
buildModule.depends[i] = st.nextToken();
}
***************
*** 269,273 ****
class BabeldocBuildModule {
String name;
! String [] depends;
String path;
--- 328,332 ----
class BabeldocBuildModule {
String name;
! String[] depends;
String path;
***************
*** 278,283 ****
sb.append(path);
sb.append(", depends: ");
! if(depends!=null) {
! for(int i = 0; i < depends.length; ++i) {
sb.append(depends[i]);
sb.append(", ");
--- 337,342 ----
sb.append(path);
sb.append(", depends: ");
! if (depends != null) {
! for (int i = 0; i < depends.length; ++i) {
sb.append(depends[i]);
sb.append(", ");
|