ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@locus.apache.org
Subject cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs Available.java Filter.java Property.java Tstamp.java
Date Thu, 14 Sep 2000 07:19:53 GMT
bodewig     00/09/14 00:19:53

  Modified:    .        WHATSNEW build.xml
               docs     index.html
               src/main/org/apache/tools/ant ProjectHelper.java Target.java
                        Task.java
               src/main/org/apache/tools/ant/taskdefs Available.java
                        Filter.java Property.java Tstamp.java
  Added:       src/main/org/apache/tools/ant RuntimeConfigurable.java
  Log:
  Moved ${} expansion and task evaluation to runtime.
  
  This has a lot of consequences, most notably those listed in
  WHATSNEW. This also affects the behavior of several other tasks like
  <available> who will now do their job at runtime instead of parser
  time as well.
  
  I've changed the version number in build.xml to reflect this bigger
  change.
  
  Revision  Changes    Path
  1.27      +10 -0     jakarta-ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/WHATSNEW,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- WHATSNEW	2000/09/11 13:08:33	1.26
  +++ WHATSNEW	2000/09/14 07:19:50	1.27
  @@ -3,6 +3,16 @@
   Changes that could break older environments:
   --------------------------------------------
   
  +* Semantics of <property> has changed again in the hope to be more
  +intuitive. ${} expansion now happens at runtime and <property> tags
  +living inside of targets only take effect if they are visited at
  +runtime.
  +
  +As a side effect of this change, task's attributes get set at runtime
  +not at parser time as well, which might change the results of
  +<script>s or other custom tasks that reference other tasks by their id
  +attribute.
  +
   * copying of support files in <javac> has been removed - as well as
   the filtering attribute.
   
  
  
  
  1.70      +1 -1      jakarta-ant/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.xml,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- build.xml	2000/09/12 14:44:02	1.69
  +++ build.xml	2000/09/14 07:19:50	1.70
  @@ -12,7 +12,7 @@
   
     <property name="Name" value="Ant"/>
     <property name="name" value="ant"/>
  -  <property name="version" value="1.2alpha"/>
  +  <property name="version" value="1.2alpha2"/>
   
     <property name="ant.home" value="."/>
     <property name="src.bin.dir" value="src/bin"/>
  
  
  
  1.99      +39 -3     jakarta-ant/docs/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/index.html,v
  retrieving revision 1.98
  retrieving revision 1.99
  diff -u -r1.98 -r1.99
  --- index.html	2000/09/12 14:44:05	1.98
  +++ index.html	2000/09/14 07:19:51	1.99
  @@ -25,7 +25,7 @@
     <li>Dave Walend (<a href="mailto:dwalend@cs.tufts.edu">dwalend@cs.tufts.edu</a>)</li>
   </ul>
   
  -<p>Version 1.2 - 2000/09/07</p>
  +<p>Version 1.2 - 2000/09/14</p>
   
   <hr>
   <h2>Table of Contents</h2>
  @@ -4778,8 +4778,44 @@
       throws a <code>BuildException</code>. This method implements the task
       itself.</li>
   </ol>
  -<p>It is important to know that Ant first calls the setters for the attributes
  -it encounters for a specific task in the buildfile, before it executes is.</p>
  +<h3>The life cycle of a task</h3>
  +<ol>
  +  <li>The task gets instantiated using a no-arg constructor at parser
  +    time. This means even tasks that are never executed get
  +    instantiated.</li>
  +
  +  <li>The tasks gets references to its project and location inside the
  +    build file via their inherited <code>project</code> and
  +    <code>location</code> variables.</li>
  +
  +  <li>If the user specified an id attribute to this task, the project
  +    registers a reference to this newly created task - at parser
  +    time.</li>
  +
  +  <li><code>init()</code> is called at parser time.</li>
  +
  +  <li>The task gets a reference to the target it belongs to via its
  +    inherited <code>target</code> variable.</li>
  +
  +  <li>All child elements of the XML element corresponding to this task
  +    are created via this task's <code>createXXX()</code> methods or
  +    instantiated and added to this task via its <code>addXXX()</code>
  +    methods - at parser time.</li>
  +
  +  <li>All attributes of this task get set via their corresponding
  +    <code>setXXX</code> methods - at runtime.</li>
  +
  +  <li>The content character data sections inside the XML element
  +    corresponding to this task is added to the task via its
  +    <code>addText</code> method - at runtime.</li>
  +
  +  <li>All attributes of all child elements get set via their corresponding
  +    <code>setXXX</code> methods - at runtime.</li>
  +
  +  <li><code>execute()</code> is called at runtime.</li>
  +
  +</ol>
  +<h3>Example</h3>
   <p>Let's write our own task, that prints a message on the System.out stream. The
   task has one attribute called &quot;message&quot;.</p>
   <blockquote>
  
  
  
  1.28      +86 -41    jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java
  
  Index: ProjectHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- ProjectHelper.java	2000/09/08 07:20:57	1.27
  +++ ProjectHelper.java	2000/09/14 07:19:51	1.28
  @@ -354,6 +354,7 @@
       private class TaskHandler extends AbstractHandler {
           private Target target;
           private Task task;
  +        private RuntimeConfigurable wrapper = null;
   
           public TaskHandler(DocumentHandler parentHandler, Target target) {
               super(parentHandler);
  @@ -363,35 +364,37 @@
   
           public void init(String tag, AttributeList attrs) throws SAXParseException {
               task = project.createTask(tag);
  -            configure(task, attrs);
  +
               task.setLocation(new Location(buildFile.toString(), locator.getLineNumber(),
locator.getColumnNumber()));
  +            configureId(task, attrs);
               task.init();
   
               // Top level tasks don't have associated targets
               if (target != null) {
                   task.setOwningTarget(target);
                   target.addTask(task);
  +                wrapper = task.getRuntimeConfigurableWrapper();
  +                wrapper.setAttributes(attrs);
               } else {
  +                configure(task, attrs, project);
                   task.execute();
               }
           }
   
           public void characters(char[] buf, int start, int end) throws SAXParseException
{
  -            String text = new String(buf, start, end).trim();
  -            if (text.length() == 0) return;
  -
  -            IntrospectionHelper ih = 
  -                IntrospectionHelper.getHelper(task.getClass());
  -
  -            try {
  -                ih.addText(task, text);
  -            } catch (BuildException exc) {
  -                throw new SAXParseException(exc.getMessage(), locator, exc);
  +            if (wrapper == null) {
  +                try {
  +                    addText(task, buf, start, end);
  +                } catch (BuildException exc) {
  +                    throw new SAXParseException(exc.getMessage(), locator, exc);
  +                }
  +            } else {
  +                wrapper.addText(buf, start, end);
               }
           }
   
           public void startElement(String name, AttributeList attrs) throws SAXParseException
{
  -            new NestedElementHandler(this, task).init(name, attrs);
  +            new NestedElementHandler(this, task, wrapper).init(name, attrs);
           }
       }
   
  @@ -401,11 +404,16 @@
       private class NestedElementHandler extends AbstractHandler {
           private Object target;
           private Object child;
  +        private RuntimeConfigurable parentWrapper;
  +        private RuntimeConfigurable childWrapper = null;
   
  -        public NestedElementHandler(DocumentHandler parentHandler, Object target) {
  +        public NestedElementHandler(DocumentHandler parentHandler, 
  +                                    Object target,
  +                                    RuntimeConfigurable parentWrapper) {
               super(parentHandler);
   
               this.target = target;
  +            this.parentWrapper = parentWrapper;
           }
   
           public void init(String propType, AttributeList attrs) throws SAXParseException
{
  @@ -415,28 +423,34 @@
   
               try {
                   child = ih.createElement(target, propType.toLowerCase());
  -                configure(child, attrs);
  +                configureId(child, attrs);
  +
  +                if (parentWrapper != null) {
  +                    childWrapper = new RuntimeConfigurable(child);
  +                    childWrapper.setAttributes(attrs);
  +                    parentWrapper.addChild(childWrapper);
  +                } else {
  +                    configure(child, attrs, project);
  +                }
               } catch (BuildException exc) {
                   throw new SAXParseException(exc.getMessage(), locator, exc);
               }
           }
   
           public void characters(char[] buf, int start, int end) throws SAXParseException
{
  -            String text = new String(buf, start, end).trim();
  -            if (text.length() == 0) return;
  -
  -            IntrospectionHelper ih = 
  -                IntrospectionHelper.getHelper(child.getClass());
  -
  -            try {
  -                ih.addText(child, text);
  -            } catch (BuildException exc) {
  -                throw new SAXParseException(exc.getMessage(), locator, exc);
  +            if (parentWrapper == null) {
  +                try {
  +                    addText(child, buf, start, end);
  +                } catch (BuildException exc) {
  +                    throw new SAXParseException(exc.getMessage(), locator, exc);
  +                }
  +            } else {
  +                childWrapper.addText(buf, start, end);
               }
           }
   
           public void startElement(String name, AttributeList attrs) throws SAXParseException
{
  -            new NestedElementHandler(this, child).init(name, attrs);
  +            new NestedElementHandler(this, child, childWrapper).init(name, attrs);
           }
       }
   
  @@ -457,32 +471,28 @@
                       throw new BuildException("Unknown data type "+propType);
                   }
                   
  -                configure(element, attrs);
  +                configureId(element, attrs);
  +                configure(element, attrs, project);
               } catch (BuildException exc) {
                   throw new SAXParseException(exc.getMessage(), locator, exc);
               }
           }
   
           public void characters(char[] buf, int start, int end) throws SAXParseException
{
  -            String text = new String(buf, start, end).trim();
  -            if (text.length() == 0) return;
  -
  -            IntrospectionHelper ih = 
  -                IntrospectionHelper.getHelper(element.getClass());
  -
               try {
  -                ih.addText(element, text);
  +                addText(element, buf, start, end);
               } catch (BuildException exc) {
                   throw new SAXParseException(exc.getMessage(), locator, exc);
               }
           }
   
           public void startElement(String name, AttributeList attrs) throws SAXParseException
{
  -            new NestedElementHandler(this, element).init(name, attrs);
  +            new NestedElementHandler(this, element, null).init(name, attrs);
           }
       }
   
  -    private void configure(Object target, AttributeList attrs) throws BuildException {
  +    public static void configure(Object target, AttributeList attrs, 
  +                                 Project project) throws BuildException {
           if( target instanceof TaskAdapter )
               target=((TaskAdapter)target).getProxy();
   
  @@ -498,19 +508,39 @@
                                   attrs.getName(i).toLowerCase(), value);
   
               } catch (BuildException be) {
  -                if (attrs.getName(i).equals("id")) {
  -                    project.addReference(attrs.getValue(i), target);
  -                } else {
  -                    be.setLocation(new Location(buildFile.toString(), 
  -                                                locator.getLineNumber(), 
  -                                                locator.getColumnNumber()));
  +                // id attribute must be set externally
  +                if (!attrs.getName(i).equals("id")) {
                       throw be;
                   }
               }
           }
       }
   
  +    /**
  +     * Adds the content of #PCDATA sections to an element.
  +     */
  +    public static void addText(Object target, char[] buf, int start, int end)
  +        throws BuildException {
  +        addText(target, new String(buf, start, end).trim());
  +    }
  +
  +    /**
  +     * Adds the content of #PCDATA sections to an element.
  +     */
  +    public static void addText(Object target, String text)
  +        throws BuildException {
  +
  +        if (text == null || text.length() == 0) {
  +            return;
  +        }
   
  +        if(target instanceof TaskAdapter)
  +            target = ((TaskAdapter) target).getProxy();
  +
  +        IntrospectionHelper.getHelper(target.getClass()).addText(target, text);
  +    }
  +
  +
       /** Replace ${NAME} with the property value
        */
       public static String replaceProperties( String value, Hashtable keys )
  @@ -562,4 +592,19 @@
   
           return parserFactory;
       }
  +
  +    /**
  +     * Scan AttributeList for the id attribute and maybe add a
  +     * reference to project.  
  +     *
  +     * <p>Moved out of {@link #configure configure} to make it happen
  +     * at parser time.</p> 
  +     */
  +    private void configureId(Object target, AttributeList attr) {
  +        String id = attr.getValue("id");
  +        if (id != null) {
  +            project.addReference(id, target);
  +        }
  +    }
  +
   }
  
  
  
  1.10      +1 -0      jakarta-ant/src/main/org/apache/tools/ant/Target.java
  
  Index: Target.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Target.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Target.java	2000/08/22 15:38:33	1.9
  +++ Target.java	2000/09/14 07:19:51	1.10
  @@ -138,6 +138,7 @@
   
                   try {
                       project.fireTaskStarted(task);
  +                    task.maybeConfigure();
                  	    task.execute();
                       project.fireTaskFinished(task, null);
   		}
  
  
  
  1.13      +20 -0     jakarta-ant/src/main/org/apache/tools/ant/Task.java
  
  Index: Task.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Task.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Task.java	2000/07/12 11:51:30	1.12
  +++ Task.java	2000/09/14 07:19:51	1.13
  @@ -68,6 +68,7 @@
       protected Location location = Location.UNKNOWN_LOCATION;
       protected String taskName = null;
       protected String taskType = null;
  +    protected RuntimeConfigurable wrapper;
   
       /**
        * Sets the project object of this task. This method is used by
  @@ -192,6 +193,25 @@
        */
       public void setLocation(Location location) {
           this.location = location;
  +    }
  +
  +    /**
  +     * Returns the wrapper class for runtime configuration.
  +     */
  +    public RuntimeConfigurable getRuntimeConfigurableWrapper() {
  +        if (wrapper == null) {
  +            wrapper = new RuntimeConfigurable(this);
  +        }
  +        return wrapper;
  +    }
  +
  +    /**
  +     * Configure this task - if it hasn't been done already.
  +     */
  +    public void maybeConfigure() throws BuildException {
  +        if (wrapper != null) {
  +            wrapper.maybeConfigure(project);
  +        }
       }
   }
   
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java
  
  Index: RuntimeConfigurable.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.tools.ant;
  
  import java.util.Enumeration;
  import java.util.Vector;
  import org.xml.sax.AttributeList;
  import org.xml.sax.helpers.AttributeListImpl;
  
  /**
   * Wrapper class that holds the attributes of a Task (or elements
   * nested below that level) and takes care of configuring that element
   * at runtime.
   *
   * @author <a href="stefan.bodewig@megabit.net">Stefan Bodewig</a> 
   */
  public class RuntimeConfigurable {
  
      private Vector children = new Vector();
      private Object wrappedObject = null;
      private AttributeList attributes;
      private StringBuffer characters = new StringBuffer();
  
      /**
       * @param proxy The element to wrap.
       */
      public RuntimeConfigurable(Object proxy) {
          wrappedObject = proxy;
      }
  
      /**
       * Set's the attributes for the wrapped element.
       */
      public void setAttributes(AttributeList attributes) {
          this.attributes = new AttributeListImpl(attributes);
      }
  
      /**
       * Adds child elements to the wrapped element.
       */
      public void addChild(RuntimeConfigurable child) {
          children.addElement(child);
      }
  
      /**
       * Add characters from #PCDATA areas to the wrapped element.
       */
      public void addText(String data) {
          characters.append(data);
      }
  
      /**
       * Add characters from #PCDATA areas to the wrapped element.
       */
      public void addText(char[] buf, int start, int end) {
          addText(new String(buf, start, end).trim());
      }
  
      /**
       * Configure the wrapped element and all children.
       */
      public void maybeConfigure(Project p) throws BuildException {
          if (attributes != null) {
              ProjectHelper.configure(wrappedObject, attributes, p);
              attributes = null;
          }
          if (characters.length() != 0) {
              ProjectHelper.addText(wrappedObject, characters.toString());
              characters.setLength(0);
          }
          Enumeration enum = children.elements();
          while (enum.hasMoreElements()) {
              RuntimeConfigurable child = (RuntimeConfigurable) enum.nextElement();
              child.maybeConfigure(p);
          }
      }
  
  }
  
  
  
  1.9       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Available.java
  
  Index: Available.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Available.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Available.java	2000/08/10 12:58:54	1.8
  +++ Available.java	2000/09/14 07:19:52	1.9
  @@ -94,7 +94,7 @@
           this.resource = resource;
       }
   
  -    public void init() throws BuildException {
  +    public void execute() throws BuildException {
           if ((classname != null) && !checkClass(classname)) return;
           if ((file != null) && !checkFile(file)) return;
           if ((resource != null) && !checkResource(resource)) return;
  
  
  
  1.2       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Filter.java
  
  Index: Filter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Filter.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Filter.java	2000/02/13 18:24:18	1.1
  +++ Filter.java	2000/09/14 07:19:52	1.2
  @@ -75,7 +75,7 @@
           this.value = value;
       }
   
  -    public void init() throws BuildException {
  +    public void execute() throws BuildException {
           project.addFilter(token, value);
       }
   }
  
  
  
  1.15      +1 -1      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Property.java
  
  Index: Property.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Property.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Property.java	2000/09/04 13:29:50	1.14
  +++ Property.java	2000/09/14 07:19:52	1.15
  @@ -107,7 +107,7 @@
           return resource;
       }
   
  -    public void init() throws BuildException {
  +    public void execute() throws BuildException {
           try {
               if ((name != null) && (value != null)) {
                   addProperty(name, value);
  
  
  
  1.5       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
  
  Index: Tstamp.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Tstamp.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Tstamp.java	2000/02/11 16:17:03	1.4
  +++ Tstamp.java	2000/09/14 07:19:52	1.5
  @@ -67,7 +67,7 @@
    */
   public class Tstamp extends Task {
   
  -    public void init() throws BuildException {
  +    public void execute() throws BuildException {
           try {
               Date d = new Date();
   
  
  
  

Mime
View raw message