ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan.Mate...@rzf.fin-nrw.de
Subject AW: AW: Creating custom InputHandler
Date Wed, 14 Jul 2004 07:35:46 GMT
Mmh, if your IH only "extends" the default IH with 
    input = project.replaceProperties(input);

then you try the decorator pattern:

PropertyExpandInputHandler {
    InputHandler base; // setter, constructor
    public void handleInput(InputRequest request) {
        base.handleInput(request);
        String input = request.getInput();
        input.replace ...
        request.setInput(input);
    }
}

> Do you think, I will lose
> something if I extend DefaultInputHandler and let ant
> call setProject via refelection? 

Have you tried?
On the other hand: the decorator above could also be a ProjectComponent.


> Can you recommend me a
> way to make the above code more extensible in terms of
> the used Swing Components?

The Ant way of collecting multiple values is using a properties file.
So in that case I would write a simple java application which creates this
file and
do in Ant something like that:
    <copy file="automated.props" tofile="theGeneratedPropertyFile"/>  
    <java ReadUserInput.java />
    <property file="theGeneratedPropertyFile"/>
    <delete file="theGeneratedPropertyFile"/>  
      <!-- dont let pwd exist for long time in a readable form -->

The ReadUserInput application can silently quit if the prop file already
exists. Then
you can do the full automated build by simply adding the property file
"automated.props".


Jan


