You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Anthony Young-Garner <no...@yahoo.com> on 2001/07/24 19:40:52 UTC

[PATCH] PropertyPrompt.java

This task prompts build user for property values, allowing interactive builds. It is somewhat tangential to Ant's primary purpose but useful enough for inclusion as an optional task.

----------------------------------------

Example build.xml file demonstrating use:

<?xml version="1.0"?>
<project name="PropertyPromptExample" default="main" basedir=".">
 <property name="promptTimeout" value="0"/>
 <taskdef name="propertyprompt" classname="org.apache.jakarta.tools.ant.taskdefs.optional.PropertyPrompt"/>
 <target name="main">
 <property name="propA" value="oldValA"/>
 <property name="propA" value="oldValA1"/>
 <echo>value of propA: ${propA}</echo>
 <echo>value of propB: ${propB}</echo>
 <propertyprompt propertyname="propA" promptcharacter=":">Enter value for propA</propertyprompt>
 <propertyprompt propertyname="propB" defaultvalue="defvalB">What is the value for propB</propertyprompt>
 <echo>value of propA: ${propA}</echo>
 <echo>value of propB: ${propB}</echo>
 </target>
</project>

--------------------------------------------------

package org.apache.tools.ant.taskdefs.optional;

/**
 * Task that prompts user for property values to allow interactive builds.
 * Admittedly, this task definitely falls way outside the bounds of
 * Ant's core functionality but is useful enough to warrant
 * inclusion amongst the optional tasks.
 * @author: <a href=mailto:ajyoung@alum.mit.edu>Anthony J. Young-Garner</a>
 * Set project property "promptTimeout" to control behavior.
 * timeout = -1 --> Cancel prompting. Use default property values.
 * timeout =  0 --> Wait indefinitely for user response (default).
 * timeout =  x --> Wait x seconds for user reponse before using default
 *                  property values (for x > 0). IMPLEMENTATION POSTPONED UNTIL
 *                  JDK 1.4 provides non-blocking I/O.
 */

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Hashtable;
import org.apache.tools.ant.taskdefs.Property;
 
public class PropertyPrompt extends org.apache.tools.ant.Task {

