You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by um...@apache.org on 2002/03/06 04:25:51 UTC

cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs CopyTest.java LoadFileTest.java MoveTest.java

umagesh     02/03/05 19:25:51

  Modified:    .        WHATSNEW build.xml
               docs/manual conceptstypeslist.html coretasklist.html
               docs/manual/CoreTasks loadfile.html
               src/etc/testcases/taskdefs copy.xml loadfile.xml move.xml
               src/main/org/apache/tools/ant/taskdefs Copy.java
                        LoadFile.java Move.java defaults.properties
               src/main/org/apache/tools/ant/util FileUtils.java
               src/testcases/org/apache/tools/ant/taskdefs CopyTest.java
                        LoadFileTest.java MoveTest.java
  Added:       docs/manual/CoreTasks loadproperties.html
               src/main/org/apache/tools/ant/filters BaseFilterReader.java
                        BaseParamFilterReader.java ChainableReader.java
                        ClassConstants.java ExpandProperties.java
                        HeadFilter.java LineContains.java
                        LineContainsRegExp.java PrefixLines.java
                        ReplaceTokens.java StringInputStream.java
                        StripJavaComments.java StripLineBreaks.java
                        StripLineComments.java TabsToSpaces.java
                        TailFilter.java
               src/main/org/apache/tools/ant/filters/util
                        ChainReaderHelper.java JavaClassHelper.java
               src/main/org/apache/tools/ant/taskdefs LoadProperties.java
               src/main/org/apache/tools/ant/types AntFilterReader.java
                        FilterChain.java Parameter.java
                        Parameterizable.java
  Log:
  Promote Filter Reader proposal to main trunk.
  
  Revision  Changes    Path
  1.222     +10 -0     jakarta-ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/WHATSNEW,v
  retrieving revision 1.221
  retrieving revision 1.222
  diff -u -r1.221 -r1.222
  --- WHATSNEW	3 Mar 2002 06:52:07 -0000	1.221
  +++ WHATSNEW	6 Mar 2002 03:25:49 -0000	1.222
  @@ -77,6 +77,16 @@
   
   Other changes:
   --------------
  +* New filter readers: ClassConstants, ExpandProperties, HeadFilter, 
  +  LineContains, LineContainsRegExp, PrefixLines, ReplaceTokens, 
  +  StripJavaComments, StripLineBreaks, StripLineComments, TabsToSpaces, 
  +  TailFilter.
  +
  +* <copy>, <loadfile>, <loadproperties>, <move> support FilterChains 
  +  of FilterReaders.
  +  
  +* New task <loadproperties> to load contents of file as Ant properties.
  +  
   * Users can control what <zip> and <jar> must do when duplicate files 
     are found.  A new element <zipgroupfileset> allows for multiple zip 
     files to be merged into the archive.  In addition, <jar> also has 
  
  
  
  1.260     +2 -0      jakarta-ant/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.xml,v
  retrieving revision 1.259
  retrieving revision 1.260
  diff -u -r1.259 -r1.260
  --- build.xml	4 Mar 2002 08:43:51 -0000	1.259
  +++ build.xml	6 Mar 2002 03:25:49 -0000	1.260
  @@ -208,6 +208,8 @@
                unless="jakarta.oro.present"/>
     </patternset>
     <patternset id="needs.jakarta.bcel">
  +    <exclude name="${ant.package}/filters/util/JavaClassHelper.java" 
  +             unless="bcel.present" />
       <exclude name="${optional.type.package}/depend/*.java" 
                unless="bcel.present" />
       <exclude name="${util.package}/depend/*.java"
  
  
  
  1.2       +1 -0      jakarta-ant/docs/manual/conceptstypeslist.html
  
  Index: conceptstypeslist.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/manual/conceptstypeslist.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- conceptstypeslist.html	20 Feb 2002 01:16:20 -0000	1.1
  +++ conceptstypeslist.html	6 Mar 2002 03:25:49 -0000	1.2
  @@ -18,6 +18,7 @@
   <a href="CoreTypes/filelist.html">FileList</a><br>
   <a href="CoreTypes/fileset.html">FileSet</a><br>
   <a href="CoreTypes/mapper.html">File Mappers</a><br>
  +<a href="CoreTypes/filterchain.html">FilterChains and FilterReaders</a><br>
   <a href="CoreTypes/filterset.html">Filterset</a><br>
   <a href="CoreTypes/patternset.html">Patternset</a><br>
   
  
  
  
  1.33      +1 -0      jakarta-ant/docs/manual/coretasklist.html
  
  Index: coretasklist.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/manual/coretasklist.html,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- coretasklist.html	20 Feb 2002 01:16:20 -0000	1.32
  +++ coretasklist.html	6 Mar 2002 03:25:49 -0000	1.33
  @@ -48,6 +48,7 @@
   <a href="CoreTasks/javac.html">Javac</a><br>
   <a href="CoreTasks/javadoc.html">Javadoc/<i>Javadoc2</i></a><br>
   <a href="CoreTasks/loadfile.html">LoadFile</a><br>
  +<a href="CoreTasks/loadproperties.html">LoadProperties</a><br>
   <a href="CoreTasks/mail.html">Mail</a><br>
   <a href="CoreTasks/manifest.html">Manifest</a><br>
   <a href="CoreTasks/mkdir.html">Mkdir</a><br>
  
  
  
  1.5       +15 -35    jakarta-ant/docs/manual/CoreTasks/loadfile.html
  
  Index: loadfile.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/manual/CoreTasks/loadfile.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- loadfile.html	3 Feb 2002 22:00:42 -0000	1.4
  +++ loadfile.html	6 Mar 2002 03:25:49 -0000	1.5
  @@ -10,10 +10,7 @@
   <h3>Description</h3>
   <p>
    Load a text file into a single property. Unless an encoding is specified,
  - the encoding of the current locale is used. There is no explicit limit
  - upon the size of the file which can be loaded, but loading very large
  - files is not something anyone has yet explored. Because the file is
  - converted to text
  + the encoding of the current locale is used.
   
   </p>
   
  @@ -44,40 +41,21 @@
       <td valign="top">Whether to halt the build on failure</td>
       <td align="center" valign="top">No, default "true"</td>
     </tr>
  -  <tr>
  -    <td valign="top">evaluateProperties</td>
  -    <td valign="top">flag to enable property evalation in the file</td>
  -    <td align="center" valign="top">No, default "false"</td>
  -  </tr>
  -  <tr>
  -    <td valign="top">makeOneLine</td>
  -    <td valign="top">flag to strip out newlines (but not spaces or
  -        tabs) from the file</td>
  -    <td align="center" valign="top">No, default "false"</td>
  -  </tr>
   </table>
   <p>
  -The <tt>makeOneLine</tt> parameter enables you to use a file as an
  -input to task parameters which expect single line input. It flattens
  -the file by removing all carriage return and line feed characters,
  -so that the file
  -<pre>a
  -b
  -c
  -</pre>would become "abc": you need spaces or
  -commas at the end/start of line to stop alphanumeric characters
  -being merged together.
  +The LoadFile task supports nested <a href="../CoreTypes/filterchain.html">
  +FilterChain</a>s.
   
   <h3>Examples</h3>
   <pre>    &lt;loadfile property="message"
  -      srcFile="message.txt" / &gt;
  +      srcFile="message.txt" /&gt;
   </pre>
   Load file message.txt into property "message"; an <tt>&lt;echo&gt;</tt>
   can print this.
   
   <pre>    &lt;loadfile property="encoded-file"
         srcFile="loadfile.xml"
  -      encoding="ISO-8859-1" / &gt;
  +      encoding="ISO-8859-1" /&gt;
   </pre>
   Load a file using the latin-1 encoding
   
  @@ -90,20 +68,22 @@
   
   <pre>    &lt;loadfile
         property="mail.recipients"
  -      srcFile="recipientlist.txt"
  -      makeOneLine="true" /&gt;
  +      srcFile="recipientlist.txt"&gt;
  +      &lt;filterchain&gt;
  +        &lt;<a href="../CoreTypes/filterchain.html#striplinebreaks">striplinebreaks</a>/&gt;
  +      &lt;/filterchaint&gt;
  +    &lt;/loadfile&gt;
   </pre>
  -
  -load a property which can be used as a parameter for another task (in this case mail),
  +Load a property which can be used as a parameter for another task (in this case mail),
   merging lines to ensure this happens.
   
   <pre>    &lt;loadfile
         property="system.configuration.xml"
  -      srcFile="configuration.xml"
  -      evaluateProperties="true" /&gt;
  +      srcFile="configuration.xml"&gt;
  +        &lt;<a href="../CoreTypes/filterchain.html#expandproperties">expandproperties</a>/&gt;
  +    &lt;/loadfile&gt;
   </pre>
  -
  -load an XML file into a property, expanding all properties declared
  +Load an XML file into a property, expanding all properties declared
   in the file in the process.
   
   
  
  
  
  1.1                  jakarta-ant/docs/manual/CoreTasks/loadproperties.html
  
  Index: loadproperties.html
  ===================================================================
  <html>
  <head>
  <title>LoadProperties Task</title>
  </head>
  
  <body>
  
  
  <h2><a name="loadproperties">LoadProperties</a></h2>
  <h3>Description</h3>
  <p>
  Load a file's contents as Ant properties.  This is equivalent
  to &lt;property file=&quot;...&quot;/&gt; except that it
  supports nested &lt;filterchain&gt; elements and it cannot be
  specified outside a target.
  
  </p>
  
  <h3>Parameters</h3>
  <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">srcFile</td>
      <td valign="top">source file</td>
      <td valign="top" align="center">Yes</td>
    </tr>
  </table>
  <p>
  The LoadProperties task supports nested <a href="../CoreTypes/filterchain.html">
  FilterChain</a>s.
  
  <h3>Examples</h3>
  <pre>    &lt;loadproperties srcFile="file.properties" /&gt;
  </pre>
  Load contents of file.properties as Ant properties.
  
  <pre>    &lt;loadproperties srcFile="file.properties"&gt;
        &lt;filterchain&gt;
          &lt;<a href="../CoreTypes/filterchain.html#linecontains">linecontains</a>&gt;
            &lt;contains value="import.&quot;/&gt;
          &lt;linecontains/&gt;
        &lt;/filterchaint&gt;
      &lt;/loadproperties&gt;
  </pre>
  Read the lines that contain the string &quot;import.&quot;
  from the file &quot;file.properties&quot; and load them as
  Ant properties.
  <hr>
  
  <p align="center">Copyright &copy; 2002 Apache Software Foundation. All rights
  Reserved.</p>
  
  </body>
  </html>
  
  
  
  
  1.8       +11 -0     jakarta-ant/src/etc/testcases/taskdefs/copy.xml
  
  Index: copy.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/etc/testcases/taskdefs/copy.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- copy.xml	3 Mar 2002 01:30:03 -0000	1.7
  +++ copy.xml	6 Mar 2002 03:25:50 -0000	1.8
  @@ -52,6 +52,16 @@
       </copy>
     </target>
   
  +  <target name="testFilterChain">
  +    <copy file="copy.filterset" tofile="copy.filterchain.tmp">
  +      <filterchain>
  +        <replacetokens>
  +          <token key="TITLE" value="Apache Ant Project"/>
  +        </replacetokens>
  +      </filterchain>
  +    </copy>
  +  </target>
  +
     <target name="cleanup"> 
       <delete file="copytest1.tmp"/>
       <delete file="copytest3.tmp"/>
  @@ -60,6 +70,7 @@
       <delete file="copytest3c.tmp"/>
       <delete file="copytest_single_file_fileset.tmp"/>
       <delete file="copy.filterset.tmp"/>
  +    <delete file="copy.filterchain.tmp"/>
       <delete dir="copytest1dir"/>
     </target>
   
  
  
  
  1.4       +37 -8     jakarta-ant/src/etc/testcases/taskdefs/loadfile.xml
  
  Index: loadfile.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/etc/testcases/taskdefs/loadfile.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- loadfile.xml	1 Feb 2002 07:23:14 -0000	1.3
  +++ loadfile.xml	6 Mar 2002 03:25:50 -0000	1.4
  @@ -53,12 +53,39 @@
         file="loadfile1.tmp"
         />
       <loadfile property="testEvalProps"
  -        srcFile="loadfile1.tmp"
  -        evaluateProperties="true"
  -        />
  -    <echo>${testLoadAFile}</echo>
  +        srcFile="loadfile1.tmp">
  +        <filterchain>
  +          <expandproperties/>
  +        </filterchain>
  +    </loadfile>
  +    <echo>${testEvalProps}</echo>
     </target>
   
  +  <target name="testFilterChain"
  +    depends="init">
  +      <echo file="loadfile1.tmp">#Line 1
  +REM Line 2
  +--Line 3
  +Line 4
  +Hello World!</echo>
  +      <loadfile srcFile="loadfile1.tmp" 
  +        property="testFilterChain">
  +        <filterchain>
  +          <headfilter lines="5"/>
  +          <striplinecomments>
  +            <comment value="--"/>
  +            <comment value="REM "/>
  +            <comment value="#"/>
  +          </striplinecomments>
  +          <filterreader classname="org.apache.tools.ant.filters.TailFilter">
  +            <param name="lines" value="1"/>
  +          </filterreader>
  +          <linecontains>
  +            <contains value="World!"/>
  +          </linecontains>
  +        </filterchain>
  +      </loadfile>
  +  </target>
   
     <target name="testOneLine"
       depends="init">
  @@ -67,10 +94,12 @@
         file="loadfile1.tmp"
         />
       <loadfile property="testOneLine"
  -        srcFile="loadfile1.tmp"
  -        makeOneLine="true"
  -        />
  -    <echo>${testLoadAFile}</echo>
  +        srcFile="loadfile1.tmp">
  +      <filterchain>
  +        <striplinebreaks/>
  +      </filterchain>
  +    </loadfile>
  +    <echo>${testOneLine}</echo>
     </target>
   
   
  
  
  
  1.2       +12 -0     jakarta-ant/src/etc/testcases/taskdefs/move.xml
  
  Index: move.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/etc/testcases/taskdefs/move.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- move.xml	3 Mar 2002 01:30:03 -0000	1.1
  +++ move.xml	6 Mar 2002 03:25:50 -0000	1.2
  @@ -11,8 +11,20 @@
       </move>
     </target>
   
  +  <target name="testFilterChain">
  +    <copy file="copy.filterset" tofile="move.filterchain"/>
  +    <move file="move.filterchain" tofile="move.filterchain.tmp">
  +      <filterchain>
  +        <replacetokens>
  +          <token key="TITLE" value="Apache Ant Project"/>
  +        </replacetokens>
  +      </filterchain>
  +    </move>
  +  </target>
  +
     <target name="cleanup"> 
       <delete file="move.filterset.tmp"/>
  +    <delete file="move.filterchain.tmp"/>
     </target>
   
   </project>
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/BaseFilterReader.java
  
  Index: BaseFilterReader.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.FilterReader;
  import java.io.IOException;
  import java.io.Reader;
  import java.io.StringReader;
  
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.util.FileUtils;
  
  /**
   * Base class for core filter readers.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public abstract class BaseFilterReader
      extends FilterReader
  {
      /** Have the parameters passed been interpreted? */
      private boolean initialized = false;
  
      /** The Ant project */
      private Project project = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public BaseFilterReader() {
          // Dummy constructor to be invoked by Ant's Introspector
          super(new StringReader(new String()));
          try {
              close();
          } catch (IOException  ioe) {
              // Ignore
          }
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public BaseFilterReader(final Reader in) {
          super(in);
      }
  
      /**
       * Read characters into a portion of an array.  This method will block
       * until some input is available, an I/O error occurs, or the end of the
       * stream is reached.
       *
       * @param      cbuf  Destination buffer
       * @param      off   Offset at which to start storing characters
       * @param      len   Maximum number of characters to read
       *
       * @return     The number of characters read, or -1 if the end of the
       *             stream has been reached
       *
       * @exception  IOException  If an I/O error occurs
       */
      public final int read(final char cbuf[], final int off,
                            final int len) throws IOException {
          for (int i = 0; i < len; i++) {
              final int ch = read();
              if (ch == -1) {
                  if (i == 0) {
                      return -1;
                  } else {
                      return i;
                  }
              }
              cbuf[off + i] = (char) ch;
          }
          return len;
      }
  
      /**
       * Skip characters.  This method will block until some characters are
       * available, an I/O error occurs, or the end of the stream is reached.
       *
       * @param  n  The number of characters to skip
       *
       * @return    The number of characters actually skipped
       *
       * @exception  IllegalArgumentException  If <code>n</code> is negative.
       * @exception  IOException  If an I/O error occurs
       */
      public final long skip(final long n) throws IOException {
          if (n < 0L) {
              throw new IllegalArgumentException("skip value is negative");
          }
  
          for (long i = 0; i < n; i++) {
              if (read() == -1) {
                  return i;
              }
          }
          return n;
      }
  
      /**
       * Set the initialized status.
       */
      protected final void setInitialized(final boolean initialized) {
          this.initialized = initialized;
      }
  
      /**
       * Get the initialized status.
       */
      protected final boolean getInitialized() {
          return initialized;
      }
  
      /**
       * Set the project to work with
       */
      public final void setProject(final Project project) {
          this.project = project;
      }
  
      /**
       * Get the project
       */
      protected final Project getProject() {
          return project;
      }
  
      /**
       * Read till EOL
       */
      protected final String readLine() throws IOException {
          int ch = in.read();
          String line = (ch == -1) ? null : "";
          while (ch != -1) {
              line += (char) ch;
              if (ch == '\n') {
                  break;
              }
              ch = in.read();
          }
          return line;
      }
  
      /**
       * Read till EOF
       */
      protected final String readFully() throws IOException {
          return FileUtils.readFully(in, 8192);
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java
  
  Index: BaseParamFilterReader.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.FilterReader;
  import java.io.IOException;
  import java.io.Reader;
  import java.io.StringReader;
  
  import org.apache.tools.ant.types.Parameter;
  import org.apache.tools.ant.types.Parameterizable;
  
  /**
   * Parameterized Base class for core filter readers.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public abstract class BaseParamFilterReader
      extends BaseFilterReader
      implements Parameterizable
  {
      /** The passed in parameter array. */
      private Parameter[] parameters;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public BaseParamFilterReader() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public BaseParamFilterReader(final Reader in) {
          super(in);
      }
  
      /**
       * Set Parameters
       */
      public final void setParameters(final Parameter[] parameters) {
          this.parameters = parameters;
          setInitialized(false);
      }
  
      protected final Parameter[] getParameters() {
          return parameters;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/ChainableReader.java
  
  Index: ChainableReader.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.Reader;
  
  /**
   * Chains readers.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public interface ChainableReader {
      public Reader chain(Reader rdr);
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/ClassConstants.java
  
  Index: ClassConstants.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.Reader;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  
  import org.apache.tools.ant.Project;
  
  /**
   * Assemble the constants declared in a Java class in
   * key1=value1(line separator)key2=value2
   * format
   *
   * Notes:
   * =====
   * 1. This filter uses the BCEL external toolkit.
   * 2. This assembles only those constants that are not created
   *    using the syntax new whatever().
   * 3. This assembles constants declared using the basic datatypes
   *    and String only.
   * 4. The access modifiers of the declared constants do not matter.
   *
   * Example:
   * =======
   *
   * &lt;classconstants/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ClassConstants&quot;/&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class ClassConstants
      extends BaseFilterReader
      implements ChainableReader
  {
      /** Data that must be read from, if not null. */
      private String queuedData = null;
  
      /** Helper Class to be invoked via reflection. */
      private String JAVA_CLASS_HELPER =
          "org.apache.tools.ant.filters.util.JavaClassHelper";
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public ClassConstants() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public ClassConstants(final Reader in) {
          super(in);
      }
  
      /**
       * Read and assemble the constants declared in a class file.
       */
      public final int read() throws IOException {
  
          int ch = -1;
  
          if (queuedData != null && queuedData.length() == 0) {
              queuedData = null;
          }
  
          if (queuedData != null) {
              ch = queuedData.charAt(0);
              queuedData = queuedData.substring(1);
              if (queuedData.length() == 0) {
                  queuedData = null;
              }
          } else {
              final String clazz = readFully();
              if (clazz == null) {
                  ch = -1;
              } else {
                  final byte[] bytes = clazz.getBytes();
                  try {
                      final Class javaClassHelper =
                          Class.forName(JAVA_CLASS_HELPER);
                      if (javaClassHelper != null) {
                          final Class params[] = {
                              byte[].class
                          };
                          final Method getConstants =
                              javaClassHelper.getMethod("getConstants", params);
                          final Object[] args = {
                              bytes
                          };
                          // getConstants is a staic method, no need to
                          // pass in the object
                          final StringBuffer sb = (StringBuffer)
                                  getConstants.invoke(null, args);
                          if (sb.length() > 0) {
                              queuedData = sb.toString();
                              return read();
                          }
                      }
                  } catch (ClassNotFoundException cnfe) {
                      throw new IOException(cnfe.getMessage());
                  } catch (NoSuchMethodException nsme) {
                      throw new IOException(nsme.getMessage());
                  } catch (IllegalAccessException iae) {
                      throw new IOException(iae.getMessage());
                  } catch (IllegalArgumentException iarge) {
                      throw new IOException(iarge.getMessage());
                  } catch (InvocationTargetException ite) {
                      throw new IOException(ite.getMessage());
                  }
              }
          }
          return ch;
      }
  
      /**
       * Create a new ClassConstants using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          ClassConstants newFilter = new ClassConstants(rdr);
          return newFilter;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/ExpandProperties.java
  
  Index: ExpandProperties.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.Project;
  
  /**
   * Expand Ant properties, if any, in the data.
   *
   * Example:
   * =======
   *
   * &lt;expandproperties/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ExpandProperties&quot;/&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class ExpandProperties
      extends BaseFilterReader
      implements ChainableReader
  {
      /** Data that must be read from, if not null. */
      private String queuedData = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public ExpandProperties() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public ExpandProperties(final Reader in) {
          super(in);
      }
  
      /**
       * Prefix lines with user defined prefix.
       */
      public final int read() throws IOException {
  
          int ch = -1;
  
          if (queuedData != null && queuedData.length() == 0) {
              queuedData = null;
          }
  
          if (queuedData != null) {
              ch = queuedData.charAt(0);
              queuedData = queuedData.substring(1);
              if (queuedData.length() == 0) {
                  queuedData = null;
              }
          } else {
              queuedData = readFully();
              if (queuedData == null) {
                  ch = -1;
              } else {
                  Project project = getProject();
                  queuedData = project.replaceProperties(queuedData);
                  return read();
              }
          }
          return ch;
      }
  
      /**
       * Create a new PrefixLines using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          ExpandProperties newFilter = new ExpandProperties(rdr);
          newFilter.setProject(getProject());
          return newFilter;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/HeadFilter.java
  
  Index: HeadFilter.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Read the first n lines (Default is first 10 lines)
   *
   * Example:
   * =======
   *
   * &lt;headfilter lines=&quot;3&quot;/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
   *    &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
   * &lt;/filterreader&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class HeadFilter
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** Lines key to represent the number of lines to be returned. */
      private static final String LINES_KEY = "lines";
  
      /** Number of lines currently read in. */
      private long linesRead = 0;
  
      /** Default number of lines returned. */
      private long lines = 10;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public HeadFilter() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public HeadFilter(final Reader in) {
          super(in);
      }
  
      /**
       * Read the first n lines.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (linesRead < lines) {
  
              ch = in.read();
  
              if (ch == '\n') {
                  linesRead++;
              }
          }
  
          return ch;
      }
  
      /**
       * Set number of lines to be returned.
       */
      public final void setLines(final long lines) {
          this.lines = lines;
      }
  
      /**
       * Get number of lines to be returned.
       */
      private final long getLines() {
          return lines;
      }
  
      /**
       * Create a new HeadFilter using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          HeadFilter newFilter = new HeadFilter(rdr);
          newFilter.setLines(getLines());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Scan for the lines parameter.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (LINES_KEY.equals(params[i].getName())) {
                      lines = new Long(params[i].getValue()).longValue();
                      break;
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/LineContains.java
  
  Index: LineContains.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.util.Vector;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Filter Reader to fetch only those lines that contain user specified
   * strings.
   *
   * Example:
   * =======
   *
   * &lt;linecontains&gt;
   *   &lt;contains value=&quot;foo&quot;&gt;
   *   &lt;contains value=&quot;bar&quot;&gt;
   * &lt;/linecontains&gt;
   *
   * Or:
   *
   * &lt;filterreader classname="org.apache.tools.ant.filters.LineContains"&gt;
   *    &lt;param type="contains" value="foo"/&gt;
   *    &lt;param type="contains" value="bar"/&gt;
   * &lt;/filterreader&gt;
   *
   * This will fetch all those lines that contain foo and bar
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class LineContains
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** contains key */
      private static final String CONTAINS_KEY = "contains";
  
      /** Vector that holds the strings that input lines must contain. */
      private Vector contains = new Vector();
  
      /** Currently read in line. */
      private String line = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public LineContains() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public LineContains(final Reader in) {
          super(in);
      }
  
      /**
       * Choose only those lines that contains
       * user defined values.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (line != null) {
              ch = line.charAt(0);
              if (line.length() == 1) {
                  line = null;
              } else {
                  line = line.substring(1);
              }
          } else {
              line = readLine();
              if (line == null) {
                  ch = -1;
              } else {
                  int containsSize = contains.size();
                  for (int i = 0; i < containsSize; i++) {
                      String containsStr = (String) contains.elementAt(i);
                      if (line.indexOf(containsStr) == -1) {
                          line = null;
                          break;
                      }
                  }
  
                  return read();
              }
          }
  
          return ch;
      }
  
      /**
       * Add a contains element.
       */
      public final void addConfiguredContains(final Contains contains) {
          this.contains.addElement(contains.getValue());
      }
  
      /**
       * Set contains vector.
       */
      private void setContains(final Vector contains) {
          this.contains = contains;
      }
  
      /**
       * Get contains vector.
       */
      private final Vector getContains() {
          return contains;
      }
  
      /**
       * Create a new LineContains using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          LineContains newFilter = new LineContains(rdr);
          newFilter.setContains(getContains());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Parse params to add user defined contains strings.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (CONTAINS_KEY.equals(params[i].getType())) {
                      contains.addElement(params[i].getValue());
                  }
              }
          }
      }
  
      /**
       * Holds a contains element
       */
      public static class Contains {
  
          /** User defined contains string */
          private String value;
  
          /**
           * Set the contains string
           */
          public final void setValue(String contains) {
              value = contains;
          }
  
          /**
           * Get the contains string
           */
          public final String getValue() {
              return value;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
  
  Index: LineContainsRegExp.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.util.Vector;
  
  import org.apache.tools.ant.types.Parameter;
  import org.apache.tools.ant.types.RegularExpression;
  import org.apache.tools.ant.util.regexp.Regexp;
  
  /**
   * Filter Reader to fetch only those lines that contain user specified
   * regular expression matching strings.
   *
   * Example:
   * =======
   *
   * &lt;linecontainsregexp&gt;
   *   &lt;regexp pattern=&quot;foo*&quot;&gt;
   * &lt;/linecontainsregexp&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContainsRegExp&quot;&gt;
   *    &lt;param type=&quot;regexp&quot; value=&quot;foo*&quot;/&gt;
   * &lt;/filterreader&gt;
   *
   * This will fetch all those lines that contain the pattern foo
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class LineContainsRegExp
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** contains key */
      private static final String REGEXP_KEY = "regexp";
  
      /** Vector that holds the strings that input lines must contain. */
      private Vector regexps = new Vector();
  
      /** Currently read in line. */
      private String line = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public LineContainsRegExp() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public LineContainsRegExp(final Reader in) {
          super(in);
      }
  
      /**
       * Choose only those lines that contains
       * user defined values.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (line != null) {
              ch = line.charAt(0);
              if (line.length() == 1) {
                  line = null;
              } else {
                  line = line.substring(1);
              }
          } else {
              line = readLine();
              if (line == null) {
                  ch = -1;
              } else {
                  final int regexpsSize = regexps.size();
                  for (int i = 0; i < regexpsSize; i++) {
                      RegularExpression regexp = (RegularExpression)
                                                          regexps.elementAt(i);
                      Regexp re = regexp.getRegexp(getProject());
                      boolean matches = re.matches(line);
                      if (!matches) {
                          line = null;
                          break;
                      }
                  }
  
                  return read();
              }
          }
  
          return ch;
      }
  
      /**
       * Add a contains element.
       */
      public final void addConfiguredRegexp(final RegularExpression regExp) {
          this.regexps.addElement(regExp);
      }
  
      /**
       * Set regexps vector.
       */
      private void setRegexps(final Vector regexps) {
          this.regexps = regexps;
      }
  
      /**
       * Get regexps vector.
       */
      private final Vector getRegexps() {
          return regexps;
      }
  
      /**
       * Create a new LineContainsRegExp using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          LineContainsRegExp newFilter = new LineContainsRegExp(rdr);
          newFilter.setRegexps(getRegexps());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Parse params to add user defined contains strings.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (REGEXP_KEY.equals(params[i].getType())) {
                      String pattern = params[i].getValue();
                      RegularExpression regexp = new RegularExpression();
                      regexp.setPattern(pattern);
                      regexps.addElement(regexp);
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/PrefixLines.java
  
  Index: PrefixLines.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Attach a prefix to every line
   *
   * Example:
   * =======
   *
   * &lt;prefixlines prefix=&quot;Foo&quot;/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.PrefixLines&quot;&gt;
   *    &lt;param name=&quot;prefix&quot; value=&quot;Foo&quot;/&gt;
   * &lt;/filterreader&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class PrefixLines
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** prefix key */
      private static final String PREFIX_KEY = "prefix";
  
      /** The prefix to be used. */
      private String prefix = null;
  
      /** Data that must be read from, if not null. */
      private String queuedData = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public PrefixLines() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public PrefixLines(final Reader in) {
          super(in);
      }
  
      /**
       * Prefix lines with user defined prefix.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (queuedData != null && queuedData.length() == 0) {
              queuedData = null;
          }
  
          if (queuedData != null) {
              ch = queuedData.charAt(0);
              queuedData = queuedData.substring(1);
              if (queuedData.length() == 0) {
                  queuedData = null;
              }
          } else {
              queuedData = readLine();
              if (queuedData == null) {
                  ch = -1;
              } else {
                  if (prefix != null) {
                      queuedData = prefix + queuedData;
                  }
                  return read();
              }
          }
          return ch;
      }
  
      /**
       * Set the prefix
       */
      public final void setPrefix(final String prefix) {
          this.prefix = prefix;
      }
  
      /**
       * Get the prefix
       */
      private final String getPrefix() {
          return prefix;
      }
  
      /**
       * Create a new PrefixLines using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          PrefixLines newFilter = new PrefixLines(rdr);
          newFilter.setPrefix(getPrefix());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Initialize prefix if available from the param element.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (PREFIX_KEY.equals(params[i].getName())) {
                      prefix = params[i].getValue();
                      break;
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/ReplaceTokens.java
  
  Index: ReplaceTokens.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.util.Hashtable;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Replace tokens with user supplied values
   *
   * Example Usage:
   * =============
   *
   * &lt;replacetokens begintoken=&quot;#&quot; endtoken=&quot;#&quot;&gt;
   *   &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
   * &lt;/replacetokens&gt;
   *
   * Or:
   *
   * &lt;filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"&gt;
   *    &lt;param type="tokenchar" name="begintoken" value="#"/&gt;
   *    &lt;param type="tokenchar" name="endtoken" value="#"/&gt;
   *    &lt;param type="token" name="DATE" value="${TODAY}"/&gt;
   * &lt;/filterreader&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class ReplaceTokens
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** Default begin token character. */
      private static final char DEFAULT_BEGIN_TOKEN = '@';
  
      /** Default end token character. */
      private static final char DEFAULT_END_TOKEN = '@';
  
      /** Data that must be read from, if not null. */
      private String queuedData = null;
  
      /** Hashtable to hold the replacee-replacer pairs. */
      private Hashtable hash = new Hashtable();
  
      /** Begin token. */
      private char beginToken = DEFAULT_BEGIN_TOKEN;
  
      /** End token. */
      private char endToken = DEFAULT_END_TOKEN;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public ReplaceTokens() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public ReplaceTokens(final Reader in) {
          super(in);
      }
  
      /**
       * Replace tokens with values.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          if (queuedData != null && queuedData.length() > 0) {
              final int ch = queuedData.charAt(0);
              if (queuedData.length() > 1) {
                  queuedData = queuedData.substring(1);
              } else {
                  queuedData = null;
              }
              return ch;
          }
  
          int ch = in.read();
          if (ch == beginToken) {
              final StringBuffer key = new StringBuffer("");
              do  {
                  ch = in.read();
                  if (ch != -1) {
                      key.append((char) ch);
                  } else {
                      break;
                  }
              } while (ch != endToken);
  
              if (ch == -1) {
                  queuedData = beginToken + key.toString();
                  return read();
              } else {
                  key.setLength(key.length() - 1);
                  final String replaceWith = (String) hash.get(key.toString());
                  if (replaceWith != null) {
                      queuedData = replaceWith;
                      return read();
                  } else {
                      queuedData = beginToken + key.toString() + endToken;
                      return read();
                  }
              }
          }
          return ch;
      }
  
      /**
       * Set begin token.
       */
      public final void setBeginToken(final char beginToken) {
          this.beginToken = beginToken;
      }
  
      /**
       * Get begin token.
       */
      private final char getBeginToken() {
          return beginToken;
      }
  
      /**
       * Set end token.
       */
      public final void setEndToken(final char endToken) {
          this.endToken = endToken;
      }
  
      /**
       * Get begin token.
       */
      private final char getEndToken() {
          return endToken;
      }
  
      /**
       * Add a token element.
       */
      public final void addConfiguredToken(final Token token) {
          hash.put(token.getKey(), token.getValue());
      }
  
      /**
       * Set the tokens.
       */
      private void setTokens(final Hashtable hash) {
          this.hash = hash;
      }
  
      /**
       * Get the tokens.
       */
      private final Hashtable getTokens() {
          return hash;
      }
  
      /**
       * Create a new ReplaceTokens using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          ReplaceTokens newFilter = new ReplaceTokens(rdr);
          newFilter.setBeginToken(getBeginToken());
          newFilter.setEndToken(getEndToken());
          newFilter.setTokens(getTokens());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Initialize tokens and load the replacee-replacer hashtable.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (params[i] != null) {
                      final String type = params[i].getType();
                      if ("tokenchar".equals(type)) {
                          final String name = params[i].getName();
                          if ("begintoken".equals(name)) {
                              beginToken = params[i].getValue().charAt(0);
                          } else if ("endtoken".equals(name)) {
                              endToken = params[i].getValue().charAt(0);
                          }
                      } else if ("token".equals(type)) {
                          final String name = params[i].getName();
                          final String value = params[i].getValue();
                          hash.put(name, value);
                      }
                  }
              }
          }
      }
  
      /**
       * Holds a token
       */
      public static class Token {
  
          /** token key */
          private String key;
  
          /** token value */
          private String value;
  
          /**
           * Set the token key
           */
          public final void setKey(String key) {
              this.key = key;
          }
  
          /**
           * Set the token value
           */
          public final void setValue(String value) {
              this.value = value;
          }
  
          /**
           * Get the token key
           */
          public final String getKey() {
              return key;
          }
  
          /**
           * Get the token value
           */
          public final String getValue() {
              return value;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/StringInputStream.java
  
  Index: StringInputStream.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.StringReader;
  
  /**
   * Wrap a String as an InputStream
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   * @created 20 February 2002
   */
  public class StringInputStream
      extends InputStream
  {
      /** Source string is stored as a StringReader */
      private StringReader in;
  
      /**
       * Compose a stream from a String
       */
      public StringInputStream(String source) {
          in = new StringReader(source);
      }
  
      /**
       * Read from the Stringreader
       */
      public int read() throws IOException {
          return in.read();
      }
  
      /**
       * Close the Stringreader
       */
      public void close() throws IOException {
          in.close();
      }
  
      /**
       * Mark the read limit of the StringReader
       */
      public synchronized void mark(final int limit) {
          try {
              in.mark(limit);
          } catch (IOException ioe) {
              throw new RuntimeException(ioe.getMessage());
          }
      }
  
      /**
       * Resetthe StringReader
       */
      public synchronized void reset() throws IOException {
          in.reset();
      }
  
      public boolean markSupported() {
          return true;
      }
  }
  
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/StripJavaComments.java
  
  Index: StripJavaComments.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  /**
   * This is a java comment and string stripper reader that filters
   * these lexical tokens out for purposes of simple Java parsing.
   * (if you have more complex Java parsing needs, use a real lexer).
   * Since this class heavily relies on the single char read function,
   * you are reccomended to make it work on top of a buffered reader.
   */
  public final class StripJavaComments
      extends BaseFilterReader
      implements ChainableReader
  {
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public StripJavaComments() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public StripJavaComments(final Reader in) {
          super(in);
      }
  
      /**
       * Filter out Java Style comments
       */
      public final int read() throws IOException {
          int ch = in.read();
          if (ch == '/') {
              ch = in.read();
              if (ch == '/') {
                  while (ch != '\n' && ch != -1) {
                      ch = in.read();
                  }
              } else if (ch == '*') {
                  while (ch != -1) {
                      ch = in.read();
                      if (ch == '*') {
                          ch = in.read();
                          while (ch == '*' && ch != -1) {
                              ch = in.read();
                          }
  
                          if (ch == '/') {
                              ch = read();
                              break;
                          }
                      }
                  }
              }
          }
  
          if (ch == '"') {
              while (ch != -1) {
                  ch = in.read();
                  if (ch == '\\') {
                      ch = in.read();
                  } else if (ch == '"') {
                      ch = read();
                      break;
                  }
              }
          }
  
          if (ch == '\'') {
              ch = in.read();
              if (ch == '\\') {
                  ch = in.read();
              }
              ch = in.read();
              ch = read();
          }
  
          return ch;
      }
  
      /**
       * Create a new StripJavaComments object using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          StripJavaComments newFilter = new StripJavaComments(rdr);
          return newFilter;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/StripLineBreaks.java
  
  Index: StripLineBreaks.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Filter to flatten the stream to a single line.
   *
   * &lt;striplinebreaks/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripLineBreaks&quot;/&gt;
   *
   * @author Steve Loughran
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class StripLineBreaks
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /**
       * Linebreaks. What do to on funny IBM mainframes with odd line endings?
       */
      private static final String DEFAULT_LINE_BREAKS = "\r\n";
  
      /**
       * Linebreaks key that can be set via param element of
       * AntFilterReader
       */
      private static final String LINE_BREAKS_KEY = "linebreaks";
  
  
      /** Holds the characters that are recognized as line breaks. */
      private String lineBreaks = DEFAULT_LINE_BREAKS;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public StripLineBreaks() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public StripLineBreaks(final Reader in) {
          super(in);
      }
  
      /**
       * If the character that is being read in is a
       * line break character, ignore it and move on to the
       * next one.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = in.read();
          while (ch != -1) {
              if (lineBreaks.indexOf(ch) == -1) {
                  break;
              } else {
                  ch = in.read();
              }
          }
          return ch;
      }
  
      /**
       * Set the line break characters.
       */
      public final void setLineBreaks(final String lineBreaks) {
          this.lineBreaks = lineBreaks;
      }
  
      /**
       * Get the line breaks characters
       */
      private final String getLineBreaks() {
          return lineBreaks;
      }
  
      /**
       * Create a new StripLineBreaks object using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          StripLineBreaks newFilter = new StripLineBreaks(rdr);
          newFilter.setLineBreaks(getLineBreaks());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Line break characters set using the param element.
       */
      private final void initialize() {
          String userDefinedLineBreaks = null;
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (LINE_BREAKS_KEY.equals(params[i].getName())) {
                      userDefinedLineBreaks = params[i].getValue();
                      break;
                  }
              }
          }
          if (userDefinedLineBreaks != null) {
              lineBreaks = userDefinedLineBreaks;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/StripLineComments.java
  
  Index: StripLineComments.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.util.Vector;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * This is a line comment stripper reader
   *
   * Example:
   * =======
   *
   * &lt;striplinecomments&gt;
   *   &lt;comment value=&quot;#&quot;/&gt;
   *   &lt;comment value=&quot;--&quot;/&gt;
   *   &lt;comment value=&quot;REM &quot;/&gt;
   *   &lt;comment value=&quot;rem &quot;/&gt;
   *   &lt;comment value=&quot;//&quot;/&gt;
   * &lt;/striplinecomments&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripLineComments&quot;&gt;
   *    &lt;param type=&quot;comment&quot; value="#&quot;/&gt;
   *    &lt;param type=&quot;comment&quot; value=&quot;--&quot;/&gt;
   *    &lt;param type=&quot;comment&quot; value=&quot;REM &quot;/&gt;
   *    &lt;param type=&quot;comment&quot; value=&quot;rem &quot;/&gt;
   *    &lt;param type=&quot;comment&quot; value=&quot;//&quot;/&gt;
   * &lt;/filterreader&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class StripLineComments
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** The type that param recognizes to set the comments. */
      private static final String COMMENTS_KEY = "comment";
  
      /** Vector that holds comments. */
      private Vector comments = new Vector();
  
      /** The line that has been read ahead. */
      private String line = null;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public StripLineComments() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public StripLineComments(final Reader in) {
          super(in);
      }
  
      /**
       * Read in line by line; Ignore line if it
       * begins with a comment string.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (line != null) {
              ch = line.charAt(0);
              if (line.length() == 1) {
                  line = null;
              } else {
                  line = line.substring(1);
              }
          } else {
              line = readLine();
              if (line == null) {
                  ch = -1;
              } else {
                  int commentsSize = comments.size();
                  for (int i = 0; i < commentsSize; i++) {
                      String comment = (String) comments.elementAt(i);
                      if (line.startsWith(comment)) {
                          line = null;
                          break;
                      }
                  }
                  return read();
              }
          }
  
          return ch;
      }
  
      /**
       * Add the Comment element.
       */
      public final void addConfiguredComment(final Comment comment) {
          comments.addElement(comment.getValue());
      }
  
      /**
       * Set the comments vector.
       */
      private void setComments(final Vector comments) {
          this.comments = comments;
      }
  
      /**
       * Get the comments vector.
       */
      private final Vector getComments() {
          return comments;
      }
  
      /**
       * Create a new StripLineComments object using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          StripLineComments newFilter = new StripLineComments(rdr);
          newFilter.setComments(getComments());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Comments set using the param element.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (COMMENTS_KEY.equals(params[i].getType())) {
                      comments.addElement(params[i].getValue());
                  }
              }
          }
      }
  
      /**
       * The class that holds a comment.
       */
      public static class Comment {
  
          /** The comment*/
          private String value;
  
          /**
           * Set the comment.
           */
          public final void setValue(String comment) {
              value = comment;
          }
  
          /**
           * Get the comment.
           */
          public final String getValue() {
              return value;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/TabsToSpaces.java
  
  Index: TabsToSpaces.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Converts tabs to spaces.
   *
   * Example Usage:
   * =============
   *
   * &lt;tabtospaces tablength=&quot;8&quot;/&gt;
   *
   * Or:
   *
   * <filterreader classname=&quot;org.apache.tools.ant.filters.TabsToSpaces&quot;>
   *    <param name=&quot;tablength&quot; value=&quot;8&quot;/>
   * </filterreader>
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class TabsToSpaces
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** The default tab length is 8 */
      private static final int DEFAULT_TAB_LENGTH = 8;
  
      /** The name that param recognizes to set the tablength. */
      private static final String TAB_LENGTH_KEY = "tablength";
  
      /** Default tab length. */
      private int tabLength = DEFAULT_TAB_LENGTH;
  
      /** How many more spaces must be returned to replace a tab? */
      private int spacesRemaining = 0;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public TabsToSpaces() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public TabsToSpaces(final Reader in) {
          super(in);
      }
  
      /**
       * Convert tabs with spaces
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          int ch = -1;
  
          if (spacesRemaining > 0) {
              spacesRemaining--;
              ch = ' ';
          } else {
              ch = in.read();
              if (ch == '\t') {
                  spacesRemaining = tabLength - 1;
                  ch = ' ';
              }
          }
          return ch;
      }
  
      /**
       * Set the tab length.
       */
      public final void setTablength(final int tabLength) {
          this.tabLength = tabLength;
      }
  
      /**
       * Get the tab length
       */
      private final int getTablength() {
          return tabLength;
      }
  
      /**
       * Create a new TabsToSpaces object using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          TabsToSpaces newFilter = new TabsToSpaces(rdr);
          newFilter.setTablength(getTablength());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Initialize tokens
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (params[i] != null) {
                      if (TAB_LENGTH_KEY.equals(params[i].getName())) {
                          tabLength =
                              new Integer(params[i].getValue()).intValue();
                          break;
                      }
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/TailFilter.java
  
  Index: TailFilter.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters;
  
  import java.io.IOException;
  import java.io.Reader;
  
  import org.apache.tools.ant.types.Parameter;
  
  /**
   * Read the last n lines.  Default is last 10 lines.
   *
   * Example:
   * =======
   *
   * &lt;tailfilter lines=&quot;3&quot;/&gt;
   *
   * Or:
   *
   * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
   *    &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
   * &lt;/filterreader&gt;
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class TailFilter
      extends BaseParamFilterReader
      implements ChainableReader
  {
      /** The name that param recognizes to set the number of lines. */
      private static final String LINES_KEY = "lines";
  
      /** Number of lines currently read in. */
      private long linesRead = 0;
  
      /** Default number of lines returned. */
      private long lines = 10;
  
      /** Buffer to hold in characters read ahead. */
      private char[] buffer = new char[4096];
  
      /** The character position that has been returned from the buffer. */
      private int returnedCharPos = -1;
  
      /** Has read ahead been completed? */
      private boolean completedReadAhead = false;
  
      /** Current index position on the buffer. */
      private int bufferPos = 0;
  
      /**
       * This constructor is a dummy constructor and is
       * not meant to be used by any class other than Ant's
       * introspection mechanism. This will close the filter
       * that is created making it useless for further operations.
       */
      public TailFilter() {
          super();
      }
  
      /**
       * Create a new filtered reader.
       *
       * @param in  a Reader object providing the underlying stream.
       */
      public TailFilter(final Reader in) {
          super(in);
      }
  
      /**
       * Read ahead and keep in buffer last n lines only at any given
       * point.  Grow buffer as needed.
       */
      public final int read() throws IOException {
          if (!getInitialized()) {
              initialize();
              setInitialized(true);
          }
  
          if (!completedReadAhead) {
              int ch = -1;
              while ((ch = in.read()) != -1) {
                  if (buffer.length == bufferPos) {
                      if (returnedCharPos != -1) {
                          final char[] tmpBuffer = new char[buffer.length];
                          System.arraycopy(buffer, returnedCharPos + 1, tmpBuffer,
                                           0, buffer.length - (returnedCharPos + 1));
                          buffer = tmpBuffer;
                          bufferPos = bufferPos - (returnedCharPos + 1);
                          returnedCharPos = -1;
                      } else {
                          final char[] tmpBuffer = new char[buffer.length * 2];
                          System.arraycopy(buffer, 0, tmpBuffer, 0, bufferPos);
                          buffer = tmpBuffer;
                      }
                  }
  
                  if (ch == '\n' || ch == -1) {
                      ++linesRead;
  
                      if (linesRead == lines) {
                          int i = 0;
                          for (i = returnedCharPos + 1;
                              buffer[i] != 0 && buffer[i] != '\n'; i++) {
                          }
                          returnedCharPos = i;
                          --linesRead;
                      }
                  }
                  if (ch == -1) {
                      break;
                  }
  
                  buffer[bufferPos] = (char) ch;
                  bufferPos++;
              }
              completedReadAhead = true;
          }
  
          ++returnedCharPos;
          if (returnedCharPos >= bufferPos) {
              return -1;
          } else {
              return buffer[returnedCharPos];
          }
      }
  
      /**
       * Set number of lines to be returned.
       */
      public final void setLines(final long lines) {
          this.lines = lines;
      }
  
      /**
       * Get number of lines to be returned.
       */
      private final long getLines() {
          return lines;
      }
  
      /**
       * Create a new TailFilter using the passed in
       * Reader for instantiation.
       */
      public final Reader chain(final Reader rdr) {
          TailFilter newFilter = new TailFilter(rdr);
          newFilter.setLines(getLines());
          newFilter.setInitialized(true);
          return newFilter;
      }
  
      /**
       * Scan for the lines parameter.
       */
      private final void initialize() {
          Parameter[] params = getParameters();
          if (params != null) {
              for (int i = 0; i < params.length; i++) {
                  if (LINES_KEY.equals(params[i].getName())) {
                      setLines(new Long(params[i].getValue()).longValue());
                      break;
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
  
  Index: ChainReaderHelper.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters.util;
  
  import org.apache.tools.ant.AntClassLoader;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.filters.BaseFilterReader;
  import org.apache.tools.ant.filters.ChainableReader;
  import org.apache.tools.ant.types.AntFilterReader;
  import org.apache.tools.ant.types.FilterChain;
  import org.apache.tools.ant.types.Path;
  import org.apache.tools.ant.types.Parameter;
  import org.apache.tools.ant.types.Parameterizable;
  import org.apache.tools.ant.util.FileUtils;
  
  import java.io.*;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationTargetException;
  import java.util.Vector;
  
  /**
   * Process a FilterReader chain.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   * @created 23 February 2002
   */
  public final class ChainReaderHelper {
  
      /**
       * The primary reader to which the reader chain is to be attached.
       */
      public Reader primaryReader;
  
      /**
       * The size of the buffer to be used.
       */
      public int bufferSize = 8192;
  
      /**
       * Chain of filters
       */
      public Vector filterChains = new Vector();
  
      /** The Ant project */
      private Project project = null;
  
      /**
       * Sets the primary reader
       */
      public final void setPrimaryReader(Reader rdr) {
          primaryReader = rdr;
      }
  
      /**
       * Set the project to work with
       */
      public final void setProject(final Project project) {
          this.project = project;
      }
  
      /**
       * Get the project
       */
      public final Project getProject() {
          return project;
      }
  
      /**
       * Sets the buffer size to be used.  Defaults to 4096,
       * if this method is not invoked.
       */
      public final void setBufferSize(int size) {
          bufferSize = size;
      }
  
      /**
       * Sets the collection of filter reader sets
       */
      public final void setFilterChains(Vector fchain) {
          filterChains = fchain;
      }
  
      /**
       * Assemble the reader
       */
      public final Reader getAssembledReader() throws BuildException {
          if (primaryReader == null) {
              throw new BuildException("primaryReader must not be null.");
          }
  
          Reader instream = primaryReader;
          final int filterReadersCount = filterChains.size();
          final Vector finalFilters = new Vector();
  
          for (int i = 0; i < filterReadersCount; i++) {
              final FilterChain filterchain =
                  (FilterChain) filterChains.elementAt(i);
              final Vector filterReaders = filterchain.getFilterReaders();
              final int readerCount = filterReaders.size();
              for (int j = 0; j < readerCount; j++) {
                  finalFilters.addElement(filterReaders.elementAt(j));
              }
          }
  
          final int filtersCount = finalFilters.size();
  
          if (filtersCount > 0) {
              for (int i = 0; i < filtersCount; i++) {
                  Object o = finalFilters.elementAt(i);
  
                  if (o instanceof AntFilterReader) {
                      final AntFilterReader filter = (AntFilterReader) finalFilters.elementAt(i);
                      final String className = filter.getClassName();
                      final Path classpath = filter.getClasspath();
                      final Project project = filter.getProject();
                      if (className != null) {
                          try {
                              Class clazz = null;
                              if (classpath == null) {
                                  clazz = Class.forName(className);
                              } else {
                                  AntClassLoader al = new AntClassLoader(project,
                                                                         classpath);
                                  clazz = al.loadClass(className);
                                  AntClassLoader.initializeClass(clazz);
                              }
                              if (clazz != null) {
                                  if (!FilterReader.class.isAssignableFrom(clazz)) {
                                      throw new BuildException(className +
                                          " does not extend java.io.FilterReader");
                                  }
                                  final Constructor[] constructors =
                                      clazz.getConstructors();
                                  int j = 0;
                                  for (; j < constructors.length; j++) {
                                      Class[] types = constructors[j]
                                                        .getParameterTypes();
                                      if (types.length == 1 &&
                                          types[0].isAssignableFrom(Reader.class)) {
                                          break;
                                      }
                                  }
                                  final Reader[] rdr = {instream};
                                  instream =
                                      (Reader) constructors[j].newInstance(rdr);
                                  if (Parameterizable.class.isAssignableFrom(clazz)) {
                                      final Parameter[] params = filter.getParams();
                                      ((Parameterizable)
                                          instream).setParameters(params);
                                  }
                              }
                          } catch (final ClassNotFoundException cnfe) {
                              throw new BuildException(cnfe);
                          } catch (final InstantiationException ie) {
                              throw new BuildException(ie);
                          } catch (final IllegalAccessException iae) {
                              throw new BuildException(iae);
                          } catch (final InvocationTargetException ite) {
                              throw new BuildException(ite);
                          }
                      }
                  } else if (o instanceof ChainableReader &&
                             o instanceof Reader) {
                      if (project != null && o instanceof BaseFilterReader) {
                          ((BaseFilterReader) o).setProject(project);
                      }
                      instream = ((ChainableReader) o).chain(instream);
                  }
              }
          }
          return instream;
      }
  
      /**
       * Read data from the reader and return the
       * contents as a string.
       */
      public final String readFully(Reader rdr)
          throws IOException {
          return FileUtils.readFully(rdr, bufferSize);
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java
  
  Index: JavaClassHelper.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.filters.util;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  
  import org.apache.bcel.classfile.ClassParser;
  import org.apache.bcel.classfile.ConstantValue;
  import org.apache.bcel.classfile.Field;
  import org.apache.bcel.classfile.JavaClass;
  
  /**
   * Helper class that filters constants from a Java Class
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class JavaClassHelper {
  
      /** System specific line separator. */
      private static final String LS = System.getProperty("line.separator");
  
      /**
       * Get the constants declared in a file as name=value
       */
      public static final StringBuffer getConstants(byte[] bytes)
          throws IOException {
          final StringBuffer sb = new StringBuffer();
          final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
          final ClassParser parser = new ClassParser(bis, "");
          final JavaClass javaClass = parser.parse();
          final Field[] fields = javaClass.getFields();
          for (int i = 0; i < fields.length; i++) {
              final Field field = fields[i];
              if (field != null) {
                  final ConstantValue cv = field.getConstantValue();
                  if (cv != null) {
                      String cvs = cv.toString();
                      //Remove start and end quotes if field is a String
                      if (cvs.startsWith("\"") && cvs.endsWith("\"")) {
                          cvs = cvs.substring(1, cvs.length() - 1);
                      }
                      sb.append(field.getName());
                      sb.append('=');
                      sb.append(cvs);
                      sb.append(LS);
                  }
              }
          }
          return sb;
      }
  }
  
  
  
  1.36      +24 -4     jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Copy.java
  
  Index: Copy.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Copy.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- Copy.java	3 Mar 2002 01:46:20 -0000	1.35
  +++ Copy.java	6 Mar 2002 03:25:50 -0000	1.36
  @@ -60,6 +60,7 @@
   import org.apache.tools.ant.DirectoryScanner;
   import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.Mapper;
  +import org.apache.tools.ant.types.FilterChain;
   import org.apache.tools.ant.types.FilterSet;
   import org.apache.tools.ant.types.FilterSetCollection;
   import org.apache.tools.ant.util.FileUtils;
  @@ -89,9 +90,9 @@
    * @author <A href="gholam@xtra.co.nz">Michael McCallum</A>
    * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
    *
  - * @version $Revision: 1.35 $
  + * @version $Revision: 1.36 $
    *
  - * @ant.task category="filesystem"
  + * @ant:task category="filesystem"
    */
   public class Copy extends Task {
       protected File file = null;     // the source file
  @@ -111,6 +112,7 @@
       protected Hashtable completeDirMap = new Hashtable();
   
       protected Mapper mapperElement = null;
  +    private Vector filterChains = new Vector();
       private Vector filterSets = new Vector();
       private FileUtils fileUtils;
       private String encoding = null;
  @@ -143,6 +145,15 @@
       }
   
       /**
  +     * Create a nested filterchain
  +     */
  +    public FilterChain createFilterChain() {
  +        FilterChain filterChain = new FilterChain();
  +        filterChains.addElement(filterChain);
  +        return filterChain;
  +    }
  +
  +    /**
        * Create a nested filterset
        */
       public FilterSet createFilterSet() {
  @@ -188,6 +199,15 @@
       }
   
       /**
  +     * Get the filterchains being applied to this operation.
  +     *
  +     * @return a vector of FilterChain objects
  +     */
  +    protected Vector getFilterChains() {
  +        return filterChains;
  +    }
  +
  +    /**
        * Sets filtering.
        */
       public void setFiltering(boolean filtering) {
  @@ -457,9 +477,9 @@
                       for (Enumeration filterEnum = filterSets.elements(); filterEnum.hasMoreElements();) {
                           executionFilters.addFilterSet((FilterSet)filterEnum.nextElement());
                       }
  -                    fileUtils.copyFile(fromFile, toFile, executionFilters,
  +                    fileUtils.copyFile(fromFile, toFile, executionFilters, filterChains,
                                          forceOverwrite, preserveLastModified,
  -                                       encoding);
  +                                       encoding, project);
                   } catch (IOException ioe) {
                       String msg = "Failed to copy " + fromFile + " to " + toFile
                           + " due to " + ioe.getMessage();
  
  
  
  1.11      +44 -72    jakarta-ant/src/main/org/apache/tools/ant/taskdefs/LoadFile.java
  
  Index: LoadFile.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/LoadFile.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- LoadFile.java	3 Mar 2002 01:46:20 -0000	1.10
  +++ LoadFile.java	6 Mar 2002 03:25:50 -0000	1.11
  @@ -56,18 +56,20 @@
   import org.apache.tools.ant.Task;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.BuildException;
  -
  +import org.apache.tools.ant.types.FilterChain;
  +import org.apache.tools.ant.filters.util.ChainReaderHelper;
   
   import java.io.*;
  +import java.util.Vector;
   
   /**
    * Load a file into a property
    *
    * @author Steve Loughran
  - *
  - * @ant.task category="utility"
  + * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
  + * @created 10 December 2001
    */
  -public class LoadFile extends Task {
  +public final class LoadFile extends Task {
   
       /**
        * source file, usually null
  @@ -90,16 +92,10 @@
        */
       private String property = null;
   
  -
  -    /** flag to control if we flatten the file or no'
  -     *
  -     */
  -    private boolean makeOneLine=false;
  -
       /**
  -     * flag to control whether props get evaluated or not
  +     * Holds FilterChains
        */
  -    private boolean evaluateProperties=false;
  +    private final Vector filterChains = new Vector();
   
       /**
        * Encoding to use for filenames, defaults to the platform's default
  @@ -112,7 +108,7 @@
        * @param encoding The new Encoding value
        */
   
  -    public void setEncoding(String encoding) {
  +    public final void setEncoding(final String encoding) {
           this.encoding = encoding;
       }
   
  @@ -122,7 +118,7 @@
        *
        * @param property The new Property value
        */
  -    public void setProperty(String property) {
  +    public final void setProperty(final String property) {
           this.property = property;
       }
   
  @@ -132,7 +128,7 @@
        *
        * @param srcFile The new SrcFile value
        */
  -    public void setSrcFile(File srcFile) {
  +    public final void setSrcFile(final File srcFile) {
           this.srcFile = srcFile;
       }
   
  @@ -142,33 +138,17 @@
        *
        * @param fail The new Failonerror value
        */
  -    public void setFailonerror(boolean fail) {
  +    public final void setFailonerror(final boolean fail) {
           failOnError = fail;
       }
   
  -    /**
  -     * setter to flatten the file to a single line
  -     * @since 1.6
  -     */
  -    public void setMakeOneLine(boolean makeOneLine) {
  -        this.makeOneLine=makeOneLine;
  -    }
  -
  -    /**
  -     * setter to eval properties.
  -     * @since 1.6
  -     */
  -    public void setEvaluateProperties(boolean evaluateProperties) {
  -        this.evaluateProperties=evaluateProperties;
  -    }
  -
   
       /**
        * read in a source file to a property
        *
        * @exception BuildException if something goes wrong with the build
        */
  -    public void execute()
  +    public final void execute()
           throws BuildException {
           //validation
           if (srcFile == null) {
  @@ -182,14 +162,10 @@
           Reader instream = null;
           log("loading "+srcFile+" into property "+property,Project.MSG_VERBOSE);
           try {
  -            long len = srcFile.length();
  +            final long len = srcFile.length();
               log("file size = "+len,Project.MSG_DEBUG);
               //discard most of really big files
  -            if (len > Integer.MAX_VALUE) {
  -                log("this file is far to big to load completely");
  -            }
  -            int size=(int) len;
  -            char[] buffer = new char[size];
  +            final int size=(int) len;
               //open up the file
               fis = new FileInputStream(srcFile);
               bis = new BufferedInputStream(fis);
  @@ -199,57 +175,53 @@
               else {
                   instream = new InputStreamReader(bis, encoding);
               }
  -            instream.read(buffer);
  -            String text = new String(buffer);
  -            if (makeOneLine) {
  -                text=stripLineBreaks(text);
  -            }
  -            if(evaluateProperties) {
  -                text = project.replaceProperties(text);
  -            }
  -            project.setNewProperty(property, text);
  -            log("loaded "+buffer.length+" characters",Project.MSG_VERBOSE);
  -            log(property+" := "+text,Project.MSG_DEBUG);
   
  -        } catch (IOException ioe) {
  -            String message = "Unable to load file: " + ioe.toString();
  +            ChainReaderHelper crh = new ChainReaderHelper();
  +            crh.setBufferSize(size);
  +            crh.setPrimaryReader(instream);
  +            crh.setFilterChains(filterChains);
  +            crh.setProject(project);
  +            instream = crh.getAssembledReader();
  +
  +            String text = crh.readFully(instream);
  +
  +            if (text != null) {
  +                project.setNewProperty(property, text);
  +                log("loaded " + text.length() + " characters",Project.MSG_VERBOSE);
  +                log(property+" := "+text,Project.MSG_DEBUG);
  +            }
  +
  +        } catch (final IOException ioe) {
  +            final String message = "Unable to load file: " + ioe.toString();
               if (failOnError) {
                   throw new BuildException(message, ioe, location);
               }
               else {
                   log(message, Project.MSG_ERR);
               }
  +        } catch (final BuildException be) {
  +            if (failOnError) {
  +                throw be;
  +            }
  +            else {
  +                log(be.getMessage(), Project.MSG_ERR);
  +            }
           } finally {
               try {
                   if (fis != null) {
                       fis.close();
                   }
               } catch (IOException ioex) {
  +                //ignore
               }
           }
       }
   
       /**
  -     * strip out all line breaks from a string.
  -     * @param source source
  -     * This implementation always duplicates the string; it is nominally possible to probe
  -     * the string first looking for any line breaks before bothering to do a copy. But we assume if
  -     * the option is requested, then line breaks are probably in the source string.
  -     */
  -    protected String stripLineBreaks(String source) {
  -        //Linebreaks. What do to on funny IBM mainframes with odd line endings?
  -        String linebreaks="\r\n";
  -        int len=source.length();
  -
  -        StringBuffer dest=new StringBuffer(len);
  -        for(int i=0;i<len;++i) {
  -            char ch=source.charAt(i);
  -            if(linebreaks.indexOf(ch)==-1) {
  -                dest.append(ch);
  -            }
  -        }
  -        return new String(dest);
  -
  +     * Add the FilterChain element.
  +     */
  +    public final void addFilterChain(FilterChain filter) {
  +        filterChains.addElement(filter);
       }
   
   //end class
  
  
  
  1.20      +8 -5      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Move.java
  
  Index: Move.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Move.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- Move.java	3 Mar 2002 01:46:20 -0000	1.19
  +++ Move.java	6 Mar 2002 03:25:50 -0000	1.20
  @@ -82,13 +82,14 @@
    *
    * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
    * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
  - * @version $Revision: 1.19 $
  + * @version $Revision: 1.20 $
    *
  - * @ant.task category="filesystem"
  + * @ant:task category="filesystem"
    */
   public class Move extends Copy {
   
       private Vector filterSets = null;
  +    private Vector filterChains = null;
   
       public Move() {
           super();
  @@ -101,6 +102,7 @@
   
       protected void doFileOperations() {
           filterSets = getFilterSets();
  +        filterChains = getFilterChains();
   
           //Attempt complete directory renames, if any, first.
           if (completeDirMap.size() > 0) {
  @@ -162,10 +164,10 @@
                               for (Enumeration filterEnum = getFilterSets().elements(); filterEnum.hasMoreElements();) {
                                   executionFilters.addFilterSet((FilterSet)filterEnum.nextElement());
                               }
  -                            getFileUtils().copyFile(f, d, executionFilters,
  +                            getFileUtils().copyFile(f, d, executionFilters, filterChains,
                                                       forceOverwrite,
                                                       getPreserveLastModified(),
  -                                                    getEncoding());
  +                                                    getEncoding(), project);
   
                               f = new File(fromFile);
                               if (!f.delete()) {
  @@ -279,7 +281,8 @@
           throws IOException, BuildException {
   
           boolean renamed = true;
  -        if (filterSets != null && filterSets.size() > 0) {
  +        if ((filterSets != null && filterSets.size() > 0) ||
  +            (filterChains != null && filterChains.size() > 0)) {
               renamed = false;
           } else {
               if (!filtering) {
  
  
  
  1.110     +1 -0      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
  retrieving revision 1.109
  retrieving revision 1.110
  diff -u -r1.109 -r1.110
  --- defaults.properties	22 Feb 2002 08:29:37 -0000	1.109
  +++ defaults.properties	6 Mar 2002 03:25:50 -0000	1.110
  @@ -60,6 +60,7 @@
   input=org.apache.tools.ant.taskdefs.Input
   loadfile=org.apache.tools.ant.taskdefs.LoadFile
   manifest=org.apache.tools.ant.taskdefs.Manifest
  +loadproperties=org.apache.tools.ant.taskdefs.LoadProperties
   
   # optional tasks
   script=org.apache.tools.ant.taskdefs.optional.Script
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
  
  Index: LoadProperties.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.taskdefs;
  
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.types.FilterChain;
  import org.apache.tools.ant.filters.StringInputStream;
  import org.apache.tools.ant.filters.util.ChainReaderHelper;
  
  import java.io.*;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.Vector;
  
  /**
   * Load a file's contents as Ant Properties.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   * @created 20 February 2002
   */
  public final class LoadProperties extends Task {
  
      /**
       * Source file
       */
      private File srcFile = null;
  
      /**
       * Holds filterchains
       */
      private final Vector filterChains = new Vector();
  
      /**
       * Sets the srcfile attribute.
       *
       * @param srcFile The new SrcFile value
       */
      public final void setSrcFile(final File srcFile) {
          this.srcFile = srcFile;
      }
  
      /**
       * read in a source file's contents and load them up as Ant properties
       *
       * @exception BuildException if something goes wrong with the build
       */
      public final void execute() throws BuildException {
          //validation
          if (srcFile == null) {
              throw new BuildException("Source file not defined.");
          }
  
          if (!srcFile.exists()) {
              throw new BuildException("Source file does not exist.");
          }
  
          if (!srcFile.isFile()) {
              throw new BuildException("Source file is not a file.");
          }
  
          FileInputStream fis = null;
          BufferedInputStream bis = null;
          Reader instream = null;
  
          try {
              final long len = srcFile.length();
              final int size=(int) len;
  
              //open up the file
              fis = new FileInputStream(srcFile);
              bis = new BufferedInputStream(fis);
              instream = new InputStreamReader(bis);
  
              ChainReaderHelper crh = new ChainReaderHelper();
              crh.setBufferSize(size);
              crh.setPrimaryReader(instream);
              crh.setFilterChains(filterChains);
              crh.setProject(project);
              instream = crh.getAssembledReader();
  
              String text = crh.readFully(instream);
  
              if (text != null) {
                  if (!text.endsWith("\n")) {
                      text = text + "\n";
                  }
  
                  final StringInputStream sis = new StringInputStream(text);
                  final Properties props = new Properties();
                  props.load(sis);
                  final Enumeration e = props.keys();
                  while (e.hasMoreElements()) {
                      final String key = (String) e.nextElement();
                      final String value = props.getProperty(key);
                      if (key != null && value != null
                              && value.trim().length() > 0) {
                          project.setNewProperty(key, value);
                      }
                  }
                  sis.close();
              }
  
          } catch (final IOException ioe) {
              final String message = "Unable to load file: " + ioe.toString();
              throw new BuildException(message, ioe, location);
          } catch (final BuildException be) {
              throw be;
          } finally {
              try {
                  if (fis != null) {
                      fis.close();
                  }
              } catch (IOException ioex) {
                  //ignore
              }
          }
      }
  
      /**
       * Add the FilterChain element.
       */
      public final void addFilterChain(FilterChain filter) {
          filterChains.addElement(filter);
      }
  
  //end class
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/types/AntFilterReader.java
  
  Index: AntFilterReader.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.types;
  
  import java.io.FilterReader;
  import java.util.Hashtable;
  import java.util.Vector;
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Project;
  
  /**
   * An AntFileReader is a wrapper class that encloses the classname
   * and configuration of a Configurable FilterReader.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class AntFilterReader
      extends DataType
      implements Cloneable {
  
      private String className;
  
      private final Vector parameters = new Vector();
  
      private Path classpath;
  
      public final void setClassName(final String className) {
          this.className = className;
      }
  
      public final String getClassName() {
          return className;
      }
  
      public final void addParam(final Parameter param) {
          parameters.addElement(param);
      }
  
      /**
       * Set the classpath to load the FilterReader through (attribute).
       */
      public final void setClasspath(Path classpath) {
          if (isReference()) {
              throw tooManyAttributes();
          }
          if (this.classpath == null) {
              this.classpath = classpath;
          } else {
              this.classpath.append(classpath);
          }
      }
  
      /**
       * Set the classpath to load the FilterReader through (nested element).
       */
      public final Path createClasspath() {
          if (isReference()) {
              throw noChildrenAllowed();
          }
          if (this.classpath == null) {
              this.classpath = new Path(getProject());
          }
          return this.classpath.createPath();
      }
  
      /**
       * Get the classpath
       */
      public final Path getClasspath() {
          return classpath;
      }
  
      /**
       * Set the classpath to load the FilterReader through via
       * reference (attribute).
       */
      public void setClasspathRef(Reference r) {
          if (isReference()) {
              throw tooManyAttributes();
          }
          createClasspath().setRefid(r);
      }
  
      public final Parameter[] getParams() {
          Parameter[] params = new Parameter[parameters.size()];
          parameters.copyInto(params);
          return params;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/types/FilterChain.java
  
  Index: FilterChain.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.types;
  
  import java.util.Vector;
  
  import org.apache.tools.ant.filters.ClassConstants;
  import org.apache.tools.ant.filters.ExpandProperties;
  import org.apache.tools.ant.filters.HeadFilter;
  import org.apache.tools.ant.filters.LineContains;
  import org.apache.tools.ant.filters.LineContainsRegExp;
  import org.apache.tools.ant.filters.PrefixLines;
  import org.apache.tools.ant.filters.ReplaceTokens;
  import org.apache.tools.ant.filters.StripJavaComments;
  import org.apache.tools.ant.filters.StripLineBreaks;
  import org.apache.tools.ant.filters.StripLineComments;
  import org.apache.tools.ant.filters.TabsToSpaces;
  import org.apache.tools.ant.filters.TailFilter;
  
  /**
   * FilterChain may contain a chained set of filter readers.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class FilterChain {
  
      private final Vector filterReaders = new Vector();
  
      public final void addFilterReader(final AntFilterReader filterReader) {
          filterReaders.addElement(filterReader);
      }
  
      public final Vector getFilterReaders() {
          return filterReaders;
      }
  
      public final void addClassConstants(final ClassConstants classConstants) {
          filterReaders.addElement(classConstants);
      }
  
      public final void addExpandProperties(final ExpandProperties expandProperties) {
          filterReaders.addElement(expandProperties);
      }
  
      public final void addHeadFilter(final HeadFilter headFilter) {
          filterReaders.addElement(headFilter);
      }
  
      public final void addLineContains(final LineContains lineContains) {
          filterReaders.addElement(lineContains);
      }
  
      public final void addLineContainsRegExp(final LineContainsRegExp
                                                  lineContainsRegExp) {
          filterReaders.addElement(lineContainsRegExp);
      }
  
      public final void addPrefixLines(final PrefixLines prefixLines) {
          filterReaders.addElement(prefixLines);
      }
  
      public final void addReplaceTokens(final ReplaceTokens replaceTokens) {
          filterReaders.addElement(replaceTokens);
      }
  
      public final void addStripJavaComments(final StripJavaComments
                                                  stripJavaComments) {
          filterReaders.addElement(stripJavaComments);
      }
  
      public final void addStripLineBreaks(final StripLineBreaks
                                                  stripLineBreaks) {
          filterReaders.addElement(stripLineBreaks);
      }
  
      public final void addStripLineComments(final StripLineComments
                                                  stripLineComments) {
          filterReaders.addElement(stripLineComments);
      }
  
      public final void addTabsToSpaces(final TabsToSpaces tabsToSpaces) {
          filterReaders.addElement(tabsToSpaces);
      }
  
      public final void addTailFilter(final TailFilter tailFilter) {
          filterReaders.addElement(tailFilter);
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/types/Parameter.java
  
  Index: Parameter.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.types;
  
  /**
   * A parameter is composed of a name, type and value.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public final class Parameter {
      private String name = null;
      private String type = null;
      private String value = null;
  
      public final void setName(final String name) {
          this.name = name;
      }
  
      public final void setType(final String type) {
          this.type = type;
      }
  
      public final void setValue(final String value) {
          this.value = value;
      }
  
      public final String getName() {
          return name;
      }
  
      public final String getType() {
          return type;
      }
  
      public final String getValue() {
          return value;
      }
  }
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/types/Parameterizable.java
  
  Index: Parameterizable.java
  ===================================================================
  /*
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 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", "Ant", 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.types;
  
  import java.util.Vector;
  
  /**
   * Parameterizable objects take genric key value pairs.
   *
   * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
   */
  public interface Parameterizable {
      void setParameters(Parameter[] parameters);
  }
  
  
  
  1.15      +140 -40   jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java
  
  Index: FileUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- FileUtils.java	25 Feb 2002 11:03:40 -0000	1.14
  +++ FileUtils.java	6 Mar 2002 03:25:51 -0000	1.15
  @@ -66,16 +66,19 @@
   import java.io.InputStream;
   import java.io.InputStreamReader;
   import java.io.OutputStreamWriter;
  +import java.io.Reader;
   
   import java.lang.reflect.Method;
   import java.text.DecimalFormat;
   import java.util.Random;
   import java.util.Stack;
   import java.util.StringTokenizer;
  +import java.util.Vector;
   
  -import org.apache.tools.ant.BuildException; 
  -import org.apache.tools.ant.Project; 
  -import org.apache.tools.ant.types.FilterSetCollection; 
  +import org.apache.tools.ant.BuildException;
  +import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.filters.util.ChainReaderHelper;
  +import org.apache.tools.ant.types.FilterSetCollection;
   
   /**
    * This class also encapsulates methods which allow Files to be
  @@ -85,11 +88,12 @@
    *
    * @author duncan@x180.com
    * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
  - * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> 
  + * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
  + * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
    *
  - * @version $Revision: 1.14 $
  + * @version $Revision: 1.15 $
    */
  - 
  +
   public class FileUtils {
       private static Random rand = new Random(System.currentTimeMillis());
       private static Object lockReflection = new Object();
  @@ -134,27 +138,27 @@
        * destination specifying if token filtering must be used and if
        * source files may overwrite newer destination files.
        *
  -     * @throws IOException 
  +     * @throws IOException
        */
       public void copyFile(String sourceFile, String destFile, FilterSetCollection filters,
                            boolean overwrite) throws IOException {
  -        copyFile(new File(sourceFile), new File(destFile), filters, 
  +        copyFile(new File(sourceFile), new File(destFile), filters,
                    overwrite, false);
       }
   
  -    /**
  +     /**
        * Convienence method to copy a file from a source to a
        * destination specifying if token filtering must be used, if
        * source files may overwrite newer destination files and the
        * last modified time of <code>destFile</code> file should be made equal
        * to the last modified time of <code>sourceFile</code>.
        *
  -     * @throws IOException 
  +     * @throws IOException
        */
       public void copyFile(String sourceFile, String destFile, FilterSetCollection filters,
                            boolean overwrite, boolean preserveLastModified)
           throws IOException {
  -        copyFile(new File(sourceFile), new File(destFile), filters, 
  +        copyFile(new File(sourceFile), new File(destFile), filters,
                    overwrite, preserveLastModified);
       }
   
  @@ -165,19 +169,41 @@
        * last modified time of <code>destFile</code> file should be made equal
        * to the last modified time of <code>sourceFile</code>.
        *
  -     * @throws IOException 
  +     * @throws IOException
        *
        * @since 1.14, Ant 1.5
        */
  -    public void copyFile(String sourceFile, String destFile, 
  -                         FilterSetCollection filters, boolean overwrite, 
  +    public void copyFile(String sourceFile, String destFile,
  +                         FilterSetCollection filters, boolean overwrite,
                            boolean preserveLastModified, String encoding)
           throws IOException {
  -        copyFile(new File(sourceFile), new File(destFile), filters, 
  +        copyFile(new File(sourceFile), new File(destFile), filters,
                    overwrite, preserveLastModified, encoding);
       }
   
       /**
  +     * Convienence method to copy a file from a source to a
  +     * destination specifying if token filtering must be used, if
  +     * filter chains must be used, if source files may overwrite
  +     * newer destination files and the last modified time of
  +     * <code>destFile</code> file should be made equal
  +     * to the last modified time of <code>sourceFile</code>.
  +     *
  +     * @throws IOException
  +     *
  +     * @since 1.15, Ant 1.5
  +     */
  +    public void copyFile(String sourceFile, String destFile,
  +                         FilterSetCollection filters, Vector filterChains,
  +                         boolean overwrite, boolean preserveLastModified,
  +                         String encoding, Project project)
  +        throws IOException {
  +        copyFile(new File(sourceFile), new File(destFile), filters,
  +                 filterChains, overwrite, preserveLastModified,
  +                 encoding, project);
  +    }
  +
  +    /**
        * Convienence method to copy a file from a source to a destination.
        * No filtering is performed.
        *
  @@ -203,7 +229,7 @@
        * destination specifying if token filtering must be used and if
        * source files may overwrite newer destination files.
        *
  -     * @throws IOException 
  +     * @throws IOException
        */
       public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
                            boolean overwrite) throws IOException {
  @@ -217,12 +243,12 @@
        * last modified time of <code>destFile</code> file should be made equal
        * to the last modified time of <code>sourceFile</code>.
        *
  -     * @throws IOException 
  +     * @throws IOException
        */
       public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
                            boolean overwrite, boolean preserveLastModified)
           throws IOException {
  -        copyFile(sourceFile, destFile, filters, overwrite, 
  +        copyFile(sourceFile, destFile, filters, overwrite,
                    preserveLastModified, null);
       }
   
  @@ -234,15 +260,36 @@
        * equal to the last modified time of <code>sourceFile</code> and
        * which character encoding to assume.
        *
  -     * @throws IOException 
  +     * @throws IOException
        *
        * @since 1.14, Ant 1.5
        */
  -    public void copyFile(File sourceFile, File destFile, 
  -                         FilterSetCollection filters, boolean overwrite, 
  +    public void copyFile(File sourceFile, File destFile,
  +                         FilterSetCollection filters, boolean overwrite,
                            boolean preserveLastModified, String encoding)
           throws IOException {
  -        
  +        copyFile(sourceFile, destFile, filters, null, overwrite,
  +                 preserveLastModified, encoding, null);
  +    }
  +
  +    /**
  +     * Convienence method to copy a file from a source to a
  +     * destination specifying if token filtering must be used, if
  +     * filter chains must be used, if source files may overwrite
  +     * newer destination files and the last modified time of
  +     * <code>destFile</code> file should be made equal
  +     * to the last modified time of <code>sourceFile</code>.
  +     *
  +     * @throws IOException
  +     *
  +     * @since 1.15, Ant 1.5
  +     */
  +    public void copyFile(File sourceFile, File destFile,
  +                         FilterSetCollection filters, Vector filterChains,
  +                         boolean overwrite, boolean preserveLastModified,
  +                         String encoding, Project project)
  +        throws IOException {
  +
           if (overwrite || !destFile.exists() ||
               destFile.lastModified() < sourceFile.lastModified()) {
   
  @@ -257,7 +304,12 @@
                   parent.mkdirs();
               }
   
  -            if (filters != null && filters.hasFilters()) {
  +            final boolean filterSetsAvailable = (filters != null
  +                                                 && filters.hasFilters());
  +            final boolean filterChainsAvailable = (filterChains != null
  +                                                   && filterChains.size() > 0);
  +
  +            if (filterSetsAvailable || filterChainsAvailable) {
                   BufferedReader in = null;
                   BufferedWriter out = null;
   
  @@ -265,8 +317,20 @@
                       in = new BufferedReader(new FileReader(sourceFile));
                       out = new BufferedWriter(new FileWriter(destFile));
                   } else {
  -                    in = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), encoding));
  -                    out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), encoding));
  +                    in = new BufferedReader(new InputStreamReader(
  +                            new FileInputStream(sourceFile), encoding));
  +                    out = new BufferedWriter(new OutputStreamWriter(
  +                            new FileOutputStream(destFile), encoding));
  +                }
  +
  +                if (filterChainsAvailable) {
  +                    ChainReaderHelper crh = new ChainReaderHelper();
  +                    crh.setBufferSize(8192);
  +                    crh.setPrimaryReader(in);
  +                    crh.setFilterChains(filterChains);
  +                    crh.setProject(project);
  +                    Reader rdr = crh.getAssembledReader();
  +                    in = new BufferedReader(rdr);
                   }
   
                   int length;
  @@ -276,7 +340,11 @@
                       if (line.length() == 0) {
                           out.newLine();
                       } else {
  -                        newline = filters.replaceTokens(line);
  +                        if (filterSetsAvailable) {
  +                            newline = filters.replaceTokens(line);
  +                        } else {
  +                            newline = line;
  +                        }
                           out.write(newline);
                           out.newLine();
                       }
  @@ -317,8 +385,8 @@
               synchronized (lockReflection) {
                   if (setLastModified == null) {
                       try {
  -                        setLastModified = 
  -                            java.io.File.class.getMethod("setLastModified", 
  +                        setLastModified =
  +                            java.io.File.class.getMethod("setLastModified",
                                                            new Class[] {Long.TYPE});
                       } catch (NoSuchMethodException nse) {
                           throw new BuildException("File.setlastModified not in JDK > 1.1?",
  @@ -399,7 +467,7 @@
                   helpFile = getParentFile(helpFile);
                   if (helpFile == null) {
                       String msg = "The file or path you specified ("
  -                        + filename + ") is invalid relative to " 
  +                        + filename + ") is invalid relative to "
                           + file.getPath();
                       throw new BuildException(msg);
                   }
  @@ -422,7 +490,7 @@
        *   <li>Remove redundant slashes after the drive spec.</li>
        *   <li>resolve all ./, .\, ../ and ..\ sequences.</li>
        *   <li>DOS style paths that start with a drive letter will have
  -     *     \ as the separator.</li> 
  +     *     \ as the separator.</li>
        * </ul>
        *
        * @throws java.lang.NullPointerException if the file path is
  @@ -439,11 +507,11 @@
               ! (path.length() >= 2 &&
                  Character.isLetter(path.charAt(0)) &&
                  path.charAt(1) == ':')
  -            ) {             
  +            ) {
               String msg = path + " is not an absolute path";
               throw new BuildException(msg);
           }
  -            
  +
           boolean dosWithDrive = false;
           String root = null;
           // Eliminate consecutive slashes after the drive spec
  @@ -473,7 +541,7 @@
                   root = path.substring(0, 3);
                   path = path.substring(3);
               }
  -            
  +
           } else {
               if (path.length() == 1) {
                   root = File.separator;
  @@ -515,7 +583,7 @@
               }
               sb.append(s.elementAt(i));
           }
  -        
  +
   
           path = sb.toString();
           if (dosWithDrive) {
  @@ -552,8 +620,8 @@
           DecimalFormat fmt = new DecimalFormat("#####");
           synchronized (rand) {
               do {
  -                result = new File(parent, 
  -                                  prefix + fmt.format(rand.nextInt()) 
  +                result = new File(parent,
  +                                  prefix + fmt.format(rand.nextInt())
                                     + suffix);
               } while (result.exists());
           }
  @@ -579,22 +647,22 @@
               // two not existing files are equal
               return true;
           }
  -        
  +
           if (f1.isDirectory() || f2.isDirectory()) {
               // don't want to compare directory contents for now
               return false;
           }
  -        
  +
           if (f1.equals(f2)) {
               // same filename => true
               return true;
           }
  -        
  +
           if (f1.length() != f2.length()) {
               // different size =>false
               return false;
           }
  -        
  +
           InputStream in1 = null;
           InputStream in2 = null;
           try {
  @@ -639,6 +707,38 @@
               }
           }
           return null;
  +    }
  +
  +    /**
  +     * Read from reader till EOF
  +     */
  +    public static final String readFully(Reader rdr) throws IOException {
  +        return readFully(rdr, 8192);
  +    }
  +
  +    /**
  +     * Read from reader till EOF
  +     */
  +    public static final String readFully(Reader rdr, int bufferSize) throws IOException {
  +        final char[] buffer = new char[bufferSize];
  +        int bufferLength = 0;
  +        String text = null;
  +        StringBuffer textBuffer = null;
  +        while (bufferLength != -1) {
  +            bufferLength = rdr.read(buffer);
  +            if (bufferLength != -1) {
  +                if (textBuffer == null) {
  +                    textBuffer = new StringBuffer(
  +                                    new String(buffer, 0, bufferLength));
  +                } else {
  +                    textBuffer.append(new String(buffer, 0, bufferLength));
  +                }
  +            }
  +        }
  +        if (textBuffer != null) {
  +            text = textBuffer.toString();
  +        }
  +        return text;
       }
   }
   
  
  
  
  1.8       +17 -10    jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java
  
  Index: CopyTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/CopyTest.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- CopyTest.java	3 Mar 2002 01:30:04 -0000	1.7
  +++ CopyTest.java	6 Mar 2002 03:25:51 -0000	1.8
  @@ -57,7 +57,6 @@
   import org.apache.tools.ant.BuildFileTest;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.util.FileUtils;
  -
   import java.io.File;
   import java.io.IOException;
   
  @@ -126,20 +125,28 @@
   
       }
   
  -    public void testSingleFileFileset() {
  -        executeTarget("test_single_file_fileset");
  -        File file  = new File(getProjectDir(),
  -                                        "copytest_single_file_fileset.tmp");
  -        assertTrue(file.exists());
  -    }
  -
       public void testFilterSet() throws IOException {
           executeTarget("testFilterSet");
           FileUtils fileUtils = FileUtils.newFileUtils();
           File tmp  = new File(getProjectDir(), "copy.filterset.tmp");
  -        File check  = new File(getProjectDir(),
  -                        "expected/copy.filterset.filtered");
  +        File check  = new File(getProjectDir(), "expected/copy.filterset.filtered");
  +        assertTrue(tmp.exists());
  +        assertTrue(fileUtils.contentEquals(tmp, check));
  +    }
  +
  +    public void testFilterChain() throws IOException {
  +        executeTarget("testFilterChain");
  +        FileUtils fileUtils = FileUtils.newFileUtils();
  +        File tmp  = new File(getProjectDir(), "copy.filterchain.tmp");
  +        File check  = new File(getProjectDir(), "expected/copy.filterset.filtered");
           assertTrue(tmp.exists());
           assertTrue(fileUtils.contentEquals(tmp, check));
  +    }
  +
  +    public void testSingleFileFileset() {
  +        executeTarget("test_single_file_fileset");
  +        File file  = new File(getProjectDir(),
  +                                        "copytest_single_file_fileset.tmp");
  +        assertTrue(file.exists());
       }
   }
  
  
  
  1.6       +14 -4     jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java
  
  Index: LoadFileTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/LoadFileTest.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- LoadFileTest.java	1 Feb 2002 07:23:33 -0000	1.5
  +++ LoadFileTest.java	6 Mar 2002 03:25:51 -0000	1.6
  @@ -151,7 +151,7 @@
           }
       }
   
  -        /**
  +    /**
        * A unit test for JUnit
        */
       public void testEvalProps()
  @@ -162,7 +162,19 @@
           }
       }
   
  -        /**
  +    /**
  +     * A unit test for JUnit
  +     */
  +    public void testFilterChain()
  +            throws BuildException {
  +        executeTarget("testFilterChain");
  +        if(project.getProperty("testFilterChain").indexOf("World!")<0) {
  +            fail("Filter Chain broken");
  +        }
  +    }
  +
  +
  +    /**
        * A unit test for JUnit
        */
       public void testOneLine()
  @@ -171,5 +183,3 @@
   
       }
   }
  -
  -
  
  
  
  1.3       +10 -1     jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java
  
  Index: MoveTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/MoveTest.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MoveTest.java	3 Mar 2002 01:33:19 -0000	1.2
  +++ MoveTest.java	6 Mar 2002 03:25:51 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2002 The Apache Software Foundation.  All rights
  + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -83,6 +83,15 @@
           executeTarget("testFilterSet");
           FileUtils fileUtils = FileUtils.newFileUtils();
           File tmp  = new File(getProjectDir(), "move.filterset.tmp");
  +        File check  = new File(getProjectDir(), "expected/copy.filterset.filtered");
  +        assertTrue(tmp.exists());
  +        assertTrue(fileUtils.contentEquals(tmp, check));
  +    }
  +
  +    public void testFilterChain() throws IOException {
  +        executeTarget("testFilterChain");
  +        FileUtils fileUtils = FileUtils.newFileUtils();
  +        File tmp  = new File(getProjectDir(), "move.filterchain.tmp");
           File check  = new File(getProjectDir(), "expected/copy.filterset.filtered");
           assertTrue(tmp.exists());
           assertTrue(fileUtils.contentEquals(tmp, check));
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>