Browse Source

Cleanup

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272497 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 23 years ago
parent
commit
944aa460d4
8 changed files with 370 additions and 263 deletions
  1. +167
    -122
      proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java
  2. +172
    -128
      proposal/sandbox/input/src/main/org/apache/tools/ant/Project.java
  3. +8
    -4
      proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java
  4. +1
    -0
      proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java
  5. +1
    -0
      proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java
  6. +5
    -1
      proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
  7. +13
    -2
      proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
  8. +3
    -6
      proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java

+ 167
- 122
proposal/sandbox/input/src/main/org/apache/tools/ant/Main.java View File

@@ -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
* <code>null</code>.
*
*
* @param t Throwable to print the message of.
* Must not be <code>null</code>.
*/
@@ -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 <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.
* @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.
*/
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 <code>null</code>.
*
*
* @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 <code>null</code>.
* @param suffix Suffix filename to look for in parents.
* Must not be <code>null</code>.
*
*
* @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 <code>null</code>, 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 <code>null</code>.
*/
@@ -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 <code>System.out</code>.
*
*
* @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-<code>null</code>)
*
*
* @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
* <code>System.out</code>.
*
*
* @param project The project to display a description of.
* 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.
*
*
* @param project The project to display a description of.
* Must not be <code>null</code>.
* @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 <code>null</code>.
* @param name The name to find a place for.
* Must not be <code>null</code>.
*
*
* @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; 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;
}
}
@@ -871,23 +901,38 @@ public class Main {

/**
* 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
String lSep = System.getProperty("line.separator");
// got a bit annoyed that I couldn't find a pad function
String spaces = " ";
while (spaces.length()<maxlen) {
while (spaces.length() < maxlen) {
spaces += spaces;
}
StringBuffer msg = new StringBuffer();
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(names.elementAt(i));
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(lSep);


+ 172
- 128
proposal/sandbox/input/src/main/org/apache/tools/ant/Project.java View File

@@ -68,6 +68,7 @@ import java.lang.reflect.Modifier;
import org.apache.tools.ant.types.FilterSet;
import org.apache.tools.ant.types.FilterSetCollection;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.input.InputHandler;

/**
@@ -88,45 +89,42 @@ import org.apache.tools.ant.input.InputHandler;
public class Project {

/** Message priority of "error". */
public final static int MSG_ERR = 0;
public static final int MSG_ERR = 0;
/** Message priority of "warning". */
public final static int MSG_WARN = 1;
public static final int MSG_WARN = 1;
/** Message priority of "information". */
public final static int MSG_INFO = 2;
public static final int MSG_INFO = 2;
/** Message priority of "verbose". */
public final static int MSG_VERBOSE = 3;
public static final int MSG_VERBOSE = 3;
/** 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
* 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
* 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 */
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 */
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 */
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 */
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 */
public final static String JAVA_1_4 = "1.4";
public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4;

/** 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. */
public final static String TOKEN_END = FilterSet.DEFAULT_TOKEN_END;
public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END;

/** Name of this project. */
private String name;
@@ -166,7 +164,9 @@ public class Project {
* contains one FilterSet, but the wrapper is needed in order to
* make it easier to use the FileUtils interface.
*/
private FilterSetCollection globalFilters = new FilterSetCollection(globalFilterSet);
private FilterSetCollection globalFilters
= new FilterSetCollection(globalFilterSet);
/** Project base directory. */
private File baseDir;

@@ -207,31 +207,6 @@ public class Project {
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. */
private FileUtils fileUtils;

@@ -272,9 +247,11 @@ public class Project {
Class taskClass = Class.forName(value);
addTaskDefinition(key, taskClass);
} 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) {
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) {
@@ -283,7 +260,7 @@ public class Project {

String dataDefs = "/org/apache/tools/ant/types/defaults.properties";

try{
try {
Properties props = new Properties();
InputStream in = this.getClass().getResourceAsStream(dataDefs);
if (in == null) {
@@ -481,6 +458,10 @@ public class Project {
/**
* Sets a property unless it is already defined as a user property
* (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) {
if (null != userProperties.get(name)) {
@@ -517,8 +498,8 @@ public class Project {
* by values, or <code>null</code> if the given string is
* <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)
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 <code>null</code>.
* @param value The replacement value.
* Must not be <code>null</code>.
* @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 <code>null</code>.
*
* @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 <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>.
*/
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 <code>null</code>.
*
* @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});
}
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 (<code>false</code>).
*/
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 <code>null</code>, 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 <code>null</code>.
*
* @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 <code>null</code>.
*
* @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 <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);
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 <code>null</code>.
*/
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 <code>null</code>.
* @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 <code>null</code>.
* @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 <code>null</code>.
* @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);
}
}

+ 8
- 4
proposal/sandbox/input/src/main/org/apache/tools/ant/input/DefaultInputHandler.java View File

@@ -67,6 +67,7 @@ import org.apache.tools.ant.BuildException;
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @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.
*
* <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>
*
* @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();


+ 1
- 0
proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputHandler.java View File

@@ -59,6 +59,7 @@ package org.apache.tools.ant.input;
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
* @since Ant 1.5
*/
public interface InputHandler {



+ 1
- 0
proposal/sandbox/input/src/main/org/apache/tools/ant/input/InputRequest.java View File

@@ -59,6 +59,7 @@ package org.apache.tools.ant.input;
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
* @since Ant 1.5
*/
public class InputRequest {
private String prompt;


+ 5
- 1
proposal/sandbox/input/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java View File

@@ -61,6 +61,7 @@ import java.util.Vector;
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @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());
}


+ 13
- 2
proposal/sandbox/input/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java View File

@@ -66,6 +66,7 @@ import java.util.Properties;
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @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);
}
}
}


+ 3
- 6
proposal/sandbox/input/src/main/org/apache/tools/ant/taskdefs/Input.java View File

@@ -70,6 +70,8 @@ import org.apache.tools.ant.util.StringUtils;
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*
* @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());
}
}



Loading…
Cancel
Save