 private java.lang.String propertyname;
 private java.lang.String defaultvalue;
 private java.lang.String proposedValue;
 private java.lang.String prompttext;
 private java.lang.String promptcharacter;
 private int timeout;
/**
 * PropertyPrompt default constructor.
 */
public PropertyPrompt() {
 super();
}
/**
 * Sets the prompt text that will be presented to the user.
 * @param prompt java.lang.String
 */
public void addText(String prompt) {
 setPrompttext(prompt);
}
/**
 * Run the PropertyPrompt task.
 * @exception org.apache.tools.ant.BuildException The exception description.
 */
public void execute() throws org.apache.tools.ant.BuildException {
 if (timeout > -1) {
  log("Prompting user for " + propertyname + ". Default value is " + defaultvalue + ".");
  StringBuffer prompt = new StringBuffer();
  prompt.append("\n");
  prompt.append(prompttext);
  prompt.append(" [");
  prompt.append(defaultvalue);
  prompt.append("] ");
  prompt.append(promptcharacter);
  prompt.append(" ");
  System.out.print(prompt.toString());

  /** future version should have hooks for validation of user input.*/
  BufferedReader reader = new BufferedReader(new InputStreamReader (System.in));
  try {
   /**
    * when we get to JDK 1.4 (yeah, right), this should be non-blocking so that
    * user-input can be time limited. (Threads could be used as a work-around
    * but I'm not comfortable introducing the complexity of threads for such a
    * small feature).
    */
    if (timeout < 0) {
    }
   proposedValue  = reader.readLine();
  } catch (IOException e) {
   log("Prompt failed. Using default.");
   proposedValue = defaultvalue;
  }
  if (!proposedValue.equals("")) {
   /**
    * According to the mailing list, properties are API mutable
    * (as opposed to user-properties and the use of multiple
    * <property> tags to 'mutate' property values).
    */
   project.setProperty(propertyname, proposedValue);
  }
 } 
}
/**
 * Returns defaultValue specified 
 * in this task for the Property
 * being set.
 * @return java.lang.String
 */
public java.lang.String getDefaultvalue() {
 return defaultvalue;
}
/**
 * Returns the terminating character used to 
 * punctuate the prompt text.
 */
public java.lang.String getPromptcharacter() {
 return promptcharacter;
}
/**
 * Returns text of the prompt.
 * @return java.lang.String
 */
public java.lang.String getPrompttext() {
 return prompttext;
}
/**
 * Returns name of the Ant Project Property
 * being set by this task.
 * @return java.lang.String
 */
public java.lang.String getPropertyname() {
 return propertyname;
}
/**
 * Initializes this task.
 */
public void init() {
 super.init();
 String timeoutProperty = project.getProperty("promptTimeout");

 if (timeoutProperty == null) {
  timeout = 0;
 } else {
  try{
   timeout = Integer.parseInt(timeoutProperty);
  } catch(NumberFormatException e) {
   log("Invalid promptTimeout value: " + timeoutProperty + ". Using default (wait indefinitely).");
   timeout = 0;
  }
 }

 promptcharacter = "?";
}
/**
 * Sets defaultValue for the Property
 * being set by this task.
 * @param newDefaultvalue java.lang.String
 */
public void setDefaultvalue(java.lang.String newDefaultvalue) {
 defaultvalue = newDefaultvalue;
}
/**
 * Sets the terminating character used to 
 * punctuate the prompt text (default is "?").
 * @param newPromptcharacter java.lang.String
 */
public void setPromptcharacter(java.lang.String newPromptcharacter) {
 promptcharacter = newPromptcharacter;
}
/**
 * Sets text of the prompt.
 * @param newPrompttext java.lang.String
 */
public void setPrompttext(java.lang.String newPrompttext) {
 prompttext = newPrompttext;
}
/**
 * Specifies the Ant Project Property
 * being set by this task.
 * @param newPropertyname java.lang.String
 */
public void setPropertyname(java.lang.String newPropertyname) {
 propertyname = newPropertyname;
}
}

 

------------------------------



---------------------------------
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

Re: [PATCH] PropertyPrompt.java

Posted by Stefan Reich <do...@drjava.de>.
You humble me, man... no need for giving me thanks in the source for such a
small suggestion :-)

Anyways, TimedBufferedReader is a nice reusable class the way you wrote it.

-Stefan

----- Original Message -----
From: "Anthony Young-Garner" <no...@yahoo.com>
To: <an...@jakarta.apache.org>
Cc: <do...@drjava.de>
Sent: Friday, August 10, 2001 6:33 PM
Subject: [PATCH] PropertyPrompt.java


> Stefan,
>
> Thanks for the hint. Here's a new version with the
> timeout feature added.
>
> - Anthony



[PATCH] PropertyPrompt.java

Posted by Anthony Young-Garner <no...@yahoo.com>.
Stefan,

Thanks for the hint. Here's a new version with the
timeout feature added.

- Anthony
------------------------------------------
PropertyPrompt.java is a task that prompt build
user for property value(s), allowing interactive
builds. Query text, prompt character and default
response may all be specified in the build file. In
addition, the timeout property allows the build file
author to limit how many seconds the task should wait
for user input.

A sample build file demonstrating use and the source
code for the task follow.

------------------------------------
<?xml version="1.0"?>
<project name="PropertyPromptExample" default="main"
basedir=".">
	<property name="promptTimeout" value="5"/>
	<taskdef name="propertyprompt"
classname="com.ibm.samples.apache.tools.ant.taskdefs.optional.PropertyPrompt"/>
	<target name="main">
