git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@359317 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -339,6 +339,8 @@ Other changes: | |||
| * added the onmissingfiltersfile attribute to filterset. Bugzilla report 19845. | |||
| * added the inline handler element to the input task. | |||
| Changes from Ant 1.6.4 to Ant 1.6.5 | |||
| =================================== | |||
| @@ -78,6 +78,55 @@ file and load in before the input task.</p> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters Specified as Nested Elements</h3> | |||
| <h4>Handler</h4> | |||
| <p>Since <b>Ant 1.7</b>, a nested <handler> element can be used to | |||
| specify an InputHandler, so that different InputHandlers may be used | |||
| among different Input tasks. | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">type</td> | |||
| <td valign="top">one of "default","propertyfile", or "greedy". | |||
| </td> | |||
| <td align="center" valign="top" rowspan="3">One of these</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">refid</td> | |||
| <td valign="top">Reference to an <code>InputHandler</code> | |||
| defined elsewhere in the project. | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classname</td> | |||
| <td valign="top">The name of an <code>InputHandler</code> subclass.</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpath</td> | |||
| <td valign="top">The classpath to use with <i>classname</i>.</td> | |||
| <td valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpathref</td> | |||
| <td valign="top">The refid of a classpath to use with <i>classname</i>.</td> | |||
| <td valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">loaderref</td> | |||
| <td valign="top">The refid of a classloader to use with <i>classname</i>. | |||
| </td> | |||
| <td valign="top">No</td> | |||
| </tr> | |||
| </table> | |||
| <br /> | |||
| The classpath can also be specified by means of one or more nested | |||
| <classpath> elements.</p> | |||
| <h3>Examples</h3> | |||
| <pre> <input/></pre> | |||
| <p>Will pause the build run until return key is pressed when using the | |||
| @@ -0,0 +1,2 @@ | |||
| foo | |||
| bar | |||
| @@ -28,4 +28,76 @@ | |||
| /> | |||
| </target> | |||
| <target name="testPropertyFileInlineHandler"> | |||
| <input message="Press Return key to continue..." addproperty="test"> | |||
| <handler type="propertyfile" /> | |||
| </input> | |||
| <fail> | |||
| <condition> | |||
| <not> | |||
| <equals arg1="${test}" arg2="test" /> | |||
| </not> | |||
| </condition> | |||
| </fail> | |||
| </target> | |||
| <target name="testDefaultInlineHandler"> | |||
| <input message="Press Return key to continue..." addproperty="test"> | |||
| <handler type="default" /> | |||
| </input> | |||
| <fail message="$${test} = ${test}"> | |||
| <condition> | |||
| <not> | |||
| <equals arg1="${test}" arg2="foo" /> | |||
| </not> | |||
| </condition> | |||
| </fail> | |||
| </target> | |||
| <target name="testGreedyInlineHandler"> | |||
| <input message="Press Return key to continue..." addproperty="test"> | |||
| <handler type="greedy" /> | |||
| </input> | |||
| <fail message="$${test} = ${test}"> | |||
| <condition> | |||
| <not> | |||
| <equals arg1="${test}" | |||
| arg2="foo${line.separator}bar${line.separator}" /> | |||
| </not> | |||
| </condition> | |||
| </fail> | |||
| </target> | |||
| <target name="testGreedyInlineHandlerClassname"> | |||
| <input message="Press Return key to continue..." addproperty="test"> | |||
| <handler classname="org.apache.tools.ant.input.GreedyInputHandler" /> | |||
| </input> | |||
| <fail message="$${test} = ${test}"> | |||
| <condition> | |||
| <not> | |||
| <equals arg1="${test}" | |||
| arg2="foo${line.separator}bar${line.separator}" /> | |||
| </not> | |||
| </condition> | |||
| </fail> | |||
| </target> | |||
| <target name="testGreedyInlineHandlerRefid"> | |||
| <typedef name="greedy" | |||
| classname="org.apache.tools.ant.input.GreedyInputHandler" /> | |||
| <greedy id="greedy" /> | |||
| <input message="Press Return key to continue..." addproperty="test"> | |||
| <handler refid="greedy" /> | |||
| </input> | |||
| <fail message="$${test} = ${test}"> | |||
| <condition> | |||
| <not> | |||
| <equals arg1="${test}" | |||
| arg2="foo${line.separator}bar${line.separator}" /> | |||
| </not> | |||
| </condition> | |||
| </fail> | |||
| </target> | |||
| </project> | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Copyright 2001-2004 The Apache Software Foundation | |||
| * Copyright 2001-2005 The Apache Software Foundation | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| @@ -18,11 +18,20 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.input.InputHandler; | |||
| import org.apache.tools.ant.input.InputRequest; | |||
| import org.apache.tools.ant.input.GreedyInputHandler; | |||
| import org.apache.tools.ant.input.DefaultInputHandler; | |||
| import org.apache.tools.ant.input.PropertyFileInputHandler; | |||
| import org.apache.tools.ant.input.MultipleChoiceInputRequest; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||
| import org.apache.tools.ant.util.StringUtils; | |||
| import org.apache.tools.ant.util.ClasspathUtils; | |||
| /** | |||
| * Reads an input line from the console. | |||
| @@ -32,10 +41,108 @@ import org.apache.tools.ant.util.StringUtils; | |||
| * @ant.task category="control" | |||
| */ | |||
| public class Input extends Task { | |||
| /** | |||
| * Represents an InputHandler. | |||
| */ | |||
| public class Handler extends DefBase { | |||
| private String refid = null; | |||
| private HandlerType type = null; | |||
| private String classname = null; | |||
| /** | |||
| * Specify that the handler is a reference on the project; | |||
| * this allows the use of a custom inputhandler. | |||
| * @param refid the String refid. | |||
| */ | |||
| public void setRefid(String refid) { | |||
| this.refid = refid; | |||
| } | |||
| /** | |||
| * Get the refid of this Handler. | |||
| * @return String refid. | |||
| */ | |||
| public String getRefid() { | |||
| return refid; | |||
| } | |||
| /** | |||
| * Set the InputHandler classname. | |||
| * @param classname the String classname. | |||
| */ | |||
| public void setClassname(String classname) { | |||
| this.classname = classname; | |||
| } | |||
| /** | |||
| * Get the classname of the InputHandler. | |||
| * @return String classname. | |||
| */ | |||
| public String getClassname() { | |||
| return classname; | |||
| } | |||
| /** | |||
| * Set the handler type. | |||
| * @param type a HandlerType. | |||
| */ | |||
| public void setType(HandlerType type) { | |||
| this.type = type; | |||
| } | |||
| /** | |||
| * Get the handler type. | |||
| * @return a HandlerType object. | |||
| */ | |||
| public HandlerType getType() { | |||
| return type; | |||
| } | |||
| private InputHandler getInputHandler() { | |||
| if (type != null) { | |||
| return type.getInputHandler(); | |||
| } | |||
| if (refid != null) { | |||
| try { | |||
| return (InputHandler) (getProject().getReference(refid)); | |||
| } catch (ClassCastException e) { | |||
| throw new BuildException( | |||
| refid + " does not denote an InputHandler", e); | |||
| } | |||
| } | |||
| if (classname != null) { | |||
| return (InputHandler) (ClasspathUtils.newInstance(classname, | |||
| createLoader(), InputHandler.class)); | |||
| } | |||
| throw new BuildException( | |||
| "Must specify refid, classname or type"); | |||
| } | |||
| } | |||
| /** | |||
| * EnumeratedAttribute representing the built-in input handler types: | |||
| * "default", "propertyfile", "greedy". | |||
| */ | |||
| public static class HandlerType extends EnumeratedAttribute { | |||
| private static final String[] VALUES | |||
| = {"default", "propertyfile", "greedy"}; | |||
| private static final InputHandler[] HANDLERS | |||
| = {new DefaultInputHandler(), | |||
| new PropertyFileInputHandler(), | |||
| new GreedyInputHandler()}; | |||
| //inherit doc | |||
| public String[] getValues() { | |||
| return VALUES; | |||
| } | |||
| private InputHandler getInputHandler() { | |||
| return HANDLERS[getIndex()]; | |||
| } | |||
| } | |||
| private String validargs = null; | |||
| private String message = ""; | |||
| private String addproperty = null; | |||
| private String defaultvalue = null; | |||
| private Handler handler = null; | |||
| private boolean messageAttribute; | |||
| /** | |||
| * Defines valid input parameters as comma separated strings. If set, input | |||
| @@ -66,6 +173,7 @@ public class Input extends Task { | |||
| */ | |||
| public void setMessage (String message) { | |||
| this.message = message; | |||
| messageAttribute = true; | |||
| } | |||
| /** | |||
| @@ -84,7 +192,11 @@ public class Input extends Task { | |||
| * @param msg The message to be displayed. | |||
| */ | |||
| public void addText(String msg) { | |||
| message += getProject().replaceProperties(msg); | |||
| msg = getProject().replaceProperties(msg); | |||
| if (messageAttribute && "".equals(msg.trim())) { | |||
| return; | |||
| } | |||
| message += msg; | |||
| } | |||
| /** | |||
| @@ -113,7 +225,11 @@ public class Input extends Task { | |||
| request = new InputRequest(message); | |||
| } | |||
| getProject().getInputHandler().handleInput(request); | |||
| InputHandler h = handler == null | |||
| ? getProject().getInputHandler() | |||
| : handler.getInputHandler(); | |||
| h.handleInput(request); | |||
| String value = request.getInput(); | |||
| if ((value == null || value.trim().length() == 0) | |||
| @@ -125,4 +241,17 @@ public class Input extends Task { | |||
| } | |||
| } | |||
| /** | |||
| * Create a nested handler element. | |||
| * @return a Handler for this Input task. | |||
| */ | |||
| public Handler createHandler() { | |||
| if (handler != null) { | |||
| throw new BuildException( | |||
| "Cannot define > 1 nested input handler"); | |||
| } | |||
| handler = new Handler(); | |||
| return handler; | |||
| } | |||
| } | |||
| @@ -17,6 +17,9 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.InputStream; | |||
| import java.io.FileInputStream; | |||
| import org.apache.tools.ant.BuildFileTest; | |||
| import org.apache.tools.ant.input.PropertyFileInputHandler; | |||
| @@ -62,6 +65,40 @@ public class InputTest extends BuildFileTest { | |||
| assertEquals("scott", project.getProperty("db.user")); | |||
| } | |||
| public void testPropertyFileInlineHandler() { | |||
| executeTarget("testPropertyFileInlineHandler"); | |||
| } | |||
| public void testDefaultInlineHandler() { | |||
| stdin(); | |||
| executeTarget("testDefaultInlineHandler"); | |||
| } | |||
| public void testGreedyInlineHandler() { | |||
| stdin(); | |||
| executeTarget("testGreedyInlineHandler"); | |||
| } | |||
| public void testGreedyInlineHandlerClassname() { | |||
| stdin(); | |||
| executeTarget("testGreedyInlineHandlerClassname"); | |||
| } | |||
| public void testGreedyInlineHandlerRefid() { | |||
| stdin(); | |||
| executeTarget("testGreedyInlineHandlerRefid"); | |||
| } | |||
| private void stdin() { | |||
| try { | |||
| System.setIn(new FileInputStream( | |||
| getProject().resolveFile("input.stdin"))); | |||
| } catch (Exception e) { | |||
| throw e instanceof RuntimeException | |||
| ? (RuntimeException) e : new RuntimeException(e.getMessage()); | |||
| } | |||
| } | |||
| private String getKey(String key) { | |||
| return key; // XXX what is this for? | |||
| } | |||