mbenson     2005/02/03 11:18:07

  Modified:    .        WHATSNEW
               src/main/org/apache/tools/ant/types FilterSet.java
               src/testcases/org/apache/tools/ant/types FilterSetTest.java
               docs/manual/CoreTypes filterset.html
  Log:
  Add recurse attribute to filterset.
  
  Revision  Changes    Path
  1.740     +3 -0      ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/ant/WHATSNEW,v
  retrieving revision 1.739
  retrieving revision 1.740
  diff -u -r1.739 -r1.740
  --- WHATSNEW  2 Feb 2005 23:55:49 -0000       1.739
  +++ WHATSNEW  3 Feb 2005 19:18:06 -0000       1.740
  @@ -205,6 +205,9 @@
   
   * <native2ascii> now also supports Kaffe's version.
   
  +* Recursive token expansion in a filterset can now be disabled by
  +  setting its recurse attribute to false.
  +
   Fixed bugs:
   -----------
   
  
  
  
  1.31      +116 -105  ant/src/main/org/apache/tools/ant/types/FilterSet.java
  
  Index: FilterSet.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/FilterSet.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- FilterSet.java    12 Nov 2004 15:15:22 -0000      1.30
  +++ FilterSet.java    3 Feb 2005 19:18:07 -0000       1.31
  @@ -1,5 +1,5 @@
   /*
  - * Copyright  2001-2004 The Apache Software Foundation
  + * Copyright  2001-2005 The Apache Software Foundation
    *
    *  Licensed under the Apache License, Version 2.0 (the "License");
    *  you may not use this file except in compliance with the License.
  @@ -16,7 +16,6 @@
    */
   package org.apache.tools.ant.types;
   
  -// java io classes
   import java.io.File;
   import java.io.FileInputStream;
   import java.io.IOException;
  @@ -24,10 +23,10 @@
   import java.util.Hashtable;
   import java.util.Properties;
   import java.util.Vector;
  +
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
   
  -
   /**
    * A set of filters to be applied to something.
    *
  @@ -37,64 +36,64 @@
   public class FilterSet extends DataType implements Cloneable {
   
       /**
  -     * Individual filter component of filterset
  +     * Individual filter component of filterset.
        *
        */
       public static class Filter {
  -        /** Token which will be replaced in the filter operation */
  +        /** Token which will be replaced in the filter operation. */
           String token;
   
  -        /** The value which will replace the token in the filtering 
operation */
  +        /** The value which will replace the token in the filtering 
operation. */
           String value;
   
           /**
  -         * Constructor for the Filter object
  +         * Constructor for the Filter object.
            *
  -         * @param token  The token which will be replaced when filtering
  -         * @param value  The value which will replace the token when 
filtering
  +         * @param token  The token which will be replaced when filtering.
  +         * @param value  The value which will replace the token when 
filtering.
            */
           public Filter(String token, String value) {
  -           this.token = token;
  -           this.value = value;
  +           setToken(token);
  +           setValue(value);
           }
   
           /**
  -         * No argument conmstructor
  +         * No-argument conmstructor.
            */
           public Filter() {
           }
   
           /**
  -         * Sets the Token attribute of the Filter object
  +         * Sets the Token attribute of the Filter object.
            *
  -         * @param token  The new Token value
  +         * @param token  The new Token value.
            */
           public void setToken(String token) {
              this.token = token;
           }
   
           /**
  -         * Sets the Value attribute of the Filter object
  +         * Sets the Value attribute of the Filter object.
            *
  -         * @param value  The new Value value
  +         * @param value  The new Value value.
            */
           public void setValue(String value) {
              this.value = value;
           }
   
           /**
  -         * Gets the Token attribute of the Filter object
  +         * Gets the Token attribute of the Filter object.
            *
  -         * @return   The Token value
  +         * @return   The Token value.
            */
           public String getToken() {
              return token;
           }
   
           /**
  -         * Gets the Value attribute of the Filter object
  +         * Gets the Value attribute of the Filter object.
            *
  -         * @return   The Value value
  +         * @return   The Value value.
            */
           public String getValue() {
              return value;
  @@ -108,7 +107,7 @@
       public class FiltersFile {
   
           /**
  -         * Constructor for the Filter object
  +         * Constructor for the FiltersFile object.
            */
           public FiltersFile() {
           }
  @@ -132,19 +131,27 @@
       private String startOfToken = DEFAULT_TOKEN_START;
       private String endOfToken = DEFAULT_TOKEN_END;
   
  +    /** Contains a list of parsed tokens */
  +    private Vector passedTokens;
  +    /** if a duplicate token is found, this is set to true */
  +    private boolean duplicateToken = false;
  +
  +    private boolean recurse = true;
  +    private Hashtable filterHash = null;
  +
       /**
        * List of ordered filters and filter files.
        */
       private Vector filters = new Vector();
   
       /**
  -     * Default constructor
  +     * Default constructor.
        */
       public FilterSet() {
       }
   
       /**
  -     * Create a Filterset from another filterset
  +     * Create a Filterset from another filterset.
        *
        * @param filterset the filterset upon which this filterset will be 
based.
        */
  @@ -154,11 +161,11 @@
       }
   
       /**
  -     * Get the filters in the filter set
  +     * Get the filters in the filter set.
        *
  -     * @return a Vector of Filter instances
  +     * @return a Vector of Filter instances.
        */
  -    protected Vector getFilters() {
  +    protected synchronized Vector getFilters() {
           if (isReference()) {
               return getRef().getFilters();
           }
  @@ -166,7 +173,7 @@
       }
   
       /**
  -     * Get the referred filter set
  +     * Get the referenced filter set.
        *
        * @return the filterset from the reference.
        */
  @@ -179,21 +186,23 @@
        *
        * @return   The hash of the tokens and values for quick lookup.
        */
  -    public Hashtable getFilterHash() {
  -        int filterSize = getFilters().size();
  -        Hashtable filterHash = new Hashtable(filterSize + 1);
  -        for (Enumeration e = getFilters().elements(); e.hasMoreElements();) {
  -           Filter filter = (Filter) e.nextElement();
  -           filterHash.put(filter.getToken(), filter.getValue());
  +    public synchronized Hashtable getFilterHash() {
  +        if (filterHash == null) {
  +            filterHash = new Hashtable(getFilters().size());
  +            for (Enumeration e = getFilters().elements(); 
e.hasMoreElements();) {
  +               Filter filter = (Filter) e.nextElement();
  +               filterHash.put(filter.getToken(), filter.getValue());
  +            }
           }
           return filterHash;
       }
   
       /**
  -     * set the file containing the filters for this filterset.
  +     * Set the file containing the filters for this filterset.
        *
  -     * @param filtersFile sets the filter fil to read filters for this 
filter set from.
  -     * @exception BuildException if there is a problem reading the filters
  +     * @param filtersFile sets the filter file from which to read filters
  +     *        for this filter set.
  +     * @exception BuildException if there is a problem reading the filters.
        */
       public void setFiltersfile(File filtersFile) throws BuildException {
           if (isReference()) {
  @@ -203,9 +212,9 @@
       }
   
       /**
  -     * The string used to id the beginning of a token.
  +     * Set the string used to id the beginning of a token.
        *
  -     * @param startOfToken  The new Begintoken value
  +     * @param startOfToken  The new Begintoken value.
        */
       public void setBeginToken(String startOfToken) {
           if (isReference()) {
  @@ -218,9 +227,9 @@
       }
   
       /**
  -     * Get the begin token for this filterset
  +     * Get the begin token for this filterset.
        *
  -     * @return the filter set's begin token for filtering
  +     * @return the filter set's begin token for filtering.
        */
       public String getBeginToken() {
           if (isReference()) {
  @@ -229,11 +238,10 @@
           return startOfToken;
       }
   
  -
       /**
  -     * The string used to id the end of a token.
  +     * Set the string used to id the end of a token.
        *
  -     * @param endOfToken  The new Endtoken value
  +     * @param endOfToken  The new Endtoken value.
        */
       public void setEndToken(String endOfToken) {
           if (isReference()) {
  @@ -246,9 +254,9 @@
       }
   
       /**
  -     * Get the end token for this filterset
  +     * Get the end token for this filterset.
        *
  -     * @return the filter set's end token for replacement delimiting
  +     * @return the filter set's end token for replacement delimiting.
        */
       public String getEndToken() {
           if (isReference()) {
  @@ -257,24 +265,36 @@
           return endOfToken;
       }
   
  +    /**
  +     * Set whether recursive token expansion is enabled.
  +     * @param recurse <code>boolean</code> whether to recurse.
  +     */
  +    public void setRecurse(boolean recurse) {
  +        this.recurse = recurse;
  +    }
  +
  +    /**
  +     * Get whether recursive token expansion is enabled.
  +     * @return <code>boolean</code> whether enabled.
  +     */
  +    public boolean isRecurse() {
  +        return recurse;
  +    }
   
       /**
        * Read the filters from the given file.
        *
  -     * @param filtersFile         the file from which filters are read
  -     * @exception BuildException  Throw a build exception when unable to 
read the
  -     * file.
  +     * @param filtersFile        the file from which filters are read.
  +     * @exception BuildException when the file cannot be read.
        */
  -    public void readFiltersFromFile(File filtersFile) throws BuildException {
  +    public synchronized void readFiltersFromFile(File filtersFile) throws 
BuildException {
           if (isReference()) {
               throw tooManyAttributes();
           }
  -
           if (!filtersFile.exists()) {
               throw new BuildException("Could not read filters from file "
                                        + filtersFile + " as it doesn't 
exist.");
           }
  -
           if (filtersFile.isFile()) {
              log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
              FileInputStream in = null;
  @@ -315,10 +335,10 @@
        * This resets the passedTokens and calls iReplaceTokens to
        * do the actual replacements.
        *
  -     * @param line  The line to process the tokens in.
  -     * @return      The string with the tokens replaced.
  +     * @param line  The line in which to process embedded tokens.
  +     * @return      The input string after token replacement.
        */
  -    public String replaceTokens(String line) {
  +    public synchronized String replaceTokens(String line) {
           passedTokens = null; // reset for new line
           return iReplaceTokens(line);
       }
  @@ -331,7 +351,7 @@
        * @param line  The line to process the tokens in.
        * @return      The string with the tokens replaced.
        */
  -    private String iReplaceTokens(String line) {
  +    private synchronized String iReplaceTokens(String line) {
           String beginToken = getBeginToken();
           String endToken = getEndToken();
           int index = line.indexOf(beginToken);
  @@ -345,6 +365,7 @@
                   String value = null;
   
                   do {
  +                    //can't have zero-length token
                       int endIndex = line.indexOf(endToken,
                           index + beginToken.length() + 1);
                       if (endIndex == -1) {
  @@ -355,7 +376,7 @@
                       b.append(line.substring(i, index));
                       if (tokens.containsKey(token)) {
                           value = (String) tokens.get(token);
  -                        if (!value.equals(token)) {
  +                        if (recurse && !value.equals(token)) {
                               // we have another token, let's parse it.
                               value = replaceTokens(value, token);
                           }
  @@ -381,48 +402,40 @@
           }
       }
   
  -    /** Contains a list of parsed tokens */
  -    private Vector passedTokens;
  -    /** if a ducplicate token is found, this is set to true */
  -    private boolean duplicateToken = false;
  -
       /**
        * This parses tokens which point to tokens.
        * It also maintains a list of currently used tokens, so we cannot
  -     * get into an infinite loop
  -     * @param line the value / token to parse
  -     * @param parent the parant token (= the token it was parsed from)
  +     * get into an infinite loop.
  +     * @param line the value / token to parse.
  +     * @param parent the parent token (= the token it was parsed from).
        */
  -    private String replaceTokens(String line, String parent)
  +    private synchronized String replaceTokens(String line, String parent)
           throws BuildException {
  +        String beginToken = getBeginToken();
  +        String endToken = getEndToken();
           if (passedTokens == null) {
               passedTokens = new Vector();
           }
           if (passedTokens.contains(parent) && !duplicateToken) {
               duplicateToken = true;
  -            StringBuffer sb = new StringBuffer();
  -            sb.append("Infinite loop in tokens. Currently known tokens : ");
  -            sb.append(passedTokens);
  -            sb.append("\nProblem token : " + getBeginToken() + parent
  -                + getEndToken());
  -            sb.append(" called from " + getBeginToken()
  -                + passedTokens.lastElement());
  -            sb.append(getEndToken());
  -            System.out.println(sb.toString());
  +            System.out.println(
  +                "Infinite loop in tokens. Currently known tokens : "
  +                + passedTokens.toString() + "\nProblem token : " + beginToken
  +                + parent + endToken + " called from " + beginToken
  +                + passedTokens.lastElement().toString() + endToken);
               return parent;
           }
           passedTokens.addElement(parent);
           String value = iReplaceTokens(line);
  -        if (value.indexOf(getBeginToken()) == -1 && !duplicateToken) {
  +        if (value.indexOf(beginToken) == -1 && !duplicateToken) {
               duplicateToken = false;
               passedTokens = null;
           } else if (duplicateToken) {
               // should always be the case...
               if (passedTokens.size() > 0) {
  -                value = (String) passedTokens.lastElement();
  -                passedTokens.removeElementAt(passedTokens.size() - 1);
  +                value = (String) passedTokens.remove(passedTokens.size() - 
1);
                   if (passedTokens.size() == 0) {
  -                    value = getBeginToken() + value + getEndToken();
  +                    value = beginToken + value + endToken;
                       duplicateToken = false;
                   }
               }
  @@ -431,21 +444,22 @@
       }
   
       /**
  -     * Create a new filter
  +     * Add a new filter.
        *
  -     * @param filter the filter to be added
  +     * @param filter the filter to be added.
        */
  -    public void addFilter(Filter filter) {
  +    public synchronized void addFilter(Filter filter) {
           if (isReference()) {
               throw noChildrenAllowed();
           }
           filters.addElement(filter);
  +        filterHash = null;
       }
   
       /**
  -     * Create a new FiltersFile
  +     * Create a new FiltersFile.
        *
  -     * @return   The filter that was created.
  +     * @return The filtersfile that was created.
        */
       public FiltersFile createFiltersfile() {
           if (isReference()) {
  @@ -455,49 +469,49 @@
       }
   
       /**
  -    * Add a new filter made from the given token and value.
  -    *
  -    * @param token  The token for the new filter.
  -    * @param value  The value for the new filter.
  -    */
  -    public void addFilter(String token, String value) {
  +     * Add a new filter made from the given token and value.
  +     *
  +     * @param token The token for the new filter.
  +     * @param value The value for the new filter.
  +     */
  +    public synchronized void addFilter(String token, String value) {
           if (isReference()) {
               throw noChildrenAllowed();
           }
  -        filters.addElement(new Filter(token, value));
  +        addFilter(new Filter(token, value));
       }
   
       /**
  -    * Add a Filterset to this filter set
  -    *
  -    * @param filterSet the filterset to be added to this filterset
  -    */
  -    public void addConfiguredFilterSet(FilterSet filterSet) {
  +     * Add a Filterset to this filter set.
  +     *
  +     * @param filterSet the filterset to be added to this filterset
  +     */
  +    public synchronized void addConfiguredFilterSet(FilterSet filterSet) {
           if (isReference()) {
               throw noChildrenAllowed();
           }
           for (Enumeration e = filterSet.getFilters().elements(); 
e.hasMoreElements();) {
  -            filters.addElement(e.nextElement());
  +            addFilter((Filter) e.nextElement());
           }
       }
   
       /**
  -    * Test to see if this filter set it empty.
  +    * Test to see if this filter set has filters.
       *
  -    * @return   Return true if there are filter in this set otherwise false.
  +    * @return Return true if there are filters in this set.
       */
  -    public boolean hasFilters() {
  +    public synchronized boolean hasFilters() {
           return getFilters().size() > 0;
       }
   
       /**
  -     * clone the filterset
  +     * Clone the filterset.
        *
  -     * @return a deep clone of this filterset
  +     * @return a deep clone of this filterset.
        *
        * @throws BuildException if the clone cannot be performed.
        */
  -    public Object clone() throws BuildException {
  +    public synchronized Object clone() throws BuildException {
           if (isReference()) {
               return ((FilterSet) getRef()).clone();
           } else {
  @@ -511,8 +525,5 @@
               }
           }
       }
  -
   }
   
  -
  -
  
  
  
  1.15      +18 -1     
ant/src/testcases/org/apache/tools/ant/types/FilterSetTest.java
  
  Index: FilterSetTest.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/testcases/org/apache/tools/ant/types/FilterSetTest.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- FilterSetTest.java        7 Dec 2004 09:10:38 -0000       1.14
  +++ FilterSetTest.java        3 Feb 2005 19:18:07 -0000       1.15
  @@ -1,5 +1,5 @@
   /*
  - * Copyright  2001-2002,2004 The Apache Software Foundation
  + * Copyright  2001-2002, 2004-2005 The Apache Software Foundation
    *
    *  Licensed under the Apache License, Version 2.0 (the "License");
    *  you may not use this file except in compliance with the License.
  @@ -99,6 +99,23 @@
           assertEquals(result, fs.replaceTokens(line));
       }
   
  +    /**
  +     * Test to see what happens when the resolving occurs in
  +     * what would be an infinite loop, but with recursion disabled.
  +     */
  +    public void testRecursionDisabled() {
  +        String result = "@test1@ line testvalue";
  +        String line = "@test@ line @test2@";
  +        FilterSet fs = new FilterSet();
  +        fs.addFilter("test", "@test1@");
  +        fs.addFilter("test1","@test@");
  +        fs.addFilter("test2", "testvalue");
  +        fs.setBeginToken("@");
  +        fs.setEndToken("@");
  +        fs.setRecurse(false);
  +        assertEquals(result, fs.replaceTokens(line));
  +    }
  +
       public void testNestedFilterSets() {
           executeTarget("test-nested-filtersets");
   
  
  
  
  1.15      +86 -79    ant/docs/manual/CoreTypes/filterset.html
  
  Index: filterset.html
  ===================================================================
  RCS file: /home/cvs/ant/docs/manual/CoreTypes/filterset.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- filterset.html    9 Feb 2004 21:50:07 -0000       1.14
  +++ filterset.html    3 Feb 2005 19:18:07 -0000       1.15
  @@ -1,19 +1,19 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
   
  -<HTML>
  -<HEAD>
  -  <TITLE>FilterSet Type</TITLE>
  -</HEAD>
  +<html>
  +<head>
  +  <title>FilterSet Type</title>
  +</head>
   
  -<BODY>
  -<H2><A name="filterset">FilterSet</A></H2>
  +<body>
  +<h2><a name="filterset">FilterSet</a></h2>
   
  -<P>FilterSets are groups of filters. Filters can be defined as token-value
  +<p>FilterSets are groups of filters. Filters can be defined as token-value
   pairs 
   or be read in from a file. FilterSets can appear inside tasks that support 
this 
  -feature or at the same level as <CODE>&lt;target&gt;</CODE> - i.e., as
  +feature or at the same level as <code>&lt;target&gt;</code> - i.e., as
   children of 
  -<CODE>&lt;project&gt;</CODE>.</P>
  +<code>&lt;project&gt;</code>.</p>
   
   <p>FilterSets support the <code>id</code> and <code>refid</code>
   attributes.  You can define a FilterSet with an <code>id</code>
  @@ -35,92 +35,99 @@
   you should ensure that the set of files being filtered are all text files.
   </p>
   
  -<H2>Filterset</H2>
  +<h2>Filterset</h2>
   
  -<TABLE cellSpacing=0 cellPadding=2 border=1>
  -  <TR>
  -    <TD vAlign=top><B>Attribute</B></TD>
  -    <TD vAlign=top><B>Description</B></TD>
  -    <TD vAlign=top><B>Default</B></TD>
  -    <TD vAlign=top align="center"><B>Required</B></TD>
  -  </TR>
  -  <TR>
  -    <TD vAlign=top>begintoken</TD>
  -    <TD vAlign=top>The string marking the beginning of a token (eg.,
  -      <code>&#64;DATE&#64;</code>).</TD>
  -    <TD vAlign=top>@</TD>
  -    <TD vAlign=top align="center">No</TD>
  -  </TR>
  -  <TR>
  -    <TD vAlign=top>endtoken</TD>
  -    <TD vAlign=top>The string marking the end of a token (eg.,
  -      <code>&#64;DATE&#64;</code>).</TD>
  -    <TD vAlign=top>@</TD>
  -    <TD vAlign=top align="center">No</TD>
  -  </TR>
  -</TABLE>
  -
  -<H2>Filter</H2>
  -<TABLE cellSpacing=0 cellPadding=2 border=1>
  -  <TR>
  -    <TD vAlign=top><B>Attribute</B></TD>
  -    <TD vAlign=top><B>Description</B></TD>
  -    <TD vAlign=top align="center"><B>Required</B></TD>
  -  </TR>
  -  <TR>
  -    <TD vAlign=top>token</TD>
  -    <TD vAlign=top>The token to replace (eg., 
<code>&#64;DATE&#64;</code>)</TD>
  -    <TD vAlign=top align="center">Yes</TD>
  -  </TR>
  -  <TR>
  -    <TD vAlign=top>value</TD>
  -    <TD vAlign=top>The value to replace it with
  -     (eg., <code>Thursday, April 26, 2001</code>).</TD>
  -    <TD vAlign=top align="center">Yes</TD>
  -  </TR>
  -</TABLE>
  -
  -<H2>Filtersfile</H2>
  -<TABLE cellSpacing=0 cellPadding=2 border=1>
  -  <TR>
  -    <TD vAlign=top><B>Attribute</B></TD>
  -    <TD vAlign=top><B>Description</B></TD>
  -    <TD vAlign=top align="center"><B>Required</B></TD>
  -  </TR>
  -  <TR>
  -    <TD vAlign=top>file</TD>
  -    <TD vAlign=top>A properties file of 
  -      name-value pairs from which to load the tokens.</TD>
  -    <TD vAlign=top align="center">Yes</TD>
  -  </TR>
  -</TABLE>
  +<table cellSpacing=0 cellPadding=2 border=1>
  +  <tr>
  +    <td vAlign=top><b>Attribute</b></td>
  +    <td vAlign=top><b>Description</b></td>
  +    <td vAlign=top><b>Default</b></td>
  +    <td vAlign=top align="center"><b>Required</b></td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>begintoken</td>
  +    <td vAlign=top>The string marking the beginning of a token (eg.,
  +      <code>&#64;DATE&#64;</code>).</td>
  +    <td vAlign=top>@</td>
  +    <td vAlign=top align="center">No</td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>endtoken</td>
  +    <td vAlign=top>The string marking the end of a token (eg.,
  +      <code>&#64;DATE&#64;</code>).</td>
  +    <td vAlign=top>@</td>
  +    <td vAlign=top align="center">No</td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>recurse</td>
  +    <td vAlign=top>Indicates whether the replacement text of tokens
  +      should be searched for more tokens. <b>Since Ant 1.6.3</b></td>
  +    <td vAlign=top><i>true</i></td>
  +    <td vAlign=top align="center">No</td>
  +  </tr>
  +</table>
  +
  +<h2>Filter</h2>
  +<table cellSpacing=0 cellPadding=2 border=1>
  +  <tr>
  +    <td vAlign=top><b>Attribute</b></td>
  +    <td vAlign=top><b>Description</b></td>
  +    <td vAlign=top align="center"><b>Required</b></td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>token</td>
  +    <td vAlign=top>The token to replace (eg., 
<code>&#64;DATE&#64;</code>)</td>
  +    <td vAlign=top align="center">Yes</td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>value</td>
  +    <td vAlign=top>The value to replace it with
  +     (eg., <code>Thursday, April 26, 2001</code>).</td>
  +    <td vAlign=top align="center">Yes</td>
  +  </tr>
  +</table>
  +
  +<h2>Filtersfile</h2>
  +<table cellSpacing=0 cellPadding=2 border=1>
  +  <tr>
  +    <td vAlign=top><b>Attribute</b></td>
  +    <td vAlign=top><b>Description</b></td>
  +    <td vAlign=top align="center"><b>Required</b></td>
  +  </tr>
  +  <tr>
  +    <td vAlign=top>file</td>
  +    <td vAlign=top>A properties file of 
  +      name-value pairs from which to load the tokens.</td>
  +    <td vAlign=top align="center">Yes</td>
  +  </tr>
  +</table>
   
  -<H4>Examples</H4>
  +<h4>Examples</h4>
   
   <p>You are copying the <code>version.txt</code> file to the <code>dist</code>
   directory from the <code>build</code> directory 
   but wish to replace the token <code>&#64;DATE&#64;</code> with today's 
date.</p>
  -<BLOCKQUOTE><PRE>
  +<blockquote><pre>
   &lt;copy file=&quot;${build.dir}/version.txt&quot; 
toFile=&quot;${dist.dir}/version.txt&quot;&gt;
     &lt;filterset&gt;
       &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
     &lt;/filterset&gt;
   &lt;/copy&gt;
  -</PRE></BLOCKQUOTE>
  +</pre></blockquote>
   
   <p>You are copying the <code>version.txt</code> file to the <code>dist</code>
   directory from the build directory 
   but wish to replace the token <code>%DATE*</code> with today's date.</p>
  -<BLOCKQUOTE><PRE>
  +<blockquote><pre>
   &lt;copy file=&quot;${build.dir}/version.txt&quot; 
toFile=&quot;${dist.dir}/version.txt&quot;&gt;
     &lt;filterset begintoken=&quot;%&quot; endtoken=&quot;*&quot;&gt;
       &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
     &lt;/filterset&gt;
   &lt;/copy&gt;
  -</PRE></BLOCKQUOTE>
  +</pre></blockquote>
   
   <p>Copy all the docs but change all dates and appropriate notices as stored 
in a file.</p>
  -<BLOCKQUOTE><PRE>
  +<blockquote><pre>
   &lt;copy toDir=&quot;${dist.dir}/docs&quot;&gt;
     &lt;fileset dir=&quot;${build.dir}/docs&quot;&gt;
       &lt;include name=&quot;**/*.html&quot;&gt;
  @@ -129,10 +136,10 @@
       &lt;filtersfile file=&quot;${user.dir}/dist.properties&quot;/&gt;
     &lt;/filterset&gt;
   &lt;/copy&gt;
  -</PRE></BLOCKQUOTE>
  +</pre></blockquote>
   
   <p>Define a FilterSet and reference it later.</p>
  -<BLOCKQUOTE><PRE>
  +<blockquote><pre>
   &lt;filterset id=&quot;myFilterSet&quot; begintoken=&quot;%&quot; 
endtoken=&quot;*&quot;&gt;
     &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
   &lt;/filterset&gt;
  @@ -140,8 +147,8 @@
   &lt;copy file=&quot;${build.dir}/version.txt&quot; 
toFile=&quot;${dist.dir}/version.txt&quot;&gt;
     &lt;filterset refid=&quot;myFilterSet&quot;/&gt;
   &lt;/copy&gt;
  -</PRE></BLOCKQUOTE>
  -<HR>
  +</pre></blockquote>
  +<hr>
   
  -<P align=center>Copyright &copy; 2001-2004 The Apache Software Foundation.
  -All rights Reserved.</P></BODY></HTML>
  +<p align=center>Copyright &copy; 2001-2005 The Apache Software Foundation.
  +All rights Reserved.</p></body></html>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to