<!--	<javac srcdir="." destdir="." verbose="on"/>  
-->
	<property name="propA" value="oldValA"/>
	<property name="propA" value="oldValA1"/>
	<echo>value of propA: ${propA}</echo>
	<echo>value of propB: ${propB}</echo>
	<propertyprompt propertyname="propA"
promptcharacter=":">Enter value for
propA</propertyprompt>
	<propertyprompt propertyname="propB"
defaultvalue="defvalB">What is the value for
propB</propertyprompt>
	<echo>value of propA: ${propA}</echo>
	<echo>value of propB: ${propB}</echo>
	</target>
</project>

---------source code -----------------
package org.apache.tools.ant.taskdefs.optional;

/**
 * Task that prompts user for property values to allow
interactive builds.
 * Admittedly, this task definitely falls way outside
the bounds of
 * Ant's core functionality but is useful enough to
warrant
 * inclusion amongst the optional tasks.
 * @author: <a
href=mailto:ajyoung@alum.mit.edu>Anthony J.
Young-Garner</a>
 * Set project property "promptTimeout" to control
behavior.
 * timeout = -1 --> Cancel prompting. Use default
property values.
 * timeout =  0 --> Wait indefinitely for user
response (default).
 * timeout =  x --> Wait x seconds for user reponse
before using default
 *                  property values (for x > 0). 
 */

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Hashtable;
import org.apache.tools.ant.taskdefs.Property;
 
