git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272497 13f79535-47bb-0310-9956-ffa450edef68master
@@ -82,7 +82,7 @@ import java.util.Enumeration; | |||||
public class Main { | public class Main { | ||||
/** The default build file name. */ | /** The default build file name. */ | ||||
public final static String DEFAULT_BUILD_FILENAME = "build.xml"; | |||||
public static final String DEFAULT_BUILD_FILENAME = "build.xml"; | |||||
/** Our current message output status. Follows Project.MSG_XXX. */ | /** Our current message output status. Follows Project.MSG_XXX. */ | ||||
private int msgOutputLevel = Project.MSG_INFO; | private int msgOutputLevel = Project.MSG_INFO; | ||||
@@ -91,10 +91,10 @@ public class Main { | |||||
private File buildFile; /* null */ | private File buildFile; /* null */ | ||||
/** Stream to use for logging. */ | /** Stream to use for logging. */ | ||||
private PrintStream out = System.out; | |||||
private static PrintStream out = System.out; | |||||
/** Stream that we are using for logging error messages. */ | /** Stream that we are using for logging error messages. */ | ||||
private PrintStream err = System.err; | |||||
private static PrintStream err = System.err; | |||||
/** The build targets. */ | /** The build targets. */ | ||||
private Vector targets = new Vector(5); | private Vector targets = new Vector(5); | ||||
@@ -104,13 +104,13 @@ public class Main { | |||||
/** Names of classes to add as listeners to project. */ | /** Names of classes to add as listeners to project. */ | ||||
private Vector listeners = new Vector(5); | private Vector listeners = new Vector(5); | ||||
/** File names of property files to load on startup. */ | /** File names of property files to load on startup. */ | ||||
private Vector propertyFiles = new Vector(5); | private Vector propertyFiles = new Vector(5); | ||||
/** | /** | ||||
* The Ant logger class. There may be only one logger. It will have | |||||
* the right to use the 'out' PrintStream. The class must implements the | |||||
* The Ant logger class. There may be only one logger. It will have | |||||
* the right to use the 'out' PrintStream. The class must implements the | |||||
* BuildLogger interface. | * BuildLogger interface. | ||||
*/ | */ | ||||
private String loggerClassname = null; | private String loggerClassname = null; | ||||
@@ -135,15 +135,21 @@ public class Main { | |||||
private boolean readyToRun = false; | private boolean readyToRun = false; | ||||
/** | /** | ||||
* Whether or not we should only parse and display the project help | |||||
* Whether or not we should only parse and display the project help | |||||
* information. | * information. | ||||
*/ | */ | ||||
private boolean projectHelp = false; | private boolean projectHelp = false; | ||||
/** | /** | ||||
* Prints the message of the Throwable if it (the message) is not | |||||
* Is a logfile being used? This is used to | |||||
* check if the output streams must be closed. | |||||
*/ | |||||
private static boolean isLogFileUsed = false; | |||||
/** | |||||
* Prints the message of the Throwable if it (the message) is not | |||||
* <code>null</code>. | * <code>null</code>. | ||||
* | |||||
* | |||||
* @param t Throwable to print the message of. | * @param t Throwable to print the message of. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
*/ | */ | ||||
@@ -158,12 +164,12 @@ public class Main { | |||||
* Creates a new instance of this class using the | * Creates a new instance of this class using the | ||||
* arguments specified, gives it any extra user properties which have been | * arguments specified, gives it any extra user properties which have been | ||||
* specified, and then runs the build using the classloader provided. | * specified, and then runs the build using the classloader provided. | ||||
* | |||||
* | |||||
* @param args Command line arguments. Must not be <code>null</code>. | * @param args Command line arguments. Must not be <code>null</code>. | ||||
* @param additionalUserProperties Any extra properties to use in this | |||||
* build. May be <code>null</code>, which is the equivalent to | |||||
* @param additionalUserProperties Any extra properties to use in this | |||||
* build. May be <code>null</code>, which is the equivalent to | |||||
* passing in an empty set of properties. | * passing in an empty set of properties. | ||||
* @param coreLoader Classloader used for core classes. May be | |||||
* @param coreLoader Classloader used for core classes. May be | |||||
* <code>null</code> in which case the system classloader is used. | * <code>null</code> in which case the system classloader is used. | ||||
*/ | */ | ||||
public static void start(String[] args, Properties additionalUserProperties, | public static void start(String[] args, Properties additionalUserProperties, | ||||
@@ -172,19 +178,20 @@ public class Main { | |||||
try { | try { | ||||
m = new Main(args); | m = new Main(args); | ||||
} catch(Throwable exc) { | |||||
} catch (Throwable exc) { | |||||
printMessage(exc); | printMessage(exc); | ||||
System.exit(1); | System.exit(1); | ||||
} | } | ||||
if (additionalUserProperties != null) { | if (additionalUserProperties != null) { | ||||
for (Enumeration e = additionalUserProperties.keys(); e.hasMoreElements(); ) { | |||||
for (Enumeration e = additionalUserProperties.keys(); | |||||
e.hasMoreElements();) { | |||||
String key = (String) e.nextElement(); | String key = (String) e.nextElement(); | ||||
String property = additionalUserProperties.getProperty(key); | String property = additionalUserProperties.getProperty(key); | ||||
m.definedProps.put(key, property); | m.definedProps.put(key, property); | ||||
} | } | ||||
} | } | ||||
try { | try { | ||||
m.runBuild(coreLoader); | m.runBuild(coreLoader); | ||||
System.exit(0); | System.exit(0); | ||||
@@ -193,13 +200,30 @@ public class Main { | |||||
printMessage(be); | printMessage(be); | ||||
} | } | ||||
System.exit(1); | System.exit(1); | ||||
} catch(Throwable exc) { | |||||
} catch (Throwable exc) { | |||||
exc.printStackTrace(); | exc.printStackTrace(); | ||||
printMessage(exc); | printMessage(exc); | ||||
System.exit(1); | System.exit(1); | ||||
} finally { | |||||
if (isLogFileUsed) { | |||||
if (out != null) { | |||||
try { | |||||
out.close(); | |||||
} catch (final Exception e) { | |||||
//ignore | |||||
} | |||||
} | |||||
if (err != null) { | |||||
try { | |||||
err.close(); | |||||
} catch (final Exception e) { | |||||
//ignore | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Command line entry point. This method kicks off the building | * Command line entry point. This method kicks off the building | ||||
* of a project object and executes a build using either a given | * of a project object and executes a build using either a given | ||||
@@ -216,11 +240,11 @@ public class Main { | |||||
// BuildException is thrown. What's the rationale for when to do | // BuildException is thrown. What's the rationale for when to do | ||||
// what? | // what? | ||||
/** | /** | ||||
* Sole constructor, which parses and deals with command line | |||||
* Sole constructor, which parses and deals with command line | |||||
* arguments. | * arguments. | ||||
* | |||||
* | |||||
* @param args Command line arguments. Must not be <code>null</code>. | * @param args Command line arguments. Must not be <code>null</code>. | ||||
* | |||||
* | |||||
* @exception BuildException if the specified build file doesn't exist | * @exception BuildException if the specified build file doesn't exist | ||||
* or is a directory. | * or is a directory. | ||||
*/ | */ | ||||
@@ -249,15 +273,17 @@ public class Main { | |||||
msgOutputLevel = Project.MSG_DEBUG; | msgOutputLevel = Project.MSG_DEBUG; | ||||
} else if (arg.equals("-logfile") || arg.equals("-l")) { | } else if (arg.equals("-logfile") || arg.equals("-l")) { | ||||
try { | try { | ||||
File logFile = new File(args[i+1]); | |||||
File logFile = new File(args[i + 1]); | |||||
i++; | i++; | ||||
out = new PrintStream(new FileOutputStream(logFile)); | out = new PrintStream(new FileOutputStream(logFile)); | ||||
err = out; | err = out; | ||||
System.setOut(out); | System.setOut(out); | ||||
System.setErr(out); | System.setErr(out); | ||||
isLogFileUsed = true; | |||||
} catch (IOException ioe) { | } catch (IOException ioe) { | ||||
String msg = "Cannot write on the specified log file. " + | |||||
"Make sure the path exists and you have write permissions."; | |||||
String msg = "Cannot write on the specified log file. " | |||||
+ "Make sure the path exists and you have write " | |||||
+ "permissions."; | |||||
System.out.println(msg); | System.out.println(msg); | ||||
return; | return; | ||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | } catch (ArrayIndexOutOfBoundsException aioobe) { | ||||
@@ -266,9 +292,10 @@ public class Main { | |||||
System.out.println(msg); | System.out.println(msg); | ||||
return; | return; | ||||
} | } | ||||
} else if (arg.equals("-buildfile") || arg.equals("-file") || arg.equals("-f")) { | |||||
} else if (arg.equals("-buildfile") || arg.equals("-file") | |||||
|| arg.equals("-f")) { | |||||
try { | try { | ||||
buildFile = new File(args[i+1]); | |||||
buildFile = new File(args[i + 1]); | |||||
i++; | i++; | ||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | } catch (ArrayIndexOutOfBoundsException aioobe) { | ||||
String msg = "You must specify a buildfile when " + | String msg = "You must specify a buildfile when " + | ||||
@@ -278,7 +305,7 @@ public class Main { | |||||
} | } | ||||
} else if (arg.equals("-listener")) { | } else if (arg.equals("-listener")) { | ||||
try { | try { | ||||
listeners.addElement(args[i+1]); | |||||
listeners.addElement(args[i + 1]); | |||||
i++; | i++; | ||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | } catch (ArrayIndexOutOfBoundsException aioobe) { | ||||
String msg = "You must specify a classname when " + | String msg = "You must specify a classname when " + | ||||
@@ -303,35 +330,35 @@ public class Main { | |||||
String value = null; | String value = null; | ||||
int posEq = name.indexOf("="); | int posEq = name.indexOf("="); | ||||
if (posEq > 0) { | if (posEq > 0) { | ||||
value = name.substring(posEq+1); | |||||
value = name.substring(posEq + 1); | |||||
name = name.substring(0, posEq); | name = name.substring(0, posEq); | ||||
} else if (i < args.length-1) { | |||||
} else if (i < args.length - 1) { | |||||
value = args[++i]; | value = args[++i]; | ||||
} | } | ||||
definedProps.put(name, value); | definedProps.put(name, value); | ||||
} else if (arg.equals("-logger")) { | } else if (arg.equals("-logger")) { | ||||
if (loggerClassname != null) { | if (loggerClassname != null) { | ||||
System.out.println("Only one logger class may be specified."); | |||||
System.out.println("Only one logger class may " | |||||
+ " be specified."); | |||||
return; | return; | ||||
} | } | ||||
try { | try { | ||||
loggerClassname = args[++i]; | loggerClassname = args[++i]; | ||||
} | |||||
catch (ArrayIndexOutOfBoundsException aioobe) { | |||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | |||||
System.out.println("You must specify a classname when " + | System.out.println("You must specify a classname when " + | ||||
"using the -logger argument"); | "using the -logger argument"); | ||||
return; | return; | ||||
} | } | ||||
} else if (arg.equals("-inputhandler")) { | } else if (arg.equals("-inputhandler")) { | ||||
if (inputHandlerClassname != null) { | if (inputHandlerClassname != null) { | ||||
System.out.println("Only one input handler class may be specified."); | |||||
System.out.println("Only one input handler class may " + | |||||
"be specified."); | |||||
return; | return; | ||||
} | } | ||||
try { | try { | ||||
inputHandlerClassname = args[++i]; | inputHandlerClassname = args[++i]; | ||||
} | |||||
catch (ArrayIndexOutOfBoundsException aioobe) { | |||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | |||||
System.out.println("You must specify a classname when " + | System.out.println("You must specify a classname when " + | ||||
"using the -inputhandler argument"); | "using the -inputhandler argument"); | ||||
return; | return; | ||||
@@ -343,14 +370,14 @@ public class Main { | |||||
projectHelp = true; | projectHelp = true; | ||||
} else if (arg.equals("-find")) { | } else if (arg.equals("-find")) { | ||||
// eat up next arg if present, default to build.xml | // eat up next arg if present, default to build.xml | ||||
if (i < args.length-1) { | |||||
if (i < args.length - 1) { | |||||
searchForThis = args[++i]; | searchForThis = args[++i]; | ||||
} else { | } else { | ||||
searchForThis = DEFAULT_BUILD_FILENAME; | searchForThis = DEFAULT_BUILD_FILENAME; | ||||
} | } | ||||
} else if (arg.startsWith("-propertyfile")) { | } else if (arg.startsWith("-propertyfile")) { | ||||
try { | try { | ||||
propertyFiles.addElement(args[i+1]); | |||||
propertyFiles.addElement(args[i + 1]); | |||||
i++; | i++; | ||||
} catch (ArrayIndexOutOfBoundsException aioobe) { | } catch (ArrayIndexOutOfBoundsException aioobe) { | ||||
String msg = "You must specify a property filename when " + | String msg = "You must specify a property filename when " + | ||||
@@ -369,12 +396,12 @@ public class Main { | |||||
targets.addElement(arg); | targets.addElement(arg); | ||||
} | } | ||||
} | } | ||||
// if buildFile was not specified on the command line, | // if buildFile was not specified on the command line, | ||||
if (buildFile == null) { | if (buildFile == null) { | ||||
// but -find then search for it | // but -find then search for it | ||||
if (searchForThis != null) { | if (searchForThis != null) { | ||||
buildFile = findBuildFile(System.getProperty("user.dir"), | |||||
buildFile = findBuildFile(System.getProperty("user.dir"), | |||||
searchForThis); | searchForThis); | ||||
} else { | } else { | ||||
buildFile = new File(DEFAULT_BUILD_FILENAME); | buildFile = new File(DEFAULT_BUILD_FILENAME); | ||||
@@ -396,17 +423,17 @@ public class Main { | |||||
} | } | ||||
// Load the property files specified by -propertyfile | // Load the property files specified by -propertyfile | ||||
for (int propertyFileIndex=0; | |||||
for (int propertyFileIndex = 0; | |||||
propertyFileIndex < propertyFiles.size(); | propertyFileIndex < propertyFiles.size(); | ||||
propertyFileIndex++) { | propertyFileIndex++) { | ||||
String filename = (String) propertyFiles.elementAt(propertyFileIndex); | |||||
String filename | |||||
= (String) propertyFiles.elementAt(propertyFileIndex); | |||||
Properties props = new Properties(); | Properties props = new Properties(); | ||||
FileInputStream fis = null; | FileInputStream fis = null; | ||||
try { | try { | ||||
fis = new FileInputStream(filename); | fis = new FileInputStream(filename); | ||||
props.load(fis); | props.load(fis); | ||||
} | |||||
catch (IOException e) { | |||||
} catch (IOException e) { | |||||
System.out.println("Could not load property file " | System.out.println("Could not load property file " | ||||
+ filename + ": " + e.getMessage()); | + filename + ": " + e.getMessage()); | ||||
} finally { | } finally { | ||||
@@ -417,7 +444,7 @@ public class Main { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
// ensure that -D properties take precedence | // ensure that -D properties take precedence | ||||
Enumeration propertyNames = props.propertyNames(); | Enumeration propertyNames = props.propertyNames(); | ||||
while (propertyNames.hasMoreElements()) { | while (propertyNames.hasMoreElements()) { | ||||
@@ -445,7 +472,7 @@ public class Main { | |||||
filename = file.getParent(); | filename = file.getParent(); | ||||
if (filename != null && msgOutputLevel >= Project.MSG_VERBOSE) { | if (filename != null && msgOutputLevel >= Project.MSG_VERBOSE) { | ||||
System.out.println("Searching in "+filename); | |||||
System.out.println("Searching in " + filename); | |||||
} | } | ||||
return (filename == null) ? null : new File(filename); | return (filename == null) ? null : new File(filename); | ||||
@@ -463,34 +490,35 @@ public class Main { | |||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* @param suffix Suffix filename to look for in parents. | * @param suffix Suffix filename to look for in parents. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* | |||||
* | |||||
* @return A handle to the build file if one is found | * @return A handle to the build file if one is found | ||||
* | * | ||||
* @exception BuildException if no build file is found | * @exception BuildException if no build file is found | ||||
*/ | */ | ||||
private File findBuildFile(String start, String suffix) throws BuildException { | |||||
private File findBuildFile(String start, String suffix) | |||||
throws BuildException { | |||||
if (msgOutputLevel >= Project.MSG_INFO) { | if (msgOutputLevel >= Project.MSG_INFO) { | ||||
System.out.println("Searching for " + suffix + " ..."); | System.out.println("Searching for " + suffix + " ..."); | ||||
} | } | ||||
File parent = new File(new File(start).getAbsolutePath()); | File parent = new File(new File(start).getAbsolutePath()); | ||||
File file = new File(parent, suffix); | File file = new File(parent, suffix); | ||||
// check if the target file exists in the current directory | // check if the target file exists in the current directory | ||||
while (!file.exists()) { | while (!file.exists()) { | ||||
// change to parent directory | // change to parent directory | ||||
parent = getParentFile(parent); | parent = getParentFile(parent); | ||||
// if parent is null, then we are at the root of the fs, | // if parent is null, then we are at the root of the fs, | ||||
// complain that we can't find the build file. | // complain that we can't find the build file. | ||||
if (parent == null) { | if (parent == null) { | ||||
throw new BuildException("Could not locate a build file!"); | throw new BuildException("Could not locate a build file!"); | ||||
} | } | ||||
// refresh our file handle | // refresh our file handle | ||||
file = new File(parent, suffix); | file = new File(parent, suffix); | ||||
} | } | ||||
return file; | return file; | ||||
} | } | ||||
@@ -498,11 +526,11 @@ public class Main { | |||||
* Executes the build. If the constructor for this instance failed | * Executes the build. If the constructor for this instance failed | ||||
* (e.g. returned after issuing a warning), this method returns | * (e.g. returned after issuing a warning), this method returns | ||||
* immediately. | * immediately. | ||||
* | |||||
* | |||||
* @param coreLoader The classloader to use to find core classes. | * @param coreLoader The classloader to use to find core classes. | ||||
* May be <code>null</code>, in which case the | * May be <code>null</code>, in which case the | ||||
* system classloader is used. | * system classloader is used. | ||||
* | |||||
* | |||||
* @exception BuildException if the build fails | * @exception BuildException if the build fails | ||||
*/ | */ | ||||
private void runBuild(ClassLoader coreLoader) throws BuildException { | private void runBuild(ClassLoader coreLoader) throws BuildException { | ||||
@@ -532,11 +560,11 @@ public class Main { | |||||
// use a system manager that prevents from System.exit() | // use a system manager that prevents from System.exit() | ||||
// only in JDK > 1.1 | // only in JDK > 1.1 | ||||
SecurityManager oldsm = null; | SecurityManager oldsm = null; | ||||
if ( !Project.JAVA_1_0.equals(Project.getJavaVersion()) && | |||||
!Project.JAVA_1_1.equals(Project.getJavaVersion()) ){ | |||||
if (!Project.JAVA_1_0.equals(Project.getJavaVersion()) && | |||||
!Project.JAVA_1_1.equals(Project.getJavaVersion())){ | |||||
oldsm = System.getSecurityManager(); | oldsm = System.getSecurityManager(); | ||||
//SecurityManager can not be installed here for backwards | |||||
//SecurityManager can not be installed here for backwards | |||||
//compatability reasons (PD). Needs to be loaded prior to | //compatability reasons (PD). Needs to be loaded prior to | ||||
//ant class if we are going to implement it. | //ant class if we are going to implement it. | ||||
//System.setSecurityManager(new NoExitSecurityManager()); | //System.setSecurityManager(new NoExitSecurityManager()); | ||||
@@ -554,17 +582,19 @@ public class Main { | |||||
// set user-define properties | // set user-define properties | ||||
Enumeration e = definedProps.keys(); | Enumeration e = definedProps.keys(); | ||||
while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
String arg = (String)e.nextElement(); | |||||
String value = (String)definedProps.get(arg); | |||||
String arg = (String) e.nextElement(); | |||||
String value = (String) definedProps.get(arg); | |||||
project.setUserProperty(arg, value); | project.setUserProperty(arg, value); | ||||
} | } | ||||
project.setUserProperty("ant.file" , buildFile.getAbsolutePath() ); | |||||
project.setUserProperty("ant.file", | |||||
buildFile.getAbsolutePath()); | |||||
// first use the ProjectHelper to create the project object | // first use the ProjectHelper to create the project object | ||||
// from the given build file. | // from the given build file. | ||||
String noParserMessage = | |||||
"No JAXP compliant XML parser found. Please visit http://xml.apache.org for a suitable parser"; | |||||
String noParserMessage = "No JAXP compliant XML parser found. " | |||||
+ "Please visit http://xml.apache.org " | |||||
+ "for a suitable parser"; | |||||
try { | try { | ||||
Class.forName("javax.xml.parsers.SAXParserFactory"); | Class.forName("javax.xml.parsers.SAXParserFactory"); | ||||
ProjectHelper.configureProject(project, buildFile); | ProjectHelper.configureProject(project, buildFile); | ||||
@@ -578,18 +608,17 @@ public class Main { | |||||
if (projectHelp) { | if (projectHelp) { | ||||
printDescription(project); | printDescription(project); | ||||
printTargets(project, msgOutputLevel > Project.MSG_INFO ); | |||||
printTargets(project, msgOutputLevel > Project.MSG_INFO); | |||||
return; | return; | ||||
} | } | ||||
// make sure that we have a target to execute | // make sure that we have a target to execute | ||||
if (targets.size() == 0) { | if (targets.size() == 0) { | ||||
targets.addElement(project.getDefaultTarget()); | targets.addElement(project.getDefaultTarget()); | ||||
} | } | ||||
project.executeTargets(targets); | project.executeTargets(targets); | ||||
} | |||||
finally { | |||||
} finally { | |||||
// put back the original security manager | // put back the original security manager | ||||
//The following will never eval to true. (PD) | //The following will never eval to true. (PD) | ||||
if (oldsm != null){ | if (oldsm != null){ | ||||
@@ -599,16 +628,13 @@ public class Main { | |||||
System.setOut(out); | System.setOut(out); | ||||
System.setErr(err); | System.setErr(err); | ||||
} | } | ||||
} | |||||
catch(RuntimeException exc) { | |||||
} catch (RuntimeException exc) { | |||||
error = exc; | error = exc; | ||||
throw exc; | throw exc; | ||||
} | |||||
catch(Error err) { | |||||
} catch (Error err) { | |||||
error = err; | error = err; | ||||
throw err; | throw err; | ||||
} | |||||
finally { | |||||
} finally { | |||||
if (!projectHelp) { | if (!projectHelp) { | ||||
project.fireBuildFinished(error); | project.fireBuildFinished(error); | ||||
} | } | ||||
@@ -618,7 +644,7 @@ public class Main { | |||||
/** | /** | ||||
* Adds the listeners specified in the command line arguments, | * Adds the listeners specified in the command line arguments, | ||||
* along with the default listener, to the specified project. | * along with the default listener, to the specified project. | ||||
* | |||||
* | |||||
* @param project The project to add listeners to. | * @param project The project to add listeners to. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
*/ | */ | ||||
@@ -633,9 +659,9 @@ public class Main { | |||||
BuildListener listener = | BuildListener listener = | ||||
(BuildListener) Class.forName(className).newInstance(); | (BuildListener) Class.forName(className).newInstance(); | ||||
project.addBuildListener(listener); | project.addBuildListener(listener); | ||||
} | |||||
catch(Throwable exc) { | |||||
throw new BuildException("Unable to instantiate listener " + className, exc); | |||||
} catch (Throwable exc) { | |||||
throw new BuildException("Unable to instantiate listener " | |||||
+ className, exc); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -654,48 +680,51 @@ public class Main { | |||||
handler = new DefaultInputHandler(); | handler = new DefaultInputHandler(); | ||||
} else { | } else { | ||||
try { | try { | ||||
handler = (InputHandler)(Class.forName(inputHandlerClassname).newInstance()); | |||||
} | |||||
catch (ClassCastException e) { | |||||
handler = (InputHandler) | |||||
(Class.forName(inputHandlerClassname).newInstance()); | |||||
} catch (ClassCastException e) { | |||||
String msg = "The specified input handler class " | String msg = "The specified input handler class " | ||||
+ inputHandlerClassname | + inputHandlerClassname | ||||
+ " does not implement the InputHandler interface"; | + " does not implement the InputHandler interface"; | ||||
throw new BuildException(msg); | throw new BuildException(msg); | ||||
} | } | ||||
catch (Exception e) { | catch (Exception e) { | ||||
String msg = "Unable to instantiate specified input handler class " | |||||
+ inputHandlerClassname + " : " + e.getClass().getName(); | |||||
String msg = "Unable to instantiate specified input handler " | |||||
+ "class " + inputHandlerClassname + " : " | |||||
+ e.getClass().getName(); | |||||
throw new BuildException(msg); | throw new BuildException(msg); | ||||
} | } | ||||
} | } | ||||
project.setInputHandler(handler); | project.setInputHandler(handler); | ||||
} | } | ||||
// XXX: (Jon Skeet) Any reason for writing a message and then using a bare | |||||
// XXX: (Jon Skeet) Any reason for writing a message and then using a bare | |||||
// RuntimeException rather than just using a BuildException here? Is it | // RuntimeException rather than just using a BuildException here? Is it | ||||
// in case the message could end up being written to no loggers (as the loggers | |||||
// could have failed to be created due to this failure)? | |||||
// in case the message could end up being written to no loggers (as the | |||||
// loggers could have failed to be created due to this failure)? | |||||
/** | /** | ||||
* Creates the default build logger for sending build events to the ant log. | |||||
* Creates the default build logger for sending build events to the ant | |||||
* log. | |||||
* | |||||
* @return the logger instance for this build. | |||||
*/ | */ | ||||
private BuildLogger createLogger() { | private BuildLogger createLogger() { | ||||
BuildLogger logger = null; | BuildLogger logger = null; | ||||
if (loggerClassname != null) { | if (loggerClassname != null) { | ||||
try { | try { | ||||
logger = (BuildLogger)(Class.forName(loggerClassname).newInstance()); | |||||
} | |||||
catch (ClassCastException e) { | |||||
System.err.println("The specified logger class " + loggerClassname + | |||||
" does not implement the BuildLogger interface"); | |||||
logger = (BuildLogger) (Class.forName(loggerClassname).newInstance()); | |||||
} catch (ClassCastException e) { | |||||
System.err.println("The specified logger class " | |||||
+ loggerClassname | |||||
+ " does not implement the BuildLogger interface"); | |||||
throw new RuntimeException(); | throw new RuntimeException(); | ||||
} | |||||
catch (Exception e) { | |||||
System.err.println("Unable to instantiate specified logger class " + | |||||
loggerClassname + " : " + e.getClass().getName()); | |||||
} catch (Exception e) { | |||||
System.err.println("Unable to instantiate specified logger " | |||||
+ "class " + loggerClassname + " : " | |||||
+ e.getClass().getName()); | |||||
throw new RuntimeException(); | throw new RuntimeException(); | ||||
} | } | ||||
} | |||||
else { | |||||
} else { | |||||
logger = new DefaultLogger(); | logger = new DefaultLogger(); | ||||
} | } | ||||
@@ -736,7 +765,7 @@ public class Main { | |||||
/** | /** | ||||
* Prints the Ant version information to <code>System.out</code>. | * Prints the Ant version information to <code>System.out</code>. | ||||
* | |||||
* | |||||
* @exception BuildException if the version information is unavailable | * @exception BuildException if the version information is unavailable | ||||
*/ | */ | ||||
private static void printVersion() throws BuildException { | private static void printVersion() throws BuildException { | ||||
@@ -752,10 +781,10 @@ public class Main { | |||||
* Returns the Ant version information, if available. Once the information | * Returns the Ant version information, if available. Once the information | ||||
* has been loaded once, it's cached and returned from the cache on future | * has been loaded once, it's cached and returned from the cache on future | ||||
* calls. | * calls. | ||||
* | |||||
* @return the Ant version information as a String | |||||
* | |||||
* @return the Ant version information as a String | |||||
* (always non-<code>null</code>) | * (always non-<code>null</code>) | ||||
* | |||||
* | |||||
* @exception BuildException if the version information is unavailable | * @exception BuildException if the version information is unavailable | ||||
*/ | */ | ||||
public static synchronized String getAntVersion() throws BuildException { | public static synchronized String getAntVersion() throws BuildException { | ||||
@@ -766,7 +795,7 @@ public class Main { | |||||
Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt"); | Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt"); | ||||
props.load(in); | props.load(in); | ||||
in.close(); | in.close(); | ||||
String lSep = System.getProperty("line.separator"); | String lSep = System.getProperty("line.separator"); | ||||
StringBuffer msg = new StringBuffer(); | StringBuffer msg = new StringBuffer(); | ||||
msg.append("Apache Ant version "); | msg.append("Apache Ant version "); | ||||
@@ -785,9 +814,9 @@ public class Main { | |||||
} | } | ||||
/** | /** | ||||
* Prints the description of a project (if there is one) to | |||||
* Prints the description of a project (if there is one) to | |||||
* <code>System.out</code>. | * <code>System.out</code>. | ||||
* | |||||
* | |||||
* @param project The project to display a description of. | * @param project The project to display a description of. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
*/ | */ | ||||
@@ -798,9 +827,9 @@ public class Main { | |||||
} | } | ||||
/** | /** | ||||
* Prints a list of all targets in the specified project to | |||||
* Prints a list of all targets in the specified project to | |||||
* <code>System.out</code>, optionally including subtargets. | * <code>System.out</code>, optionally including subtargets. | ||||
* | |||||
* | |||||
* @param project The project to display a description of. | * @param project The project to display a description of. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* @param printSubTargets Whether or not subtarget names should also be | * @param printSubTargets Whether or not subtarget names should also be | ||||
@@ -820,7 +849,7 @@ public class Main { | |||||
Vector subNames = new Vector(); | Vector subNames = new Vector(); | ||||
while (ptargets.hasMoreElements()) { | while (ptargets.hasMoreElements()) { | ||||
currentTarget = (Target)ptargets.nextElement(); | |||||
currentTarget = (Target) ptargets.nextElement(); | |||||
targetName = currentTarget.getName(); | targetName = currentTarget.getName(); | ||||
targetDescription = currentTarget.getDescription(); | targetDescription = currentTarget.getDescription(); | ||||
// maintain a sorted list of targets | // maintain a sorted list of targets | ||||
@@ -838,31 +867,32 @@ public class Main { | |||||
} | } | ||||
printTargets(topNames, topDescriptions, "Main targets:", maxLength); | printTargets(topNames, topDescriptions, "Main targets:", maxLength); | ||||
if( printSubTargets ) { | |||||
if (printSubTargets) { | |||||
printTargets(subNames, null, "Subtargets:", 0); | printTargets(subNames, null, "Subtargets:", 0); | ||||
} | } | ||||
String defaultTarget = project.getDefaultTarget(); | String defaultTarget = project.getDefaultTarget(); | ||||
if (defaultTarget != null && !"".equals(defaultTarget)) { // shouldn't need to check but... | |||||
System.out.println( "Default target: " + defaultTarget ); | |||||
if (defaultTarget != null && !"".equals(defaultTarget)) { | |||||
// shouldn't need to check but... | |||||
System.out.println("Default target: " + defaultTarget); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Searches for the correct place to insert a name into a list so as | * Searches for the correct place to insert a name into a list so as | ||||
* to keep the list sorted alphabetically. | * to keep the list sorted alphabetically. | ||||
* | |||||
* | |||||
* @param names The current list of names. Must not be <code>null</code>. | * @param names The current list of names. Must not be <code>null</code>. | ||||
* @param name The name to find a place for. | * @param name The name to find a place for. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* | |||||
* | |||||
* @return the correct place in the list for the given name | * @return the correct place in the list for the given name | ||||
*/ | */ | ||||
private static int findTargetPosition(Vector names, String name) { | private static int findTargetPosition(Vector names, String name) { | ||||
int res = names.size(); | int res = names.size(); | ||||
for (int i=0; i<names.size() && res == names.size(); i++) { | |||||
if (name.compareTo((String)names.elementAt(i)) < 0) { | |||||
for (int i = 0; i < names.size() && res == names.size(); i++) { | |||||
if (name.compareTo((String) names.elementAt(i)) < 0) { | |||||
res = i; | res = i; | ||||
} | } | ||||
} | } | ||||
@@ -871,23 +901,38 @@ public class Main { | |||||
/** | /** | ||||
* Writes a formatted list of target names to <code>System.out</code> | * Writes a formatted list of target names to <code>System.out</code> | ||||
* with an optional description | |||||
* with an optional description. | |||||
* | |||||
* @param names The names to be printed. | |||||
* Must not be <code>null</code>. | |||||
* @param descriptions The associated target descriptions. | |||||
* May be <code>null</code>, in which case | |||||
* no descriptions are displayed. | |||||
* If non-<code>null</code>, this should have | |||||
* as many elements as <code>names</code>. | |||||
* @param heading The heading to display. | |||||
* Should not be <code>null</code>. | |||||
* @param maxlen The maximum length of the names of the targets. | |||||
* If descriptions are given, they are padded to this | |||||
* position so they line up (so long as the names really | |||||
* <i>are</i> shorter than this). | |||||
*/ | */ | ||||
private static void printTargets(Vector names, Vector descriptions, String heading, int maxlen) { | |||||
private static void printTargets(Vector names, Vector descriptions, | |||||
String heading, int maxlen) { | |||||
// now, start printing the targets and their descriptions | // now, start printing the targets and their descriptions | ||||
String lSep = System.getProperty("line.separator"); | String lSep = System.getProperty("line.separator"); | ||||
// got a bit annoyed that I couldn't find a pad function | // got a bit annoyed that I couldn't find a pad function | ||||
String spaces = " "; | String spaces = " "; | ||||
while (spaces.length()<maxlen) { | |||||
while (spaces.length() < maxlen) { | |||||
spaces += spaces; | spaces += spaces; | ||||
} | } | ||||
StringBuffer msg = new StringBuffer(); | StringBuffer msg = new StringBuffer(); | ||||
msg.append(heading + lSep + lSep); | msg.append(heading + lSep + lSep); | ||||
for (int i=0; i<names.size(); i++) { | |||||
for (int i = 0; i < names.size(); i++) { | |||||
msg.append(" "); | msg.append(" "); | ||||
msg.append(names.elementAt(i)); | msg.append(names.elementAt(i)); | ||||
if (descriptions != null) { | if (descriptions != null) { | ||||
msg.append(spaces.substring(0, maxlen - ((String)names.elementAt(i)).length() + 2)); | |||||
msg.append(spaces.substring(0, maxlen - ((String) names.elementAt(i)).length() + 2)); | |||||
msg.append(descriptions.elementAt(i)); | msg.append(descriptions.elementAt(i)); | ||||
} | } | ||||
msg.append(lSep); | msg.append(lSep); | ||||
@@ -68,6 +68,7 @@ import java.lang.reflect.Modifier; | |||||
import org.apache.tools.ant.types.FilterSet; | import org.apache.tools.ant.types.FilterSet; | ||||
import org.apache.tools.ant.types.FilterSetCollection; | import org.apache.tools.ant.types.FilterSetCollection; | ||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
import org.apache.tools.ant.util.JavaEnvUtils; | |||||
import org.apache.tools.ant.input.InputHandler; | import org.apache.tools.ant.input.InputHandler; | ||||
/** | /** | ||||
@@ -88,45 +89,42 @@ import org.apache.tools.ant.input.InputHandler; | |||||
public class Project { | public class Project { | ||||
/** Message priority of "error". */ | /** Message priority of "error". */ | ||||
public final static int MSG_ERR = 0; | |||||
public static final int MSG_ERR = 0; | |||||
/** Message priority of "warning". */ | /** Message priority of "warning". */ | ||||
public final static int MSG_WARN = 1; | |||||
public static final int MSG_WARN = 1; | |||||
/** Message priority of "information". */ | /** Message priority of "information". */ | ||||
public final static int MSG_INFO = 2; | |||||
public static final int MSG_INFO = 2; | |||||
/** Message priority of "verbose". */ | /** Message priority of "verbose". */ | ||||
public final static int MSG_VERBOSE = 3; | |||||
public static final int MSG_VERBOSE = 3; | |||||
/** Message priority of "debug". */ | /** Message priority of "debug". */ | ||||
public final static int MSG_DEBUG = 4; | |||||
public static final int MSG_DEBUG = 4; | |||||
/** | /** | ||||
* Constant for the "visiting" state, used when | * Constant for the "visiting" state, used when | ||||
* traversing a DFS of target dependencies. | * traversing a DFS of target dependencies. | ||||
*/ | */ | ||||
private final static String VISITING = "VISITING"; | |||||
private static final String VISITING = "VISITING"; | |||||
/** | /** | ||||
* Constant for the "visited" state, used when | * Constant for the "visited" state, used when | ||||
* traversing a DFS of target dependencies. | * traversing a DFS of target dependencies. | ||||
*/ | */ | ||||
private final static String VISITED = "VISITED"; | |||||
/** Version of currently running VM. */ | |||||
private static String javaVersion; | |||||
private static final String VISITED = "VISITED"; | |||||
/** Version constant for Java 1.0 */ | /** Version constant for Java 1.0 */ | ||||
public final static String JAVA_1_0 = "1.0"; | |||||
public static final String JAVA_1_0 = JavaEnvUtils.JAVA_1_0; | |||||
/** Version constant for Java 1.1 */ | /** Version constant for Java 1.1 */ | ||||
public final static String JAVA_1_1 = "1.1"; | |||||
public static final String JAVA_1_1 = JavaEnvUtils.JAVA_1_1; | |||||
/** Version constant for Java 1.2 */ | /** Version constant for Java 1.2 */ | ||||
public final static String JAVA_1_2 = "1.2"; | |||||
public static final String JAVA_1_2 = JavaEnvUtils.JAVA_1_2; | |||||
/** Version constant for Java 1.3 */ | /** Version constant for Java 1.3 */ | ||||
public final static String JAVA_1_3 = "1.3"; | |||||
public static final String JAVA_1_3 = JavaEnvUtils.JAVA_1_3; | |||||
/** Version constant for Java 1.4 */ | /** Version constant for Java 1.4 */ | ||||
public final static String JAVA_1_4 = "1.4"; | |||||
public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4; | |||||
/** Default filter start token. */ | /** Default filter start token. */ | ||||
public final static String TOKEN_START = FilterSet.DEFAULT_TOKEN_START; | |||||
public static final String TOKEN_START = FilterSet.DEFAULT_TOKEN_START; | |||||
/** Default filter end token. */ | /** Default filter end token. */ | ||||
public final static String TOKEN_END = FilterSet.DEFAULT_TOKEN_END; | |||||
public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END; | |||||
/** Name of this project. */ | /** Name of this project. */ | ||||
private String name; | private String name; | ||||
@@ -166,7 +164,9 @@ public class Project { | |||||
* contains one FilterSet, but the wrapper is needed in order to | * contains one FilterSet, but the wrapper is needed in order to | ||||
* make it easier to use the FileUtils interface. | * make it easier to use the FileUtils interface. | ||||
*/ | */ | ||||
private FilterSetCollection globalFilters = new FilterSetCollection(globalFilterSet); | |||||
private FilterSetCollection globalFilters | |||||
= new FilterSetCollection(globalFilterSet); | |||||
/** Project base directory. */ | /** Project base directory. */ | ||||
private File baseDir; | private File baseDir; | ||||
@@ -207,31 +207,6 @@ public class Project { | |||||
return inputHandler; | return inputHandler; | ||||
} | } | ||||
static { | |||||
// Determine the Java version by looking at available classes | |||||
// java.lang.CharSequence was introduced in JDK 1.4 | |||||
// java.lang.StrictMath was introduced in JDK 1.3 | |||||
// java.lang.ThreadLocal was introduced in JDK 1.2 | |||||
// java.lang.Void was introduced in JDK 1.1 | |||||
// Count up version until a NoClassDefFoundError ends the try | |||||
try { | |||||
javaVersion = JAVA_1_0; | |||||
Class.forName("java.lang.Void"); | |||||
javaVersion = JAVA_1_1; | |||||
Class.forName("java.lang.ThreadLocal"); | |||||
javaVersion = JAVA_1_2; | |||||
Class.forName("java.lang.StrictMath"); | |||||
javaVersion = JAVA_1_3; | |||||
Class.forName("java.lang.CharSequence"); | |||||
javaVersion = JAVA_1_4; | |||||
} catch (ClassNotFoundException cnfe) { | |||||
// swallow as we've hit the max class version that | |||||
// we have | |||||
} | |||||
} | |||||
/** Instance of a utility class to use for file operations. */ | /** Instance of a utility class to use for file operations. */ | ||||
private FileUtils fileUtils; | private FileUtils fileUtils; | ||||
@@ -272,9 +247,11 @@ public class Project { | |||||
Class taskClass = Class.forName(value); | Class taskClass = Class.forName(value); | ||||
addTaskDefinition(key, taskClass); | addTaskDefinition(key, taskClass); | ||||
} catch (NoClassDefFoundError ncdfe) { | } catch (NoClassDefFoundError ncdfe) { | ||||
log("Could not load a dependent class (" + ncdfe.getMessage() + ") for task " + key, MSG_DEBUG); | |||||
log("Could not load a dependent class (" | |||||
+ ncdfe.getMessage() + ") for task " + key, MSG_DEBUG); | |||||
} catch (ClassNotFoundException cnfe) { | } catch (ClassNotFoundException cnfe) { | ||||
log("Could not load class (" + value + ") for task " + key, MSG_DEBUG); | |||||
log("Could not load class (" + value | |||||
+ ") for task " + key, MSG_DEBUG); | |||||
} | } | ||||
} | } | ||||
} catch (IOException ioe) { | } catch (IOException ioe) { | ||||
@@ -283,7 +260,7 @@ public class Project { | |||||
String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; | String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; | ||||
try{ | |||||
try { | |||||
Properties props = new Properties(); | Properties props = new Properties(); | ||||
InputStream in = this.getClass().getResourceAsStream(dataDefs); | InputStream in = this.getClass().getResourceAsStream(dataDefs); | ||||
if (in == null) { | if (in == null) { | ||||
@@ -481,6 +458,10 @@ public class Project { | |||||
/** | /** | ||||
* Sets a property unless it is already defined as a user property | * Sets a property unless it is already defined as a user property | ||||
* (in which case the method returns silently). | * (in which case the method returns silently). | ||||
* | |||||
* @param name The name of the property. | |||||
* Must not be <code>null</code>. | |||||
* @param value The property value. Must not be <code>null</code>. | |||||
*/ | */ | ||||
private void setPropertyInternal(String name, String value) { | private void setPropertyInternal(String name, String value) { | ||||
if (null != userProperties.get(name)) { | if (null != userProperties.get(name)) { | ||||
@@ -517,8 +498,8 @@ public class Project { | |||||
* by values, or <code>null</code> if the given string is | * by values, or <code>null</code> if the given string is | ||||
* <code>null</code>. | * <code>null</code>. | ||||
* | * | ||||
* @exception BuildException if the given value has an unclosed property name, | |||||
* e.g. <code>${xxx</code> | |||||
* @exception BuildException if the given value has an unclosed | |||||
* property name, e.g. <code>${xxx</code> | |||||
*/ | */ | ||||
public String replaceProperties(String value) | public String replaceProperties(String value) | ||||
throws BuildException { | throws BuildException { | ||||
@@ -544,7 +525,8 @@ public class Project { | |||||
/** | /** | ||||
* Returns a copy of the properties table. | * Returns a copy of the properties table. | ||||
* @return a hashtable containing all properties (including user properties). | |||||
* @return a hashtable containing all properties | |||||
* (including user properties). | |||||
*/ | */ | ||||
public Hashtable getProperties() { | public Hashtable getProperties() { | ||||
Hashtable propertiesCopy = new Hashtable(); | Hashtable propertiesCopy = new Hashtable(); | ||||
@@ -656,6 +638,8 @@ public class Project { | |||||
* | * | ||||
* @param token The token to filter. | * @param token The token to filter. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* @param value The replacement value. | |||||
* Must not be <code>null</code>. | |||||
* @deprecated Use getGlobalFilterSet().addFilter(token,value) | * @deprecated Use getGlobalFilterSet().addFilter(token,value) | ||||
* | * | ||||
* @see #getGlobalFilterSet() | * @see #getGlobalFilterSet() | ||||
@@ -710,13 +694,15 @@ public class Project { | |||||
public void setBaseDir(File baseDir) throws BuildException { | public void setBaseDir(File baseDir) throws BuildException { | ||||
baseDir = fileUtils.normalize(baseDir.getAbsolutePath()); | baseDir = fileUtils.normalize(baseDir.getAbsolutePath()); | ||||
if (!baseDir.exists()) { | if (!baseDir.exists()) { | ||||
throw new BuildException("Basedir " + baseDir.getAbsolutePath() + " does not exist"); | |||||
throw new BuildException("Basedir " + baseDir.getAbsolutePath() | |||||
+ " does not exist"); | |||||
} | } | ||||
if (!baseDir.isDirectory()) { | if (!baseDir.isDirectory()) { | ||||
throw new BuildException("Basedir " + baseDir.getAbsolutePath() + " is not a directory"); | |||||
throw new BuildException("Basedir " + baseDir.getAbsolutePath() | |||||
+ " is not a directory"); | |||||
} | } | ||||
this.baseDir = baseDir; | this.baseDir = baseDir; | ||||
setPropertyInternal( "basedir", this.baseDir.getPath()); | |||||
setPropertyInternal("basedir", this.baseDir.getPath()); | |||||
String msg = "Project base dir set to: " + this.baseDir; | String msg = "Project base dir set to: " + this.baseDir; | ||||
log(msg, MSG_VERBOSE); | log(msg, MSG_VERBOSE); | ||||
} | } | ||||
@@ -741,9 +727,10 @@ public class Project { | |||||
/** | /** | ||||
* Returns the version of Java this class is running under. | * Returns the version of Java this class is running under. | ||||
* @return the version of Java as a String, e.g. "1.1" | * @return the version of Java as a String, e.g. "1.1" | ||||
* @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion | |||||
*/ | */ | ||||
public static String getJavaVersion() { | public static String getJavaVersion() { | ||||
return javaVersion; | |||||
return JavaEnvUtils.getJavaVersion(); | |||||
} | } | ||||
/** | /** | ||||
@@ -754,17 +741,19 @@ public class Project { | |||||
* | * | ||||
* @exception BuildException if this Java version is not supported | * @exception BuildException if this Java version is not supported | ||||
* | * | ||||
* @see #getJavaVersion() | |||||
* @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion | |||||
*/ | */ | ||||
public void setJavaVersionProperty() throws BuildException { | public void setJavaVersionProperty() throws BuildException { | ||||
String javaVersion = JavaEnvUtils.getJavaVersion(); | |||||
setPropertyInternal("ant.java.version", javaVersion); | setPropertyInternal("ant.java.version", javaVersion); | ||||
// sanity check | // sanity check | ||||
if (javaVersion == JAVA_1_0) { | |||||
if (javaVersion == JavaEnvUtils.JAVA_1_0) { | |||||
throw new BuildException("Ant cannot work on Java 1.0"); | throw new BuildException("Ant cannot work on Java 1.0"); | ||||
} | } | ||||
log("Detected Java version: " + javaVersion + " in: " + System.getProperty("java.home"), MSG_VERBOSE); | |||||
log("Detected Java version: " + javaVersion + " in: " | |||||
+ System.getProperty("java.home"), MSG_VERBOSE); | |||||
log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE); | log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE); | ||||
} | } | ||||
@@ -803,8 +792,9 @@ public class Project { | |||||
* | * | ||||
* @see #checkTaskClass(Class) | * @see #checkTaskClass(Class) | ||||
*/ | */ | ||||
public void addTaskDefinition(String taskName, Class taskClass) throws BuildException { | |||||
Class old = (Class)taskClassDefinitions.get(taskName); | |||||
public void addTaskDefinition(String taskName, Class taskClass) | |||||
throws BuildException { | |||||
Class old = (Class) taskClassDefinitions.get(taskName); | |||||
if (null != old) { | if (null != old) { | ||||
if (old.equals(taskClass)) { | if (old.equals(taskClass)) { | ||||
log("Ignoring override for task " + taskName | log("Ignoring override for task " + taskName | ||||
@@ -812,7 +802,7 @@ public class Project { | |||||
MSG_VERBOSE); | MSG_VERBOSE); | ||||
return; | return; | ||||
} else { | } else { | ||||
log("Trying to override old definition of task "+taskName, | |||||
log("Trying to override old definition of task " + taskName, | |||||
MSG_WARN); | MSG_WARN); | ||||
invalidateCreatedTasks(taskName); | invalidateCreatedTasks(taskName); | ||||
} | } | ||||
@@ -829,31 +819,35 @@ public class Project { | |||||
* Ant task implementation classes must be public, concrete, and have | * Ant task implementation classes must be public, concrete, and have | ||||
* a no-arg constructor. | * a no-arg constructor. | ||||
* | * | ||||
* @param taskClass The class to be checked. | |||||
* Must not be <code>null</code>. | |||||
* | |||||
* @exception BuildException if the class is unsuitable for being an Ant | * @exception BuildException if the class is unsuitable for being an Ant | ||||
* task. An error level message is logged before | |||||
* task. An error level message is logged before | |||||
* this exception is thrown. | * this exception is thrown. | ||||
*/ | */ | ||||
public void checkTaskClass(final Class taskClass) throws BuildException { | public void checkTaskClass(final Class taskClass) throws BuildException { | ||||
if(!Modifier.isPublic(taskClass.getModifiers())) { | |||||
if (!Modifier.isPublic(taskClass.getModifiers())) { | |||||
final String message = taskClass + " is not public"; | final String message = taskClass + " is not public"; | ||||
log(message, Project.MSG_ERR); | log(message, Project.MSG_ERR); | ||||
throw new BuildException(message); | throw new BuildException(message); | ||||
} | } | ||||
if(Modifier.isAbstract(taskClass.getModifiers())) { | |||||
if (Modifier.isAbstract(taskClass.getModifiers())) { | |||||
final String message = taskClass + " is abstract"; | final String message = taskClass + " is abstract"; | ||||
log(message, Project.MSG_ERR); | log(message, Project.MSG_ERR); | ||||
throw new BuildException(message); | throw new BuildException(message); | ||||
} | } | ||||
try { | try { | ||||
taskClass.getConstructor( null ); | |||||
taskClass.getConstructor(null); | |||||
// don't have to check for public, since | // don't have to check for public, since | ||||
// getConstructor finds public constructors only. | // getConstructor finds public constructors only. | ||||
} catch(NoSuchMethodException e) { | |||||
final String message = "No public no-arg constructor in " + taskClass; | |||||
} catch (NoSuchMethodException e) { | |||||
final String message = "No public no-arg constructor in " | |||||
+ taskClass; | |||||
log(message, Project.MSG_ERR); | log(message, Project.MSG_ERR); | ||||
throw new BuildException(message); | throw new BuildException(message); | ||||
} | } | ||||
if( !Task.class.isAssignableFrom(taskClass) ) { | |||||
if (!Task.class.isAssignableFrom(taskClass)) { | |||||
TaskAdapter.checkTaskClass(taskClass, this); | TaskAdapter.checkTaskClass(taskClass, this); | ||||
} | } | ||||
} | } | ||||
@@ -879,11 +873,11 @@ public class Project { | |||||
* | * | ||||
* @param typeName The name of the datatype. | * @param typeName The name of the datatype. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* @param taskClass The full name of the class implementing the datatype. | |||||
* @param typeClass The full name of the class implementing the datatype. | |||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
*/ | */ | ||||
public void addDataTypeDefinition(String typeName, Class typeClass) { | public void addDataTypeDefinition(String typeName, Class typeClass) { | ||||
Class old = (Class)dataClassDefinitions.get(typeName); | |||||
Class old = (Class) dataClassDefinitions.get(typeName); | |||||
if (null != old) { | if (null != old) { | ||||
if (old.equals(typeClass)) { | if (old.equals(typeClass)) { | ||||
log("Ignoring override for datatype " + typeName | log("Ignoring override for datatype " + typeName | ||||
@@ -891,19 +885,20 @@ public class Project { | |||||
MSG_VERBOSE); | MSG_VERBOSE); | ||||
return; | return; | ||||
} else { | } else { | ||||
log("Trying to override old definition of datatype "+typeName, | |||||
MSG_WARN); | |||||
log("Trying to override old definition of datatype " | |||||
+ typeName, MSG_WARN); | |||||
} | } | ||||
} | } | ||||
String msg = " +User datatype: " + typeName + " " + typeClass.getName(); | |||||
String msg = " +User datatype: " + typeName + " " | |||||
+ typeClass.getName(); | |||||
log(msg, MSG_DEBUG); | log(msg, MSG_DEBUG); | ||||
dataClassDefinitions.put(typeName, typeClass); | dataClassDefinitions.put(typeName, typeClass); | ||||
} | } | ||||
/** | /** | ||||
* Returns the current datatype definition hashtable. The returned hashtable is | |||||
* "live" and so should not be modified. | |||||
* Returns the current datatype definition hashtable. The returned | |||||
* hashtable is "live" and so should not be modified. | |||||
* | * | ||||
* @return a map of from datatype name to implementing class | * @return a map of from datatype name to implementing class | ||||
* (String to Class). | * (String to Class). | ||||
@@ -922,10 +917,10 @@ public class Project { | |||||
* | * | ||||
* @see Project#addOrReplaceTarget | * @see Project#addOrReplaceTarget | ||||
*/ | */ | ||||
public void addTarget(Target target) { | |||||
public void addTarget(Target target) throws BuildException { | |||||
String name = target.getName(); | String name = target.getName(); | ||||
if (targets.get(name) != null) { | if (targets.get(name) != null) { | ||||
throw new BuildException("Duplicate target: `"+name+"'"); | |||||
throw new BuildException("Duplicate target: `" + name + "'"); | |||||
} | } | ||||
addOrReplaceTarget(name, target); | addOrReplaceTarget(name, target); | ||||
} | } | ||||
@@ -945,7 +940,7 @@ public class Project { | |||||
public void addTarget(String targetName, Target target) | public void addTarget(String targetName, Target target) | ||||
throws BuildException { | throws BuildException { | ||||
if (targets.get(targetName) != null) { | if (targets.get(targetName) != null) { | ||||
throw new BuildException("Duplicate target: `"+targetName+"'"); | |||||
throw new BuildException("Duplicate target: `" + targetName + "'"); | |||||
} | } | ||||
addOrReplaceTarget(targetName, target); | addOrReplaceTarget(targetName, target); | ||||
} | } | ||||
@@ -1008,14 +1003,14 @@ public class Project { | |||||
try { | try { | ||||
Object o = c.newInstance(); | Object o = c.newInstance(); | ||||
Task task = null; | Task task = null; | ||||
if( o instanceof Task ) { | |||||
task=(Task)o; | |||||
if (o instanceof Task) { | |||||
task = (Task) o; | |||||
} else { | } else { | ||||
// "Generic" Bean - use the setter pattern | // "Generic" Bean - use the setter pattern | ||||
// and an Adapter | // and an Adapter | ||||
TaskAdapter taskA=new TaskAdapter(); | |||||
taskA.setProxy( o ); | |||||
task=taskA; | |||||
TaskAdapter taskA = new TaskAdapter(); | |||||
taskA.setProxy(o); | |||||
task = taskA; | |||||
} | } | ||||
task.setProject(this); | task.setProject(this); | ||||
task.setTaskType(taskType); | task.setTaskType(taskType); | ||||
@@ -1080,7 +1075,7 @@ public class Project { | |||||
/** | /** | ||||
* Creates a new instance of a data type. | * Creates a new instance of a data type. | ||||
* | * | ||||
* @param taskType The name of the data type to create an instance of. | |||||
* @param typeName The name of the data type to create an instance of. | |||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* | * | ||||
* @return an instance of the specified data type, or <code>null</code> if | * @return an instance of the specified data type, or <code>null</code> if | ||||
@@ -1116,7 +1111,7 @@ public class Project { | |||||
o = ctor.newInstance(new Object[] {this}); | o = ctor.newInstance(new Object[] {this}); | ||||
} | } | ||||
if (o instanceof ProjectComponent) { | if (o instanceof ProjectComponent) { | ||||
((ProjectComponent)o).setProject(this); | |||||
((ProjectComponent) o).setProject(this); | |||||
} | } | ||||
String msg = " +DataType: " + typeName; | String msg = " +DataType: " + typeName; | ||||
log (msg, MSG_DEBUG); | log (msg, MSG_DEBUG); | ||||
@@ -1146,7 +1141,7 @@ public class Project { | |||||
Throwable error = null; | Throwable error = null; | ||||
for (int i = 0; i < targetNames.size(); i++) { | for (int i = 0; i < targetNames.size(); i++) { | ||||
executeTarget((String)targetNames.elementAt(i)); | |||||
executeTarget((String) targetNames.elementAt(i)); | |||||
} | } | ||||
} | } | ||||
@@ -1160,15 +1155,13 @@ public class Project { | |||||
* or information (<code>false</code>). | * or information (<code>false</code>). | ||||
*/ | */ | ||||
public void demuxOutput(String line, boolean isError) { | public void demuxOutput(String line, boolean isError) { | ||||
Task task = (Task)threadTasks.get(Thread.currentThread()); | |||||
Task task = (Task) threadTasks.get(Thread.currentThread()); | |||||
if (task == null) { | if (task == null) { | ||||
fireMessageLogged(this, line, isError ? MSG_ERR : MSG_INFO); | fireMessageLogged(this, line, isError ? MSG_ERR : MSG_INFO); | ||||
} | |||||
else { | |||||
} else { | |||||
if (isError) { | if (isError) { | ||||
task.handleErrorOutput(line); | task.handleErrorOutput(line); | ||||
} | |||||
else { | |||||
} else { | |||||
task.handleOutput(line); | task.handleOutput(line); | ||||
} | } | ||||
} | } | ||||
@@ -1221,6 +1214,8 @@ public class Project { | |||||
* respect to. May be <code>null</code>, in which case | * respect to. May be <code>null</code>, in which case | ||||
* the current directory is used. | * the current directory is used. | ||||
* | * | ||||
* @return the resolved File. | |||||
* | |||||
* @deprecated | * @deprecated | ||||
*/ | */ | ||||
public File resolveFile(String fileName, File rootDir) { | public File resolveFile(String fileName, File rootDir) { | ||||
@@ -1235,6 +1230,9 @@ public class Project { | |||||
* | * | ||||
* @param fileName The name of the file to resolve. | * @param fileName The name of the file to resolve. | ||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* | |||||
* @return the resolved File. | |||||
* | |||||
*/ | */ | ||||
public File resolveFile(String fileName) { | public File resolveFile(String fileName) { | ||||
return fileUtils.resolveFile(baseDir, fileName); | return fileUtils.resolveFile(baseDir, fileName); | ||||
@@ -1257,7 +1255,7 @@ public class Project { | |||||
* @see PathTokenizer | * @see PathTokenizer | ||||
*/ | */ | ||||
public static String translatePath(String toProcess) { | public static String translatePath(String toProcess) { | ||||
if ( toProcess == null || toProcess.length() == 0 ) { | |||||
if (toProcess == null || toProcess.length() == 0) { | |||||
return ""; | return ""; | ||||
} | } | ||||
@@ -1289,7 +1287,8 @@ public class Project { | |||||
* | * | ||||
* @deprecated | * @deprecated | ||||
*/ | */ | ||||
public void copyFile(String sourceFile, String destFile) throws IOException { | |||||
public void copyFile(String sourceFile, String destFile) | |||||
throws IOException { | |||||
fileUtils.copyFile(sourceFile, destFile); | fileUtils.copyFile(sourceFile, destFile); | ||||
} | } | ||||
@@ -1310,7 +1309,8 @@ public class Project { | |||||
*/ | */ | ||||
public void copyFile(String sourceFile, String destFile, boolean filtering) | public void copyFile(String sourceFile, String destFile, boolean filtering) | ||||
throws IOException { | throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null); | |||||
} | } | ||||
/** | /** | ||||
@@ -1333,7 +1333,8 @@ public class Project { | |||||
*/ | */ | ||||
public void copyFile(String sourceFile, String destFile, boolean filtering, | public void copyFile(String sourceFile, String destFile, boolean filtering, | ||||
boolean overwrite) throws IOException { | boolean overwrite) throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null, overwrite); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null, overwrite); | |||||
} | } | ||||
/** | /** | ||||
@@ -1362,8 +1363,8 @@ public class Project { | |||||
public void copyFile(String sourceFile, String destFile, boolean filtering, | public void copyFile(String sourceFile, String destFile, boolean filtering, | ||||
boolean overwrite, boolean preserveLastModified) | boolean overwrite, boolean preserveLastModified) | ||||
throws IOException { | throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null, | |||||
overwrite, preserveLastModified); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null, overwrite, preserveLastModified); | |||||
} | } | ||||
/** | /** | ||||
@@ -1400,7 +1401,8 @@ public class Project { | |||||
*/ | */ | ||||
public void copyFile(File sourceFile, File destFile, boolean filtering) | public void copyFile(File sourceFile, File destFile, boolean filtering) | ||||
throws IOException { | throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null); | |||||
} | } | ||||
/** | /** | ||||
@@ -1417,13 +1419,14 @@ public class Project { | |||||
* @param overwrite Whether or not the destination file should be | * @param overwrite Whether or not the destination file should be | ||||
* overwritten if it already exists. | * overwritten if it already exists. | ||||
* | * | ||||
* @exception IOException | |||||
* @exception IOException if the file cannot be copied. | |||||
* | * | ||||
* @deprecated | * @deprecated | ||||
*/ | */ | ||||
public void copyFile(File sourceFile, File destFile, boolean filtering, | public void copyFile(File sourceFile, File destFile, boolean filtering, | ||||
boolean overwrite) throws IOException { | boolean overwrite) throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null, overwrite); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null, overwrite); | |||||
} | } | ||||
/** | /** | ||||
@@ -1445,32 +1448,35 @@ public class Project { | |||||
* the resulting file should be set to that | * the resulting file should be set to that | ||||
* of the source file. | * of the source file. | ||||
* | * | ||||
* @exception IOException if the copying fails | |||||
* @exception IOException if the file cannot be copied. | |||||
* | * | ||||
* @deprecated | * @deprecated | ||||
*/ | */ | ||||
public void copyFile(File sourceFile, File destFile, boolean filtering, | public void copyFile(File sourceFile, File destFile, boolean filtering, | ||||
boolean overwrite, boolean preserveLastModified) | boolean overwrite, boolean preserveLastModified) | ||||
throws IOException { | throws IOException { | ||||
fileUtils.copyFile(sourceFile, destFile, filtering ? globalFilters : null, | |||||
overwrite, preserveLastModified); | |||||
fileUtils.copyFile(sourceFile, destFile, | |||||
filtering ? globalFilters : null, overwrite, preserveLastModified); | |||||
} | } | ||||
/** | /** | ||||
* Calls File.setLastModified(long time) on Java above 1.1, and logs | * Calls File.setLastModified(long time) on Java above 1.1, and logs | ||||
* a warning on Java 1.1. | * a warning on Java 1.1. | ||||
* | * | ||||
* @param File The file to set the last modified time on. | |||||
* @param file The file to set the last modified time on. | |||||
* Must not be <code>null</code>. | * Must not be <code>null</code>. | ||||
* | * | ||||
* @param time the required modification time. | |||||
* | |||||
* @deprecated | * @deprecated | ||||
* | * | ||||
* @exception BuildException if the last modified time cannot be set | * @exception BuildException if the last modified time cannot be set | ||||
* despite running on a platform with a version | * despite running on a platform with a version | ||||
* above 1.1. | * above 1.1. | ||||
*/ | */ | ||||
public void setFileLastModified(File file, long time) throws BuildException { | |||||
if (getJavaVersion() == JAVA_1_1) { | |||||
public void setFileLastModified(File file, long time) | |||||
throws BuildException { | |||||
if (JavaEnvUtils.getJavaVersion() == JavaEnvUtils.JAVA_1_1) { | |||||
log("Cannot change the modification time of " + file | log("Cannot change the modification time of " + file | ||||
+ " in JDK 1.1", Project.MSG_WARN); | + " in JDK 1.1", Project.MSG_WARN); | ||||
return; | return; | ||||
@@ -1526,18 +1532,18 @@ public class Project { | |||||
// build Target. | // build Target. | ||||
tsort(root, targets, state, visiting, ret); | tsort(root, targets, state, visiting, ret); | ||||
log("Build sequence for target `"+root+"' is "+ret, MSG_VERBOSE); | |||||
for (Enumeration en=targets.keys(); en.hasMoreElements();) { | |||||
String curTarget = (String)(en.nextElement()); | |||||
log("Build sequence for target `" + root + "' is " + ret, MSG_VERBOSE); | |||||
for (Enumeration en = targets.keys(); en.hasMoreElements();) { | |||||
String curTarget = (String) en.nextElement(); | |||||
String st = (String) state.get(curTarget); | String st = (String) state.get(curTarget); | ||||
if (st == null) { | if (st == null) { | ||||
tsort(curTarget, targets, state, visiting, ret); | tsort(curTarget, targets, state, visiting, ret); | ||||
} | |||||
else if (st == VISITING) { | |||||
throw new RuntimeException("Unexpected node in visiting state: "+curTarget); | |||||
} else if (st == VISITING) { | |||||
throw new RuntimeException("Unexpected node in visiting state: " | |||||
+ curTarget); | |||||
} | } | ||||
} | } | ||||
log("Complete build sequence is "+ret, MSG_VERBOSE); | |||||
log("Complete build sequence is " + ret, MSG_VERBOSE); | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -1588,7 +1594,7 @@ public class Project { | |||||
state.put(root, VISITING); | state.put(root, VISITING); | ||||
visiting.push(root); | visiting.push(root); | ||||
Target target = (Target)(targets.get(root)); | |||||
Target target = (Target) targets.get(root); | |||||
// Make sure we exist | // Make sure we exist | ||||
if (target == null) { | if (target == null) { | ||||
@@ -1597,7 +1603,7 @@ public class Project { | |||||
sb.append("' does not exist in this project. "); | sb.append("' does not exist in this project. "); | ||||
visiting.pop(); | visiting.pop(); | ||||
if (!visiting.empty()) { | if (!visiting.empty()) { | ||||
String parent = (String)visiting.peek(); | |||||
String parent = (String) visiting.peek(); | |||||
sb.append("It is used from target `"); | sb.append("It is used from target `"); | ||||
sb.append(parent); | sb.append(parent); | ||||
sb.append("'."); | sb.append("'."); | ||||
@@ -1606,14 +1612,13 @@ public class Project { | |||||
throw new BuildException(new String(sb)); | throw new BuildException(new String(sb)); | ||||
} | } | ||||
for (Enumeration en=target.getDependencies(); en.hasMoreElements();) { | |||||
for (Enumeration en = target.getDependencies(); en.hasMoreElements();) { | |||||
String cur = (String) en.nextElement(); | String cur = (String) en.nextElement(); | ||||
String m=(String)state.get(cur); | |||||
String m = (String) state.get(cur); | |||||
if (m == null) { | if (m == null) { | ||||
// Not been visited | // Not been visited | ||||
tsort(cur, targets, state, visiting, ret); | tsort(cur, targets, state, visiting, ret); | ||||
} | |||||
else if (m == VISITING) { | |||||
} else if (m == VISITING) { | |||||
// Currently visiting this node, so have a cycle | // Currently visiting this node, so have a cycle | ||||
throw makeCircularException(cur, visiting); | throw makeCircularException(cur, visiting); | ||||
} | } | ||||
@@ -1621,14 +1626,16 @@ public class Project { | |||||
String p = (String) visiting.pop(); | String p = (String) visiting.pop(); | ||||
if (root != p) { | if (root != p) { | ||||
throw new RuntimeException("Unexpected internal error: expected to pop "+root+" but got "+p); | |||||
throw new RuntimeException("Unexpected internal error: expected to " | |||||
+ "pop " + root + " but got " + p); | |||||
} | } | ||||
state.put(root, VISITED); | state.put(root, VISITED); | ||||
ret.addElement(target); | ret.addElement(target); | ||||
} | } | ||||
/** | /** | ||||
* Builds an appropriate exception detailing a specified circular dependency. | |||||
* Builds an appropriate exception detailing a specified circular | |||||
* dependency. | |||||
* | * | ||||
* @param end The dependency to stop at. Must not be <code>null</code>. | * @param end The dependency to stop at. Must not be <code>null</code>. | ||||
* @param stk A stack of dependencies. Must not be <code>null</code>. | * @param stk A stack of dependencies. Must not be <code>null</code>. | ||||
@@ -1640,10 +1647,10 @@ public class Project { | |||||
sb.append(end); | sb.append(end); | ||||
String c; | String c; | ||||
do { | do { | ||||
c = (String)stk.pop(); | |||||
c = (String) stk.pop(); | |||||
sb.append(" <- "); | sb.append(" <- "); | ||||
sb.append(c); | sb.append(c); | ||||
} while(!c.equals(end)); | |||||
} while (!c.equals(end)); | |||||
return new BuildException(new String(sb)); | return new BuildException(new String(sb)); | ||||
} | } | ||||
@@ -1654,12 +1661,17 @@ public class Project { | |||||
* @param value The value of the reference. Must not be <code>null</code>. | * @param value The value of the reference. Must not be <code>null</code>. | ||||
*/ | */ | ||||
public void addReference(String name, Object value) { | public void addReference(String name, Object value) { | ||||
if (null != references.get(name)) { | |||||
Object old = references.get(name); | |||||
if (old == value) { | |||||
// no warning, this is not changing anything | |||||
return; | |||||
} | |||||
if (old != null) { | |||||
log("Overriding previous definition of reference to " + name, | log("Overriding previous definition of reference to " + name, | ||||
MSG_WARN); | MSG_WARN); | ||||
} | } | ||||
log("Adding reference: " + name + " -> " + value, MSG_DEBUG); | log("Adding reference: " + name + " -> " + value, MSG_DEBUG); | ||||
references.put(name,value); | |||||
references.put(name, value); | |||||
} | } | ||||
/** | /** | ||||
@@ -1792,7 +1804,7 @@ public class Project { | |||||
*/ | */ | ||||
protected void fireTaskStarted(Task task) { | protected void fireTaskStarted(Task task) { | ||||
// register this as the current task on the current thread. | // register this as the current task on the current thread. | ||||
threadTasks.put(Thread.currentThread(), task); | |||||
registerThreadTask(Thread.currentThread(), task); | |||||
BuildEvent event = new BuildEvent(task); | BuildEvent event = new BuildEvent(task); | ||||
for (int i = 0; i < listeners.size(); i++) { | for (int i = 0; i < listeners.size(); i++) { | ||||
BuildListener listener = (BuildListener) listeners.elementAt(i); | BuildListener listener = (BuildListener) listeners.elementAt(i); | ||||
@@ -1811,7 +1823,7 @@ public class Project { | |||||
* a successful build. | * a successful build. | ||||
*/ | */ | ||||
protected void fireTaskFinished(Task task, Throwable exception) { | protected void fireTaskFinished(Task task, Throwable exception) { | ||||
threadTasks.remove(Thread.currentThread()); | |||||
registerThreadTask(Thread.currentThread(), null); | |||||
System.out.flush(); | System.out.flush(); | ||||
System.err.flush(); | System.err.flush(); | ||||
BuildEvent event = new BuildEvent(task); | BuildEvent event = new BuildEvent(task); | ||||
@@ -1832,7 +1844,8 @@ public class Project { | |||||
* @param message The message to send. Should not be <code>null</code>. | * @param message The message to send. Should not be <code>null</code>. | ||||
* @param priority The priority of the message. | * @param priority The priority of the message. | ||||
*/ | */ | ||||
private void fireMessageLoggedEvent(BuildEvent event, String message, int priority) { | |||||
private void fireMessageLoggedEvent(BuildEvent event, String message, | |||||
int priority) { | |||||
event.setMessage(message, priority); | event.setMessage(message, priority); | ||||
for (int i = 0; i < listeners.size(); i++) { | for (int i = 0; i < listeners.size(); i++) { | ||||
BuildListener listener = (BuildListener) listeners.elementAt(i); | BuildListener listener = (BuildListener) listeners.elementAt(i); | ||||
@@ -1849,7 +1862,8 @@ public class Project { | |||||
* @param message The message to send. Should not be <code>null</code>. | * @param message The message to send. Should not be <code>null</code>. | ||||
* @param priority The priority of the message. | * @param priority The priority of the message. | ||||
*/ | */ | ||||
protected void fireMessageLogged(Project project, String message, int priority) { | |||||
protected void fireMessageLogged(Project project, String message, | |||||
int priority) { | |||||
BuildEvent event = new BuildEvent(project); | BuildEvent event = new BuildEvent(project); | ||||
fireMessageLoggedEvent(event, message, priority); | fireMessageLoggedEvent(event, message, priority); | ||||
} | } | ||||
@@ -1863,7 +1877,8 @@ public class Project { | |||||
* @param message The message to send. Should not be <code>null</code>. | * @param message The message to send. Should not be <code>null</code>. | ||||
* @param priority The priority of the message. | * @param priority The priority of the message. | ||||
*/ | */ | ||||
protected void fireMessageLogged(Target target, String message, int priority) { | |||||
protected void fireMessageLogged(Target target, String message, | |||||
int priority) { | |||||
BuildEvent event = new BuildEvent(target); | BuildEvent event = new BuildEvent(target); | ||||
fireMessageLoggedEvent(event, message, priority); | fireMessageLoggedEvent(event, message, priority); | ||||
} | } | ||||
@@ -1881,4 +1896,33 @@ public class Project { | |||||
BuildEvent event = new BuildEvent(task); | BuildEvent event = new BuildEvent(task); | ||||
fireMessageLoggedEvent(event, message, priority); | fireMessageLoggedEvent(event, message, priority); | ||||
} | } | ||||
/** | |||||
* Register a task as the current task for a thread. | |||||
* If the task is null, the thread's entry is removed. | |||||
* | |||||
* @param thread the thread on which the task is registered. | |||||
* @param task the task to be registered. | |||||
* @since 1.102, Ant 1.5 | |||||
*/ | |||||
public void registerThreadTask(Thread thread, Task task) { | |||||
if (task != null) { | |||||
threadTasks.put(thread, task); | |||||
} else { | |||||
threadTasks.remove(thread); | |||||
} | |||||
} | |||||
/** | |||||
* Get the current task assopciated with a thread, if any | |||||
* | |||||
* @param thread the thread for which the task is required. | |||||
* @return the task which is currently registered for the given thread or | |||||
* null if no task is registered. | |||||
*/ | |||||
public Task getThreadTask(Thread thread) { | |||||
return (Task) threadTasks.get(thread); | |||||
} | |||||
} | } |
@@ -67,6 +67,7 @@ import org.apache.tools.ant.BuildException; | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @version $Revision$ | * @version $Revision$ | ||||
* @since Ant 1.5 | |||||
*/ | */ | ||||
public class DefaultInputHandler implements InputHandler { | public class DefaultInputHandler implements InputHandler { | ||||
@@ -76,6 +77,10 @@ public class DefaultInputHandler implements InputHandler { | |||||
public DefaultInputHandler() { | public DefaultInputHandler() { | ||||
} | } | ||||
/** | |||||
* Prompts and requests input. May loop until a valid input has | |||||
* been entered. | |||||
*/ | |||||
public void handleInput(InputRequest request) throws BuildException { | public void handleInput(InputRequest request) throws BuildException { | ||||
String prompt = getPrompt(request); | String prompt = getPrompt(request); | ||||
BufferedReader in = | BufferedReader in = | ||||
@@ -95,7 +100,7 @@ public class DefaultInputHandler implements InputHandler { | |||||
/** | /** | ||||
* Constructs user prompt from a request. | * Constructs user prompt from a request. | ||||
* | * | ||||
* <p>This implemenation adds (choice1,choice2,choice3,...) to the | |||||
* <p>This implementation adds (choice1,choice2,choice3,...) to the | |||||
* prompt for <code>MultipleChoiceInputRequest</code>s.</p> | * prompt for <code>MultipleChoiceInputRequest</code>s.</p> | ||||
* | * | ||||
* @param request the request to construct the prompt for. | * @param request the request to construct the prompt for. | ||||
@@ -110,12 +115,11 @@ public class DefaultInputHandler implements InputHandler { | |||||
((MultipleChoiceInputRequest) request).getChoices().elements(); | ((MultipleChoiceInputRequest) request).getChoices().elements(); | ||||
boolean first = true; | boolean first = true; | ||||
while (enum.hasMoreElements()) { | while (enum.hasMoreElements()) { | ||||
if (first) { | |||||
first = false; | |||||
} else { | |||||
if (!first) { | |||||
sb.append(","); | sb.append(","); | ||||
} | } | ||||
sb.append(enum.nextElement()); | sb.append(enum.nextElement()); | ||||
first = false; | |||||
} | } | ||||
sb.append(")"); | sb.append(")"); | ||||
prompt = sb.toString(); | prompt = sb.toString(); | ||||
@@ -59,6 +59,7 @@ package org.apache.tools.ant.input; | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @version $Revision$ | * @version $Revision$ | ||||
* @since Ant 1.5 | |||||
*/ | */ | ||||
public interface InputHandler { | public interface InputHandler { | ||||
@@ -59,6 +59,7 @@ package org.apache.tools.ant.input; | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @version $Revision$ | * @version $Revision$ | ||||
* @since Ant 1.5 | |||||
*/ | */ | ||||
public class InputRequest { | public class InputRequest { | ||||
private String prompt; | private String prompt; | ||||
@@ -61,6 +61,7 @@ import java.util.Vector; | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @version $Revision$ | * @version $Revision$ | ||||
* @since Ant 1.5 | |||||
*/ | */ | ||||
public class MultipleChoiceInputRequest extends InputRequest { | public class MultipleChoiceInputRequest extends InputRequest { | ||||
private Vector choices = new Vector(); | private Vector choices = new Vector(); | ||||
@@ -79,12 +80,15 @@ public class MultipleChoiceInputRequest extends InputRequest { | |||||
} | } | ||||
/** | /** | ||||
* The possible values. | |||||
* @return The possible values. | |||||
*/ | */ | ||||
public Vector getChoices() { | public Vector getChoices() { | ||||
return choices; | return choices; | ||||
} | } | ||||
/** | |||||
* @return true if the input is one of the allowed values. | |||||
*/ | |||||
public boolean isInputValid() { | public boolean isInputValid() { | ||||
return choices.contains(getInput()); | return choices.contains(getInput()); | ||||
} | } | ||||
@@ -66,6 +66,7 @@ import java.util.Properties; | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @version $Revision$ | * @version $Revision$ | ||||
* @since Ant 1.5 | |||||
*/ | */ | ||||
public class PropertyFileInputHandler implements InputHandler { | public class PropertyFileInputHandler implements InputHandler { | ||||
private Properties props = null; | private Properties props = null; | ||||
@@ -81,6 +82,12 @@ public class PropertyFileInputHandler implements InputHandler { | |||||
public PropertyFileInputHandler() { | public PropertyFileInputHandler() { | ||||
} | } | ||||
/** | |||||
* Picks up the input from a property, using the prompt as the | |||||
* name of the property. | |||||
* | |||||
* @exception BuildException if no property of that name can be found. | |||||
*/ | |||||
public void handleInput(InputRequest request) throws BuildException { | public void handleInput(InputRequest request) throws BuildException { | ||||
readProps(); | readProps(); | ||||
Object o = props.get(request.getPrompt()); | Object o = props.get(request.getPrompt()); | ||||
@@ -95,13 +102,17 @@ public class PropertyFileInputHandler implements InputHandler { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Reads the properties file if it hasn't already been read. | |||||
*/ | |||||
private synchronized void readProps() throws BuildException { | private synchronized void readProps() throws BuildException { | ||||
if (props == null) { | if (props == null) { | ||||
String propsFile = System.getProperty(FILE_NAME_KEY); | String propsFile = System.getProperty(FILE_NAME_KEY); | ||||
if (propsFile == null) { | if (propsFile == null) { | ||||
throw new BuildException("System property " | throw new BuildException("System property " | ||||
+ FILE_NAME_KEY | + FILE_NAME_KEY | ||||
+ " for PropertyFileInputHandler not set"); | |||||
+ " for PropertyFileInputHandler not" | |||||
+ " set"); | |||||
} | } | ||||
props = new Properties(); | props = new Properties(); | ||||
@@ -109,7 +120,7 @@ public class PropertyFileInputHandler implements InputHandler { | |||||
try { | try { | ||||
props.load(new FileInputStream(propsFile)); | props.load(new FileInputStream(propsFile)); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new BuildException("Couldn't load "+propsFile, e); | |||||
throw new BuildException("Couldn't load " + propsFile, e); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -70,6 +70,8 @@ import org.apache.tools.ant.util.StringUtils; | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* | * | ||||
* @since Ant 1.5 | * @since Ant 1.5 | ||||
* | |||||
* @ant.task category="control" | |||||
*/ | */ | ||||
public class Input extends Task { | public class Input extends Task { | ||||
private String validargs = null; | private String validargs = null; | ||||
@@ -136,12 +138,7 @@ public class Input extends Task { | |||||
getProject().getInputHandler().handleInput(request); | getProject().getInputHandler().handleInput(request); | ||||
if (addproperty != null) { | if (addproperty != null) { | ||||
if (project.getProperty(addproperty) == null) { | |||||
project.setNewProperty(addproperty, request.getInput()); | |||||
} else { | |||||
log("Override ignored for " + addproperty, | |||||
Project.MSG_VERBOSE); | |||||
} | |||||
project.setNewProperty(addproperty, request.getInput()); | |||||
} | } | ||||
} | } | ||||