From 944aa460d4c23ae00ef6ead10666d67b9db82a6c Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 18 Apr 2002 12:10:15 +0000 Subject: [PATCH] Cleanup git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272497 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/main/org/apache/tools/ant/Main.java | 289 ++++++++++------- .../main/org/apache/tools/ant/Project.java | 300 ++++++++++-------- .../tools/ant/input/DefaultInputHandler.java | 12 +- .../apache/tools/ant/input/InputHandler.java | 1 + .../apache/tools/ant/input/InputRequest.java | 1 + .../ant/input/MultipleChoiceInputRequest.java | 6 +- .../ant/input/PropertyFileInputHandler.java | 15 +- .../org/apache/tools/ant/taskdefs/Input.java | 9 +- 8 files changed, 370 insertions(+), 263 deletions(-) diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java index 240255a65..719a5b981 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java @@ -82,7 +82,7 @@ import java.util.Enumeration; public class Main { /** 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. */ private int msgOutputLevel = Project.MSG_INFO; @@ -91,10 +91,10 @@ public class Main { private File buildFile; /* null */ /** 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. */ - private PrintStream err = System.err; + private static PrintStream err = System.err; /** The build targets. */ private Vector targets = new Vector(5); @@ -104,13 +104,13 @@ public class Main { /** Names of classes to add as listeners to project. */ private Vector listeners = new Vector(5); - + /** File names of property files to load on startup. */ 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. */ private String loggerClassname = null; @@ -135,15 +135,21 @@ public class Main { 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. */ 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 * null. - * + * * @param t Throwable to print the message of. * Must not be null. */ @@ -158,12 +164,12 @@ public class Main { * Creates a new instance of this class using the * arguments specified, gives it any extra user properties which have been * specified, and then runs the build using the classloader provided. - * + * * @param args Command line arguments. Must not be null. - * @param additionalUserProperties Any extra properties to use in this - * build. May be null, which is the equivalent to + * @param additionalUserProperties Any extra properties to use in this + * build. May be null, which is the equivalent to * 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 * null in which case the system classloader is used. */ public static void start(String[] args, Properties additionalUserProperties, @@ -172,19 +178,20 @@ public class Main { try { m = new Main(args); - } catch(Throwable exc) { + } catch (Throwable exc) { printMessage(exc); System.exit(1); } if (additionalUserProperties != null) { - for (Enumeration e = additionalUserProperties.keys(); e.hasMoreElements(); ) { + for (Enumeration e = additionalUserProperties.keys(); + e.hasMoreElements();) { String key = (String) e.nextElement(); String property = additionalUserProperties.getProperty(key); m.definedProps.put(key, property); } } - + try { m.runBuild(coreLoader); System.exit(0); @@ -193,13 +200,30 @@ public class Main { printMessage(be); } System.exit(1); - } catch(Throwable exc) { + } catch (Throwable exc) { exc.printStackTrace(); printMessage(exc); 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 * 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 // what? /** - * Sole constructor, which parses and deals with command line + * Sole constructor, which parses and deals with command line * arguments. - * + * * @param args Command line arguments. Must not be null. - * + * * @exception BuildException if the specified build file doesn't exist * or is a directory. */ @@ -249,15 +273,17 @@ public class Main { msgOutputLevel = Project.MSG_DEBUG; } else if (arg.equals("-logfile") || arg.equals("-l")) { try { - File logFile = new File(args[i+1]); + File logFile = new File(args[i + 1]); i++; out = new PrintStream(new FileOutputStream(logFile)); err = out; System.setOut(out); System.setErr(out); + isLogFileUsed = true; } 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); return; } catch (ArrayIndexOutOfBoundsException aioobe) { @@ -266,9 +292,10 @@ public class Main { System.out.println(msg); return; } - } else if (arg.equals("-buildfile") || arg.equals("-file") || arg.equals("-f")) { + } else if (arg.equals("-buildfile") || arg.equals("-file") + || arg.equals("-f")) { try { - buildFile = new File(args[i+1]); + buildFile = new File(args[i + 1]); i++; } catch (ArrayIndexOutOfBoundsException aioobe) { String msg = "You must specify a buildfile when " + @@ -278,7 +305,7 @@ public class Main { } } else if (arg.equals("-listener")) { try { - listeners.addElement(args[i+1]); + listeners.addElement(args[i + 1]); i++; } catch (ArrayIndexOutOfBoundsException aioobe) { String msg = "You must specify a classname when " + @@ -303,35 +330,35 @@ public class Main { String value = null; int posEq = name.indexOf("="); if (posEq > 0) { - value = name.substring(posEq+1); + value = name.substring(posEq + 1); name = name.substring(0, posEq); - } else if (i < args.length-1) { + } else if (i < args.length - 1) { value = args[++i]; } definedProps.put(name, value); } else if (arg.equals("-logger")) { if (loggerClassname != null) { - System.out.println("Only one logger class may be specified."); + System.out.println("Only one logger class may " + + " be specified."); return; } try { loggerClassname = args[++i]; - } - catch (ArrayIndexOutOfBoundsException aioobe) { + } catch (ArrayIndexOutOfBoundsException aioobe) { System.out.println("You must specify a classname when " + "using the -logger argument"); return; } } else if (arg.equals("-inputhandler")) { 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; } try { inputHandlerClassname = args[++i]; - } - catch (ArrayIndexOutOfBoundsException aioobe) { + } catch (ArrayIndexOutOfBoundsException aioobe) { System.out.println("You must specify a classname when " + "using the -inputhandler argument"); return; @@ -343,14 +370,14 @@ public class Main { projectHelp = true; } else if (arg.equals("-find")) { // eat up next arg if present, default to build.xml - if (i < args.length-1) { + if (i < args.length - 1) { searchForThis = args[++i]; } else { searchForThis = DEFAULT_BUILD_FILENAME; } } else if (arg.startsWith("-propertyfile")) { try { - propertyFiles.addElement(args[i+1]); + propertyFiles.addElement(args[i + 1]); i++; } catch (ArrayIndexOutOfBoundsException aioobe) { String msg = "You must specify a property filename when " + @@ -369,12 +396,12 @@ public class Main { targets.addElement(arg); } } - + // if buildFile was not specified on the command line, if (buildFile == null) { // but -find then search for it if (searchForThis != null) { - buildFile = findBuildFile(System.getProperty("user.dir"), + buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis); } else { buildFile = new File(DEFAULT_BUILD_FILENAME); @@ -396,17 +423,17 @@ public class Main { } // Load the property files specified by -propertyfile - for (int propertyFileIndex=0; + for (int propertyFileIndex = 0; propertyFileIndex < propertyFiles.size(); propertyFileIndex++) { - String filename = (String) propertyFiles.elementAt(propertyFileIndex); + String filename + = (String) propertyFiles.elementAt(propertyFileIndex); Properties props = new Properties(); FileInputStream fis = null; try { fis = new FileInputStream(filename); props.load(fis); - } - catch (IOException e) { + } catch (IOException e) { System.out.println("Could not load property file " + filename + ": " + e.getMessage()); } finally { @@ -417,7 +444,7 @@ public class Main { } } } - + // ensure that -D properties take precedence Enumeration propertyNames = props.propertyNames(); while (propertyNames.hasMoreElements()) { @@ -445,7 +472,7 @@ public class Main { filename = file.getParent(); 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); @@ -463,34 +490,35 @@ public class Main { * Must not be null. * @param suffix Suffix filename to look for in parents. * Must not be null. - * + * * @return A handle to the build file if one 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) { System.out.println("Searching for " + suffix + " ..."); } File parent = new File(new File(start).getAbsolutePath()); File file = new File(parent, suffix); - + // check if the target file exists in the current directory while (!file.exists()) { // change to parent directory parent = getParentFile(parent); - + // if parent is null, then we are at the root of the fs, // complain that we can't find the build file. if (parent == null) { throw new BuildException("Could not locate a build file!"); } - + // refresh our file handle file = new File(parent, suffix); } - + return file; } @@ -498,11 +526,11 @@ public class Main { * Executes the build. If the constructor for this instance failed * (e.g. returned after issuing a warning), this method returns * immediately. - * + * * @param coreLoader The classloader to use to find core classes. * May be null, in which case the * system classloader is used. - * + * * @exception BuildException if the build fails */ private void runBuild(ClassLoader coreLoader) throws BuildException { @@ -532,11 +560,11 @@ public class Main { // use a system manager that prevents from System.exit() // only in JDK > 1.1 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(); - //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 //ant class if we are going to implement it. //System.setSecurityManager(new NoExitSecurityManager()); @@ -554,17 +582,19 @@ public class Main { // set user-define properties Enumeration e = definedProps.keys(); 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("ant.file" , buildFile.getAbsolutePath() ); - + + project.setUserProperty("ant.file", + buildFile.getAbsolutePath()); + // first use the ProjectHelper to create the project object // 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 { Class.forName("javax.xml.parsers.SAXParserFactory"); ProjectHelper.configureProject(project, buildFile); @@ -578,18 +608,17 @@ public class Main { if (projectHelp) { printDescription(project); - printTargets(project, msgOutputLevel > Project.MSG_INFO ); + printTargets(project, msgOutputLevel > Project.MSG_INFO); return; } - + // make sure that we have a target to execute if (targets.size() == 0) { targets.addElement(project.getDefaultTarget()); } - + project.executeTargets(targets); - } - finally { + } finally { // put back the original security manager //The following will never eval to true. (PD) if (oldsm != null){ @@ -599,16 +628,13 @@ public class Main { System.setOut(out); System.setErr(err); } - } - catch(RuntimeException exc) { + } catch (RuntimeException exc) { error = exc; throw exc; - } - catch(Error err) { + } catch (Error err) { error = err; throw err; - } - finally { + } finally { if (!projectHelp) { project.fireBuildFinished(error); } @@ -618,7 +644,7 @@ public class Main { /** * Adds the listeners specified in the command line arguments, * along with the default listener, to the specified project. - * + * * @param project The project to add listeners to. * Must not be null. */ @@ -633,9 +659,9 @@ public class Main { BuildListener listener = (BuildListener) Class.forName(className).newInstance(); 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(); } else { 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 " + inputHandlerClassname + " does not implement the InputHandler interface"; throw new BuildException(msg); } 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); } } 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 - // 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() { BuildLogger logger = null; if (loggerClassname != null) { 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(); - } - 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(); } - } - else { + } else { logger = new DefaultLogger(); } @@ -736,7 +765,7 @@ public class Main { /** * Prints the Ant version information to System.out. - * + * * @exception BuildException if the version information is unavailable */ private static void printVersion() throws BuildException { @@ -752,10 +781,10 @@ public class Main { * Returns the Ant version information, if available. Once the information * has been loaded once, it's cached and returned from the cache on future * calls. - * - * @return the Ant version information as a String + * + * @return the Ant version information as a String * (always non-null) - * + * * @exception BuildException if the version information is unavailable */ public static synchronized String getAntVersion() throws BuildException { @@ -766,7 +795,7 @@ public class Main { Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt"); props.load(in); in.close(); - + String lSep = System.getProperty("line.separator"); StringBuffer msg = new StringBuffer(); 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 * System.out. - * + * * @param project The project to display a description of. * Must not be null. */ @@ -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 * System.out, optionally including subtargets. - * + * * @param project The project to display a description of. * Must not be null. * @param printSubTargets Whether or not subtarget names should also be @@ -820,7 +849,7 @@ public class Main { Vector subNames = new Vector(); while (ptargets.hasMoreElements()) { - currentTarget = (Target)ptargets.nextElement(); + currentTarget = (Target) ptargets.nextElement(); targetName = currentTarget.getName(); targetDescription = currentTarget.getDescription(); // maintain a sorted list of targets @@ -838,31 +867,32 @@ public class Main { } printTargets(topNames, topDescriptions, "Main targets:", maxLength); - - if( printSubTargets ) { + + if (printSubTargets) { printTargets(subNames, null, "Subtargets:", 0); } 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 * to keep the list sorted alphabetically. - * + * * @param names The current list of names. Must not be null. * @param name The name to find a place for. * Must not be null. - * + * * @return the correct place in the list for the given name */ private static int findTargetPosition(Vector names, String name) { int res = names.size(); - for (int i=0; iSystem.out - * with an optional description + * with an optional description. + * + * @param names The names to be printed. + * Must not be null. + * @param descriptions The associated target descriptions. + * May be null, in which case + * no descriptions are displayed. + * If non-null, this should have + * as many elements as names. + * @param heading The heading to display. + * Should not be null. + * @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 + * are 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 String lSep = System.getProperty("line.separator"); // got a bit annoyed that I couldn't find a pad function String spaces = " "; - while (spaces.length()null. + * @param value The property value. Must not be null. */ private void setPropertyInternal(String name, String value) { if (null != userProperties.get(name)) { @@ -517,8 +498,8 @@ public class Project { * by values, or null if the given string is * null. * - * @exception BuildException if the given value has an unclosed property name, - * e.g. ${xxx + * @exception BuildException if the given value has an unclosed + * property name, e.g. ${xxx */ public String replaceProperties(String value) throws BuildException { @@ -544,7 +525,8 @@ public class Project { /** * 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() { Hashtable propertiesCopy = new Hashtable(); @@ -656,6 +638,8 @@ public class Project { * * @param token The token to filter. * Must not be null. + * @param value The replacement value. + * Must not be null. * @deprecated Use getGlobalFilterSet().addFilter(token,value) * * @see #getGlobalFilterSet() @@ -710,13 +694,15 @@ public class Project { public void setBaseDir(File baseDir) throws BuildException { baseDir = fileUtils.normalize(baseDir.getAbsolutePath()); if (!baseDir.exists()) { - throw new BuildException("Basedir " + baseDir.getAbsolutePath() + " does not exist"); + throw new BuildException("Basedir " + baseDir.getAbsolutePath() + + " does not exist"); } 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; - setPropertyInternal( "basedir", this.baseDir.getPath()); + setPropertyInternal("basedir", this.baseDir.getPath()); String msg = "Project base dir set to: " + this.baseDir; log(msg, MSG_VERBOSE); } @@ -741,9 +727,10 @@ public class Project { /** * Returns the version of Java this class is running under. * @return the version of Java as a String, e.g. "1.1" + * @see org.apache.tools.ant.util.JavaEnvUtils#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 * - * @see #getJavaVersion() + * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion */ public void setJavaVersionProperty() throws BuildException { + String javaVersion = JavaEnvUtils.getJavaVersion(); setPropertyInternal("ant.java.version", javaVersion); // sanity check - if (javaVersion == JAVA_1_0) { + if (javaVersion == JavaEnvUtils.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); } @@ -803,8 +792,9 @@ public class Project { * * @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 (old.equals(taskClass)) { log("Ignoring override for task " + taskName @@ -812,7 +802,7 @@ public class Project { MSG_VERBOSE); return; } else { - log("Trying to override old definition of task "+taskName, + log("Trying to override old definition of task " + taskName, MSG_WARN); invalidateCreatedTasks(taskName); } @@ -829,31 +819,35 @@ public class Project { * Ant task implementation classes must be public, concrete, and have * a no-arg constructor. * + * @param taskClass The class to be checked. + * Must not be null. + * * @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. */ 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"; log(message, Project.MSG_ERR); throw new BuildException(message); } - if(Modifier.isAbstract(taskClass.getModifiers())) { + if (Modifier.isAbstract(taskClass.getModifiers())) { final String message = taskClass + " is abstract"; log(message, Project.MSG_ERR); throw new BuildException(message); } try { - taskClass.getConstructor( null ); + taskClass.getConstructor(null); // don't have to check for public, since // 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); throw new BuildException(message); } - if( !Task.class.isAssignableFrom(taskClass) ) { + if (!Task.class.isAssignableFrom(taskClass)) { TaskAdapter.checkTaskClass(taskClass, this); } } @@ -879,11 +873,11 @@ public class Project { * * @param typeName The name of the datatype. * Must not be null. - * @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 null. */ public void addDataTypeDefinition(String typeName, Class typeClass) { - Class old = (Class)dataClassDefinitions.get(typeName); + Class old = (Class) dataClassDefinitions.get(typeName); if (null != old) { if (old.equals(typeClass)) { log("Ignoring override for datatype " + typeName @@ -891,19 +885,20 @@ public class Project { MSG_VERBOSE); return; } 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); 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 * (String to Class). @@ -922,10 +917,10 @@ public class Project { * * @see Project#addOrReplaceTarget */ - public void addTarget(Target target) { + public void addTarget(Target target) throws BuildException { String name = target.getName(); if (targets.get(name) != null) { - throw new BuildException("Duplicate target: `"+name+"'"); + throw new BuildException("Duplicate target: `" + name + "'"); } addOrReplaceTarget(name, target); } @@ -945,7 +940,7 @@ public class Project { public void addTarget(String targetName, Target target) throws BuildException { if (targets.get(targetName) != null) { - throw new BuildException("Duplicate target: `"+targetName+"'"); + throw new BuildException("Duplicate target: `" + targetName + "'"); } addOrReplaceTarget(targetName, target); } @@ -1008,14 +1003,14 @@ public class Project { try { Object o = c.newInstance(); Task task = null; - if( o instanceof Task ) { - task=(Task)o; + if (o instanceof Task) { + task = (Task) o; } else { // "Generic" Bean - use the setter pattern // 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.setTaskType(taskType); @@ -1080,7 +1075,7 @@ public class Project { /** * 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 null. * * @return an instance of the specified data type, or null if @@ -1116,7 +1111,7 @@ public class Project { o = ctor.newInstance(new Object[] {this}); } if (o instanceof ProjectComponent) { - ((ProjectComponent)o).setProject(this); + ((ProjectComponent) o).setProject(this); } String msg = " +DataType: " + typeName; log (msg, MSG_DEBUG); @@ -1146,7 +1141,7 @@ public class Project { Throwable error = null; 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 (false). */ public void demuxOutput(String line, boolean isError) { - Task task = (Task)threadTasks.get(Thread.currentThread()); + Task task = (Task) threadTasks.get(Thread.currentThread()); if (task == null) { fireMessageLogged(this, line, isError ? MSG_ERR : MSG_INFO); - } - else { + } else { if (isError) { task.handleErrorOutput(line); - } - else { + } else { task.handleOutput(line); } } @@ -1221,6 +1214,8 @@ public class Project { * respect to. May be null, in which case * the current directory is used. * + * @return the resolved File. + * * @deprecated */ public File resolveFile(String fileName, File rootDir) { @@ -1235,6 +1230,9 @@ public class Project { * * @param fileName The name of the file to resolve. * Must not be null. + * + * @return the resolved File. + * */ public File resolveFile(String fileName) { return fileUtils.resolveFile(baseDir, fileName); @@ -1257,7 +1255,7 @@ public class Project { * @see PathTokenizer */ public static String translatePath(String toProcess) { - if ( toProcess == null || toProcess.length() == 0 ) { + if (toProcess == null || toProcess.length() == 0) { return ""; } @@ -1289,7 +1287,8 @@ public class Project { * * @deprecated */ - public void copyFile(String sourceFile, String destFile) throws IOException { + public void copyFile(String sourceFile, String destFile) + throws IOException { fileUtils.copyFile(sourceFile, destFile); } @@ -1310,7 +1309,8 @@ public class Project { */ public void copyFile(String sourceFile, String destFile, boolean filtering) 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, 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, boolean overwrite, boolean preserveLastModified) 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) 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 * overwritten if it already exists. * - * @exception IOException + * @exception IOException if the file cannot be copied. * * @deprecated */ public void copyFile(File sourceFile, File destFile, boolean filtering, 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 * of the source file. * - * @exception IOException if the copying fails + * @exception IOException if the file cannot be copied. * * @deprecated */ public void copyFile(File sourceFile, File destFile, boolean filtering, boolean overwrite, boolean preserveLastModified) 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 * 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 null. * + * @param time the required modification time. + * * @deprecated * * @exception BuildException if the last modified time cannot be set * despite running on a platform with a version * 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 + " in JDK 1.1", Project.MSG_WARN); return; @@ -1526,18 +1532,18 @@ public class Project { // build Target. 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); if (st == null) { 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; } @@ -1588,7 +1594,7 @@ public class Project { state.put(root, VISITING); visiting.push(root); - Target target = (Target)(targets.get(root)); + Target target = (Target) targets.get(root); // Make sure we exist if (target == null) { @@ -1597,7 +1603,7 @@ public class Project { sb.append("' does not exist in this project. "); visiting.pop(); if (!visiting.empty()) { - String parent = (String)visiting.peek(); + String parent = (String) visiting.peek(); sb.append("It is used from target `"); sb.append(parent); sb.append("'."); @@ -1606,14 +1612,13 @@ public class Project { 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 m=(String)state.get(cur); + String m = (String) state.get(cur); if (m == null) { // Not been visited tsort(cur, targets, state, visiting, ret); - } - else if (m == VISITING) { + } else if (m == VISITING) { // Currently visiting this node, so have a cycle throw makeCircularException(cur, visiting); } @@ -1621,14 +1626,16 @@ public class Project { String p = (String) visiting.pop(); 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); 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 null. * @param stk A stack of dependencies. Must not be null. @@ -1640,10 +1647,10 @@ public class Project { sb.append(end); String c; do { - c = (String)stk.pop(); + c = (String) stk.pop(); sb.append(" <- "); sb.append(c); - } while(!c.equals(end)); + } while (!c.equals(end)); return new BuildException(new String(sb)); } @@ -1654,12 +1661,17 @@ public class Project { * @param value The value of the reference. Must not be null. */ 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, MSG_WARN); } 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) { // register this as the current task on the current thread. - threadTasks.put(Thread.currentThread(), task); + registerThreadTask(Thread.currentThread(), task); BuildEvent event = new BuildEvent(task); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); @@ -1811,7 +1823,7 @@ public class Project { * a successful build. */ protected void fireTaskFinished(Task task, Throwable exception) { - threadTasks.remove(Thread.currentThread()); + registerThreadTask(Thread.currentThread(), null); System.out.flush(); System.err.flush(); BuildEvent event = new BuildEvent(task); @@ -1832,7 +1844,8 @@ public class Project { * @param message The message to send. Should not be null. * @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); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); @@ -1849,7 +1862,8 @@ public class Project { * @param message The message to send. Should not be null. * @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); fireMessageLoggedEvent(event, message, priority); } @@ -1863,7 +1877,8 @@ public class Project { * @param message The message to send. Should not be null. * @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); fireMessageLoggedEvent(event, message, priority); } @@ -1881,4 +1896,33 @@ public class Project { BuildEvent event = new BuildEvent(task); 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); + } + + } diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java index cb9d85b42..679e3574f 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java @@ -67,6 +67,7 @@ import org.apache.tools.ant.BuildException; * * @author Stefan Bodewig * @version $Revision$ + * @since Ant 1.5 */ public class DefaultInputHandler implements InputHandler { @@ -76,6 +77,10 @@ public class DefaultInputHandler implements InputHandler { public DefaultInputHandler() { } + /** + * Prompts and requests input. May loop until a valid input has + * been entered. + */ public void handleInput(InputRequest request) throws BuildException { String prompt = getPrompt(request); BufferedReader in = @@ -95,7 +100,7 @@ public class DefaultInputHandler implements InputHandler { /** * Constructs user prompt from a request. * - *

This implemenation adds (choice1,choice2,choice3,...) to the + *

This implementation adds (choice1,choice2,choice3,...) to the * prompt for MultipleChoiceInputRequests.

* * @param request the request to construct the prompt for. @@ -110,12 +115,11 @@ public class DefaultInputHandler implements InputHandler { ((MultipleChoiceInputRequest) request).getChoices().elements(); boolean first = true; while (enum.hasMoreElements()) { - if (first) { - first = false; - } else { + if (!first) { sb.append(","); } sb.append(enum.nextElement()); + first = false; } sb.append(")"); prompt = sb.toString(); diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java index 5fb55e564..da8a148fd 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java @@ -59,6 +59,7 @@ package org.apache.tools.ant.input; * * @author Stefan Bodewig * @version $Revision$ + * @since Ant 1.5 */ public interface InputHandler { diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java index f1fbfad43..3e4c232a1 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java @@ -59,6 +59,7 @@ package org.apache.tools.ant.input; * * @author Stefan Bodewig * @version $Revision$ + * @since Ant 1.5 */ public class InputRequest { private String prompt; diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java index 5163239a1..783accdf9 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java @@ -61,6 +61,7 @@ import java.util.Vector; * * @author Stefan Bodewig * @version $Revision$ + * @since Ant 1.5 */ public class MultipleChoiceInputRequest extends InputRequest { private Vector choices = new Vector(); @@ -79,12 +80,15 @@ public class MultipleChoiceInputRequest extends InputRequest { } /** - * The possible values. + * @return The possible values. */ public Vector getChoices() { return choices; } + /** + * @return true if the input is one of the allowed values. + */ public boolean isInputValid() { return choices.contains(getInput()); } diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java index 516a9ffcd..19eb5c997 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java @@ -66,6 +66,7 @@ import java.util.Properties; * * @author Stefan Bodewig * @version $Revision$ + * @since Ant 1.5 */ public class PropertyFileInputHandler implements InputHandler { private Properties props = null; @@ -81,6 +82,12 @@ public class PropertyFileInputHandler implements InputHandler { 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 { readProps(); 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 { if (props == null) { String propsFile = System.getProperty(FILE_NAME_KEY); if (propsFile == null) { throw new BuildException("System property " + FILE_NAME_KEY - + " for PropertyFileInputHandler not set"); + + " for PropertyFileInputHandler not" + + " set"); } props = new Properties(); @@ -109,7 +120,7 @@ public class PropertyFileInputHandler implements InputHandler { try { props.load(new FileInputStream(propsFile)); } catch (IOException e) { - throw new BuildException("Couldn't load "+propsFile, e); + throw new BuildException("Couldn't load " + propsFile, e); } } } diff --git a/proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java b/proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java index 95e55e8dc..265c6a884 100644 --- a/proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java +++ b/proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java @@ -70,6 +70,8 @@ import org.apache.tools.ant.util.StringUtils; * @author Stefan Bodewig * * @since Ant 1.5 + * + * @ant.task category="control" */ public class Input extends Task { private String validargs = null; @@ -136,12 +138,7 @@ public class Input extends Task { getProject().getInputHandler().handleInput(request); 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()); } }