public class PropertyPrompt extends
org.apache.tools.ant.Task {

	private java.lang.String propertyname;		// required
	private java.lang.String defaultvalue;
	private java.lang.String proposedValue;		// required
	private java.lang.String prompttext;		// required
	private java.lang.String promptcharacter;
	private int timeout;

		/**
 		 * Provides a BufferedReader with a readLine method
that
 		 * blocks for only a specified number of seconds.
If no
 		 * input is read in that time, a specified default
 		 * string is returned. Otherwise, the input read is
returned.
 		 * Thanks to <a href=mailto:doc@drjava.de>Stefan
Reich </a>
 		 * for suggesting this implementation.
 		 * @author: <a
href=mailto:ajyoung@alum.mit.edu>Anthony J.
Young-Garner</a>
 		 */
		private class TimedBufferedReader extends
java.io.BufferedReader {

		private boolean linefeed        = true;
		private int 	timeout 		= 0;
		private String 	defaultString 	= "";
		
		/**
 		 * TimedBufferedReader constructor.
 		 * @param in java.io.Reader
 		 */
		TimedBufferedReader(java.io.Reader in) {
			super(in);
		}

		/**
 		 * TimedBufferedReader constructor.
 		 * @param in java.io.Reader
 		 * @param sz int Size of the input buffer.
 		 */
		TimedBufferedReader(java.io.Reader in, int sz) {
			super(in, sz);
		}

		/**
 		 * Sets number of seconds to block for input.
 		 * @param seconds int
 		 */
		public void setTimeout(int seconds) {
			timeout=seconds;
		}

		/**
 		 * Sets defaultString to use if no input is read.
 		 * @param str java.lang.String
 		 */
		public void setDefaultString(String str) {
			defaultString = str;
		}

		public String readLine() throws java.io.IOException
{
			int msec = 0;
			int sec  = 0;
			while (!this.ready()) {
				try { Thread.currentThread().sleep(10); }
       			catch (InterruptedException e) { break; }
       			if (msec > 99) {
         			sec++;
         			msec = 0;
       			} else msec++;
       			if (sec >= timeout) {
	       			if (linefeed) {
		       			System.out.print("\n");
	       			}
	       			return defaultString;
       			}
			}
			return super.readLine();
		}
	}
/**
 * PropertyPrompt default constructor.
 */
public PropertyPrompt() {
	super();
}
/**
 * Sets the prompt text that will be presented to the
user.
 * @param prompt java.lang.String
 */
public void addText(String prompt) {
	setPrompttext(prompt);
}
/**
 * Run the PropertyPrompt task.
 * @exception org.apache.tools.ant.BuildException The
exception description.
 */
public void execute() throws
org.apache.tools.ant.BuildException {
	if (timeout > -1) {
		
		log("Prompting user for " + propertyname + ". " +
getDefaultMessage());
		StringBuffer prompt = new StringBuffer();
		prompt.append("\n");
		prompt.append(prompttext);
		prompt.append(" [");
		prompt.append(defaultvalue);
		prompt.append("] ");
		prompt.append(promptcharacter);
		prompt.append(" ");
		System.out.print(prompt.toString());

		/** future version should have hooks for validation
of user input.*/
		TimedBufferedReader reader = new
TimedBufferedReader(new InputStreamReader
(System.in));
		reader.setTimeout(timeout);
		reader.setDefaultString(defaultvalue);
		try {
			proposedValue  = reader.readLine();
		} catch (IOException e) {
			log("Prompt failed. Using default.");
			proposedValue = defaultvalue;
		}
		if (!proposedValue.equals("")) {
			/**
			 * According to the mailing list, properties are
API mutable
			 * (as opposed to user-properties and the use of
multiple
			 * <property> tags to 'mutate' property values).
			 */
			project.setProperty(propertyname, proposedValue);
		}
	}	
}
/**
 * Returns a string to be inserted in the log message
 * indicating whether a default response was specified
 * in the build file.
 */
private String getDefaultMessage() {
	if (defaultvalue == "") {
		return "No default response specified.";
	} else return "Default response is " + defaultvalue +
".";
}
/**
 * Returns defaultValue specified 
 * in this task for the Property
 * being set.
 * @return java.lang.String
 */
public java.lang.String getDefaultvalue() {
	return defaultvalue;
}
/**
 * Returns the terminating character used to 
 * punctuate the prompt text.
 */
public java.lang.String getPromptcharacter() {
	return promptcharacter;
}
/**
 * Returns text of the prompt.
 * @return java.lang.String
 */
public java.lang.String getPrompttext() {
	return prompttext;
}
/**
 * Returns name of the Ant Project Property
 * being set by this task.
 * @return java.lang.String
 */
public java.lang.String getPropertyname() {
	return propertyname;
}
/**
 * Initializes this task.
 */
public void init() {
	super.init();
	String timeoutProperty =
project.getProperty("promptTimeout");

	if (timeoutProperty == null) {
		timeout = 0;
	} else {
		try{
			timeout = Integer.parseInt(timeoutProperty);
		} catch(NumberFormatException e) {
			log("Invalid promptTimeout value: " +
timeoutProperty + ". Using default (wait
indefinitely).");
			timeout = 0;
		}
	}
    defaultvalue    = "";
	promptcharacter = "?";
}
/**
 * Sets defaultValue for the Property
 * being set by this task.
 * @param newDefaultvalue java.lang.String
 */
public void setDefaultvalue(java.lang.String
newDefaultvalue) {
	defaultvalue = newDefaultvalue;
}
/**
 * Sets the terminating character used to 
 * punctuate the prompt text (default is "?").
 * @param newPromptcharacter java.lang.String
 */
public void setPromptcharacter(java.lang.String
newPromptcharacter) {
	promptcharacter = newPromptcharacter;
}
/**
 * Sets text of the prompt.
 * @param newPrompttext java.lang.String
 */
public void setPrompttext(java.lang.String
newPrompttext) {
	prompttext = newPrompttext;
}
/**
 * Specifies the Ant Project Property
 * being set by this task.
 * @param newPropertyname java.lang.String
 */
public void setPropertyname(java.lang.String
newPropertyname) {
	propertyname = newPropertyname;
}
}

