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/12/17 11:55:24 UTC

cvs commit: jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional IContract.java

donaldp     01/12/17 02:55:23

  Modified:    proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional
                        IContract.java
  Added:       proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/file
                        Copy.java Delete.java Mkdir.java Move.java
  Removed:     proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs
                        Copy.java Delete.java Mkdir.java Move.java
  Log:
  MOved file tasks into separate package.
  
  Revision  Changes    Path
  1.1                  jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/file/Copy.java
  
  Index: Copy.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.tools.ant.taskdefs.file;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import org.apache.avalon.excalibur.io.FileUtil;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.types.FilterSet;
  import org.apache.tools.ant.types.FilterSetCollection;
  import org.apache.tools.ant.types.Mapper;
  import org.apache.tools.ant.util.FileNameMapper;
  import org.apache.tools.ant.util.FileUtils;
  import org.apache.tools.ant.util.FlatFileNameMapper;
  import org.apache.tools.ant.util.IdentityMapper;
  import org.apache.tools.ant.util.SourceFileScanner;
  
  /**
   * A consolidated copy task. Copies a file or directory to a new file or
   * directory. Files are only copied if the source file is newer than the
   * destination file, or when the destination file does not exist. It is possible
   * to explicitly overwrite existing files.</p> <p>
   *
   * This implementation is based on Arnout Kuiper's initial design document, the
   * following mailing list discussions, and the copyfile/copydir tasks.</p>
   *
   * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com
   *      </a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <A href="gholam@xtra.co.nz">Michael McCallum</A>
   * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
   */
  public class Copy extends Task
  {
      protected File file = null;// the source file
      protected File destFile = null;// the destination file
      protected File destDir = null;// the destination directory
      protected Vector filesets = new Vector();
  
      protected boolean filtering = false;
      protected boolean preserveLastModified = false;
      protected boolean forceOverwrite = false;
      protected boolean flatten = false;
      protected int verbosity = Project.MSG_VERBOSE;
      protected boolean includeEmpty = true;
  
      protected Hashtable fileCopyMap = new Hashtable();
      protected Hashtable dirCopyMap = new Hashtable();
      protected Hashtable completeDirMap = new Hashtable();
  
      protected Mapper mapperElement = null;
      private Vector filterSets = new Vector();
  
      /**
       * Sets a single source file to copy.
       *
       * @param file The new File value
       */
      public void setFile( File file )
      {
          this.file = file;
      }
  
      /**
       * Sets filtering.
       *
       * @param filtering The new Filtering value
       */
      public void setFiltering( boolean filtering )
      {
          this.filtering = filtering;
      }
  
      /**
       * When copying directory trees, the files can be "flattened" into a single
       * directory. If there are multiple files with the same name in the source
       * directory tree, only the first file will be copied into the "flattened"
       * directory, unless the forceoverwrite attribute is true.
       *
       * @param flatten The new Flatten value
       */
      public void setFlatten( boolean flatten )
      {
          this.flatten = flatten;
      }
  
      /**
       * Used to copy empty directories.
       *
       * @param includeEmpty The new IncludeEmptyDirs value
       */
      public void setIncludeEmptyDirs( boolean includeEmpty )
      {
          this.includeEmpty = includeEmpty;
      }
  
      /**
       * Overwrite any existing destination file(s).
       *
       * @param overwrite The new Overwrite value
       */
      public void setOverwrite( boolean overwrite )
      {
          this.forceOverwrite = overwrite;
      }
  
      /**
       * Give the copied files the same last modified time as the original files.
       *
       * @param preserve The new PreserveLastModified value
       */
      public void setPreserveLastModified( boolean preserve )
      {
          preserveLastModified = preserve;
      }
  
      /**
       * Sets the destination directory.
       *
       * @param destDir The new Todir value
       */
      public void setTodir( File destDir )
      {
          this.destDir = destDir;
      }
  
      /**
       * Sets the destination file.
       *
       * @param destFile The new Tofile value
       */
      public void setTofile( File destFile )
      {
          this.destFile = destFile;
      }
  
      /**
       * Used to force listing of all names of copied files.
       *
       * @param verbose The new Verbose value
       */
      public void setVerbose( boolean verbose )
      {
          if( verbose )
          {
              this.verbosity = Project.MSG_INFO;
          }
          else
          {
              this.verbosity = Project.MSG_VERBOSE;
          }
      }
  
      /**
       * Adds a set of files (nested fileset attribute).
       *
       * @param set The feature to be added to the Fileset attribute
       */
      public void addFileset( FileSet set )
      {
          filesets.addElement( set );
      }
  
      /**
       * Create a nested filterset
       *
       * @return Description of the Returned Value
       */
      public FilterSet createFilterSet()
      {
          FilterSet filterSet = new FilterSet();
          filterSets.addElement( filterSet );
          return filterSet;
      }
  
      /**
       * Defines the FileNameMapper to use (nested mapper element).
       *
       * @return Description of the Returned Value
       * @exception TaskException Description of Exception
       */
      public Mapper createMapper()
          throws TaskException
      {
          if( mapperElement != null )
          {
              throw new TaskException( "Cannot define more than one mapper" );
          }
          mapperElement = new Mapper( project );
          return mapperElement;
      }
  
      /**
       * Performs the copy operation.
       *
       * @exception TaskException Description of Exception
       */
      public void execute()
          throws TaskException
      {
          // make sure we don't have an illegal set of options
          validateAttributes();
  
          // deal with the single file
          if( file != null )
          {
              if( file.exists() )
              {
                  if( destFile == null )
                  {
                      destFile = new File( destDir, file.getName() );
                  }
  
                  if( forceOverwrite ||
                      ( file.lastModified() > destFile.lastModified() ) )
                  {
                      fileCopyMap.put( file.getAbsolutePath(), destFile.getAbsolutePath() );
                  }
                  else
                  {
                      log( file + " omitted as " + destFile + " is up to date.",
                           Project.MSG_VERBOSE );
                  }
              }
              else
              {
                  String message = "Could not find file "
                      + file.getAbsolutePath() + " to copy.";
                  getLogger().info( message );
                  throw new TaskException( message );
              }
          }
  
          // deal with the filesets
          for( int i = 0; i < filesets.size(); i++ )
          {
              FileSet fs = (FileSet)filesets.elementAt( i );
              DirectoryScanner ds = fs.getDirectoryScanner( project );
              File fromDir = fs.getDir( project );
  
              String[] srcFiles = ds.getIncludedFiles();
              String[] srcDirs = ds.getIncludedDirectories();
              boolean isEverythingIncluded = ds.isEverythingIncluded();
              if( isEverythingIncluded
                  && !flatten && mapperElement == null )
              {
                  completeDirMap.put( fromDir, destDir );
              }
              scan( fromDir, destDir, srcFiles, srcDirs );
          }
  
          // do all the copy operations now...
          doFileOperations();
  
          // clean up destDir again - so this instance can be used a second
          // time without throwing an exception
          if( destFile != null )
          {
              destDir = null;
          }
      }
  
      /**
       * Get the filtersets being applied to this operation.
       *
       * @return a vector of FilterSet objects
       */
      protected Vector getFilterSets()
      {
          return filterSets;
      }
  
      protected void buildMap( File fromDir, File toDir, String[] names,
                               FileNameMapper mapper, Hashtable map )
          throws TaskException
      {
  
          String[] toCopy = null;
          if( forceOverwrite )
          {
              Vector v = new Vector();
              for( int i = 0; i < names.length; i++ )
              {
                  if( mapper.mapFileName( names[ i ] ) != null )
                  {
                      v.addElement( names[ i ] );
                  }
              }
              toCopy = new String[ v.size() ];
              v.copyInto( toCopy );
          }
          else
          {
              SourceFileScanner ds = new SourceFileScanner( this );
              toCopy = ds.restrict( names, fromDir, toDir, mapper );
          }
  
          for( int i = 0; i < toCopy.length; i++ )
          {
              File src = new File( fromDir, toCopy[ i ] );
              File dest = new File( toDir, mapper.mapFileName( toCopy[ i ] )[ 0 ] );
              map.put( src.getAbsolutePath(), dest.getAbsolutePath() );
          }
      }
  
      /**
       * Actually does the file (and possibly empty directory) copies. This is a
       * good method for subclasses to override.
       */
      protected void doFileOperations()
          throws TaskException
      {
          if( fileCopyMap.size() > 0 )
          {
              getLogger().info( "Copying " + fileCopyMap.size() +
                                " file" + ( fileCopyMap.size() == 1 ? "" : "s" ) +
                                " to " + destDir.getAbsolutePath() );
  
              Enumeration e = fileCopyMap.keys();
              while( e.hasMoreElements() )
              {
                  String fromFile = (String)e.nextElement();
                  String toFile = (String)fileCopyMap.get( fromFile );
  
                  if( fromFile.equals( toFile ) )
                  {
                      log( "Skipping self-copy of " + fromFile, verbosity );
                      continue;
                  }
  
                  try
                  {
                      log( "Copying " + fromFile + " to " + toFile, verbosity );
  
                      FilterSetCollection executionFilters = new FilterSetCollection();
                      if( filtering )
                      {
                          executionFilters.addFilterSet( project.getGlobalFilterSet() );
                      }
                      for( Enumeration filterEnum = filterSets.elements(); filterEnum.hasMoreElements(); )
                      {
                          executionFilters.addFilterSet( (FilterSet)filterEnum.nextElement() );
                      }
                      final File src = new File( fromFile );
                      final File dest = new File( toFile );
                      if( forceOverwrite )
                      {
                          FileUtil.forceDelete( dest );
                      }
                      FileUtils.newFileUtils().copyFile( src, dest, executionFilters );
                      if( preserveLastModified )
                      {
                          dest.setLastModified( src.lastModified() );
                      }
                  }
                  catch( IOException ioe )
                  {
                      String msg = "Failed to copy " + fromFile + " to " + toFile
                          + " due to " + ioe.getMessage();
                      throw new TaskException( msg, ioe );
                  }
              }
          }
  
          if( includeEmpty )
          {
              Enumeration e = dirCopyMap.elements();
              int count = 0;
              while( e.hasMoreElements() )
              {
                  File d = new File( (String)e.nextElement() );
                  if( !d.exists() )
                  {
                      if( !d.mkdirs() )
                      {
                          log( "Unable to create directory " + d.getAbsolutePath(), Project.MSG_ERR );
                      }
                      else
                      {
                          count++;
                      }
                  }
              }
  
              if( count > 0 )
              {
                  getLogger().info( "Copied " + count +
                                    " empty director" +
                                    ( count == 1 ? "y" : "ies" ) +
                                    " to " + destDir.getAbsolutePath() );
              }
          }
      }
  
      /**
       * Compares source files to destination files to see if they should be
       * copied.
       *
       * @param fromDir Description of Parameter
       * @param toDir Description of Parameter
       * @param files Description of Parameter
       * @param dirs Description of Parameter
       */
      protected void scan( File fromDir, File toDir, String[] files, String[] dirs )
          throws TaskException
      {
          FileNameMapper mapper = null;
          if( mapperElement != null )
          {
              mapper = mapperElement.getImplementation();
          }
          else if( flatten )
          {
              mapper = new FlatFileNameMapper();
          }
          else
          {
              mapper = new IdentityMapper();
          }
  
          buildMap( fromDir, toDir, files, mapper, fileCopyMap );
  
          if( includeEmpty )
          {
              buildMap( fromDir, toDir, dirs, mapper, dirCopyMap );
          }
      }
  
      //************************************************************************
      //  protected and private methods
      //************************************************************************
  
      /**
       * Ensure we have a consistent and legal set of attributes, and set any
       * internal flags necessary based on different combinations of attributes.
       *
       * @exception TaskException Description of Exception
       */
      protected void validateAttributes()
          throws TaskException
      {
          if( file == null && filesets.size() == 0 )
          {
              throw new TaskException( "Specify at least one source - a file or a fileset." );
          }
  
          if( destFile != null && destDir != null )
          {
              throw new TaskException( "Only one of tofile and todir may be set." );
          }
  
          if( destFile == null && destDir == null )
          {
              throw new TaskException( "One of tofile or todir must be set." );
          }
  
          if( file != null && file.exists() && file.isDirectory() )
          {
              throw new TaskException( "Use a fileset to copy directories." );
          }
  
          if( destFile != null && filesets.size() > 0 )
          {
              if( filesets.size() > 1 )
              {
                  throw new TaskException(
                      "Cannot concatenate multiple files into a single file." );
              }
              else
              {
                  FileSet fs = (FileSet)filesets.elementAt( 0 );
                  DirectoryScanner ds = fs.getDirectoryScanner( project );
                  String[] srcFiles = ds.getIncludedFiles();
  
                  if( srcFiles.length > 0 )
                  {
                      if( file == null )
                      {
                          file = new File( srcFiles[ 0 ] );
                          filesets.removeElementAt( 0 );
                      }
                      else
                      {
                          throw new TaskException(
                              "Cannot concatenate multiple files into a single file." );
                      }
                  }
                  else
                  {
                      throw new TaskException(
                          "Cannot perform operation from directory to file." );
                  }
              }
          }
  
          if( destFile != null )
          {
              destDir = new File( destFile.getParent() );// be 1.1 friendly
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/file/Delete.java
  
  Index: Delete.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.tools.ant.taskdefs.file;
  
  import java.io.File;
  import java.util.Vector;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.taskdefs.MatchingTask;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.types.PatternSet;
  
  /**
   * Deletes a file or directory, or set of files defined by a fileset. The
   * original delete task would delete a file, or a set of files using the
   * include/exclude syntax. The deltree task would delete a directory tree. This
   * task combines the functionality of these two originally distinct tasks. <p>
   *
   * Currently Delete extends MatchingTask. This is intend <i>only</i> to provide
   * backwards compatibility for a release. The future position is to use nested
   * filesets exclusively.</p>
   *
   * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">
   *      stefano@apache.org</a>
   * @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>
   * @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com
   *      </a>
   * @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a>
   */
  public class Delete extends MatchingTask
  {
      protected File file = null;
      protected File dir = null;
      protected Vector filesets = new Vector();
      protected boolean usedMatchingTask = false;
      protected boolean includeEmpty = false;// by default, remove matching empty dirs
  
      private int verbosity = Project.MSG_VERBOSE;
      private boolean quiet = false;
      private boolean failonerror = true;
  
      /**
       * Sets whether default exclusions should be used or not.
       *
       * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
       *      should be used, "false"|"off"|"no" when they shouldn't be used.
       */
      public void setDefaultexcludes( boolean useDefaultExcludes )
      {
          usedMatchingTask = true;
          super.setDefaultexcludes( useDefaultExcludes );
      }
  
      /**
       * Set the directory from which files are to be deleted
       *
       * @param dir the directory path.
       */
      public void setDir( File dir )
      {
          this.dir = dir;
      }
  
      /**
       * Sets the set of exclude patterns. Patterns may be separated by a comma or
       * a space.
       *
       * @param excludes the string containing the exclude patterns
       */
      public void setExcludes( String excludes )
          throws TaskException
      {
          usedMatchingTask = true;
          super.setExcludes( excludes );
      }
  
      /**
       * Sets the name of the file containing the includes patterns.
       *
       * @param excludesfile A string containing the filename to fetch the include
       *      patterns from.
       */
      public void setExcludesfile( File excludesfile )
          throws TaskException
      {
          usedMatchingTask = true;
          super.setExcludesfile( excludesfile );
      }
  
      /**
       * this flag means 'note errors to the output, but keep going'
       *
       * @param failonerror true or false
       */
      public void setFailOnError( boolean failonerror )
      {
          this.failonerror = failonerror;
      }
  
      /**
       * Set the name of a single file to be removed.
       *
       * @param file the file to be deleted
       */
      public void setFile( File file )
      {
          this.file = file;
      }
  
      /**
       * Used to delete empty directories.
       *
       * @param includeEmpty The new IncludeEmptyDirs value
       */
      public void setIncludeEmptyDirs( boolean includeEmpty )
      {
          this.includeEmpty = includeEmpty;
      }
  
      /**
       * Sets the set of include patterns. Patterns may be separated by a comma or
       * a space.
       *
       * @param includes the string containing the include patterns
       */
      public void setIncludes( String includes )
          throws TaskException
      {
          usedMatchingTask = true;
          super.setIncludes( includes );
      }
  
      /**
       * Sets the name of the file containing the includes patterns.
       *
       * @param includesfile A string containing the filename to fetch the include
       *      patterns from.
       */
      public void setIncludesfile( File includesfile )
          throws TaskException
      {
          usedMatchingTask = true;
          super.setIncludesfile( includesfile );
      }
  
      /**
       * If the file does not exist, do not display a diagnostic message or modify
       * the exit status to reflect an error. This means that if a file or
       * directory cannot be deleted, then no error is reported. This setting
       * emulates the -f option to the Unix &quot;rm&quot; command. Default is
       * false meaning things are &quot;noisy&quot;
       *
       * @param quiet "true" or "on"
       */
      public void setQuiet( boolean quiet )
      {
          this.quiet = quiet;
          if( quiet )
          {
              this.failonerror = false;
          }
      }
  
      /**
       * Used to force listing of all names of deleted files.
       *
       * @param verbose "true" or "on"
       */
      public void setVerbose( boolean verbose )
      {
          if( verbose )
          {
              this.verbosity = Project.MSG_INFO;
          }
          else
          {
              this.verbosity = Project.MSG_VERBOSE;
          }
      }
  
      /**
       * Adds a set of files (nested fileset attribute).
       *
       * @param set The feature to be added to the Fileset attribute
       */
      public void addFileset( FileSet set )
      {
          filesets.addElement( set );
      }
  
      /**
       * add a name entry on the exclude list
       *
       * @return Description of the Returned Value
       */
      public PatternSet.NameEntry createExclude()
          throws TaskException
      {
          usedMatchingTask = true;
          return super.createExclude();
      }
  
      /**
       * add a name entry on the include list
       *
       * @return Description of the Returned Value
       */
      public PatternSet.NameEntry createInclude()
          throws TaskException
      {
          usedMatchingTask = true;
          return super.createInclude();
      }
  
      /**
       * add a set of patterns
       *
       * @return Description of the Returned Value
       */
      public PatternSet createPatternSet()
          throws TaskException
      {
          usedMatchingTask = true;
          return super.createPatternSet();
      }
  
      /**
       * Delete the file(s).
       *
       * @exception TaskException Description of Exception
       */
      public void execute()
          throws TaskException
      {
          if( usedMatchingTask )
          {
              getLogger().info( "DEPRECATED - Use of the implicit FileSet is deprecated.  Use a nested fileset element instead." );
          }
  
          if( file == null && dir == null && filesets.size() == 0 )
          {
              throw new TaskException( "At least one of the file or dir attributes, or a fileset element, must be set." );
          }
  
          if( quiet && failonerror )
          {
              throw new TaskException( "quiet and failonerror cannot both be set to true" );
          }
  
          // delete the single file
          if( file != null )
          {
              if( file.exists() )
              {
                  if( file.isDirectory() )
                  {
                      getLogger().info( "Directory " + file.getAbsolutePath() + " cannot be removed using the file attribute.  Use dir instead." );
                  }
                  else
                  {
                      getLogger().info( "Deleting: " + file.getAbsolutePath() );
  
                      if( !file.delete() )
                      {
                          String message = "Unable to delete file " + file.getAbsolutePath();
                          if( failonerror )
                              throw new TaskException( message );
                          else
                              log( message,
                                   quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                      }
                  }
              }
              else
              {
                  log( "Could not find file " + file.getAbsolutePath() + " to delete.",
                       Project.MSG_VERBOSE );
              }
          }
  
          // delete the directory
          if( dir != null && dir.exists() && dir.isDirectory() && !usedMatchingTask )
          {
              /*
               * If verbosity is MSG_VERBOSE, that mean we are doing regular logging
               * (backwards as that sounds).  In that case, we want to print one
               * message about deleting the top of the directory tree.  Otherwise,
               * the removeDir method will handle messages for _all_ directories.
               */
              if( verbosity == Project.MSG_VERBOSE )
              {
                  getLogger().info( "Deleting directory " + dir.getAbsolutePath() );
              }
              removeDir( dir );
          }
  
          // delete the files in the filesets
          for( int i = 0; i < filesets.size(); i++ )
          {
              FileSet fs = (FileSet)filesets.elementAt( i );
              try
              {
                  DirectoryScanner ds = fs.getDirectoryScanner( project );
                  String[] files = ds.getIncludedFiles();
                  String[] dirs = ds.getIncludedDirectories();
                  removeFiles( fs.getDir( project ), files, dirs );
              }
              catch( TaskException be )
              {
                  // directory doesn't exist or is not readable
                  if( failonerror )
                  {
                      throw be;
                  }
                  else
                  {
                      log( be.getMessage(),
                           quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                  }
              }
          }
  
          // delete the files from the default fileset
          if( usedMatchingTask && dir != null )
          {
              try
              {
                  DirectoryScanner ds = super.getDirectoryScanner( dir );
                  String[] files = ds.getIncludedFiles();
                  String[] dirs = ds.getIncludedDirectories();
                  removeFiles( dir, files, dirs );
              }
              catch( TaskException be )
              {
                  // directory doesn't exist or is not readable
                  if( failonerror )
                  {
                      throw be;
                  }
                  else
                  {
                      log( be.getMessage(),
                           quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                  }
              }
          }
      }
  
      //************************************************************************
      //  protected and private methods
      //************************************************************************
  
      protected void removeDir( File d )
          throws TaskException
      {
          String[] list = d.list();
          if( list == null )
              list = new String[ 0 ];
          for( int i = 0; i < list.length; i++ )
          {
              String s = list[ i ];
              File f = new File( d, s );
              if( f.isDirectory() )
              {
                  removeDir( f );
              }
              else
              {
                  log( "Deleting " + f.getAbsolutePath(), verbosity );
                  if( !f.delete() )
                  {
                      String message = "Unable to delete file " + f.getAbsolutePath();
                      if( failonerror )
                          throw new TaskException( message );
                      else
                          log( message,
                               quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                  }
              }
          }
          log( "Deleting directory " + d.getAbsolutePath(), verbosity );
          if( !d.delete() )
          {
              String message = "Unable to delete directory " + dir.getAbsolutePath();
              if( failonerror )
                  throw new TaskException( message );
              else
                  log( message,
                       quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
          }
      }
  
      /**
       * remove an array of files in a directory, and a list of subdirectories
       * which will only be deleted if 'includeEmpty' is true
       *
       * @param d directory to work from
       * @param files array of files to delete; can be of zero length
       * @param dirs array of directories to delete; can of zero length
       */
      protected void removeFiles( File d, String[] files, String[] dirs )
          throws TaskException
      {
          if( files.length > 0 )
          {
              getLogger().info( "Deleting " + files.length + " files from " + d.getAbsolutePath() );
              for( int j = 0; j < files.length; j++ )
              {
                  File f = new File( d, files[ j ] );
                  log( "Deleting " + f.getAbsolutePath(), verbosity );
                  if( !f.delete() )
                  {
                      String message = "Unable to delete file " + f.getAbsolutePath();
                      if( failonerror )
                          throw new TaskException( message );
                      else
                          log( message,
                               quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                  }
              }
          }
  
          if( dirs.length > 0 && includeEmpty )
          {
              int dirCount = 0;
              for( int j = dirs.length - 1; j >= 0; j-- )
              {
                  File dir = new File( d, dirs[ j ] );
                  String[] dirFiles = dir.list();
                  if( dirFiles == null || dirFiles.length == 0 )
                  {
                      log( "Deleting " + dir.getAbsolutePath(), verbosity );
                      if( !dir.delete() )
                      {
                          String message = "Unable to delete directory "
                              + dir.getAbsolutePath();
                          if( failonerror )
                              throw new TaskException( message );
                          else
                              log( message,
                                   quiet ? Project.MSG_VERBOSE : Project.MSG_WARN );
                      }
                      else
                      {
                          dirCount++;
                      }
                  }
              }
  
              if( dirCount > 0 )
              {
                  getLogger().info( "Deleted " + dirCount + " director" +
                       ( dirCount == 1 ? "y" : "ies" ) +
                       " from " + d.getAbsolutePath() );
              }
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/file/Mkdir.java
  
  Index: Mkdir.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.tools.ant.taskdefs.file;
  
  import java.io.File;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.tools.ant.Task;
  
  /**
   * Creates a given directory.
   *
   * @author duncan@x180.com
   */
  
  public class Mkdir extends Task
  {
  
      private File dir;
  
      public void setDir( File dir )
      {
          this.dir = dir;
      }
  
      public void execute()
          throws TaskException
      {
          if( dir == null )
          {
              throw new TaskException( "dir attribute is required" );
          }
  
          if( dir.isFile() )
          {
              throw new TaskException( "Unable to create directory as a file already exists with that name: " + dir.getAbsolutePath() );
          }
  
          if( !dir.exists() )
          {
              boolean result = dir.mkdirs();
              if( result == false )
              {
                  String msg = "Directory " + dir.getAbsolutePath() + " creation was not " +
                      "successful for an unknown reason";
                  throw new TaskException( msg );
              }
              getLogger().info( "Created dir: " + dir.getAbsolutePath() );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/file/Move.java
  
  Index: Move.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.tools.ant.taskdefs.file;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.Enumeration;
  import org.apache.avalon.excalibur.io.FileUtil;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.util.FileUtils;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.types.FilterSet;
  import org.apache.tools.ant.types.FilterSetCollection;
  
  /**
   * Moves a file or directory to a new file or directory. By default, the
   * destination is overwriten when existing. When overwrite is turned off, then
   * files are only moved if the source file is newer than the destination file,
   * or when the destination file does not exist.</p> <p>
   *
   * Source files and directories are only deleted when the file or directory has
   * been copied to the destination successfully. Filtering also works.</p> <p>
   *
   * This implementation is based on Arnout Kuiper's initial design document, the
   * following mailing list discussions, and the copyfile/copydir tasks.</p>
   *
   * @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>
   */
  public class Move extends Copy
  {
  
      public Move()
      {
          super();
          forceOverwrite = true;
      }
  
      /**
       * Go and delete the directory tree.
       *
       * @param d Description of Parameter
       */
      protected void deleteDir( File d )
          throws TaskException
      {
          String[] list = d.list();
          if( list == null )
              return;// on an io error list() can return null
  
          for( int i = 0; i < list.length; i++ )
          {
              String s = list[ i ];
              File f = new File( d, s );
              if( f.isDirectory() )
              {
                  deleteDir( f );
              }
              else
              {
                  throw new TaskException( "UNEXPECTED ERROR - The file " + f.getAbsolutePath() + " should not exist!" );
              }
          }
          log( "Deleting directory " + d.getAbsolutePath(), verbosity );
          if( !d.delete() )
          {
              throw new TaskException( "Unable to delete directory " + d.getAbsolutePath() );
          }
      }
  
      //************************************************************************
      //  protected and private methods
      //************************************************************************
  
      protected void doFileOperations()
          throws TaskException
      {
          //Attempt complete directory renames, if any, first.
          if( completeDirMap.size() > 0 )
          {
              Enumeration e = completeDirMap.keys();
              while( e.hasMoreElements() )
              {
                  File fromDir = (File)e.nextElement();
                  File toDir = (File)completeDirMap.get( fromDir );
                  try
                  {
                      log( "Attempting to rename dir: " + fromDir +
                           " to " + toDir, verbosity );
                      renameFile( fromDir, toDir, filtering, forceOverwrite );
                  }
                  catch( IOException ioe )
                  {
                      String msg = "Failed to rename dir " + fromDir
                          + " to " + toDir
                          + " due to " + ioe.getMessage();
                      throw new TaskException( msg, ioe );
                  }
              }
          }
          if( fileCopyMap.size() > 0 )
          {// files to move
              getLogger().info( "Moving " + fileCopyMap.size() + " files to " +
                                destDir.getAbsolutePath() );
  
              Enumeration e = fileCopyMap.keys();
              while( e.hasMoreElements() )
              {
                  String fromFile = (String)e.nextElement();
                  String toFile = (String)fileCopyMap.get( fromFile );
  
                  if( fromFile.equals( toFile ) )
                  {
                      log( "Skipping self-move of " + fromFile, verbosity );
                      continue;
                  }
  
                  boolean moved = false;
                  File f = new File( fromFile );
  
                  if( f.exists() )
                  {//Is this file still available to be moved?
                      File d = new File( toFile );
  
                      try
                      {
                          log( "Attempting to rename: " + fromFile +
                               " to " + toFile, verbosity );
                          moved = renameFile( f, d, filtering, forceOverwrite );
                      }
                      catch( IOException ioe )
                      {
                          String msg = "Failed to rename " + fromFile
                              + " to " + toFile
                              + " due to " + ioe.getMessage();
                          throw new TaskException( msg, ioe );
                      }
  
                      if( !moved )
                      {
                          try
                          {
                              log( "Moving " + fromFile + " to " + toFile, verbosity );
  
                              FilterSetCollection executionFilters = new FilterSetCollection();
                              if( filtering )
                              {
                                  executionFilters.addFilterSet( project.getGlobalFilterSet() );
                              }
                              for( Enumeration filterEnum = getFilterSets().elements(); filterEnum.hasMoreElements(); )
                              {
                                  executionFilters.addFilterSet( (FilterSet)filterEnum.nextElement() );
                              }
  
                              if( forceOverwrite )
                              {
                                  FileUtil.forceDelete( d );
                              }
                              FileUtils.newFileUtils().copyFile( f, d, executionFilters );
  
                              f = new File( fromFile );
                              if( !f.delete() )
                              {
                                  throw new TaskException( "Unable to delete file "
                                                           + f.getAbsolutePath() );
                              }
                          }
                          catch( IOException ioe )
                          {
                              String msg = "Failed to copy " + fromFile + " to "
                                  + toFile
                                  + " due to " + ioe.getMessage();
                              throw new TaskException( msg, ioe );
                          }
                      }
                  }
              }
          }
  
          if( includeEmpty )
          {
              Enumeration e = dirCopyMap.elements();
              int count = 0;
              while( e.hasMoreElements() )
              {
                  File d = new File( (String)e.nextElement() );
                  if( !d.exists() )
                  {
                      if( !d.mkdirs() )
                      {
                          log( "Unable to create directory " + d.getAbsolutePath(), Project.MSG_ERR );
                      }
                      else
                      {
                          count++;
                      }
                  }
              }
  
              if( count > 0 )
              {
                  getLogger().info( "Moved " + count + " empty directories to " + destDir.getAbsolutePath() );
              }
          }
  
          if( filesets.size() > 0 )
          {
              Enumeration e = filesets.elements();
              while( e.hasMoreElements() )
              {
                  FileSet fs = (FileSet)e.nextElement();
                  File dir = fs.getDir( project );
  
                  if( okToDelete( dir ) )
                  {
                      deleteDir( dir );
                  }
              }
          }
      }
  
      /**
       * Its only ok to delete a directory tree if there are no files in it.
       *
       * @param d Description of Parameter
       * @return Description of the Returned Value
       */
      protected boolean okToDelete( File d )
      {
          String[] list = d.list();
          if( list == null )
              return false;// maybe io error?
  
          for( int i = 0; i < list.length; i++ )
          {
              String s = list[ i ];
              File f = new File( d, s );
              if( f.isDirectory() )
              {
                  if( !okToDelete( f ) )
                      return false;
              }
              else
              {
                  return false;// found a file
              }
          }
  
          return true;
      }
  
      /**
       * Attempts to rename a file from a source to a destination. If overwrite is
       * set to true, this method overwrites existing file even if the destination
       * file is newer. Otherwise, the source file is renamed only if the
       * destination file is older than it. Method then checks if token filtering
       * is used. If it is, this method returns false assuming it is the
       * responsibility to the copyFile method.
       *
       * @param sourceFile Description of Parameter
       * @param destFile Description of Parameter
       * @param filtering Description of Parameter
       * @param overwrite Description of Parameter
       * @return Description of the Returned Value
       * @exception TaskException Description of Exception
       * @throws IOException
       */
      protected boolean renameFile( File sourceFile, File destFile,
                                    boolean filtering, boolean overwrite )
          throws IOException, TaskException
      {
  
          boolean renamed = true;
          if( !filtering )
          {
              // ensure that parent dir of dest file exists!
              // not using getParentFile method to stay 1.1 compat
              String parentPath = destFile.getParent();
              if( parentPath != null )
              {
                  File parent = new File( parentPath );
                  if( !parent.exists() )
                  {
                      parent.mkdirs();
                  }
              }
  
              if( destFile.exists() )
              {
                  if( !destFile.delete() )
                  {
                      throw new TaskException( "Unable to remove existing file "
                                               + destFile );
                  }
              }
              renamed = sourceFile.renameTo( destFile );
          }
          else
          {
              renamed = false;
          }
          return renamed;
      }
  }
  
  
  
  1.7       +1 -1      jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/IContract.java
  
  Index: IContract.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/IContract.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- IContract.java	2001/12/16 05:44:55	1.6
  +++ IContract.java	2001/12/17 10:55:23	1.7
  @@ -22,7 +22,7 @@
   import org.apache.tools.ant.taskdefs.Java;
   import org.apache.tools.ant.taskdefs.Javac;
   import org.apache.tools.ant.taskdefs.MatchingTask;
  -import org.apache.tools.ant.taskdefs.Mkdir;
  +import org.apache.tools.ant.taskdefs.file.Mkdir;
   import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
   import org.apache.tools.ant.types.Path;
   import org.apache.tools.ant.types.Reference;
  
  
  

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