ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject cvs commit: ant/docs/manual/CoreTypes mapper.html
Date Thu, 11 Mar 2004 19:25:48 GMT
mbenson     2004/03/11 11:25:48

  Modified:    .        WHATSNEW
               src/main/org/apache/tools/ant/types Mapper.java
                        defaults.properties
               src/testcases/org/apache/tools/ant/types MapperTest.java
               docs/manual/CoreTypes mapper.html
  Added:       src/main/org/apache/tools/ant/util ContainerMapper.java
  Log:
  Nested file mappers; container mapper.
  PR: 26364
  
  Revision  Changes    Path
  1.1                  ant/src/main/org/apache/tools/ant/util/ContainerMapper.java
  
  Index: ContainerMapper.java
  ===================================================================
  /*
   * Copyright 2004 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.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  
  package org.apache.tools.ant.util;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import org.apache.tools.ant.types.Mapper;
  import org.apache.tools.ant.util.FileNameMapper;
  
  /**
   * A filenamemapper that contains other filename mappers.
   * The mappers proceeded in a chain or separately.
   * @see FileNameMapper
   */
  
  public class ContainerMapper implements FileNameMapper {
  
      private boolean chained = false;
      private List mappers = new ArrayList();
  
      /**
       * Add a file name mapper.
       *
       * @param fileNameMapper a file name mapper.
       */
      public void add(FileNameMapper fileNameMapper) {
          mappers.add(fileNameMapper);
      }
  
      /**
       * Add a Mapper
       * @param mapper the mapper to add
       */
      public void addConfiguredMapper(Mapper mapper) {
          mappers.add(mapper.getImplementation());
      }
                      
      /**
       * Set the chained attribute.
       *
       * @param chained if true the mappers are processed in
       *                   a chained fashion. The outputs of
       *                a mapper are the inputs for the next mapper.
       *                if false the mappers are processed indepentanly, the
       *                outputs are combined.
       */
      public void setChained(boolean chained) {
          this.chained = chained;
      }
  
      /**
       * This method is ignored, present to fullfill the FileNameMapper
       * interface.
       * @param ignore this parameter is ignored.
       */
      public void setFrom(String ignore) {
      }
  
      /**
       * This method is ignored, present to fullfill the FileNameMapper
       * interface.
       * @param ignore this parameter is ignored.
       */
      public void setTo(String ignore) {
      }
  
      /**
       * Map a filename using the list of mappers.
       *
       * @param sourceFileName The filename to map.
       * @return a <code>String[]</code> value or null if there
       *         are no mappings.
       */
      public String[] mapFileName(String sourceFileName) {
          List ret = new ArrayList();
          if (chained) {
              List inputs = new ArrayList();
              ret.add(sourceFileName);
              for (int i = 0; i < mappers.size(); ++i) {
                  inputs = ret;
                  ret = new ArrayList();
                  FileNameMapper mapper = (FileNameMapper) mappers.get(i);
                  for (Iterator it = inputs.iterator(); it.hasNext();) {
                      String[] mapped = mapper.mapFileName(
                          (String) it.next());
                      if (mapped != null) {
                          for (int m = 0; m < mapped.length; ++m) {
                              ret.add(mapped[m]);
                          }
                      }
                  }
                  if (ret.size() == 0) {
                      return null;
                  }
              }
          } else {
              for (int i = 0; i < mappers.size(); ++i) {
                  FileNameMapper mapper = (FileNameMapper) mappers.get(i);
                  String[] mapped = mapper.mapFileName(sourceFileName);
                  if (mapped != null) {
                      for (int m = 0; m < mapped.length; ++m) {
                          ret.add(mapped[m]);
                      }
                  }
              }
              if (ret.size() == 0) {
                  return null;
              }
          }
          return (String[]) ret.toArray(new String[ret.size()]);
      }
  }
  
  
  
  
  1.569     +5 -0      ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/ant/WHATSNEW,v
  retrieving revision 1.568
  retrieving revision 1.569
  diff -u -r1.568 -r1.569
  --- WHATSNEW	11 Mar 2004 11:22:10 -0000	1.568
  +++ WHATSNEW	11 Mar 2004 19:25:48 -0000	1.569
  @@ -41,6 +41,11 @@
     a granularity of two seconds).  The default remains to round up.
     Bugzilla Report 17934.
   
  +* Nested file mappers and a container mapper implementation have been
  +  introduced.  Additionally, the <mapper> element now accepts "defined"
  +  nested FileNameMapper implementations directly, allowing a usage
  +  comparable to those of <condition>, <filter>, and <selector>.
  +
   Changes from Ant 1.6.1 to current Ant 1.6 CVS version
   =============================================
   
  
  
  
  1.27      +51 -4     ant/src/main/org/apache/tools/ant/types/Mapper.java
  
  Index: Mapper.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/Mapper.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Mapper.java	9 Mar 2004 16:48:41 -0000	1.26
  +++ Mapper.java	11 Mar 2004 19:25:48 -0000	1.27
  @@ -23,6 +23,7 @@
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.util.FileNameMapper;
  +import org.apache.tools.ant.util.ContainerMapper;
   
   /**
    * Element to define a FileNameMapper.
  @@ -30,7 +31,9 @@
    */
   public class Mapper extends DataType implements Cloneable {
   
  -    protected MapperType type = null;
  +    protected MapperType      type = null;
  +    private   ContainerMapper container = null;
  +    private   Boolean         chained = null;
   
       public Mapper(Project p) {
           setProject(p);
  @@ -49,6 +52,34 @@
       protected String classname = null;
   
       /**
  +     * Add a nested filename mapper
  +     * @param fileNameMapper the mapper to add
  +     */
  +    public void add(FileNameMapper fileNameMapper) {
  +        if (container == null) {
  +            container = new ContainerMapper();
  +        }
  +        container.add(fileNameMapper);
  +    }
  +
  +    /**
  +     * Add a Mapper
  +     * @param mapper the mapper to add
  +     */
  +    public void addConfiguredMapper(Mapper mapper) {
  +        add(mapper.getImplementation());
  +    }
  +                    
  +    /**
  +     * Set the chained attribute of the nested mapper container
  +     * @param chained the setting for the chained attribute of the
  +     *        nested mapper container.
  +     */
  +    public void setChained(Boolean chained) {
  +        this.chained = chained;
  +    }
  +    
  +    /**
        * Set the class name of the FileNameMapper to use.
        */
       public void setClassname(String classname) {
  @@ -143,12 +174,28 @@
               return getRef().getImplementation();
           }
   
  -        if (type == null && classname == null) {
  -            throw new BuildException("one of the attributes type or classname is required");
  +        if (type == null && classname == null && container == null) {
  +            throw new BuildException(
  +                "nested mapper or "
  +                + "one of the attributes type or classname is required");
  +        }
  +
  +        if (container != null) {
  +            if (type != null || classname != null ||
  +                to != null || from != null) {
  +                throw new BuildException(
  +                    "for nested mappers, type, classname, to and from" +
  +                    " attributes are not allowed");
  +            }
  +            if (chained != null) {
  +                container.setChained(chained.booleanValue());
  +            }
  +            return container;
           }
   
           if (type != null && classname != null) {
  -            throw new BuildException("must not specify both type and classname attribute");
  +            throw new BuildException(
  +                "must not specify both type and classname attribute");
           }
   
           try {
  
  
  
  1.22      +10 -0     ant/src/main/org/apache/tools/ant/types/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/defaults.properties,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- defaults.properties	23 Dec 2003 11:07:00 -0000	1.21
  +++ defaults.properties	11 Mar 2004 19:25:48 -0000	1.22
  @@ -7,6 +7,16 @@
   filterreader=org.apache.tools.ant.types.AntFilterReader
   filterset=org.apache.tools.ant.types.FilterSet
   mapper=org.apache.tools.ant.types.Mapper
  +# different filename mappers
  +identitymapper=org.apache.tools.ant.util.IdentityMapper
  +flattenmapper=org.apache.tools.ant.util.FlatFileNameMapper
  +globmapper=org.apache.tools.ant.util.GlobPatternMapper
  +mergemapper=org.apache.tools.ant.util.MergingMapper
  +regexpmapper=org.apache.tools.ant.util.RegexpPatternMapper
  +packagemapper=org.apache.tools.ant.util.PackageNameMapper
  +unpackagemapper=org.apache.tools.ant.util.UnPackageNameMapper
  +containermapper=org.apache.tools.ant.util.ContainerMapper
  +
   path=org.apache.tools.ant.types.Path
   patternset=org.apache.tools.ant.types.PatternSet
   regexp=org.apache.tools.ant.types.RegularExpression
  
  
  
  1.14      +75 -0     ant/src/testcases/org/apache/tools/ant/types/MapperTest.java
  
  Index: MapperTest.java
  ===================================================================
  RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/types/MapperTest.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- MapperTest.java	9 Mar 2004 16:49:05 -0000	1.13
  +++ MapperTest.java	11 Mar 2004 19:25:48 -0000	1.14
  @@ -26,6 +26,8 @@
   import junit.framework.AssertionFailedError;
   
   import java.io.File;
  +import java.util.List;
  +import java.util.Arrays;
   
   /**
    * JUnit 3 testcases for org.apache.tools.ant.types.Mapper.
  @@ -136,6 +138,79 @@
           String[] result = fmm.mapFileName("a.java");
           assertEquals("a.java should match", 1, result.length);
           assertEquals("a.class", result[0]);
  +    }
  +
  +    public void testContainer() {
  +        Mapper mapper1 = new Mapper(project);
  +        Mapper.MapperType mt = new Mapper.MapperType();
  +        mt.setValue("glob");
  +        mapper1.setType(mt);
  +        mapper1.setFrom("from*");
  +        mapper1.setTo("to*");
  +
  +        //mix element types
  +        FileNameMapper mapper2 = new FlatFileNameMapper();
  +        FileNameMapper mapper3 = new MergingMapper();
  +        mapper3.setTo("mergefile");
  +
  +        Mapper container = new Mapper(project);
  +        container.addConfiguredMapper(mapper1);
  +        container.add(mapper2);
  +        container.add(mapper3);
  +
  +        FileNameMapper fileNameMapper = container.getImplementation();
  +        String[] targets = fileNameMapper.mapFileName("fromfilename");
  +        assertNotNull("no filenames mapped", targets);
  +        assertEquals("wrong number of filenames mapped", 3, targets.length);
  +        List list = Arrays.asList(targets);
  +        assertTrue("cannot find expected target \"tofilename\"",
  +            list.contains("tofilename"));
  +        assertTrue("cannot find expected target \"fromfilename\"",
  +            list.contains("fromfilename"));
  +        assertTrue("cannot find expected target \"mergefile\"",
  +            list.contains("mergefile"));
  +    }
  +
  +    public void testChainedContainer() {
  +
  +        // a --> b --> c --- def
  +        //               \-- ghi
  +
  +        FileNameMapper mapperAB = new GlobPatternMapper();
  +        mapperAB.setFrom("a");
  +        mapperAB.setTo("b");
  +
  +        FileNameMapper mapperBC = new GlobPatternMapper();
  +        mapperBC.setFrom("b");
  +        mapperBC.setTo("c");
  +
  +        Mapper mapperCX = new Mapper(project);
  +
  +        FileNameMapper mapperDEF = new GlobPatternMapper();
  +        mapperDEF.setFrom("c");
  +        mapperDEF.setTo("def");
  +
  +        FileNameMapper mapperGHI = new GlobPatternMapper();
  +        mapperGHI.setFrom("c");
  +        mapperGHI.setTo("ghi");
  +
  +        mapperCX.add(mapperDEF);
  +        mapperCX.add(mapperGHI);
  +
  +        ContainerMapper chained = new ContainerMapper();
  +        chained.setChained(true);
  +        chained.add(mapperAB);
  +        chained.add(mapperBC);
  +        chained.addConfiguredMapper(mapperCX);
  +
  +        String[] targets = chained.mapFileName("a");
  +        assertNotNull("no filenames mapped", targets);
  +        assertEquals("wrong number of filenames mapped", 2, targets.length);
  +        List list = Arrays.asList(targets);
  +        assertTrue("cannot find expected target \"def\"",
  +            list.contains("def"));
  +        assertTrue("cannot find expected target \"ghi\"",
  +            list.contains("ghi"));
       }
   
       public void testCopyTaskWithTwoFilesets() {
  
  
  
  1.16      +100 -5    ant/docs/manual/CoreTypes/mapper.html
  
  Index: mapper.html
  ===================================================================
  RCS file: /home/cvs/ant/docs/manual/CoreTypes/mapper.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- mapper.html	9 Feb 2004 21:50:07 -0000	1.15
  +++ mapper.html	11 Mar 2004 19:25:48 -0000	1.16
  @@ -62,6 +62,12 @@
         implementation.</td>
       <td align="center" valign="top">Depends on implementation.</td>
     </tr>
  +  <tr>
  +    <td valign="top">chained</td> 
  +    <td valign="top">Whether to chain nested <CODE>&lt;mapper&gt;</CODE>s.
  +      <i>Since Ant 1.7</i></td>
  +    <td align="center" valign="top">No, default is <CODE>false</CODE>.</td>
  +  </tr>
   </table>
   <p>Note that Ant will not automatically convert / or \ characters in
   the <code>to</code> and <code>from</code> attributes to the correct
  @@ -71,14 +77,30 @@
   <p>The classpath can be specified via a nested
   <code>&lt;classpath&gt;</code>, as well - that is,
   a <a href="../using.html#path">path</a>-like structure.</p>
  +<p><b>Since Ant 1.7,</b> nested File Mappers can
  +be supplied via either <CODE>&lt;mapper&gt;</CODE> elements or
  +<a href="../CoreTasks/typedef.html"><code>&lt;typedef&gt;</code></a>'d
  +implementations of <CODE>org.apache.tools.ant.util.FileNameMapper</CODE>.
  +If one or more nested File Mappers are specified using either convention,
  +only the <i>chained</i> attribute will be considered in the configuration
  +of the implicitly used <a href="#container-mapper">container mapper</a>.
  +</p>
  +<hr/>
   <h3>The built-in mapper types are:</h3>
   <p>All built-in mappers are case-sensitive.</p>
  +<p><b>As of Ant 1.7,</b> each of the built-in mapper implementation
  +  types is directly accessible using a specific tagname. This makes it
  +  possible for filename mappers to support attributes in addition to
  +  the generally available <i>to</i> and <i>from</i>.<br/>
  +  The <code>&lt;mapper type|classname=&quot;...&quot;&gt;</code>
usage
  +  form remains valid for reasons of backward compatibility.</p>
   <h4><a name="identity-mapper">identity</a></h4>
   <p>The target file name is identical to the source file name. Both
   <code>to</code> and <code>from</code> will be ignored.</p>
   <b>Examples:</b>
   <blockquote><pre>
   &lt;mapper type=&quot;identity&quot;/&gt;
  +&lt;identitymapper /&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -109,6 +131,7 @@
   <b>Examples:</b>
   <blockquote><pre>
   &lt;mapper type=&quot;flatten&quot;/&gt;
  +&lt;flattenmapper /&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -138,6 +161,7 @@
   <h5>Examples:</h5>
   <blockquote><pre>
   &lt;mapper type=&quot;merge&quot; to=&quot;archive.tar&quot;/&gt;
  +&lt;mergemapper to=&quot;archive.tar&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -172,6 +196,7 @@
   <b>Examples:</b>
   <blockquote><pre>
   &lt;mapper type=&quot;glob&quot; from=&quot;*.java&quot; to=&quot;*.java.bak&quot;/&gt;
  +&lt;globmapper from=&quot;*.java&quot; to=&quot;*.java.bak&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -197,6 +222,7 @@
   </table>
   <blockquote><pre>
   &lt;mapper type=&quot;glob&quot; from=&quot;C*ies&quot; to=&quot;Q*y&quot;/&gt;
  +&lt;globmapper from=&quot;C*ies&quot; to=&quot;Q*y&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -267,6 +293,7 @@
   <b>Examples:</b>
   <blockquote><pre>
   &lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)\.java$$&quot; to=&quot;\1.java.bak&quot;/&gt;
  +&lt;regexpmapper from=&quot;^(.*)\.java$$&quot; to=&quot;\1.java.bak&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -292,6 +319,7 @@
   </table>
   <blockquote><pre>
   &lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)/([^/]+)/([^/]*)$$&quot;
to=&quot;\1/\2/\2-\3&quot;/&gt;
  +&lt;regexpmapper from=&quot;^(.*)/([^/]+)/([^/]*)$$&quot; to=&quot;\1/\2/\2-\3&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -317,6 +345,7 @@
   </table>
   <blockquote><pre>
   &lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)\.(.*)$$&quot; to=&quot;\2.\1&quot;/&gt;
  +&lt;regexpmapper from=&quot;^(.*)\.(.*)$$&quot; to=&quot;\2.\1&quot;/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -349,8 +378,8 @@
   with <code>&lt;uptodate&gt;</code> and <code>&lt;junit&gt;</code>
output.</p>
   <b>Example:</b>
   <blockquote><pre>
  -&lt;mapper type="package"
  -        from="*Test.java" to="TEST-*Test.xml"/&gt;
  +&lt;mapper type="package" from="*Test.java" to="TEST-*Test.xml"/&gt;
  +&lt;packagemapper from="*Test.java" to="TEST-*Test.xml"/&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -375,8 +404,8 @@
     </p>
   <b>Example:</b>
   <blockquote><pre>
  -&lt;mapper type="unpackage"
  -        from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"&gt;
  +&lt;mapper type="unpackage" from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"&gt;
  +&lt;unpackagemapper from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"&gt;
   </pre></blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
  @@ -388,7 +417,73 @@
       <td valign="top"><code>${test.src.dir}/org/acme/AcmeTest.java</code></td>
     </tr>
   </table>
  -
  +<h4><a name="container-mapper">container (since ant 1.7)</a></h4>
  +  <p>This mapper implementation can contain multiple nested mappers,
  +    and can process in one of two modes, controlled by the <i>chained</i>
  +    attribute.  In the default mode, file mapping is performed by passing
  +    the source filename to each nested <code>&lt;mapper&gt;</code>
in turn,
  +    returning all results.  When <i>chained</i> is set to <CODE>true</CODE>,
  +    the source filename will be passed to the first nested mapper, its
  +    results will be passed to the second, and so on.  The target filenames
  +    generated by the last nested mapper comprise the ultimate results of the
  +    mapping operation.  The <i>to</i> and <i>from</i> attributes
are ignored.</p>
  +<b>Examples:</b>
  +<blockquote><pre>
  +&lt;containermapper&gt;
  +  &lt;identitymapper /&gt;
  +  &lt;packagemapper from="*.java" to="*"/&gt;
  +&lt;/containermapper&gt;
  +</pre></blockquote>
  +<table border="1" cellpadding="2" cellspacing="0">
  +  <tr>
  +    <td valign="top"><b>Source file name</b></td>
  +    <td valign="top"><b>Target file names</b></td>
  +  </tr>
  +  <tr>
  +    <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
  +    <td valign="top"><code>foo/bar/A.java</code></td>
  +  </tr>
  +  <tr>
  +    <td valign="top"><code>foo.bar.A</code></td>
  +  </tr>
  +</table>
  +<blockquote><pre>
  +&lt;mapper chained=&quot;true&quot;&gt;
  +  &lt;flattenmapper /&gt;
  +  &lt;globmapper from="*" to="new/path/*"/&gt;
  +  &lt;mapper&gt;
  +    &lt;globmapper from="*" to="*1"/&gt;
  +    &lt;globmapper from="*" to="*2"/&gt;
  +  &lt;/mapper&gt;
  +&lt;/mapper&gt;
  +</pre></blockquote>
  +<table border="1" cellpadding="2" cellspacing="0">
  +  <tr>
  +    <td valign="top"><b>Source file name</b></td>
  +    <td valign="top"><b>Target file names</b></td>
  +  </tr>
  +  <tr>
  +    <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
  +    <td valign="top"><code>new/path/A.java1</code></td>
  +  </tr>
  +  <tr>
  +    <td valign="top"><code>new/path/A.java2</code></td>
  +  </tr>
  +  <tr>
  +    <td valign="center" rowspan="2"><code>boo/far/B.java</code></td>
  +    <td valign="top"><code>new/path/B.java1</code></td>
  +  </tr>
  +  <tr>
  +    <td valign="top"><code>new/path/B.java2</code></td>
  +  </tr>
  +</table>
  +  <p>Finally, the container mapper is <b>not</b> built-in in the same
sense
  +    as the others.  It is available via its own typedef,
  +    <code>&lt;containermapper&gt;</code>, and the use of a common
  +    <code>&lt;mapper&gt;</code> element with nested mappers will, as
mentioned
  +    previously, make implicit use of a container mapper.  The container
  +    mapper is <b>not</b> available, however (nor does it need to be), using
  +    the common <code>&lt;mapper type=&quot;...&quot;&gt;</code>
syntax.</p>
   <hr>
   <p align="center">Copyright &copy; 2000-2004 The Apache Software Foundation.
All rights
   Reserved.</p>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message