--- Stefan Reich <do...@drjava.de> wrote:
> Hi Anthony,
> 
> your task is very useful, thanks for submitting it.
> 
> I have a comment on your comment:
> 
>    /**
>     * when we get to JDK 1.4 (yeah, right), this
> should be non-blocking so that
>     * user-input can be time limited. (Threads could
> be used as a work-around
>     * but I'm not comfortable introducing the
> complexity of threads for such a
>     * small feature).
>     */
> 
> You don't need JDK 1.4 or threads to achieve this.
> You could just write your own readLine() that calls
> Reader.ready() repeatedly (with small Thread.sleeps
> inbetween) and checks for timeouts.
> 
> (It's a pity that there's no wait method in Reader
> that waits until data is available or a specified
> time elapsed...)
> 
> -Stefan


__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

Re: [PATCH] PropertyPrompt.java

Posted by Stefan Reich <do...@drjava.de>.
Hi Anthony,

your task is very useful, thanks for submitting it.

I have a comment on your comment:

   /**
    * when we get to JDK 1.4 (yeah, right), this should be non-blocking so that
    * user-input can be time limited. (Threads could be used as a work-around
    * but I'm not comfortable introducing the complexity of threads for su ch a
    * small feature).
    */

You don't need JDK 1.4 or threads to achieve this. You could just write your own readLine() that calls Reader.ready() repeatedly (with small Thread.sleeps inbetween) and checks for timeouts.

(It's a pity that there's no wait method in Reader that waits until data is available or a specified time elapsed...)

