ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Anthony Young-Garner <notadr...@yahoo.com>
Subject [PATCH] PropertyPrompt.java
Date Fri, 10 Aug 2001 16:33:21 GMT
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 <doc@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/

Mime
View raw message