You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by do...@apache.org on 2001/06/22 03:45:48 UTC

cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs PathConvert.java

donaldp     01/06/21 18:45:48

  Added:       docs/manual/CoreTasks pathconvert.html
               src/main/org/apache/tools/ant/taskdefs PathConvert.java
  Log:
  New task to convert paths to those of a different OS.
  
  Submitted by:  "Larry V. Streepy, Jr." <st...@healthlanguage.com>
  
  Revision  Changes    Path
  1.1                  jakarta-ant/docs/manual/CoreTasks/pathconvert.html
  
  Index: pathconvert.html
  ===================================================================
  <html>
  
  <head>
  <meta http-equiv="Content-Language" content="en-us">
  <title>Ant User Manual</title>
  </head>
  
  <body>
  
  <h2><a name="foreach">Pathconvert</a></h2>
  <h3>Description</h3>
  <p>Converts a nested path, path reference, or fileset reference to the form usable on a
     specified platform
     and stores the result in a given property.  This operation is useful when script files
     (batch files or shell scripts) must be generated my the build system and they contain
     path information that must be properly formatted for the target architecture, not the
     architecture on which the build is running, or when you need to create a list of files
     separated by a given character, like a comma or a space.
  </p>
  <p>Prefix maps can be specified to map Windows drive letters to Unix paths and vice
     versa.</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">targetos</td>
      <td valign="top">
          The target architecture.  Must be one of 'unix' or 'windows'.  <BR>This is a
          shorthand mechanism for specifying both <tt>pathsep</tt> and <tt>dirsep</tt>
          according to the specified target architecture.
      </td>
      <td valign="top" align="center">
         Must specify one of <tt>targetos</tt>, <tt>pathsep</tt>,or <tt>dirsep</tt>.
      </td>
    </tr>
    <tr>
      <td valign="top">dirsep</td>
      <td valign="top">
         The character to use as the directory separator in the generated paths.
      </td>
      <td valign="top" align="center">No, defaults to current JVM <tt>File.separator</tt></td>
    </tr>
    <tr>
      <td valign="top">pathsep</td>
      <td valign="top">
         The character to use as the path element separator in the generated paths.
      </td>
      <td valign="top" align="center">No, defaults to current JVM <tt>File.pathSeparator</tt></td>
    </tr>
    <tr>
      <td valign="top">property</td>
      <td valign="top">The name of the property in which to place the converted path</td>
      <td valign="top" align="center">Yes</td>
    </tr>
    <tr>
      <td valign="top">refid</td>
      <td valign="top">What to convert, given as a
          <a href="../using.html#references">reference</a> to a PATH or FILESET
          defined elsewhere</td>
      <td valign="top" align="center">No, if omitted a nested &lt;path> element must be supplied.</td>
    </tr>
  </table>
  <h3>Parameters specified as nested elements</h3>
  <h4>map</h4>
  <p>Specifies the mapping of path prefixes between Unix and Windows.</p>
  <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">from</td>
      <td valign="top">The prefix to match.  Note that this value is case insensitive when
      the build is running on a windows platform and case sensitive when running on a
      Unix platform.</td>
      <td valign="top" align="center">Yes</td>
    </tr>
    <tr>
      <td valign="top">to</td>
      <td valign="top">The replacement text to use when <i>from</i> is matched.</td>
      <td valign="top" align="center">Yes</td>
    </tr>
  </table>
  
  <p>Each map element specifies a single replacement map to be applied to the elements of
     the path being processed.  If no map entries are specified, then no path prefix mapping
     is performed.
  </p>
  <p><i>Note that the map elements are applied in the order specified and the only the first
     matching map element is applied.  So, the ordering of your map elements can be important
     if any <TT>from</tt> values are prefixes of other <tt>from</tt> values.</i>
  </p>   
  <h4>path</h4>
  <p>If a path reference is not supplied using the <i>refid</i> attribute, then a
     nested path element must be supplied.  See
     <a href="../using.html#path">Path-like Structures</a> for details.</p>
  
  <h3>Examples</h3>
  <p>In the examples below, assume that the property <b>wl.home</b> has the value
  <tt>d:\weblogic</tt> on Windows and <tt>/weblogic</tt> on Unix.</p>
  <h4>Example 1</h4>
  <pre>
      &lt;path id="wl.path"&gt;
        &lt;pathelement location=&quot;${wl.home}/lib/weblogicaux.jar&quot; /&gt;
        &lt;pathelement location=&quot;${wl.home}/classes&quot; /&gt;
        &lt;pathelement location=&quot;${wl.home}/mssqlserver4/classes&quot; /&gt;
        &lt;pathelement location=&quot;c:\winnt\System32&quot; /&gt;
      &lt;/path&gt;
      
      &lt;pathconvert targetos=&quot;unix&quot; property=&quot;newpath&quot; refid=&quot;wl.path&quot;/&gt;
  </pre>
  <p>Assuming wl.property has the value "d:\weblogic", will generate the path shown below
     and store it in the property named <tt>newpath</tt>
  </p>   
  <pre>
  /weblogic/lib/weblogicaux.jar:/weblogic/classes:/weblogic/mssqlserver4/classes:/WINNT/SYSTEM32
  </pre>
  Note that the drive letters have been removed.  This is the default behavior when no map
  elements have been specified.
  
  <h4>Example 2</h4>
  <pre>
      
      &lt;pathconvert targetos=&quot;unix&quot; property=&quot;newpath&quot; &gt;
        &lt;path id="wl.path"&gt;
          &lt;pathelement location=&quot;${wl.home}/lib/weblogicaux.jar&quot; /&gt;
          &lt;pathelement location=&quot;${wl.home}/classes&quot; /&gt;
          &lt;pathelement location=&quot;${wl.home}/mssqlserver4/classes&quot; /&gt;
          &lt;pathelement location=&quot;c:\winnt\System32&quot; /&gt;
        &lt;/path&gt;
      &lt;/pathconvert&gt;
  </pre>
  This generates the exact same path as the previous example.  It demonstrates the use of
  a nested path element.
  <h4>Example 3</h4>
  <pre>
      &lt;pathconvert targetos=&quot;unix&quot; property=&quot;newpath&quot; refid=&quot;wl.path&quot;&gt;
        &lt;map from=&quot;d:&quot; to=&quot;/foo&quot;/&gt;
        &lt;map from=&quot;c:&quot; to=&quot;/bar&quot;/&gt;
      &lt;/pathconvert&gt;
  </pre>
  <p>This example specifies two map entries that will convert path elements that start with
  <tt>c:</tt> to <TT>/dos</tt> and <tt>d:</tt> to <TT>/</tt>.  The resulting path is shown
  below.</p>
  <pre>
  /weblogic/lib/weblogicaux.jar:/weblogic/classes:/weblogic/mssqlserver4/classes:/dos/WINNT/SYSTEM32
  </pre>
  <h4>Example 4</h4>
  <pre>
      &lt;pathconvert targetos=&quot;windows&quot; property=&quot;newpath&quot; &gt;
        &lt;path id="wl.path"&gt;
          &lt;pathelement location=&quot;${wl.home}/lib/weblogicaux.jar&quot; /&gt;
          &lt;pathelement location=&quot;${wl.home}/classes&quot; /&gt;
          &lt;pathelement location=&quot;${wl.home}/mssqlserver4/classes&quot; /&gt;
          &lt;pathelement location=&quot;/dos/winnt/System32&quot; /&gt;
        &lt;/path&gt;
        &lt;map from=&quot;/dos&quot; to=&quot;c:\&quot;/&gt;
        &lt;map from=&quot;/&quot; to=&quot;d:\&quot;/&gt;
      &lt;/pathconvert&gt;
  </pre>
  <p>This example, similar to the one above but targetting windows, specifies two map
  entries that will convert path elements that start with
  <tt>/dos</tt> to <TT>c:\</tt> and <tt>/</tt> to <TT>d:\</tt>.  Note that the order of the
  map elements was important here since <tt>/</tt> is a prefix of <tt>/dos</tt>.
  The resulting path is shown below.</p>
  <pre>
  d:\weblogic\lib\weblogicaux.jar;d:\weblogic\classes;d:\weblogic\mssqlserver4\classes;c:\WINNT\SYSTEM32
  </pre>
  <h4>Example 5</h4>
  <pre>
      &lt;fileset dir=&quot;${src.dir}&quot; id=&quot;src.files&quot;&gt;
        &lt;include name=&quot;**/*.java&quot;/&gt;
      &lt;/fileset&gt;
    
      &lt;pathconvert pathsep=&quot;,&quot; property=&quot;javafiles&quot; refid=&quot;src.files&quot;/&gt;
  </pre>
  <p>This example takes the set of files determined by the fileset (all files ending
  in <tt>.java</tt>), joins them together separated by commas, and places the resulting
  list into the property <tt>javafiles</tt>.  The directory separator is not specified, so
  it defaults to the appropriate character for the current platform.  Such a list could
  then be used in another task, like <tt>javadoc</tt>, that requires a comma separated
  list of files.
  </p>
  <hr>
  
  </body>
  </html>
  
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
  
  Index: PathConvert.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 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.BuildException;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.types.*;
  
  import java.util.*;
  import java.io.File;
  
  /**
   * This task converts path and classpath information to a specific target OS format.
   * The resulting formatted path is placed into a specified property.
   * <p>
   * LIMITATION: Currently this implementation groups all machines into one of two
   * types: Unix or Windows.  Unix is defined as NOT windows.
   *
   * @author Larry Streepy <a href="mailto:streepy@healthlanguage.com">streepy@healthlanguage.com</a>
   */
  public class PathConvert extends Task {
  
      /**
       * Helper class, holds the nested <map> values.  Elements will look like this:
       * &lt;map from="d:" to="/foo"/>
       * <p>
       * When running on windows, the prefix comparison will be case insensitive.
       */
      public class MapEntry {
  
          /**
           * Set the "from" attribute of the map entry
           */
          public void setFrom( String from ) {
              this.from = from;
          }
  
          /**
           * Set the "to" attribute of the map entry
           */
          public void setTo( String to ) {
              this.to = to;
          }
  
          /**
           * Apply this map entry to a given path element
           * @param elem Path element to process
           * @return String Updated path element after mapping
           */
          public String apply( String elem ) {
              if( from == null || to == null ) {
                  throw new BuildException( "Both 'from' and 'to' must be set in a map entry" );
              }
  
              // If we're on windows, then do the comparison ignoring case
              String cmpElem = onWindows ? elem.toLowerCase() : elem;
              String cmpFrom = onWindows ? from.toLowerCase() : from;
  
              // If the element starts with the configured prefix, then convert the prefix
              // to the configured 'to' value.
  
              if( cmpElem.startsWith( cmpFrom ) ) {
                  int len = from.length();
  
                  if( len >= elem.length() ) {
                      elem = to;
                  } else {
                      elem = to + elem.substring( len );
                  }
              }
  
              return elem;
          }
  
          // Members
          private String from = null;
          private String to = null;
      }
  
      /**
       * Create a nested PATH element
       */
      public Path createPath() {
  
          if( isReference() )
              throw noChildrenAllowed();
  
          if( path == null ) {
              path = new Path(getProject());
          }
          return path.createPath();
      }
  
      /**
       * Create a nested MAP element
       */
      public MapEntry createMap() {
  
          MapEntry entry = new MapEntry();
          prefixMap.add( entry );
          return entry;
      }
  
      /**
       * Set the value of the targetos attribute
       */
      public void setTargetos( String target ) {
  
          targetOS = target.toLowerCase();
  
          if( ! targetOS.equals( "windows" ) && ! target.equals( "unix" ) ) {
              throw new BuildException( "targetos must be one of 'unix' or 'windows'" );
          }
  
          // Currently, we deal with only two path formats: Unix and Windows
          // And Unix is everything that is not Windows
  
          targetWindows = targetOS.equals("windows");
      }
  
      /**
       * Set the value of the proprty attribute - this is the property into which our
       * converted path will be placed.
       */
      public void setProperty( String p ) {
          property = p;
      }
  
      /**
       * Adds a reference to a PATH or FILESET defined elsewhere.
       */
      public void setRefid(Reference r) {
          if( path != null )
              throw noChildrenAllowed();
  
          refid = r;
      }
  
      /**
       * Override the default path separator string for the target os
       */
      public void setPathSep( String sep ) {
          pathSep = sep;
      }
  
      /**
       * Override the default directory separator string for the target os
       */
      public void setDirSep( String sep ) {
          dirSep = sep;
      }
  
      /**
       * Has the refid attribute of this element been set?
       */
      public boolean isReference() {
          return refid != null;
      }
  
      /**
       * Do the execution.
       */
      public void execute() throws BuildException {
  
          // If we are a reference, the create a Path from the reference
          if( isReference() ) {
              path = new Path(getProject()).createPath();
  
              Object obj = refid.getReferencedObject(getProject());
  
              if( obj instanceof Path ) {
                  path.setRefid(refid);
              } else if( obj instanceof FileSet ) {
                  FileSet fs = (FileSet)obj;
                  path.addFileset( fs );
              } else {
                  throw new BuildException( "'refid' does not refer to a path or fileset" );
              }
          }
  
          validateSetup();                    // validate our setup
  
          // Currently, we deal with only two path formats: Unix and Windows
          // And Unix is everything that is not Windows
  
          String osname = System.getProperty("os.name").toLowerCase();
          onWindows = ( osname.indexOf("windows") >= 0 );
  
          // Determine the from/to char mappings for dir sep
          char fromDirSep = onWindows ? '\\' : '/';
          char toDirSep   = dirSep.charAt(0);
  
          StringBuffer rslt = new StringBuffer( 100 );
  
          // Get the list of path components in canonical form
          String[] elems = path.list();
  
          for( int i=0; i < elems.length; i++ ) {
              String elem = elems[i];
  
              elem = mapElement( elem );      // Apply the path prefix map
  
              // Now convert the path and file separator characters from the
              // current os to the target os.
  
              elem = elem.replace( fromDirSep, toDirSep );
  
              if( i != 0 ) rslt.append( pathSep );
              rslt.append( elem );
          }
  
          // Place the result into the specified property
          String value = rslt.toString();
  
          log( "Set property " + property + " = " + value, Project.MSG_VERBOSE );
  
          getProject().setProperty( property, value );
      }
  
      /**
       * Apply the configured map to a path element.  The map is used to convert
       * between Windows drive letters and Unix paths.  If no map is configured,
       * then the input string is returned unchanged.
       *
       * @param elem The path element to apply the map to
       * @return String Updated element
       */
      private String mapElement( String elem ) {
  
          int size = prefixMap.size();
  
          if( size != 0 ) {
  
              // Iterate over the map entries and apply each one.  Stop when one of the
              // entries actually changes the element
  
              for( int i=0; i < size; i++ ) {
                  MapEntry entry = (MapEntry)prefixMap.get(i);
                  String newElem = entry.apply( elem );
  
                  // Note I'm using "!=" to see if we got a new object back from
                  // the apply method.
  
                  if( newElem != elem ) {
                      elem = newElem;
                      break;                  // We applied one, so we're done
                  }
              }
          }
  
          return elem;
      }
  
      /**
       * Validate that all our parameters have been properly initialized.
       * @throws BuildException if something is not setup properly
       */
      private void validateSetup() throws BuildException {
  
          if( path == null )
              throw new BuildException( "You must specify a path to convert" );
  
          if( property == null )
              throw new BuildException( "You must specify a property" );
  
          // Must either have a target OS or both a dirSep and pathSep
  
          if( targetOS == null && pathSep == null && dirSep == null )
              throw new BuildException( "You must specify at least one of targetOS, dirSep, or pathSep" );
  
          // Determine the separator strings.  The dirsep and pathsep attributes
          // override the targetOS settings.
          String dsep = File.separator;
          String psep = File.pathSeparator;
  
          if( targetOS != null ) {
              psep = targetWindows ? ";" : ":";
              dsep = targetWindows ? "\\" : "/";
          }
  
          if( pathSep != null ) {             // override with pathsep=
              psep = pathSep;
          }
  
          if( dirSep != null ) {              // override with dirsep=
              dsep = dirSep;
          }
  
          pathSep = psep;
          dirSep = dsep;
      }
  
      /**
       * Creates an exception that indicates that this XML element must
       * not have child elements if the refid attribute is set.  
       */
      private BuildException noChildrenAllowed() {
          return new BuildException("You must not specify nested PATH elements when using refid");
      }
  
  
      // Members
      private Path path = null;               // Path to be converted
      private Reference refid = null;         // Reference to path/fileset to convert
      private String targetOS = null;         // The target OS type
      private boolean targetWindows = false;  // Set when targetOS is set
      private boolean onWindows = false;      // Set if we're running on windows
      private String property = null;         // The property to receive the results
      private ArrayList prefixMap = new ArrayList();  // Path prefix map
      private String pathSep = null;          // User override on path sep char
      private String dirSep = null;           // User override on directory sep char
  }
  
  
  

Re: cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs PathConvert.java

Posted by Stefan Bodewig <bo...@apache.org>.
<do...@apache.org> wrote:

>   <h2><a name="foreach">Pathconvert</a></h2>

should have something else in its name attribute 8-)

Stefan