-Stefan
  ----- Original Message ----- 
  From: Anthony Young-Garner 
  To: ant-dev@jakarta.apache.org 
  Sent: Tuesday, July 24, 2001 7:40 PM
  Subject: [PATCH] PropertyPrompt.java


  This task prompts build user for property values, allowing interactive builds. It is somewhat tangential to Ant's primary purpose but useful enough for inclusion as an optional task.

  ----------------------------------------

  Example build.xml file demonstrating use:

  <?xml version="1.0"?>
  <project name="PropertyPromptExample" default="main" basedir=".">
   <property name="promptTimeout" value="0"/>
   <taskdef name="propertyprompt" classname="org.apache.jakarta.tools.ant.taskdefs.optional.PropertyPrompt"/>
   <target name="main">
   <property name="propA" value="oldValA"/>
   <property name="propA" value="oldValA1"/>
   <echo>value of propA: ${propA}</echo>
   <ech o>value of propB: ${propB}</echo>
   <propertyprompt propertyname="propA" promptcharacter=":">Enter value for propA</propertyprompt>
   <propertyprompt propertyname="propB" defaultvalue="defvalB">What is the value for propB</propertyprompt>
   <echo>value of propA: ${propA}</echo>
   <echo>value of propB: ${propB}</echo>
   </target>
  </project>

  --------------------------------------------------

  package org.apache.tools.ant.taskdefs.optional;

  /**
   * Task that prompts user for property values to allow interactive builds.
   * Admittedly, this task definitely falls way outside the bounds of
   * Ant's core functionality but is useful enough to warrant
   * inclusion amongst the optional tasks.
   * @author: <a href=mailto:ajyoung@alum.mit.edu>Anthony J. Young-Garner</a>
   * Set project property "promptTimeout" to control behavior.
    ;* timeout = -1 --> Cancel prompting. Use default property values.
   * timeout =  0 --> Wait indefinitely for user response (default).
   * timeout =  x --> Wait x seconds for user reponse before using default
   *                  property values (for x > 0). IMPLEMENTATION POSTPONED UNTIL
   *             &nbs p;    JDK 1.4 provides non-blocking I/O.
   */

  import java.io.InputStreamReader;
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.util.Hashtable;
  import org.apache.tools.ant.taskdefs.Property;
   
  public class PropertyPrompt extends org.apache.tools.ant.Task {

   private java.lang.String propertyname;
   private java.lang.String defaultvalue;
   private java.lang.String proposedValue;
   private java.lang.String prompttext;
   private java.lang.String promptcharacter;
   private int timeout;
  /**
   * PropertyPrompt default constructor.
   */
  public PropertyPrompt() {
   super();
  }
  /**
   * Sets the prompt text that will be presented to the user.
   * @param prompt java.lang.String
   */
  public void addText(String prompt) {
   setPrompttext(prompt);
  }
  /**
   * Run the PropertyPrompt task.
   * @exception org.apache.tools.ant.BuildException The exception description.
   */
  public void execute() throws org.apache.tools.ant.BuildException {
   if (timeout > -1) {
    log("Prompting user for " + propertyname + ". Default value is " + defaultvalue + ".");
    StringBuffer prompt = new StringBuffer();
    pro mpt.append("\n");
    prompt.append(prompttext);
    prompt.append(" [");
    prompt.append(defaultvalue);
    prompt.append("] ");
    prompt.append(promptcharacter);
    prompt.append(" ");
    System.out.print(prompt.toString());

    /** future version should have hooks for validation of user input.*/
    BufferedReader reader = new BufferedReader(new InputStreamReader (System.in));
    try {
     /**
      * when we get to JDK 1.4 (yeah, right), this should be non-blocking so that
      * user-input can be time limited. (Threads could be used as a work-around
      * but I'm not comfortable introducing the complexity of threads for su ch a
      * small feature).
      */
      if (timeout < 0) {
      }
     proposedValue  = reader.readLine();
    } catch (IOException e) {
     log("Prompt failed. Using default.");
     proposedValue = defaultvalue;
    }
    if (!proposedValue.equals("")) {
     /**
      * According to the mailing list, properties are API mutable
      * (as opposed to user-properties and the use of multiple
      * <property> tags to 'mutate' property values).
      */
     project.setProperty(propertyname, proposedValue);
    }
   } 
  }
  /**
   * Returns defaultValue specified 
   * in this task for the Property
   * being set.
   * @return java.lang.String
   */
  public java.lang.String getDefaultvalue() { 
   return defaultvalue;
  }
  /**
   * Returns the terminating character used to 
   * punctuate the prompt text.
   */
  public java.lang.String getPromptcharacter() {
   return promptcharacter;
  }
  /**
   * Returns text of the prompt.
   * @return java.lang.String
   */
  public java.lang.String getPrompttext() {
   return prompttext;
  }
  /**
   * Returns name of the Ant Project Property
   * being set by this task.
    * @return java.lang.String
   */
  public java.lang.String getPropertyname() {
   return propertyname;
  }
  /**
   * Initializes this task.
   */
  public void init() {
   super.init();
   String timeoutProperty = project.getProperty("promptTimeout");

   if (timeoutProperty == null) {
    timeout = 0;
   } else {
    try{
     timeout = Integer.parseInt(timeoutProperty);
    } catch(NumberFormatException e) {
     log("Invalid promptTimeout value: " + timeoutProperty + ". Using default (wait indefinitely).");
     timeout = 0;
    }
   }

   promptcharacter = "?";
  }
  /**
   * Sets defaultValue for the Property
   * being set by this task.
   * @param newDefaultvalue java.lang.String
   */
  public void setDefaultvalue(java.lang.String newDefaultvalue) {
   defaultvalue = newDefaultvalue;
  }
  /**
   * Sets the terminating character used to 
   * punctuate the prompt text (default is "?").
   * @param newPromptcharacter java.lang.String
   */
  public void setPromptcharac ter(java.lang.String newPromptcharacter) {
   promptcharacter = newPromptcharacter;
  }
  /**
   * Sets text of the prompt.
   * @param newPrompttext java.lang.String
   */
  public void setPrompttext(java.lang.String newPrompttext) {
   prompttext = newPrompttext;
  }
  /**
   * Specifies the Ant Project Property
   * being set by this task.
   * @param newPropertyname java.lang.String
   */
  public void setPropertyname(java.lang.String newProp ertyname) {
   propertyname = newPropertyname;
  }
  }



  ------------------------------





------------------------------------------------------------------------------
  Do You Yahoo!?
  Make international calls for as low as $.04/minute with Yahoo! Messenger
  http://phonecard.yahoo.com/