> -----Urspr√ľngliche Nachricht-----
> Von: Ivan Ivanov [mailto:rambiusparkisanius@yahoo.com]
> Gesendet am: Mittwoch, 14. Juli 2004 09:09
> An: Ant Users List
> Betreff: Re: AW: Creating custom InputHandler
> 
> Hello Jan,
> I implemnted carefully your ideas and here are the
> results which I received and some more questions. I am
> using ant1.6.2beta1 sources and the new input handler
> which I created is called
> org.apache.tools.ant.PropertyExpandInputHandler (shown
> below). You recommended me to create a task
> SetProjectRefrerenceOnInputHanlder, which will call
> setProject(Project) method of
> PropertyExpandInputHandler. It turned that this task
> is not needed, because Ant "magically" sets the
> project reference of the input handler. More
> precilsely
> this is done in org.apache.tools.ant.Project by
> setProjectReference() method:
> 
> public final void setProjectReference(final Object
> obj) {
>     if (obj instanceof ProjectComponent) {
>         ((ProjectComponent) obj).setProject(this);
>         return;
>     }
>     try {
>         Method method =
>             obj.getClass().getMethod(
>                 "setProject", new Class[]
> {Project.class});
>         if (method != null) {
>             method.invoke(obj, new Object[] {this});
>         }
>     } catch (Throwable e) {
>         // ignore this if the object does not have
>         // a set project method or the method
>         // is private/protected.
>     }
> },
> called on the object paramameters of the build file.
> This method shows that it is not necessary to make
> PropertyExpandInputHandler extend ProjectComponent,
> because it will call its setProject(Project)
> via reflection. However, I made it ProjectComponent
> for clarity.
> 
> Here is the actual code of PropertyExpandInputHandler
> and the question it arises.
> 
> package org.apache.tools.ant.input;
> 
> import java.io.DataInputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.util.Enumeration;
> import org.apache.tools.ant.Project;
> import org.apache.tools.ant.ProjectComponent;
> import org.apache.tools.ant.BuildException;
> import org.apache.tools.ant.util.KeepAliveInputStream;
> 
> public class PropertyExpandInputHandler extends
> ProjectComponent implements InputHandler {
> 
>     /**
>      * The project this input handler is used in.
>      * This reference is needed when we resolve the
> properties.
>      */
>     private Project project;
> 
>     /**
>      * Empty no-arg constructor
>      */
>     public PropertyExpandInputHandler() {
>     }
> 
>     /**
>      * Prompts and requests input.  When the input is
> received
>      * the properties in it are expanded to their
> values set in
>      * the current project.
>      * May loop until a valid input has been entered.
>      * @param request the request to handle
>      * @throws BuildException if not possible to read
> from console
>      */
>     public void handleInput(InputRequest request)
> throws BuildException {
>         String prompt = getPrompt(request);
>         DataInputStream in = null;
>         try {
>             in =
>                 new DataInputStream(new
> KeepAliveInputStream(getInputStream()));
>             do {
>                 System.err.println(prompt);
>                 System.err.flush();
>                 try {
>                     String input = in.readLine();
>                     input =
> project.replaceProperties(input);
>                     request.setInput(input);
>                 } catch (IOException e) {
>                     throw new BuildException("Failed
> to read input from"
>                                              + "
> Console.", e);
>                 }
>             } while (!request.isInputValid());
>         } finally {
>             if (in != null) {
>                 try {
>                     in.close();
>                 } catch (IOException e) {
>                     throw new BuildException("Failed
> to close input.", e);
>                 }
>             }
>         }
>     }
> 
>     /**
>      * Constructs user prompt from a request.
>      *
>      * <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.
>      *                Must not be <code>null</code>.
>      * @return the prompt to ask the user
>      */
>     protected String getPrompt(InputRequest request) {
>         String prompt = request.getPrompt();
>         if (request instanceof
> MultipleChoiceInputRequest) {
>             StringBuffer sb = new
> StringBuffer(prompt);
>             sb.append("(");
>             Enumeration e =
>                 ((MultipleChoiceInputRequest)
> request).getChoices().elements();
>             boolean first = true;
>             while (e.hasMoreElements()) {
>                 if (!first) {
>                     sb.append(",");
>                 }
>                 sb.append(e.nextElement());
>                 first = false;
>             }
>             sb.append(")");
>             prompt = sb.toString();
>         }
>         return prompt;
>     }
> 
>     /**
>      * Returns the input stream from which the user
> input should be read.
>      * @return the input stream from which the user
> input should be read.
>      */
>     protected InputStream getInputStream() {
>         return System.in;
>     }
> 
>     /**
>      * Sets the project to which this input handler
> belongs to.
>      *
>      * param project the project in which this input
> handler is used.
>      */
>     public void setProject(Project project) {
>         this.project = project;
>     }
> 
>     public Project getProject() {
>         return project;
>     }
> }
> 
> The issue here is that PropertyExpandInputHandler
> simply duplicates DefaultInputHandler with the single
> difference in the line 
> input = project.replaceProperties(input);
> I thought that PropertyExpandInputHandler can extend
> DefaultInputHandler but then it cannot extend
> ProjectComponent. Do you think, I will lose
> something if I extend DefaultInputHandler and let ant
> call setProject via refelection? I would ask you also
> to point me any weaknesses of the above code since it
> is my first extesion of Ant :)).
> 
> Thank you very much for your help.
> 
> Ivan
> 
> --- Jan.Materne@rzf.fin-nrw.de wrote:
> > Indeed, seems to be a problem.
> > 
> > The initialization procedure for InputHandlers
> > doesnt store a project
> > reference (and 
> > couldnt do it, because the IH-Interface doesnt
> > requires a
> > setProject(Project) method).
> > 
> > So only a workaround comes into my mind:
> > - your InputHandler has to provide the setProject
> > method
> > - set the reference for yourself before using the
> > handler by using a Task:
> >   (code not tested - even compiled):
> >   public class SetProjectReferenceOnInputHandler
> > extends Task {
> >       public void execute() {
> >           InputHandler ih =
> > getProject().getInputHandler();
> >           if (ih instanceof MyInputHandler) {
> >              
> > ((MyInputHandler)ih).setProject(getProject());
> >           }
> >       }
> >   }
> >   
> > 
> > Maybe we should check if the InputHandler is a
> > ProjectComponent and set the
> > project
> > reference then ... 
> > 
> > 
> > Jan
> 
> 
> 
> 	
> 		
> __________________________________
> Do you Yahoo!?
> New and Improved Yahoo! Mail - 100MB free storage!
> http://promotions.yahoo.com/new_mail 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
> 

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message