ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/nativelib Exec.java LoadEnvironment.java OsCondition.java Resources.properties
Date Sun, 14 Apr 2002 10:56:04 GMT
donaldp     02/04/14 03:56:03

  Added:       antlib/src/java/org/apache/antlib/cvslib CVSEntry.java
                        CVSPass.java ChangeLog.java ChangeLogParser.java
                        ChangeLogWriter.java Cvs.java CvsUser.java
                        RCSFile.java Resources.properties
               antlib/src/java/org/apache/antlib/dotnet CSharp.java
                        Ilasm.java
               antlib/src/java/org/apache/antlib/file CopyTask.java
                        Delete.java FilteredCopyTask.java ListPathTask.java
                        Mkdir.java MoveTask.java Resources.properties
                        Touch.java
               antlib/src/java/org/apache/antlib/java
                        ExternalCompilerAdaptor.java
                        JavaCompilerAdaptor.java JavaTask.java
                        JavacAdaptor.java JavacTask.java JikesAdaptor.java
               antlib/src/java/org/apache/antlib/nativelib Exec.java
                        LoadEnvironment.java OsCondition.java
                        Resources.properties
  Log:
  More tasks
  
  Revision  Changes    Path
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/CVSEntry.java
  
  Index: CVSEntry.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.util.ArrayList;
  import java.util.Date;
  
  /**
   * CVS Entry.
   *
   * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   */
  class CVSEntry
  {
      private Date m_date;
      private final String m_author;
      private final String m_comment;
      private final ArrayList m_files = new ArrayList();
  
      public CVSEntry( Date date, String author, String comment )
      {
          m_date = date;
          m_author = author;
          m_comment = comment;
      }
  
      public void addFile( String file, String revision )
      {
          m_files.add( new RCSFile( file, revision ) );
      }
  
      public void addFile( String file, String revision, String previousRevision )
      {
          m_files.add( new RCSFile( file, revision, previousRevision ) );
      }
  
      Date getDate()
      {
          return m_date;
      }
  
      String getAuthor()
      {
          return m_author;
      }
  
      String getComment()
      {
          return m_comment;
      }
  
      ArrayList getFiles()
      {
          return m_files;
      }
  
      public String toString()
      {
          return getAuthor() + "\n" + getDate() + "\n" + getFiles() + "\n" + getComment();
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/CVSPass.java
  
  Index: CVSPass.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileReader;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.util.StringUtil;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * CVSLogin Adds an new entry to a CVS password file
   *
   * @author <a href="jeff@custommonkey.org">Jeff Martin</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   * @ant.task name="cvs-pass"
   */
  public class CVSPass
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( CVSPass.class );
  
      /**
       * CVS Root
       */
      private String m_cvsRoot;
  
      /**
       * Password file to add password to
       */
      private File m_passwordFile;
  
      /**
       * Password to add to file
       */
      private String m_password;
  
      /**
       * Array contain char conversion data
       */
      private static final char[] c_shifts = new char[]
      {
          0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
          16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
          114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87,
          111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105,
          41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35,
          125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56,
          36, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,
          58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223,
          225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190,
          199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193,
          174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212,
          207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246,
          192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176,
          227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127,
          182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195,
          243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152
      };
  
      public CVSPass()
      {
          final String location = System.getProperty( "user.home" ) + "/.cvspass";
          m_passwordFile = new File( location );
      }
  
      /**
       * Sets cvs root to be added to the password file
       */
      public void setCvsroot( final String cvsRoot )
      {
          m_cvsRoot = cvsRoot;
      }
  
      /**
       * Sets the password file attribute.
       */
      public void setPassfile( final File passFile )
      {
          m_passwordFile = passFile;
      }
  
      /**
       * Sets the password attribute.
       */
      public void setPassword( final String password )
      {
          m_password = password;
      }
  
      /**
       * Does the work.
       *
       * @exception TaskException if someting goes wrong with the build
       */
      public final void execute()
          throws TaskException
      {
          validate();
  
          notify( "root", m_cvsRoot );
          notify( "password", m_password );
          notify( "passFile", m_passwordFile );
  
          //FIXME: Should not be writing the whole file - Just append to the file
          //Also should have EOL configurable
          try
          {
              final StringBuffer sb = new StringBuffer();
              if( m_passwordFile.exists() )
              {
                  final BufferedReader reader =
                      new BufferedReader( new FileReader( m_passwordFile ) );
  
                  String line = null;
  
                  while( ( line = reader.readLine() ) != null )
                  {
                      if( !line.startsWith( m_cvsRoot ) )
                      {
                          sb.append( line + StringUtil.LINE_SEPARATOR );
                      }
                  }
  
                  reader.close();
              }
  
              final String pwdfile =
                  sb.toString() + m_cvsRoot + " A" + mangle( m_password );
  
              notify( "write", pwdfile );
  
              final PrintWriter writer =
                  new PrintWriter( new FileWriter( m_passwordFile ) );
  
              writer.println( pwdfile );
  
              writer.close();
          }
          catch( final IOException ioe )
          {
              throw new TaskException( ioe.toString(), ioe );
          }
      }
  
      /**
       * Utility method that looks specified key up in resources and
       * prints it out adding specified value as param.
       *
       * @param key the key into resource file
       * @param value the accompanying value
       */
      private void notify( final String key, final Object value )
      {
          final String message = REZ.getString( "cvspass." + key + ".notice", value );
          getContext().debug( message );
      }
  
      /**
       * Validate the attributes of the task.
       *
       * @throws TaskException if invalid parameters supplied
       */
      private void validate() throws TaskException
      {
          if( null == m_cvsRoot )
          {
              final String message = REZ.getString( "cvspass.noroot.error" );
              throw new TaskException( message );
          }
  
          if( null == m_password )
          {
              final String message = REZ.getString( "cvspass.nopassword.error" );
              throw new TaskException( message );
          }
      }
  
      /**
       * This encoding method and the accompanying LUT should
       * be pushed into another method ... somewhere.
       */
      private final String mangle( final String password )
      {
          final int size = password.length();
  
          final StringBuffer sb = new StringBuffer();
          for( int i = 0; i < size; i++ )
          {
              sb.append( c_shifts[ password.charAt( i ) ] );
          }
          return sb.toString();
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/ChangeLog.java
  
  Index: ChangeLog.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.io.UnsupportedEncodingException;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.Vector;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.io.IOUtil;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.myrmidon.framework.nativelib.Commandline;
  
  /**
   * Change log task.
   * The task will examine the output of cvs log and group related changes together.
   * It produces an XML output representing the list of changes.
   * <PRE>
   * <FONT color=#0000ff>&lt;!-- Root element --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> changelog <FONT color=#ff00ff>(entry</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- CVS Entry --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> entry <FONT color=#ff00ff>(date,author,file</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>,msg)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- Date of cvs entry --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> date <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- Author of change --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> author <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- List of files affected --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> msg <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- File changed --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> file <FONT color=#ff00ff>(name,revision,prevrevision</FONT><FONT color=#ff00ff>?</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- Name of the file --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> name <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- Revision number --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> revision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * <FONT color=#0000ff>&lt;!-- Previous revision number --&gt;</FONT>
   * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> prevrevision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
   * </PRE>
   *
   * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   * @ant.task name="changelog"
   */
  public class ChangeLog
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( ChangeLog.class );
  
      /** User list */
      private File m_usersFile;
  
      /** User list */
      private Vector m_cvsUsers = new Vector();
  
      /** Input dir */
      private File m_dir;
  
      /** Output file */
      private File m_destfile;
  
      /**
       * The earliest date at which to start processing entrys.
       */
      private Date m_start;
  
      /**
       * The latest date at which to stop processing entrys.
       */
      private Date m_stop;
  
      /**
       * Filesets containting list of files against which the cvs log will be
       * performed. If empty then all files will in the working directory will
       * be checked.
       */
      private final Vector m_filesets = new Vector();
  
      /**
       * Set the base dir for cvs.
       */
      public void setDir( final File dir )
      {
          m_dir = dir;
      }
  
      /**
       * Set the output file for the log.
       */
      public void setDestfile( final File destfile )
      {
          m_destfile = destfile;
      }
  
      /**
       * Set a lookup list of user names & addresses
       */
      public void setUsersfile( final File usersFile )
      {
          m_usersFile = usersFile;
      }
  
      /**
       * Add a user to list changelog knows about.
       *
       * @param user the user
       */
      public void addUser( final CvsUser user )
      {
          m_cvsUsers.addElement( user );
      }
  
      /**
       * Set the date at which the changelog should start.
       *
       * @param start The date at which the changelog should start.
       */
      public void setStart( final Date start )
      {
          m_start = start;
      }
  
      /**
       * Set the date at which the changelog should stop.
       *
       * @param stop The date at which the changelog should stop.
       */
      public void setEnd( final Date stop )
      {
          m_stop = stop;
      }
  
      /**
       * Set the numbers of days worth of log entries to process.
       */
      public void setDaysinpast( final int days )
      {
          final long time = System.currentTimeMillis() - (long)days * 24 * 60 * 60 * 1000;
          setStart( new Date( time ) );
      }
  
      /**
       * Adds a set of files about which cvs logs will be generated.
       *
       * @param fileSet a set of files about which cvs logs will be generated.
       */
      public void addFileset( final FileSet fileSet )
      {
          m_filesets.addElement( fileSet );
      }
  
      /**
       * Execute task
       */
      public void execute() throws TaskException
      {
          validate();
  
          final Properties userList = new Properties();
  
          loadUserlist( userList );
  
          for( Enumeration e = m_cvsUsers.elements(); e.hasMoreElements(); )
          {
              final CvsUser user = (CvsUser)e.nextElement();
              user.validate();
              userList.put( user.getUserID(), user.getDisplayname() );
          }
  
          final Execute exe = new Execute();
          exe.setWorkingDirectory( m_dir );
          exe.setExecutable( "cvs" );
  
          exe.addArgument( "log" );
  
          if( null != m_start )
          {
              final SimpleDateFormat outputDate =
                  new SimpleDateFormat( "yyyy-MM-dd" );
  
              // We want something of the form: -d ">=YYYY-MM-dd"
              final String dateRange = "-d >=" + outputDate.format( m_start );
              exe.addArgument( dateRange );
          }
  
          // Check if list of files to check has been specified
          /*
          if( !m_filesets.isEmpty() )
          {
              final Enumeration e = m_filesets.elements();
              while( e.hasMoreElements() )
              {
                  final FileSet fileSet = (FileSet)e.nextElement();
                  //FIXME: DOES NOT WORK
                  final DirectoryScanner scanner = new DirectoryScanner();
                  //fileSet.getDirectoryScanner( null );
                  final String[] files = scanner.getIncludedFiles();
                  for( int i = 0; i < files.length; i++ )
                  {
                      command.addArgument( files[ i ] );
                  }
              }
          }
          */
  
          final ChangeLogParser parser = new ChangeLogParser( userList, getContext() );
          exe.setExecOutputHandler( parser );
          exe.execute( getContext() );
  
          final CVSEntry[] entrySet = parser.getEntrySetAsArray();
          final CVSEntry[] filteredEntrySet = filterEntrySet( entrySet );
          writeChangeLog( filteredEntrySet );
      }
  
      /**
       * Validate the parameters specified for task.
       *
       * @throws TaskException if fails validation checks
       */
      private void validate()
          throws TaskException
      {
          if( null == m_dir )
          {
              m_dir = getContext().getBaseDirectory();
          }
          if( null == m_destfile )
          {
              final String message = REZ.getString( "changelog.missing-destfile.error" );
              throw new TaskException( message );
          }
          if( !m_dir.exists() )
          {
              final String message =
                  REZ.getString( "changelog.bad-basedir.error", m_dir.getAbsolutePath() );
              throw new TaskException( message );
          }
          if( null != m_usersFile && !m_usersFile.exists() )
          {
              final String message =
                  REZ.getString( "changelog.bad-userlist.error", m_usersFile.getAbsolutePath() );
              throw new TaskException( message );
          }
      }
  
      /**
       * Load the userli4st from the userList file (if specified) and
       * add to list of users.
       *
       * @throws TaskException if file can not be loaded for some reason
       */
      private void loadUserlist( final Properties userList )
          throws TaskException
      {
          if( null != m_usersFile )
          {
              try
              {
                  userList.load( new FileInputStream( m_usersFile ) );
              }
              catch( final IOException ioe )
              {
                  throw new TaskException( ioe.toString(), ioe );
              }
          }
      }
  
      /**
       * Filter the specified entrys accoridn to an appropriate
       * rule.
       *
       * @param entrySet the entry set to filter
       * @return the filtered entry set
       */
      private CVSEntry[] filterEntrySet( final CVSEntry[] entrySet )
      {
          final ArrayList results = new ArrayList();
          for( int i = 0; i < entrySet.length; i++ )
          {
              final CVSEntry cvsEntry = entrySet[ i ];
              final Date date = cvsEntry.getDate();
              if( null != m_start && m_start.after( date ) )
              {
                  //Skip dates that are too early
                  continue;
              }
              if( null != m_stop && m_stop.before( date ) )
              {
                  //Skip dates that are too late
                  continue;
              }
              results.add( cvsEntry );
          }
  
          return (CVSEntry[])results.toArray( new CVSEntry[ results.size() ] );
      }
  
      /**
       * Print changelog to file specified in task.
       *
       * @throws TaskException if theres an error writing changelog
       */
      private void writeChangeLog( final CVSEntry[] entrySet )
          throws TaskException
      {
          FileOutputStream output = null;
          try
          {
              output = new FileOutputStream( m_destfile );
              final PrintWriter writer =
                  new PrintWriter( new OutputStreamWriter( output, "UTF-8" ) );
  
              ChangeLogWriter serializer = new ChangeLogWriter();
              serializer.printChangeLog( writer, entrySet );
          }
          catch( final UnsupportedEncodingException uee )
          {
              getContext().error( uee.toString(), uee );
          }
          catch( final IOException ioe )
          {
              throw new TaskException( ioe.toString(), ioe );
          }
          finally
          {
              IOUtil.shutdownStream( output );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/ChangeLogParser.java
  
  Index: ChangeLogParser.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Hashtable;
  import java.util.Properties;
  import org.apache.aut.nativelib.ExecOutputHandler;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.TaskContext;
  
  /**
   * A class used to parse the output of the CVS log command.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   */
  class ChangeLogParser
      implements ExecOutputHandler
  {
      private final static Resources REZ =
          ResourceManager.getPackageResources( ChangeLogParser.class );
  
      //private static final int GET_ENTRY = 0;
      private static final int GET_FILE = 1;
      private static final int GET_DATE = 2;
      private static final int GET_COMMENT = 3;
      private static final int GET_REVISION = 4;
      private static final int GET_PREVIOUS_REV = 5;
  
      /** input format for dates read in from cvs log */
      private static final SimpleDateFormat c_inputDate = new SimpleDateFormat( "yyyy/MM/dd hh:mm:ss" );
  
      //The following is data used while processing stdout of CVS command
      private String m_file;
      private String m_date;
      private String m_author;
      private String m_comment;
      private String m_revision;
      private String m_previousRevision;
  
      private int m_status = GET_FILE;
  
      private final TaskContext m_context;
  
      /** rcs entries */
      private final Hashtable m_entries = new Hashtable();
  
      private final Properties m_userList;
  
      /**
       * Construct a parser that uses specified user list.
       *
       * @param userList the userlist
       */
      ChangeLogParser( final Properties userList,
                       final TaskContext context )
      {
          m_userList = userList;
          m_context = context;
      }
  
      /**
       * Get a list of rcs entrys as an array.
       *
       * @return a list of rcs entrys as an array
       */
      CVSEntry[] getEntrySetAsArray()
      {
          final CVSEntry[] array = new CVSEntry[ m_entries.values().size() ];
          return (CVSEntry[])m_entries.values().toArray( array );
      }
  
      /**
       * Receive notification about the process writing
       * to standard error.
       */
      public void stderr( String line )
      {
          m_context.error( line );
      }
  
      /**
       * Receive notification about the process writing
       * to standard output.
       */
      public void stdout( final String line )
      {
          switch( m_status )
          {
              case GET_FILE:
                  processFile( line );
                  break;
              case GET_REVISION:
                  processRevision( line );
                  break;
  
              case GET_DATE:
                  processDate( line );
                  break;
  
              case GET_COMMENT:
                  processComment( line );
                  break;
  
              case GET_PREVIOUS_REV:
                  processGetPreviousRevision( line );
                  break;
          }
      }
  
      /**
       * Process a line while in "GET_COMMENT" state.
       *
       * @param line the line
       */
      private void processComment( final String line )
      {
          final String lineSeparator = System.getProperty( "line.separator" );
          if( line.startsWith( "======" ) )
          {
              //We have ended changelog for that particular file
              //so we can save it
              final int end = m_comment.length() - lineSeparator.length(); //was -1
              m_comment = m_comment.substring( 0, end );
              saveEntry();
              m_status = GET_FILE;
          }
          else if( line.startsWith( "------" ) )
          {
              final int end = m_comment.length() - lineSeparator.length(); //was -1
              m_comment = m_comment.substring( 0, end );
              m_status = GET_PREVIOUS_REV;
          }
          else
          {
              m_comment += line + lineSeparator;
          }
      }
  
      /**
       * Process a line while in "GET_FILE" state.
       *
       * @param line the line
       */
      private void processFile( final String line )
      {
          if( line.startsWith( "Working file:" ) )
          {
              m_file = line.substring( 14, line.length() );
              m_status = GET_REVISION;
          }
      }
  
      /**
       * Process a line while in "REVISION" state.
       *
       * @param line the line
       */
      private void processRevision( final String line )
      {
          if( line.startsWith( "revision" ) )
          {
              m_revision = line.substring( 9 );
              m_status = GET_DATE;
          }
          else if( line.startsWith( "======" ) )
          {
              //There was no revisions in this changelog
              //entry so lets move unto next file
              m_status = GET_FILE;
          }
      }
  
      /**
       * Process a line while in "DATE" state.
       *
       * @param line the line
       */
      private void processDate( final String line )
      {
          if( line.startsWith( "date:" ) )
          {
              m_date = line.substring( 6, 25 );
              String lineData = line.substring( line.indexOf( ";" ) + 1 );
              m_author = lineData.substring( 10, lineData.indexOf( ";" ) );
  
              if( m_userList.containsKey( m_author ) )
              {
                  m_author = m_userList.getProperty( m_author );
              }
  
              m_status = GET_COMMENT;
  
              //Reset comment to empty here as we can accumulate multiple lines
              //in the processComment method
              m_comment = "";
          }
      }
  
      /**
       * Process a line while in "GET_PREVIOUS_REVISION" state.
       *
       * @param line the line
       */
      private void processGetPreviousRevision( final String line )
      {
          if( !line.startsWith( "revision" ) )
          {
              final String message =
                  REZ.getString( "changelog.unexpected.line", line );
              throw new IllegalStateException( message );
          }
          m_previousRevision = line.substring( 9 );
  
          saveEntry();
  
          m_revision = m_previousRevision;
          m_status = GET_DATE;
      }
  
      /**
       * Utility method that saves the current entry.
       */
      private void saveEntry()
      {
          final String entryKey = m_date + m_author + m_comment;
          CVSEntry entry;
          if( !m_entries.containsKey( entryKey ) )
          {
              entry = new CVSEntry( parseDate( m_date ), m_author, m_comment );
              m_entries.put( entryKey, entry );
          }
          else
          {
              entry = (CVSEntry)m_entries.get( entryKey );
          }
  
          entry.addFile( m_file, m_revision, m_previousRevision );
      }
  
      /**
       * Parse date out from expected format.
       *
       * @param date the string holding dat
       * @return the date object or null if unknown date format
       */
      private Date parseDate( final String date )
      {
          try
          {
              return c_inputDate.parse( date );
          }
          catch( ParseException e )
          {
              //final String message = REZ.getString( "changelog.bat-date.error", date );
              //getContext().error( message );
              return null;
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/ChangeLogWriter.java
  
  Index: ChangeLogWriter.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.io.PrintWriter;
  import java.text.SimpleDateFormat;
  import java.util.Iterator;
  
  /**
   * Class used to generate an XML changelog.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   */
  class ChangeLogWriter
  {
      /** output format for dates writtn to xml file */
      private static final SimpleDateFormat c_outputDate = new SimpleDateFormat( "yyyy-MM-dd" );
      /** output format for times writtn to xml file */
      private static final SimpleDateFormat c_outputTime = new SimpleDateFormat( "hh:mm" );
  
      /**
       * Print out the specifed entrys.
       */
      public void printChangeLog( final PrintWriter output,
                                  final CVSEntry[] entries )
      {
          output.println( "<changelog>" );
          for( int i = 0; i < entries.length; i++ )
          {
              final CVSEntry entry = entries[ i ];
              printEntry( output, entry );
          }
          output.println( "</changelog>" );
          output.flush();
          output.close();
      }
  
      /**
       * Print out an individual entry in changelog.
       *
       * @param entry the entry to print
       */
      private void printEntry( final PrintWriter output, final CVSEntry entry )
      {
          output.println( "\t<entry>" );
          output.println( "\t\t<date>" + c_outputDate.format( entry.getDate() ) + "</date>" );
          output.println( "\t\t<time>" + c_outputTime.format( entry.getDate() ) + "</time>" );
          output.println( "\t\t<author><![CDATA[" + entry.getAuthor() + "]]></author>" );
  
          final Iterator iterator = entry.getFiles().iterator();
          while( iterator.hasNext() )
          {
              final RCSFile file = (RCSFile)iterator.next();
              output.println( "\t\t<file>" );
              output.println( "\t\t\t<name>" + file.getName() + "</name>" );
              output.println( "\t\t\t<revision>" + file.getRevision() + "</revision>" );
  
              final String previousRevision = file.getPreviousRevision();
              if( previousRevision != null )
              {
                  output.println( "\t\t\t<prevrevision>" + previousRevision + "</prevrevision>" );
              }
  
              output.println( "\t\t</file>" );
          }
          output.println( "\t\t<msg><![CDATA[" + entry.getComment() + "]]></msg>" );
          output.println( "\t</entry>" );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/Cvs.java
  
  Index: Cvs.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import java.io.File;
  import java.util.Properties;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.nativelib.Commandline;
  import org.apache.tools.todo.util.FileUtils;
  
  /**
   * Task to interact with a CVS repository.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:costin@dnt.ro">costin@dnt.ro</a>
   * @author <a href="mailto:stefano@apache.org">stefano@apache.org</a>
   * @author <a href="mailto:wwerner@picturesafe.de">Wolfgang Werner</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   * @ant.task name="cvs"
   */
  public class Cvs
      extends AbstractTask
  {
      /**
       * the CVS command to execute.
       */
      private String m_command = "checkout";
  
      /**
       * suppress information messages.
       */
      private boolean m_quiet;
  
      /**
       * report only, don't change any files.
       */
      private boolean m_noexec;
  
      /**
       * CVS port
       */
      private int m_port;
  
      /**
       * CVS password file
       */
      private File m_passwordFile;
  
      /**
       * the CVSROOT variable.
       */
      private String m_cvsRoot;
  
      /**
       * the CVS_RSH variable.
       */
      private String m_cvsRsh;
  
      /**
       * the directory where the checked out files should be placed.
       */
      private File m_dest;
  
      /**
       * the module to check out.
       */
      private String m_module;
  
      /**
       * the date at which to extract files from repository
       */
      private String m_date;
  
      /**
       * the tag with which to extract files from the repository
       */
      private String m_tag;
  
      public void setCommand( final String command )
      {
          m_command = command;
      }
  
      public void setCvsRoot( final String cvsRoot )
      {
          // Check if not real cvsroot => set it to null
          m_cvsRoot = getNonEmptyString( cvsRoot );
      }
  
      public void setCvsRsh( final String cvsRsh )
      {
          // Check if not real cvsrsh => set it to null
          m_cvsRsh = getNonEmptyString( cvsRsh );
      }
  
      public void setDate( final String date )
      {
          m_date = getNonEmptyString( date );
      }
  
      public void setDest( final File dest )
      {
          m_dest = dest;
      }
  
      public void setNoexec( final boolean noexec )
      {
          m_noexec = noexec;
      }
  
      public void setModule( final String module )
      {
          m_module = module;
      }
  
      public void setPassfile( final File passwordFile )
      {
          m_passwordFile = passwordFile;
      }
  
      public void setPort( final int port )
      {
          m_port = port;
      }
  
      public void setQuiet( final boolean quiet )
      {
          m_quiet = quiet;
      }
  
      public void setTag( final String tag )
      {
          m_tag = getNonEmptyString( tag );
      }
  
      public void execute()
          throws TaskException
      {
          final Execute exe = new Execute();
          buildCommandline( exe );
          final Properties env = buildEnvironment();
  
          exe.setWorkingDirectory( m_dest );
          exe.setEnvironment( env );
          exe.execute( getContext() );
      }
  
      private Properties buildEnvironment()
      {
          final Properties env = new Properties();
          if( 0 < m_port )
          {
              env.setProperty( "CVS_CLIENT_PORT", String.valueOf( m_port ) );
          }
  
          if( null != m_passwordFile )
          {
              env.setProperty( "CVS_PASSFILE", String.valueOf( m_passwordFile ) );
          }
  
          if( null != m_cvsRsh )
          {
              env.setProperty( "CVS_RSH", String.valueOf( m_cvsRsh ) );
          }
          return env;
      }
  
      private void buildCommandline( final Commandline command ) throws TaskException
      {
          command.setExecutable( "cvs" );
          if( m_cvsRoot != null )
          {
              command.addArgument( "-d" );
              command.addArgument( m_cvsRoot );
          }
  
          if( m_noexec )
          {
              command.addArgument( "-n" );
          }
  
          if( m_quiet )
          {
              command.addArgument( "-q" );
          }
  
          command.addArguments( FileUtils.translateCommandline( m_command ) );
  
          if( null != m_date )
          {
              command.addArgument( "-D" );
              command.addArgument( m_date );
          }
  
          if( null != m_tag )
          {
              command.addArgument( "-r" );
              command.addArgument( m_tag );
          }
  
          if( m_module != null )
          {
              command.addArguments( FileUtils.translateCommandline( m_module ) );
          }
      }
  
      private String getNonEmptyString( final String value )
      {
          if( isEmpty( value ) )
          {
              return null;
          }
          else
          {
              return value;
          }
      }
  
      private boolean isEmpty( final String value )
      {
          return ( null == value ) || ( 0 == value.trim().length() );
      }
  }
  
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/CvsUser.java
  
  Index: CvsUser.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  import org.apache.myrmidon.api.TaskException;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  
  /**
   * Represents a CVS user with a userID and a full name.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:02 $
   */
  public class CvsUser
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( CvsUser.class );
  
      private String m_userID;
      private String m_displayName;
  
      public void setDisplayname( final String displayName )
      {
          m_displayName = displayName;
      }
  
      public void setUserid( final String userID )
      {
          m_userID = userID;
      }
  
      String getUserID()
      {
          return m_userID;
      }
  
      String getDisplayname()
      {
          return m_displayName;
      }
  
      void validate()
          throws TaskException
      {
          if( null == m_userID )
          {
              final String message = REZ.getString( "changelog.nouserid.error" );
              throw new TaskException( message );
          }
          if( null == m_displayName )
          {
              final String message =
                  REZ.getString( "changelog.nodisplayname.error", m_userID );
              throw new TaskException( message );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/RCSFile.java
  
  Index: RCSFile.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.txt file.
   */
  package org.apache.antlib.cvslib;
  
  /**
   * Represents a RCS File cheange.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  class RCSFile
  {
      private final String m_name;
      private final String m_revision;
      private String m_previousRevision;
  
      RCSFile( final String name, final String rev )
      {
          this( name, rev, null );
      }
  
      RCSFile( final String name,
               final String revision,
               final String previousRevision )
      {
          m_name = name;
          m_revision = revision;
          if( !revision.equals( previousRevision ) )
          {
              m_previousRevision = previousRevision;
          }
      }
  
      String getName()
      {
          return m_name;
      }
  
      String getRevision()
      {
          return m_revision;
      }
  
      String getPreviousRevision()
      {
          return m_previousRevision;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/cvslib/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  changelog.nodisplayname.error=Displayname attribute must be set for userID "{0}".
  changelog.nouserid.error=Username attribute must be set.
  changelog.missing-destfile.error=Destfile must be set.
  changelog.bad-basedir.error=Cannot find base dir {0}
  changelog.bad-userlist.error=Cannot find user lookup list {0}.
  changelog.bat-date.error=I don't understand this date -> {0}
  changelog.unexpected.line=Unexpected line from CVS: {0}
  
  cvspass.nopassword.error=Password is required.
  cvspass.noroot.error=Cvsroot is required.
  cvspass.root.notice=cvsRoot: {0}
  cvspass.password.notice=password: {0}
  cvspass.passFile.notice=passFile: {0}
  cvspass.write.notice=Writing -> {0}
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/dotnet/CSharp.java
  
  Index: CSharp.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.txt file.
   */
  package org.apache.antlib.dotnet;
  
  import java.io.File;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.tools.todo.taskdefs.MatchingTask;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.myrmidon.framework.nativelib.ArgumentList;
  import org.apache.myrmidon.framework.file.Path;
  
  /**
   * This task compiles CSharp source into executables or modules. The task will
   * only work on win2K until other platforms support csc.exe or an equivalent.
   * CSC.exe must be on the execute path too. <p>
   *
   * All parameters are optional: &lt;csc/&gt; should suffice to produce a debug
   * build of all *.cs files. References to external files do require explicit
   * enumeration, so are one of the first attributes to consider adding. <p>
   *
   * The task is a directory based task, so attributes like <b>includes="*.cs"</b>
   * and <b>excludes="broken.cs"</b> can be used to control the files pulled in.
   * By default, all *.cs files from the project folder down are included in the
   * command. When this happens the output file -if not specified- is taken as the
   * first file in the list, which may be somewhat hard to control. Specifying the
   * output file with <b>'outfile'</b> seems prudent. <p>
   *
   * <p>
   *
   * TODO
   * <ol>
   *   <li> is incremental build still broken in beta-1?
   *   <li> is Win32Icon broken?
   *   <li> all the missing options
   * </ol>
   * <p>
   *
   * History
   * <Table>
   *
   *   <tr>
   *
   *     <td>
   *       0.3
   *     </td>
   *
   *     <td>
   *       Beta 1 edition
   *     </td>
   *
   *     <td>
   *       To avoid having to remember which assemblies to include, the task
   *       automatically refers to the main dotnet libraries in Beta1.
   *     </tr>
   *
   *     <tr>
   *
   *       <td>
   *         0.2
   *       </td>
   *
   *       <td>
   *         Slightly different
   *       </td>
   *
   *       <td>
   *         Split command execution to a separate class;
   *       </tr>
   *
   *       <tr>
   *
   *         <td>
   *           0.1
   *         </td>
   *
   *         <td>
   *           "I can't believe it's so rudimentary"
   *         </td>
   *
   *         <td>
   *           First pass; minimal builds only support;
   *         </tr>
   *
   *       </table>
   *
   *
   * @author Steve Loughran steve_l@iseran.com
   * @version 0.3
   */
  public class CSharp
      extends MatchingTask
  {
      /**
       * name of the executable. the .exe suffix is deliberately not included in
       * anticipation of the unix version
       */
      private static final String EXE_NAME = "csc";
  
      /**
       * what is the file extension we search on?
       */
      private static final String FILE_EXT = "cs";
  
      /**
       * derive the search pattern from the extension
       */
      private static final String FILE_PATTERN = "**/*." + FILE_EXT;
  
      /**
       * Fix C# reference inclusion. C# is really dumb in how it handles
       * inclusion. You have to list every 'assembly' -read DLL that is imported.
       * So already you are making a platform assumption -shared libraries have a
       * .dll;"+ extension and the poor developer has to know every library which
       * is included why the compiler cant find classes on the path or in a
       * directory, is a mystery. To reduce the need to be explicit, here is a
       * long list of the core libraries used in Beta-1 of .NET ommitting the
       * blatantly non portable (MS.win32.interop) and the .designer libraries.
       * (ripping out Com was tempting) Casing is chosen to match that of the file
       * system <i>exactly</i> so may work on a unix box too.
       */
  
      private static final String DEFAULT_REFERENCE_LIST =
          "Accessibility.dll;" +
          "cscompmgd.dll;" +
          "CustomMarshalers.dll;" +
          "IEExecRemote.dll;" +
          "IEHost.dll;" +
          "IIEHost.dll;" +
          "ISymWrapper.dll;" +
          "Microsoft.JScript.dll;" +
          "Microsoft.VisualBasic.dll;" +
          "Microsoft.VisualC.dll;" +
          "Microsoft.Vsa.dll;" +
          "Mscorcfg.dll;" +
          "RegCode.dll;" +
          "System.Configuration.Install.dll;" +
          "System.Data.dll;" +
          "System.Design.dll;" +
          "System.DirectoryServices.dll;" +
          "System.EnterpriseServices.dll;" +
          "System.dll;" +
          "System.Drawing.Design.dll;" +
          "System.Drawing.dll;" +
          "System.Management.dll;" +
          "System.Messaging.dll;" +
          "System.Runtime.Remoting.dll;" +
          "System.Runtime.Serialization.Formatters.Soap.dll;" +
          "System.Security.dll;" +
          "System.ServiceProcess.dll;" +
          "System.Web.dll;" +
          "System.Web.RegularExpressions.dll;" +
          "System.Web.Services.dll;" +
          "System.Windows.Forms.dll;" +
          "System.XML.dll;";
  
      /**
       * utf out flag
       */
      private boolean m_utf8output;
  
      private boolean m_fullpaths = true;
  
      /**
       * debug flag. Controls generation of debug information.
       */
      private boolean m_debug = true;
  
      /**
       * output XML documentation flag
       */
      private File m_docFile;
  
      /**
       * any extra command options?
       */
      private String m_extraOptions;
  
      /**
       * flag to enable automatic reference inclusion
       */
      private boolean m_includeDefaultReferences = true;
  
      /**
       * incremental build flag
       */
      private boolean m_incremental;
  
      /**
       * main class (or null for automatic choice)
       */
      private String m_mainClass;
  
      /**
       * optimise flag
       */
      private boolean m_optimize;
  
      /**
       * output file. If not supplied this is derived from the source file
       */
      private File m_outputFile;
  
      /**
       * using the path approach didnt work as it could not handle the implicit
       * execution path. Perhaps that could be extracted from the runtime and then
       * the path approach would be viable
       */
      private Path m_referenceFiles;
  
      /**
       * list of reference classes. (pretty much a classpath equivalent)
       */
      private String m_references;
  
      /**
       * type of target. Should be one of exe|library|module|winexe|(null) default
       * is exe; the actual value (if not null) is fed to the command line. <br>
       * See /target
       */
      private String m_targetType;
  
      /**
       * enable unsafe code flag. Clearly set to false by default
       */
      private boolean m_unsafe;
  
      /**
       * icon for incorporation into apps
       */
      private File m_win32icon;
      /**
       * icon for incorporation into apps
       */
      private File m_win32res;
  
      /**
       * list of extra modules to refer to
       */
      private String m_additionalModules;
  
      /**
       * defines list something like 'RELEASE;WIN32;NO_SANITY_CHECKS;;SOMETHING_ELSE'
       */
      private String m_definitions;
  
      /**
       * destination directory (null means use the source directory) NB: this is
       * currently not used
       */
      private File m_destDir;
  
      /**
       * source directory upon which the search pattern is applied
       */
      private File m_srcDir;
  
      /**
       * warning level: 0-4, with 4 being most verbose
       */
      private int m_warnLevel = 3;
  
      /**
       * constructor inits everything and set up the search pattern
       */
  
      public CSharp()
          throws TaskException
      {
          setIncludes( FILE_PATTERN );
      }
  
      /**
       * Set the definitions
       */
      public void setAdditionalModules( final String additionalModules )
      {
          m_additionalModules = additionalModules;
      }
  
      /**
       * set the debug flag on or off
       *
       * @param debug on/off flag
       */
      public void setDebug( final boolean debug )
      {
          m_debug = debug;
      }
  
      /**
       * Set the definitions
       */
      public void setDefinitions( final String definitions )
      {
          m_definitions = definitions;
      }
  
      /**
       * Set the destination dir to find the files to be compiled
       *
       * @param destDir The new DestDir value
       */
      public void setDestDir( final File destDir )
      {
          m_destDir = destDir;
      }
  
      /**
       * file for generated XML documentation
       *
       * @param docFile output file
       */
      public void setDocFile( final File docFile )
      {
          m_docFile = docFile;
      }
  
      /**
       * Sets the ExtraOptions attribute
       */
      public void setExtraOptions( final String extraOptions )
      {
          m_extraOptions = extraOptions;
      }
  
      public void setFullPaths( final boolean fullpaths )
      {
          m_fullpaths = fullpaths;
      }
  
      /**
       * set the automatic reference inclusion flag on or off this flag controls
       * the string of references and the /nostdlib option in CSC
       *
       * @param includeDefaultReferences on/off flag
       */
      public void setIncludeDefaultReferences( final boolean includeDefaultReferences )
      {
          m_includeDefaultReferences = includeDefaultReferences;
      }
  
      /**
       * set the incremental compilation flag on or off
       *
       * @param incremental on/off flag
       */
      public void setIncremental( final boolean incremental )
      {
          m_incremental = incremental;
      }
  
      /**
       * Sets the MainClass attribute
       *
       * @param mainClass The new MainClass value
       */
      public void setMainClass( final String mainClass )
      {
          m_mainClass = mainClass;
      }
  
      /**
       * set the optimise flag on or off
       *
       * @param optimize on/off flag
       */
      public void setOptimize( final boolean optimize )
      {
          m_optimize = optimize;
      }
  
      /**
       * Set the definitions
       */
      public void setOutputFile( final File outputFile )
      {
          m_outputFile = outputFile;
      }
  
      /**
       * add another path to the reference file path list
       *
       * @param path another path to append
       */
      public void setReferenceFiles( final Path path )
          throws TaskException
      {
          //demand create pathlist
          if( null == m_referenceFiles )
          {
              m_referenceFiles = new Path();
          }
          m_referenceFiles.add( path );
      }
  
      /**
       * Set the reference list to be used for this compilation.
       *
       * @param references The new References value
       */
      public void setReferences( final String references )
      {
          m_references = references;
      }
  
      /**
       * Set the source dir to find the files to be compiled
       *
       * @param srcDir The new SrcDir value
       */
      public void setSrcDir( final File srcDir )
      {
          m_srcDir = srcDir;
      }
  
      /**
       * define the target
       *
       * @param targetType The new TargetType value
       * @exception TaskException if target is not one of
       *      exe|library|module|winexe
       */
      public void setTargetType( final String targetType )
          throws TaskException
      {
          final String type = targetType.toLowerCase();
          if( type.equals( "exe" ) || type.equals( "library" ) ||
              type.equals( "module" ) || type.equals( "winexe" ) )
          {
              m_targetType = type;
          }
          else
          {
              final String message = "targetType " + type + " is not a valid type";
              throw new TaskException( message );
          }
      }
  
      /**
       * Sets the Unsafe attribute
       *
       * @param unsafe The new Unsafe value
       */
      public void setUnsafe( final boolean unsafe )
      {
          m_unsafe = unsafe;
      }
  
      /**
       * enable generation of utf8 output from the compiler.
       *
       * @param enabled The new Utf8Output value
       */
      public void setUtf8Output( final boolean enabled )
      {
          m_utf8output = enabled;
      }
  
      /**
       * set warn level (no range checking)
       *
       * @param warnLevel warn level -see .net docs for valid range (probably 0-4)
       */
      public void setWarnLevel( final int warnLevel )
      {
          m_warnLevel = warnLevel;
      }
  
      /**
       * Set the win32 icon
       *
       * @param fileName path to the file. Can be relative, absolute, whatever.
       */
      public void setWin32Icon( final File fileName )
      {
          m_win32icon = fileName;
      }
  
      /**
       * Set the win32 icon
       *
       * @param win32res path to the file. Can be relative, absolute, whatever.
       */
      public void setWin32Res( final File win32res )
      {
          m_win32res = win32res;
      }
  
      /**
       * do the work by building the command line and then calling it
       */
      public void execute()
          throws TaskException
      {
          if( null == m_srcDir )
          {
              m_srcDir = getBaseDirectory();
          }
  
          final Execute exe = new Execute();
          exe.setExecutable( EXE_NAME );
  
          addArgument( exe, "/nologo" );
          addArgument( exe, getAdditionalModulesParameter() );
          addArgument( exe, getDefinitionsParameter() );
          addArgument( exe, getDebugParameter() );
          addArgument( exe, getDocFileParameter() );
          addArgument( exe, getIncrementalParameter() );
          addArgument( exe, getMainClassParameter() );
          addArgument( exe, getOptimizeParameter() );
          addArgument( exe, getReferencesParameter() );
          addArgument( exe, getTargetTypeParameter() );
          addArgument( exe, getUnsafeParameter() );
          addArgument( exe, getWarnLevelParameter() );
          addArgument( exe, getWin32IconParameter() );
          addArgument( exe, getOutputFileParameter() );
          addArgument( exe, getIncludeDefaultReferencesParameter() );
          addArgument( exe, getDefaultReferenceParameter() );
          addArgument( exe, getWin32ResParameter() );
          addArgument( exe, getUtf8OutpuParameter() );
          addArgument( exe, getFullPathsParameter() );
          addArgument( exe, getExtraOptionsParameter() );
  
          //get dependencies list.
          final DirectoryScanner scanner = super.getDirectoryScanner( m_srcDir );
          final String[] dependencies = scanner.getIncludedFiles();
          final String message = "compiling " + dependencies.length + " file" +
              ( ( dependencies.length == 1 ) ? "" : "s" );
          getContext().info( message );
          final String baseDir = scanner.getBasedir().toString();
          //add to the command
          for( int i = 0; i < dependencies.length; i++ )
          {
              final String targetFile = baseDir + File.separator + dependencies[ i ];
              addArgument( exe, targetFile );
          }
  
          //now run the command of exe + settings + files
          exe.execute( getContext() );
      }
  
      private void addArgument( final ArgumentList cmd, final String argument )
      {
          if( null != argument && 0 != argument.length() )
          {
              cmd.addArgument( argument );
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The AdditionalModules Parameter to CSC
       */
      private String getAdditionalModulesParameter()
      {
          if( notEmpty( m_additionalModules ) )
          {
              return "/addmodule:" + m_additionalModules;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the debug switch argument
       *
       * @return The Debug Parameter to CSC
       */
      private String getDebugParameter()
      {
          return "/debug" + ( m_debug ? "+" : "-" );
      }
  
      /**
       * get default reference list
       *
       * @return null or a string of references.
       */
      private String getDefaultReferenceParameter()
      {
          if( m_includeDefaultReferences )
          {
              StringBuffer s = new StringBuffer( "/reference:" );
              s.append( DEFAULT_REFERENCE_LIST );
              return new String( s );
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The Definitions Parameter to CSC
       */
      private String getDefinitionsParameter()
      {
          if( notEmpty( m_definitions ) )
          {
              return "/define:" + m_definitions;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The DocFile Parameter to CSC
       */
      private String getDocFileParameter()
      {
          if( m_docFile != null )
          {
              return "/doc:" + m_docFile.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get any extra options or null for no argument needed
       *
       * @return The ExtraOptions Parameter to CSC
       */
      private String getExtraOptionsParameter()
      {
          if( m_extraOptions != null && m_extraOptions.length() != 0 )
          {
              return m_extraOptions;
          }
          else
          {
              return null;
          }
      }
  
      private String getFullPathsParameter()
      {
          return m_fullpaths ? "/fullpaths" : null;
      }
  
      /**
       * get the include default references flag or null for no argument needed
       *
       * @return The Parameter to CSC
       */
      private String getIncludeDefaultReferencesParameter()
      {
          return "/nostdlib" + ( m_includeDefaultReferences ? "-" : "+" );
      }
  
      /**
       * get the incremental build argument
       *
       * @return The Incremental Parameter to CSC
       */
      private String getIncrementalParameter()
      {
          return "/incremental" + ( m_incremental ? "+" : "-" );
      }
  
      /**
       * get the /main argument or null for no argument needed
       *
       * @return The MainClass Parameter to CSC
       */
      private String getMainClassParameter()
      {
          if( m_mainClass != null && m_mainClass.length() != 0 )
          {
              return "/main:" + m_mainClass;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the optimise flag or null for no argument needed
       *
       * @return The Optimize Parameter to CSC
       */
      private String getOptimizeParameter()
      {
          return "/optimize" + ( m_optimize ? "+" : "-" );
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The OutputFile Parameter to CSC
       */
      private String getOutputFileParameter()
      {
          if( m_outputFile != null )
          {
              File f = m_outputFile;
              return "/out:" + f.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the reference string or null for no argument needed
       *
       * @return The References Parameter to CSC
       */
      private String getReferencesParameter()
      {
          //bail on no references
          if( notEmpty( m_references ) )
          {
              return "/reference:" + m_references;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The TargetType Parameter to CSC
       */
      private String getTargetTypeParameter()
      {
          if( notEmpty( m_targetType ) )
          {
              return "/target:" + m_targetType;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The Unsafe Parameter to CSC
       */
      private String getUnsafeParameter()
      {
          return m_unsafe ? "/unsafe" : null;
      }
  
      private String getUtf8OutpuParameter()
      {
          return m_utf8output ? "/utf8output" : null;
      }
  
      /**
       * get the warn level switch
       *
       * @return The WarnLevel Parameter to CSC
       */
      private String getWarnLevelParameter()
      {
          return "/warn:" + m_warnLevel;
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The Win32Icon Parameter to CSC
       */
      private String getWin32IconParameter()
      {
          if( m_win32icon != null )
          {
              return "/win32icon:" + m_win32icon.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The Win32Icon Parameter to CSC
       */
      private String getWin32ResParameter()
      {
          if( m_win32res != null )
          {
              return "/win32res:" + m_win32res.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * test for a string containing something useful
       *
       * @param string string in
       * @return true if the argument is not null or empty
       */
      private boolean notEmpty( final String string )
      {
          return string != null && string.length() != 0;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/dotnet/Ilasm.java
  
  Index: Ilasm.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.txt file.
   */
  package org.apache.antlib.dotnet;
  
  import java.io.File;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.tools.todo.taskdefs.MatchingTask;
  import org.apache.myrmidon.framework.nativelib.ArgumentList;
  import org.apache.tools.todo.types.DirectoryScanner;
  
  /**
   * Task to assemble .net 'Intermediate Language' files. The task will only work
   * on win2K until other platforms support csc.exe or an equivalent. ilasm.exe
   * must be on the execute path too. <p>
   *
   * <p>
   *
   * All parameters are optional: &lt;il/&gt; should suffice to produce a debug
   * build of all *.il files. The option set is roughly compatible with the CSharp
   * class; even though the command line options are only vaguely equivalent. [The
   * low level commands take things like /OUT=file, csc wants /out:file ...
   * /verbose is used some places; /quiet here in ildasm... etc.] It would be nice
   * if someone made all the command line tools consistent (and not as brittle as
   * the java cmdline tools) <p>
   *
   * The task is a directory based task, so attributes like <b>includes="*.il"</b>
   * and <b>excludes="broken.il"</b> can be used to control the files pulled in.
   * Each file is built on its own, producing an appropriately named output file
   * unless manually specified with <b>outfile</b>
   *
   * @author Steve Loughran steve_l@iseran.com
   * @version 0.2
   */
  public class Ilasm
      extends MatchingTask
  {
      /**
       * name of the executable. the .exe suffix is deliberately not included in
       * anticipation of the unix version
       */
      private static final String EXE_NAME = "ilasm";
  
      /**
       * what is the file extension we search on?
       */
      private static final String FILE_EXT = "il";
  
      /**
       * and now derive the search pattern from the extension
       */
      private static final String FILE_PATTERN = "**/*." + FILE_EXT;
  
      /**
       * debug flag. Controls generation of debug information.
       */
      private boolean m_debug;
  
      /**
       * any extra command options?
       */
      private String m_extraOptions;
  
      /**
       * listing flag
       */
      private boolean m_listing;
  
      /**
       * output file. If not supplied this is derived from the source file
       */
      private File m_outputFile;
  
      /**
       * resource file (.res format) to include in the app.
       */
      private File m_resourceFile;
  
      /**
       * type of target. Should be one of exe|library|module|winexe|(null) default
       * is exe; the actual value (if not null) is fed to the command line. <br>
       * See /target
       */
      private String m_targetType;
  
      /**
       * verbose flag
       */
      private boolean m_verbose;
  
      /**
       * file containing private key
       */
      private File m_keyfile;
  
      /**
       * source directory upon which the search pattern is applied
       */
      private File m_srcDir;
  
      /**
       * constructor inits everything and set up the search pattern
       */
      public Ilasm()
          throws TaskException
      {
          setIncludes( FILE_PATTERN );
          m_debug = true;
      }
  
      /**
       * set the debug flag on or off
       *
       * @param debug on/off flag
       */
      public void setDebug( final boolean debug )
      {
          m_debug = debug;
      }
  
      /**
       * Sets the ExtraOptions attribute
       *
       * @param extraOptions The new ExtraOptions value
       */
      public void setExtraOptions( final String extraOptions )
      {
          m_extraOptions = extraOptions;
      }
  
      public void setKeyfile( final File keyfile )
      {
          m_keyfile = keyfile;
      }
  
      /**
       * enable/disable listing
       *
       * @param listing flag set to true for listing on
       */
      public void setListing( final boolean listing )
      {
          m_listing = listing;
      }
  
      /**
       * Set the definitions
       */
      public void setOutputFile( final File outputFile )
      {
          m_outputFile = outputFile;
      }
  
      /**
       * Set the resource file
       *
       * @param resourceFile path to the file. Can be relative, absolute, whatever.
       */
      public void setResourceFile( final File resourceFile )
      {
          m_resourceFile = resourceFile;
      }
  
      /**
       * Set the source dir to find the files to be compiled
       */
      public void setSrcDir( final File srcDir )
      {
          m_srcDir = srcDir;
      }
  
      /**
       * define the target
       *
       * @param targetType one of exe|library|
       * @exception TaskException if target is not one of
       *      exe|library|module|winexe
       */
  
      public void setTargetType( final String targetType )
          throws TaskException
      {
          final String type = targetType.toLowerCase();
          if( type.equals( "exe" ) || type.equals( "library" ) )
          {
              m_targetType = type;
          }
          else
          {
              final String message = "targetType " + targetType + " is not a valid type";
              throw new TaskException( message );
          }
      }
  
      /**
       * enable/disable verbose ILASM output
       *
       * @param verbose flag set to true for verbose on
       */
      public void setVerbose( final boolean verbose )
      {
          m_verbose = verbose;
      }
  
      /**
       * This is the execution entry point. Build a list of files and call ilasm
       * on each of them.
       *
       * @throws TaskException if the assembly failed
       */
      public void execute()
          throws TaskException
      {
          if( null == m_srcDir )
          {
              m_srcDir = getBaseDirectory();
          }
  
          //get dependencies list.
          final DirectoryScanner scanner = super.getDirectoryScanner( m_srcDir );
          final String[] dependencies = scanner.getIncludedFiles();
          final String baseDir = scanner.getBasedir().toString();
  
          final String message = "assembling " + dependencies.length + " file" +
              ( ( dependencies.length == 1 ) ? "" : "s" );
          getContext().info( message );
  
          //add to the command
          for( int i = 0; i < dependencies.length; i++ )
          {
              final String targetFile = baseDir + File.separator + dependencies[ i ];
              executeOneFile( targetFile );
          }
      }
  
      /**
       * do the work for one file by building the command line then calling it
       *
       * @param targetFile name of the the file to assemble
       * @throws TaskException if the assembly failed and FailOnError is true
       */
      public void executeOneFile( final String targetFile )
          throws TaskException
      {
          final Execute exe = new Execute();
          exe.setExecutable( EXE_NAME );
          addArgument( exe, getDebugParameter() );
          addArgument( exe, getTargetTypeParameter() );
          addArgument( exe, getListingParameter() );
          addArgument( exe, getOutputFileParameter() );
          addArgument( exe, getResourceFileParameter() );
          addArgument( exe, getVerboseParameter() );
          addArgument( exe, getKeyfileParameter() );
          addArgument( exe, getExtraOptionsParameter() );
          addArgument( exe, targetFile );
          exe.execute( getContext() );
      }
  
      private void addArgument( final ArgumentList cmd, final String argument )
      {
          if( null != argument && 0 != argument.length() )
          {
              cmd.addArgument( argument );
          }
      }
  
      /**
       * get the argument or null for no argument needed
       *
       * @return The DebugParameter value
       */
      private String getDebugParameter()
      {
          return m_debug ? "/debug" : null;
      }
  
      /**
       * get any extra options or null for no argument needed
       *
       * @return The ExtraOptions Parameter to CSC
       */
      private String getExtraOptionsParameter()
      {
          if( m_extraOptions != null && m_extraOptions.length() != 0 )
          {
              return m_extraOptions;
          }
          else
          {
              return null;
          }
      }
  
      /**
       * get the argument or null for no argument needed
       */
      private String getKeyfileParameter()
      {
          if( m_keyfile != null )
          {
              return "/keyfile:" + m_keyfile.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * turn the listing flag into a parameter for ILASM
       *
       * @return the appropriate string from the state of the listing flag
       */
      private String getListingParameter()
      {
          return m_listing ? "/listing" : "/nolisting";
      }
  
      /**
       * get the output file
       *
       * @return the argument string or null for no argument
       */
      private String getOutputFileParameter()
      {
          if( null == m_outputFile || 0 == m_outputFile.length() )
          {
              return null;
          }
          return "/output=" + m_outputFile.toString();
      }
  
      private String getResourceFileParameter()
      {
          if( null != m_resourceFile )
          {
              return "/resource=" + m_resourceFile.toString();
          }
          else
          {
              return null;
          }
      }
  
      /**
       * g get the target type or null for no argument needed
       *
       * @return The TargetTypeParameter value
       */
  
      private String getTargetTypeParameter()
      {
          if( !notEmpty( m_targetType ) )
          {
              return null;
          }
          if( m_targetType.equals( "exe" ) )
          {
              return "/exe";
          }
          else if( m_targetType.equals( "library" ) )
          {
              return "/dll";
          }
          else
          {
              return null;
          }
      }
  
      /**
       * turn the verbose flag into a parameter for ILASM
       *
       * @return null or the appropriate command line string
       */
      private String getVerboseParameter()
      {
          return m_verbose ? null : "/quiet";
      }
  
      /**
       * test for a string containing something useful
       *
       * @returns true if the argument is not null or empty
       */
      private boolean notEmpty( final String string )
      {
          return string != null && string.length() != 0;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/CopyTask.java
  
  Index: CopyTask.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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.io.FileUtil;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.FileNameMapper;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  import org.apache.tools.todo.types.SourceFileScanner;
  import org.apache.tools.todo.util.mappers.IdentityMapper;
  
  /**
   * This is a task used to copy files.
   *
   * @ant.task name="copy"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</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>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class CopyTask
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( CopyTask.class );
  
      private File m_file;
      private ArrayList m_filesets = new ArrayList();
      private File m_destFile;
      private File m_destDir;
      private boolean m_preserveLastModified;
      private boolean m_overwrite;
      private boolean m_includeEmpty = true;
      private FileNameMapper m_mapper;
  
      private HashMap m_fileMap = new HashMap();
      private HashMap m_dirMap = new HashMap();
  
      /**
       * Sets a single source file to copy.
       */
      public void setFile( final File file )
      {
          m_file = file;
      }
  
      public void addFileset( final FileSet set )
      {
          m_filesets.add( set );
      }
  
      public void setDestFile( final File destFile )
      {
          m_destFile = destFile;
      }
  
      public void setDestDir( final File destDir )
      {
          m_destDir = destDir;
      }
  
      public void setPreserveLastModified( boolean preserveLastModified )
      {
          m_preserveLastModified = preserveLastModified;
      }
  
      /**
       * Overwrite any existing destination file(s).
       */
      public void setOverwrite( boolean overwrite )
      {
          m_overwrite = overwrite;
      }
  
      /**
       * Defines the FileNameMapper to use (nested mapper element).
       */
      public void addMapper( final FileNameMapper mapper )
          throws TaskException
      {
          if( null != m_mapper )
          {
              final String message = "Cannot define more than one mapper";
              throw new TaskException( message );
          }
          m_mapper = mapper;
      }
  
      protected final boolean isPreserveLastModified()
      {
          return m_preserveLastModified;
      }
  
      public void execute()
          throws TaskException
      {
          validate();
  
          // deal with the single file
          if( m_file != null )
          {
              if( null == m_destFile )
              {
                  m_destFile = new File( m_destDir, m_file.getName() );
              }
  
              if( m_overwrite ||
                  ( m_file.lastModified() > m_destFile.lastModified() ) )
              {
                  m_fileMap.put( m_file.getAbsolutePath(), m_destFile.getAbsolutePath() );
              }
              else
              {
                  final String message =
                      REZ.getString( "copy.omit-uptodate.notice", m_file, m_destFile );
                  getContext().debug( message );
              }
          }
  
          // deal with the filesets
          final int size = m_filesets.size();
          for( int i = 0; i < size; i++ )
          {
              final FileSet fileSet = (FileSet)m_filesets.get( i );
              final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
              final File fromDir = fileSet.getDir();
  
              final String[] srcFiles = scanner.getIncludedFiles();
              final String[] srcDirs = scanner.getIncludedDirectories();
  
              scan( fromDir, m_destDir, srcFiles, srcDirs );
          }
  
          // do all the copy operations now...
          doFileOperations( m_fileMap, m_dirMap );
      }
  
      protected void validate()
          throws TaskException
      {
          final int fileSetSize = m_filesets.size();
  
          if( null == m_file && 0 == fileSetSize )
          {
              final String message = REZ.getString( "copy.missing-src.error" );
              throw new TaskException( message );
          }
  
          if( null != m_destFile && null != m_destDir )
          {
              final String message = REZ.getString( "copy.one-dest-only.error" );
              throw new TaskException( message );
          }
  
          if( null != m_file && m_file.exists() && m_file.isDirectory() )
          {
              final String message = REZ.getString( "copy.fileset-for-dirs.error" );
              throw new TaskException( message );
          }
  
          if( null != m_destFile && fileSetSize > 0 )
          {
              if( fileSetSize > 1 )
              {
                  final String message = REZ.getString( "copy.need-destdir.error" );
                  throw new TaskException( message );
              }
              else
              {
                  final FileSet fileSet = (FileSet)m_filesets.get( 0 );
                  final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
                  final String[] srcFiles = scanner.getIncludedFiles();
  
                  if( srcFiles.length > 0 )
                  {
                      if( m_file == null )
                      {
                          m_file = new File( srcFiles[ 0 ] );
                          m_filesets.remove( 0 );
                      }
                      else
                      {
                          final String message = REZ.getString( "copy.bad-mapping.error" );
                          throw new TaskException( message );
                      }
                  }
                  else
                  {
                      final String message = REZ.getString( "copy.bad-operation.error" );
                      throw new TaskException( message );
                  }
              }
          }
  
          if( null != m_file && !m_file.exists() )
          {
              final String message =
                  REZ.getString( "copy.missing-file.error", m_file.getAbsolutePath() );
              throw new TaskException( message );
          }
  
          if( null != m_destFile )
          {
              m_destDir = m_destFile.getParentFile();
          }
      }
  
      /**
       * Compares source files to destination files to see if they should be
       * copied.
       */
      private void scan( final File sourceDir,
                         final File destDir,
                         final String[] files,
                         final String[] dirs )
          throws TaskException
      {
          final FileNameMapper mapper = getFilenameMapper();
  
          buildMap( sourceDir, destDir, files, mapper, m_fileMap );
  
          if( m_includeEmpty )
          {
              buildMap( sourceDir, destDir, dirs, mapper, m_dirMap );
          }
      }
  
      private void buildMap( final File sourceDir,
                             final File destDir,
                             final String[] files,
                             final FileNameMapper mapper,
                             final Map map )
          throws TaskException
      {
          final String[] toCopy = buildFilenameList( files, mapper, sourceDir, destDir );
          for( int i = 0; i < toCopy.length; i++ )
          {
              final String destFilename = mapper.mapFileName( toCopy[ i ], getContext() )[ 0 ];
              final File source = new File( sourceDir, toCopy[ i ] );
              final File destination = new File( destDir, destFilename );
              map.put( source.getAbsolutePath(), destination.getAbsolutePath() );
          }
      }
  
      /**
       * Utility method to build up a list of files needed between both
       * but only getting the files that need updating (unless overwrite is true).
       */
      private String[] buildFilenameList( final String[] names,
                                          final FileNameMapper mapper,
                                          final File fromDir,
                                          final File toDir )
          throws TaskException
      {
          if( m_overwrite )
          {
              final ArrayList list = new ArrayList( names.length );
              for( int i = 0; i < names.length; i++ )
              {
                  final String name = names[ i ];
                  if( null != mapper.mapFileName( name, getContext() ) )
                  {
                      list.add( name );
                  }
              }
  
              return (String[])list.toArray( new String[ list.size() ] );
          }
          else
          {
              final SourceFileScanner scanner = new SourceFileScanner();
              return scanner.restrict( names, fromDir, toDir, mapper, getContext() );
          }
      }
  
      /**
       * Perform the oepration on all the files (and possibly empty directorys).
       */
      private void doFileOperations( final Map fileCopyMap, final Map dirCopyMap )
          throws TaskException
      {
          final int fileCount = fileCopyMap.size();
          if( fileCount > 0 )
          {
              doOperationOnFiles( fileCopyMap );
          }
  
          if( m_includeEmpty )
          {
              doOperationOnDirs( dirCopyMap );
          }
      }
  
      /**
       * perform operation on files.
       */
      private void doOperationOnFiles( final Map fileMap )
          throws TaskException
      {
          final int fileCount = fileMap.size();
          displayFilecountNotice( fileCount );
  
          final Iterator names = fileMap.keySet().iterator();
          while( names.hasNext() )
          {
              final String source = (String)names.next();
              final String destination = (String)fileMap.get( source );
  
              if( source.equals( destination ) )
              {
                  final String message =
                      REZ.getString( "copy.selfcopy-ignored.notice", source );
                  getContext().verbose( message );
                  continue;
              }
  
              try
              {
                  final String message =
                      REZ.getString( "copy.filecopy.notice", source, destination );
                  getContext().verbose( message );
  
                  doOperation( source, destination );
              }
              catch( final IOException ioe )
              {
                  final String message =
                      REZ.getString( "copy.filecopy.error", source, destination, ioe );
                  throw new TaskException( message, ioe );
              }
          }
      }
  
      /**
       * perform operation on directories.
       */
      private void doOperationOnDirs( final Map dirMap )
      {
          final Iterator dirs = dirMap.values().iterator();
          int count = 0;
          while( dirs.hasNext() )
          {
              final String pathname = (String)dirs.next();
              final File dir = new File( pathname );
              if( !dir.exists() )
              {
                  if( !dir.mkdirs() )
                  {
                      final String message =
                          REZ.getString( "copy.dircopy.error", dir.getAbsolutePath() );
                      getContext().error( message );
                  }
                  else
                  {
                      count++;
                  }
              }
          }
  
          if( count > 0 )
          {
              displayDirCopyNotice( count );
          }
      }
  
      /**
       * Utility method to determine and retrieve FilenameMapper.
       */
      private FileNameMapper getFilenameMapper()
          throws TaskException
      {
          if( null != m_mapper )
          {
              return m_mapper;
          }
          else
          {
              return new IdentityMapper();
          }
      }
  
      /**
       * Utility method to perform operation to transform a single source file
       * to a destination.
       */
      protected void doOperation( final String sourceFilename,
                                  final String destinationFilename )
          throws IOException
      {
          final File source = new File( sourceFilename );
          final File destination = new File( destinationFilename );
  
          if( m_overwrite )
          {
              FileUtil.forceDelete( destination );
          }
  
          FileUtil.copyFile( source, destination );
  
          if( m_preserveLastModified )
          {
              destination.setLastModified( source.lastModified() );
          }
      }
  
      /**
       * Utility method to display notice about how many dirs copied.
       */
      private void displayDirCopyNotice( final int count )
      {
          final String message =
              REZ.getString( "copy.dir-count.notice",
                             new Integer( count ),
                             m_destDir.getAbsolutePath() );
          getContext().info( message );
      }
  
      /**
       * Utility method to display notice about how many files copied.
       */
      private void displayFilecountNotice( final int count )
      {
          if( getContext().isInfoEnabled() )
          {
              final String message =
                  REZ.getString( "copy.file-count.notice",
                                 new Integer( count ),
                                 m_destDir.getAbsolutePath() );
              getContext().info( message );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.File;
  import java.util.ArrayList;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  
  /**
   * Deletes a file or directory, or set of files defined by a fileset.
   *
   * @ant.task name="delete"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:tad1@cornell.edu">Tom Dimock</a>
   * @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</a>
   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class Delete
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( Delete.class );
  
      private final ArrayList filesets = new ArrayList();
      private File m_dir;
      private File m_file;
      private boolean m_includeEmpty;// by default, remove matching empty dirs
  
      /**
       * Set the directory from which files are to be deleted
       *
       * @param dir the directory path.
       */
      public void setDir( final File dir )
      {
          m_dir = dir;
      }
  
      /**
       * Set the name of a single file to be removed.
       *
       * @param file the file to be deleted
       */
      public void setFile( final File file )
      {
          m_file = file;
      }
  
      /**
       * Adds a set of files (nested fileset attribute).
       */
      public void addFileset( FileSet set )
      {
          filesets.add( set );
      }
  
      /**
       * Delete the file(s).
       */
      public void execute()
          throws TaskException
      {
          validate();
  
          // delete the single file
          if( null != m_file && m_file.exists() )
          {
              deleteFile( m_file );
          }
  
          // delete the directory
          if( m_dir != null && m_dir.exists() && m_dir.isDirectory() )
          {
              final String message =
                  REZ.getString( "delete.delete-dir.notice", m_dir.getAbsolutePath() );
              getContext().info( message );
              deleteDir( m_dir );
          }
  
          // delete the files in the filesets
          final int size = filesets.size();
          for( int i = 0; i < size; i++ )
          {
              final FileSet fileSet = (FileSet)filesets.get( i );
              final DirectoryScanner scanner =
                  ScannerUtil.getDirectoryScanner( fileSet );
              final String[] files = scanner.getIncludedFiles();
              final String[] dirs = scanner.getIncludedDirectories();
              removeFiles( fileSet.getDir(), files, dirs );
          }
      }
  
      private void validate()
          throws TaskException
      {
          if( null == m_file && null == m_dir && 0 == filesets.size() )
          {
              final String message = REZ.getString( "delete.nofiles.error" );
              throw new TaskException( message );
          }
  
          if( null != m_file && m_file.exists() && m_file.isDirectory() )
          {
              final String message =
                  REZ.getString( "delete.bad-file.error", m_file.getAbsolutePath() );
              throw new TaskException( message );
          }
  
          if( null != m_file && !m_file.exists() )
          {
              final String message =
                  REZ.getString( "delete.missing-file.error", m_file.getAbsolutePath() );
              getContext().debug( message );
          }
      }
  
      private void deleteDir( final File baseDir )
          throws TaskException
      {
          final File[] list = baseDir.listFiles();
          if( list != null )
          {
              deleteFiles( list );
          }
  
          if( getContext().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "delete.delete-dir.notice", m_dir.getAbsolutePath() );
              getContext().debug( message );
          }
  
          if( !baseDir.delete() )
          {
              final String message =
                  REZ.getString( "delete.delete-dir.error", m_dir.getAbsolutePath() );
              throw new TaskException( message );
          }
      }
  
      private void deleteFiles( final File[] list )
          throws TaskException
      {
          for( int i = 0; i < list.length; i++ )
          {
              final File file = list[ i ];
              if( file.isDirectory() )
              {
                  deleteDir( file );
              }
              else
              {
                  deleteFile( file );
              }
          }
      }
  
      private void deleteFile( final File file )
          throws TaskException
      {
          if( getContext().isDebugEnabled() )
          {
              final String message =
                  REZ.getString( "delete.delete-file.notice", file.getAbsolutePath() );
              getContext().debug( message );
          }
  
          if( !file.delete() )
          {
              final String message =
                  REZ.getString( "delete.delete-file.error", file.getAbsolutePath() );
              throw new TaskException( message );
          }
      }
  
      /**
       * 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( final File baseDir,
                                  final String[] files,
                                  final String[] dirs )
          throws TaskException
      {
          if( files.length > 0 )
          {
              final String message =
                  REZ.getString( "delete.delete-file.error",
                                 new Integer( files.length ),
                                 baseDir.getAbsolutePath() );
              getContext().info( message );
              for( int i = 0; i < files.length; i++ )
              {
                  final File file = new File( baseDir, files[ i ] );
                  deleteFile( file );
              }
          }
  
          if( dirs.length > 0 && m_includeEmpty )
          {
              int dirCount = 0;
              for( int j = dirs.length - 1; j >= 0; j-- )
              {
                  final File dir = new File( baseDir, dirs[ j ] );
                  final String[] dirFiles = dir.list();
                  if( null == dirFiles || 0 == dirFiles.length )
                  {
                      deleteDir( dir );
                      dirCount++;
                  }
              }
  
              if( dirCount > 0 )
              {
                  final String message =
                      REZ.getString( "delete.summary.notice",
                                     new Integer( dirCount ),
                                     baseDir.getAbsolutePath() );
                  getContext().info( message );
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/FilteredCopyTask.java
  
  Index: FilteredCopyTask.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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  import java.io.Reader;
  import java.io.UnsupportedEncodingException;
  import java.io.Writer;
  import org.apache.avalon.excalibur.io.IOUtil;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.filters.LineFilterSet;
  
  /**
   * A task used to copy files and simultaneously apply a
   * filter on said files.
   *
   * @ant.task name="filtered-copy"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class FilteredCopyTask
      extends CopyTask
  {
      private LineFilterSet m_filterSetCollection = new LineFilterSet();
      private String m_encoding = "US-ASCII";
  
      public void addFilterset( final LineFilterSet filter )
      {
          m_filterSetCollection.add( filter );
      }
  
      public void setEncoding( final String encoding )
      {
          m_encoding = encoding;
      }
  
      /**
       * Utility method to perform operation to transform a single source file
       * to a destination.
       */
      protected void doOperation( final String sourceFilename,
                                  final String destinationFilename )
          throws IOException
      {
          final File source = new File( sourceFilename );
          final File destination = new File( destinationFilename );
  
          InputStream inputStream = null;
          OutputStream outputStream = null;
          BufferedReader input = null;
          BufferedWriter output = null;
          try
          {
              inputStream = new FileInputStream( source );
              outputStream = new FileOutputStream( destination );
  
              final Reader fileReader = new InputStreamReader( inputStream, m_encoding );
              final Writer fileWriter = new OutputStreamWriter( outputStream, m_encoding );
              input = new BufferedReader( fileReader );
              output = new BufferedWriter( fileWriter );
  
              process( input, output );
          }
          catch( final UnsupportedEncodingException uee )
          {
              throw new IOException( uee.toString() );
          }
          finally
          {
              IOUtil.shutdownReader( input );
              IOUtil.shutdownStream( inputStream );
              IOUtil.shutdownWriter( output );
              IOUtil.shutdownStream( outputStream );
          }
  
          if( isPreserveLastModified() )
          {
              destination.setLastModified( source.lastModified() );
          }
      }
  
      private void process( final BufferedReader input,
                            final BufferedWriter output )
          throws IOException
      {
          String newline = null;
          String line = input.readLine();
          while( null != line )
          {
              if( line.length() == 0 )
              {
                  output.newLine();
              }
              else
              {
                  newline = replaceTokens( line );
                  output.write( newline );
                  output.newLine();
              }
              line = input.readLine();
          }
      }
  
      private String replaceTokens( final String line )
          throws IOException
      {
          try
          {
              final StringBuffer buffer = new StringBuffer( line );
              m_filterSetCollection.filterLine( buffer, getContext() );
              return buffer.toString();
          }
          catch( final TaskException te )
          {
              throw new IOException( te.getMessage() );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/ListPathTask.java
  
  Index: ListPathTask.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.txt file.
   */
  package org.apache.antlib.file;
  
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.file.FileList;
  import org.apache.myrmidon.framework.file.Path;
  
  /**
   * A diagnostic task that lists the contents of a path.
   *
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   *
   * @ant.task name="list-path"
   */
  public class ListPathTask
      extends AbstractTask
  {
      private final Path m_path = new Path();
  
      /**
       * Adds a nested path.
       */
      public void add( final FileList list )
      {
          m_path.add( list );
      }
  
      /**
       * Executes the task.
       */
      public void execute()
          throws TaskException
      {
          final String[] files = m_path.listFiles( getContext() );
          for( int i = 0; i < files.length; i++ )
          {
              final String file = files[ i ];
              getContext().info( file );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.File;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * Creates specified directory.
   *
   * @ant.task name="mkdir"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author duncan@x180.com
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class Mkdir
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( Mkdir.class );
  
      private File m_dir;
  
      public void setDir( final File dir )
      {
          m_dir = dir;
      }
  
      public void execute()
          throws TaskException
      {
          if( null == m_dir )
          {
              final String message = REZ.getString( "mkdir.missing-dir.error" );
              throw new TaskException( message );
          }
  
          if( m_dir.isFile() )
          {
              final String message =
                  REZ.getString( "mkdir.file-exists.error", m_dir.getAbsolutePath() );
              throw new TaskException( message );
          }
  
          if( !m_dir.exists() )
          {
              final boolean result = m_dir.mkdirs();
              if( !result )
              {
                  final String message =
                      REZ.getString( "mkdir.nocreate.error", m_dir.getAbsolutePath() );
                  throw new TaskException( message );
              }
              final String message =
                  REZ.getString( "mkdir.create.notice", m_dir.getAbsolutePath() );
              getContext().info( message );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/MoveTask.java
  
  Index: MoveTask.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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.File;
  import java.io.IOException;
  import org.apache.avalon.excalibur.io.FileUtil;
  
  /**
   * A task used to move files.
   *
   * @ant.task name="move"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class MoveTask
      extends CopyTask
  {
      /**
       * Utility method to perform operation to transform a single source file
       * to a destination.
       */
      protected void doOperation( final String sourceFilename,
                                  final String destinationFilename )
          throws IOException
      {
          final File source = new File( sourceFilename );
          final File destination = new File( destinationFilename );
  
          if( destination.exists() )
          {
              FileUtil.forceDelete( destination );
          }
          FileUtil.copyFile( source, destination );
  
          if( isPreserveLastModified() )
          {
              destination.setLastModified( source.lastModified() );
          }
  
          FileUtil.forceDelete( source );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  mkdir.missing-dir.error=dir attribute is required.
  mkdir.file-exists.error=Unable to create directory as a file already exists with that name: "{0}".
  mkdir.nocreate.error=Failed to create directory {0} due to an unknown reason.
  mkdir.create.notice=Created dir: {0}
  
  touch.neg-time.error=Date of {0} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).
  touch.no-files.error=Specify at least one source - a file or a fileset.
  touch.use-fileset.error=Use a fileset to touch directories.
  touch.readonly-file.error=Can not change modification date of read-only file {0}.
  touch.no-touch.error=Could not create file {0} due to {1}.
  touch.create.notice=Creating {0}.
  
  delete.nofiles.error=At least one of the file or dir attributes, or a fileset element, must be set.
  delete.bad-file.error=Directory {0} cannot be removed using the file attribute.  Use dir instead.
  delete.missing-file.error=Could not find file {0} to delete.
  delete.delete-dir.notice=Deleting directory {0}.
  delete.delete-dir.error=Unable to delete directory {0}.
  delete.delete-file.notice=Deleting {0}.
  delete.delete-file.error=Unable to delete file {0}.
  delete.delete-file.error=Deleting {0} files from {1}.
  delete.summary.notice=Deleted {0,choice,0#zero directories|1#1 directory|2<{0} directories} from {1}.
  
  copy.omit-uptodate.notice={0} omitted as {1} is up to date.
  copy.missing-src.error=No source file or fileset specified.
  copy.one-dest-only.error=Only one of destFile or destDir may be set.
  copy.fileset-for-dirs.error=Use a fileset to copy directories.
  copy.need-destdir.error=Cannot copy multiple files into a single file.
  copy.bad-mapping.error=Cannot concatenate multiple files into a single file.
  copy.bad-operation.error=Cannot perform operation from directory to file.
  copy.missing-file.error=Could not find file {0} to copy.
  copy.dir-count.notice=Copied {0} empty director{0,choice,1#y|2<ies} to {1}.
  copy.file-count.notice=Copying {0} file{0,choice,1#|2<s} to {1}.
  copy.dircopy.error=Unable to create directory {0}.
  copy.filecopy.error=Failed to copy {0} to {1} due to {3}.
  copy.filecopy.notice=Copying {0} to {1}.
  copy.selfcopy-ignored.notice=Skipping self-copy of {0}.
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/file/Touch.java
  
  Index: Touch.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.txt file.
   */
  package org.apache.antlib.file;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.text.DateFormat;
  import java.text.ParseException;
  import java.util.ArrayList;
  import java.util.Locale;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  
  /**
   * Touch a file and/or fileset(s) -- corresponds to the Unix touch command.
   *
   * If the file to touch doesn't exist, an empty one is created. </p>
   *
   * @ant.task name="touch"
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <a href="mailto:mj@servidium.com">Michael J. Sikorsky</a>
   * @author <a href="mailto:shaw@servidium.com">Robert Shaw</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public class Touch
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( Touch.class );
  
      private long m_millis = -1;
      private String m_datetime;
      private ArrayList m_filesets = new ArrayList();
      private File m_file;
  
      /**
       * Date in the format MM/DD/YYYY HH:MM AM_PM.
       */
      public void setDatetime( final String datetime )
      {
          m_datetime = datetime;
      }
  
      /**
       * Sets a single source file to touch. If the file does not exist an empty
       * file will be created.
       */
      public void setFile( final File file )
      {
          m_file = file;
      }
  
      /**
       * Milliseconds since 01/01/1970 00:00 am.
       */
      public void setMillis( final long millis )
      {
          m_millis = millis;
      }
  
      /**
       * Adds a set of files (nested fileset attribute).
       */
      public void addFileset( final FileSet set )
      {
          m_filesets.add( set );
      }
  
      /**
       * Execute the touch operation.
       *
       * @exception TaskException Description of Exception
       */
      public void execute()
          throws TaskException
      {
          validate();
  
          if( m_datetime != null )
          {
              final DateFormat format =
                  DateFormat.getDateTimeInstance( DateFormat.SHORT,
                                                  DateFormat.SHORT,
                                                  Locale.US );
              try
              {
                  final long millis = format.parse( m_datetime ).getTime();
                  if( 0 > millis )
                  {
                      final String message = REZ.getString( "touch.neg-time.error", m_datetime );
                      throw new TaskException( message );
                  }
                  setMillis( millis );
              }
              catch( final ParseException pe )
              {
                  throw new TaskException( pe.getMessage(), pe );
              }
          }
  
          touch();
      }
  
      private void validate()
          throws TaskException
      {
          if( null == m_file && 0 == m_filesets.size() )
          {
              final String message = REZ.getString( "touch.no-files.error" );
              throw new TaskException( message );
          }
  
          if( null != m_file && m_file.exists() && m_file.isDirectory() )
          {
              final String message = REZ.getString( "touch.use-fileset.error" );
              throw new TaskException( message );
          }
      }
  
      private void touch()
          throws TaskException
      {
          if( m_millis < 0 )
          {
              m_millis = System.currentTimeMillis();
          }
  
          if( null != m_file )
          {
              if( !m_file.exists() )
              {
                  if( getContext().isInfoEnabled() )
                  {
                      final String message = REZ.getString( "touch.create.notice", m_file );
                      getContext().info( message );
                  }
  
                  try
                  {
                      FileOutputStream fos = new FileOutputStream( m_file );
                      fos.write( new byte[ 0 ] );
                      fos.close();
                  }
                  catch( final IOException ioe )
                  {
                      final String message = REZ.getString( "touch.no-touch.error", m_file, ioe );
                      throw new TaskException( message, ioe );
                  }
              }
  
              touch( m_file );
          }
  
          // deal with the filesets
          final int size = m_filesets.size();
          for( int i = 0; i < size; i++ )
          {
              final FileSet fileSet = (FileSet)m_filesets.get( i );
              final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
              final File fromDir = fileSet.getDir();
  
              final String[] srcFiles = scanner.getIncludedFiles();
              final String[] srcDirs = scanner.getIncludedDirectories();
  
              for( int j = 0; j < srcFiles.length; j++ )
              {
                  final File file = new File( fromDir, srcFiles[ j ] );
                  touch( file );
              }
  
              for( int j = 0; j < srcDirs.length; j++ )
              {
                  final File file = new File( fromDir, srcDirs[ j ] );
                  touch( file );
              }
          }
      }
  
      private void touch( final File file )
          throws TaskException
      {
          if( !file.canWrite() )
          {
              final String message = REZ.getString( "touch.readonly-file.error", file );
              throw new TaskException( message );
          }
  
          final long time = ( m_millis < 0 ) ? System.currentTimeMillis() : m_millis;
          file.setLastModified( time );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/ExternalCompilerAdaptor.java
  
  Index: ExternalCompilerAdaptor.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.txt file.
   */
  package org.apache.antlib.java;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.PrintWriter;
  import java.io.IOException;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  
  /**
   * An abstract compiler adaptor, that forks an external compiler.
   *
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   */
  public abstract class ExternalCompilerAdaptor
      extends JavaCompilerAdaptor
  {
      /**
       * Compiles a set of files.
       */
      protected void compile( final File[] files )
          throws TaskException
      {
          // Write the file names to a temp file
          final File tempFile = createTempFile( files );
          try
          {
              final Execute exe = new Execute();
  
              // Build the command line
              buildCommandLine( exe, tempFile );
  
              // Execute
              exe.execute( getContext() );
          }
          finally
          {
              tempFile.delete();
          }
      }
  
      /**
       * Builds the command-line to execute the compiler.
       */
      protected abstract void buildCommandLine( final Execute exe, final File tempFile )
          throws TaskException;
  
      /**
       * Writes the temporary file containing the names of the files to compile.
       */
      private File createTempFile( final File[] files )
          throws TaskException
      {
          try
          {
              // Build the temp file name
              final File tmpFile = File.createTempFile( "javac", "", getContext().getBaseDirectory() );
  
              // Write file names to the temp file
              final FileWriter writer = new FileWriter( tmpFile );
              try
              {
                  final PrintWriter pwriter = new PrintWriter( writer, false );
                  for( int i = 0; i < files.length; i++ )
                  {
                      File file = files[ i ];
                      pwriter.println( file.getAbsolutePath() );
                  }
                  pwriter.close();
              }
              finally
              {
                  writer.close();
              }
  
              return tmpFile;
          }
          catch( final IOException e )
          {
              throw new TaskException( "Cannot write file list", e );
          }
      }
  
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/JavaCompilerAdaptor.java
  
  Index: JavaCompilerAdaptor.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.txt file.
   */
  package org.apache.antlib.java;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.myrmidon.api.TaskContext;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.FileSet;
  import org.apache.myrmidon.framework.file.FileList;
  import org.apache.myrmidon.framework.file.Path;
  import org.apache.tools.todo.types.DirectoryScanner;
  import org.apache.tools.todo.types.ScannerUtil;
  import org.apache.tools.todo.types.SourceFileScanner;
  import org.apache.tools.todo.util.mappers.GlobPatternMapper;
  
  /**
   * An abstract Java compiler.
   *
   * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
   * @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
   *      </a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   *
   * @ant.role shorthand="java-compiler"
   */
  public abstract class JavaCompilerAdaptor
  {
      private TaskContext m_context;
      private Path m_classPath = new Path();
      private ArrayList m_sourceFilesets = new ArrayList();
      private boolean m_debug;
      private boolean m_deprecation;
      private File m_destDir;
  
      /**
       * Sets the context for this adaptor.
       */
      public void setContext( final TaskContext context )
      {
          m_context = context;
      }
  
      /**
       * Returns the context for this adaptor.
       */
      protected TaskContext getContext()
      {
          return m_context;
      }
  
      /**
       * Enables debug in the compiled classes.
       */
      public void setDebug( final boolean debug )
      {
          m_debug = debug;
      }
  
      /**
       * Returns the 'debug' flag.
       */
      protected boolean isDebug()
      {
          return m_debug;
      }
  
      /**
       * Sets the destination directory.
       */
      public void setDestDir( final File destDir )
      {
          m_destDir = destDir;
      }
  
      /**
       * Returns the destination directory.
       */
      protected File getDestDir()
      {
          return m_destDir;
      }
  
      /**
       * Enables deprecation info.
       */
      public void setDeprecation( final boolean deprecation )
      {
          m_deprecation = deprecation;
      }
  
      /**
       * Returns the 'deprecation' flag.
       */
      protected boolean isDeprecation()
      {
          return m_deprecation;
      }
  
      /**
       * Adds a source fileset.
       */
      public void addSrc( final FileSet fileset )
      {
          m_sourceFilesets.add( fileset );
      }
  
      /**
       * Adds a class-path element.
       */
      public void addClasspath( final Path path )
      {
          m_classPath.add( path );
      }
  
      /**
       * Returns the classpath
       */
      protected FileList getClassPath()
      {
          return m_classPath;
      }
  
      /**
       * Invokes the compiler.
       */
      public void execute()
          throws TaskException
      {
          validate();
  
          // Build the list of files to compile
          final File[] compileList = getCompileList();
          logFiles( compileList );
  
          if( compileList.length == 0 )
          {
              return;
          }
  
          // Compile
          compile( compileList );
      }
  
      /**
       * Compiles a set of files.
       */
      protected abstract void compile( final File[] files )
          throws TaskException;
  
      /**
       * Logs the details of what is going to be compiled.
       */
      private void logFiles( final File[] compileList )
      {
          // Log
          final String message = "Compiling " + compileList.length + " source files to " + m_destDir;
          getContext().info( message );
          if( getContext().isVerboseEnabled() )
          {
              getContext().verbose( "Compiling the following files:" );
              for( int i = 0; i < compileList.length; i++ )
              {
                  final File file = compileList[ i ];
                  getContext().verbose( file.getAbsolutePath() );
              }
          }
      }
  
      /**
       * Builds the set of file to compile.
       */
      private File[] getCompileList()
          throws TaskException
      {
          final ArrayList allFiles = new ArrayList();
          for( int i = 0; i < m_sourceFilesets.size(); i++ )
          {
              final FileSet fileSet = (FileSet)m_sourceFilesets.get( i );
              final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
              final String[] files = scanner.getIncludedFiles();
              restrictFiles( fileSet.getDir(), files, allFiles );
          }
          return (File[])allFiles.toArray( new File[ allFiles.size() ] );
      }
  
      /**
       * Restricts a set of source files to those that are out-of-date WRT
       * their class file.
       */
      private void restrictFiles( final File srcDir,
                                  final String files[],
                                  final List acceptedFiles )
          throws TaskException
      {
          final GlobPatternMapper mapper = new GlobPatternMapper();
          mapper.setFrom( "*.java" );
          mapper.setTo( "*.class" );
          final SourceFileScanner sfs = new SourceFileScanner();
          final File[] newFiles = sfs.restrictAsFiles( files,
                                                       srcDir,
                                                       m_destDir,
                                                       mapper,
                                                       getContext() );
  
          for( int i = 0; i < newFiles.length; i++ )
          {
              final File file = newFiles[i ];
              acceptedFiles.add( file );
          }
      }
  
      /**
       * Validates the compiler settings.
       */
      private void validate() throws TaskException
      {
          // Validate the destination directory
          if( m_destDir == null )
          {
              throw new TaskException( "No destination directory specified." );
          }
          if( m_destDir.exists() )
          {
              if( !m_destDir.isDirectory() )
              {
                  throw new TaskException( "Destination " + m_destDir + " is not a directory." );
              }
          }
          else
          {
              if( !m_destDir.mkdirs() )
              {
                  throw new TaskException( "Cannot create destination directory " + m_destDir );
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/JavaTask.java
  
  Index: JavaTask.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.txt file.
   */
  package org.apache.antlib.java;
  
  import java.io.File;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.java.ExecuteJava;
  import org.apache.myrmidon.framework.nativelib.Argument;
  import org.apache.myrmidon.framework.nativelib.EnvironmentVariable;
  import org.apache.myrmidon.framework.file.Path;
  
  /**
   * This task acts as a loader for java applications but allows to use the same
   * JVM for the called application thus resulting in much faster operation.
   *
   * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">
   *      stefano@apache.org</a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   *
   * @ant.task name="java"
   */
  public class JavaTask
      extends AbstractTask
  {
      private final ExecuteJava m_exec = new ExecuteJava();
  
      /**
       * Set the class name.
       */
      public void setClassname( final String className )
      {
          m_exec.setClassName( className );
      }
  
      /**
       * Add a classpath element.
       */
      public void addClasspath( final Path classpath )
          throws TaskException
      {
          m_exec.getClassPath().add( classpath );
      }
  
      /**
       * The working directory of the process
       *
       * @param dir The new Dir value
       */
      public void setDir( final File dir )
      {
          m_exec.setWorkingDirectory( dir );
      }
  
      /**
       * Set the forking flag.
       */
      public void setFork( final boolean fork )
      {
          m_exec.setFork( fork );
      }
  
      /**
       * Set the jar name.
       */
      public void setJar( final File jar )
      {
          m_exec.setJar( jar );
      }
  
      /**
       * Set the command used to start the VM (only if fork==true).
       */
      public void setJvm( final String jvm )
      {
          m_exec.setJvm( jvm );
      }
  
      /**
       * -mx or -Xmx depending on VM version
       */
      public void setMaxmemory( final String max )
      {
          m_exec.setMaxMemory( max );
      }
  
      /**
       * Add a nested sysproperty element.
       */
      public void addSysproperty( final EnvironmentVariable sysp )
      {
          m_exec.getSysProperties().addVariable( sysp );
      }
  
      /**
       * Creates a nested arg element.
       */
      public void addArg( final Argument argument )
      {
          m_exec.getArguments().addArgument( argument );
      }
  
      /**
       * Creates a nested jvmarg element.
       */
      public void addJvmarg( final Argument argument )
      {
          m_exec.getVmArguments().addArgument( argument );
      }
  
      public void execute()
          throws TaskException
      {
          m_exec.execute( getContext() );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/JavacAdaptor.java
  
  Index: JavacAdaptor.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.txt file.
   */
  package org.apache.antlib.java;
  
  import java.io.File;
  import java.lang.reflect.Method;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.file.FileListUtil;
  import org.apache.myrmidon.framework.file.Path;
  import org.apache.myrmidon.framework.nativelib.ArgumentList;
  
  /**
   * An adaptor for the in-process Javac compiler.
   *
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   *
   * @ant.type type="java-compiler" name="javac"
   */
  public class JavacAdaptor
      extends JavaCompilerAdaptor
  {
  
      /**
       * Compiles as set of files.
       */
      protected void compile( final File[] compileList )
          throws TaskException
      {
          final ArgumentList cmd = new ArgumentList();
          setupModernJavacCommand( cmd, compileList );
  
          final String[] args = cmd.getArguments();
  
          // Use reflection to be able to build on all JDKs >= 1.2:
          final Class compilerClass;
          try
          {
              compilerClass = Class.forName( "com.sun.tools.javac.Main" );
          }
          catch( ClassNotFoundException exc )
          {
              throw new TaskException( "Could not find the javac compiler.", exc );
          }
  
          try
          {
              final Object compiler = compilerClass.newInstance();
              final Class[] paramTypes = new Class[] { args.getClass() };
              final Method compile = compilerClass.getMethod( "compile", paramTypes );
              final Object[] params = new Object[]{ args };
              final Integer result = (Integer)compile.invoke( compiler, params );
              if( result.intValue() != 0  )
              {
                  throw new TaskException( "Javac finished with non-zero return code." );
              }
          }
          catch( final TaskException exc )
          {
              throw exc;
          }
          catch( final Exception exc )
          {
              throw new TaskException( "Could not start javac compiler", exc );
          }
      }
  
      /**
       * Builds the command-line to invoke the compiler with.
       */
      private void setupModernJavacCommand( final ArgumentList cmd,
                                            final File[] files )
          throws TaskException
      {
          // Build the classpath
          Path classpath = new Path();
  
          classpath.addLocation( getDestDir() );
          classpath.add( getClassPath() );
  
          cmd.addArgument( "-classpath" );
          cmd.addArgument( FileListUtil.formatPath( classpath, getContext() ) );
  
          if( isDeprecation() )
          {
              cmd.addArgument( "-deprecation" );
          }
  
          cmd.addArgument( "-d" );
          cmd.addArgument( getDestDir() );
  
  
          if( isDebug() )
          {
              cmd.addArgument( "-g" );
          }
          else
          {
              cmd.addArgument( "-g:none" );
          }
  
          // Add the files to compile
          for( int i = 0; i < files.length; i++ )
          {
              final File file = files[i ];
              cmd.addArgument( file );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/JavacTask.java
  
  Index: JavacTask.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.txt file.
   */
  package org.apache.antlib.java;
  
  import org.apache.myrmidon.framework.AbstractFacadeTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * A task that compiles Java source files.
   *
   * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
   * @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   *
   * @ant.task name="javac"
   */
  public class JavacTask
      extends AbstractFacadeTask
  {
      public JavacTask()
      {
          super( "compiler", JavaCompilerAdaptor.class, "javac" );
      }
  
      /**
       * Execute this task.
       */
      public void execute()
          throws TaskException
      {
          getContext().verbose( "Using " + getImplementation() + " compiler." );
          final JavaCompilerAdaptor adaptor = (JavaCompilerAdaptor)prepareFacade();
          adaptor.execute();
      }
  
      /**
       * Create the instance of the facade.
       */
      protected Object createFacade()
          throws TaskException
      {
          JavaCompilerAdaptor adaptor = (JavaCompilerAdaptor)super.createFacade();
          adaptor.setContext( getContext() );
          return adaptor;
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/java/JikesAdaptor.java
  
  Index: JikesAdaptor.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.txt file.
   */
  package org.apache.antlib.java;
  
  import java.io.File;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.java.JavaRuntimeClassPath;
  import org.apache.myrmidon.framework.file.Path;
  import org.apache.myrmidon.framework.file.FileListUtil;
  
  /**
   * An adaptor for the jikes compiler.
   *
   * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
   * @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
   *      </a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
   * @author skanthak@muehlheim.de
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/14 10:56:03 $
   *
   * @ant.type type="java-compiler" name="jikes"
   */
  public class JikesAdaptor
      extends ExternalCompilerAdaptor
  {
      /**
       * Builds the command-line to execute the compiler.
       */
      protected void buildCommandLine( final Execute exe, final File tempFile )
          throws TaskException
      {
          final Path classpath = new Path();
  
          // Add the destination directory
          classpath.addLocation( getDestDir() );
  
          // Add the compile classpath
          classpath.add( getClassPath() );
  
          // If the user has set JIKESPATH we should add the contents as well
          String jikesPath = System.getProperty( "jikes.class.path" );
          if( jikesPath != null )
          {
              classpath.add( jikesPath );
          }
  
          // Add the runtime
          classpath.add( new JavaRuntimeClassPath() );
  
          // Build the command line
          exe.setExecutable( "jikes" );
  
          if( isDeprecation() )
          {
              exe.addArgument( "-deprecation" );
          }
  
          if( isDebug() )
          {
              exe.addArgument( "-g" );
          }
  
          exe.addArgument( "-d" );
          exe.addArgument( getDestDir() );
  
          exe.addArgument( "-classpath" );
          exe.addArgument( FileListUtil.formatPath( classpath, getContext() ) );
  
          // TODO - make this configurable
          exe.addArgument( "+E" );
  
          exe.addArgument( "@" + tempFile.getAbsolutePath() );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/nativelib/Exec.java
  
  Index: Exec.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.txt file.
   */
  package org.apache.antlib.nativelib;
  
  import java.io.File;
  import java.util.Properties;
  import org.apache.aut.nativelib.Os;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.nativelib.Execute;
  import org.apache.myrmidon.framework.nativelib.Argument;
  import org.apache.myrmidon.framework.nativelib.EnvironmentData;
  import org.apache.myrmidon.framework.nativelib.EnvironmentVariable;
  
  /**
   * Executes a native command.
   *
   * @author <a href="mailto:duncan@x180.com">JDD</a>
   * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a>
   * @author <a href="mailto:thomas.haas@softwired-inc.com">Thomas Haas</a>
   * @ant.task name="exec"
   */
  public class Exec
      extends AbstractTask
  {
      private final Execute m_exe = new Execute();
      private final EnvironmentData m_env = new EnvironmentData();
      private String m_os;
  
      /**
       * The working directory of the process
       */
      public void setDir( final File dir )
          throws TaskException
      {
          m_exe.setWorkingDirectory( dir );
      }
  
      /**
       * The command to execute.
       */
      public void setExecutable( final String value )
          throws TaskException
      {
          m_exe.setExecutable( value );
      }
  
      /**
       * Use a completely new environment
       */
      public void setNewenvironment( final boolean newEnvironment )
      {
          m_exe.setNewenvironment( newEnvironment );
      }
  
      /**
       * Only execute the process if running on the specified OS family.
       */
      public void setOs( final String os )
      {
          m_os = os;
      }
  
      /**
       * Timeout in milliseconds after which the process will be killed.
       */
      public void setTimeout( final long timeout )
      {
          m_exe.setTimeout( timeout );
      }
  
      /**
       * Add a nested env element - an environment variable.
       */
      public void addEnv( final EnvironmentVariable var )
      {
          m_env.addVariable( var );
      }
  
      /**
       * Add a nested arg element - a command line argument.
       */
      public void addArg( final Argument argument )
      {
          m_exe.addArgument( argument );
      }
  
      public void execute()
          throws TaskException
      {
          if( null != m_os && Os.isFamily( m_os ) )
          {
              return;
          }
  
          // Setup environment vars
          final Properties environment = m_env.getVariables();
          m_exe.setEnvironment( environment );
  
          // execute the command
          m_exe.execute( getContext() );
      }
  
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/nativelib/LoadEnvironment.java
  
  Index: LoadEnvironment.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.txt file.
   */
  package org.apache.antlib.nativelib;
  
  import java.util.Iterator;
  import java.util.Properties;
  import org.apache.aut.nativelib.ExecException;
  import org.apache.aut.nativelib.ExecManager;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.myrmidon.api.AbstractTask;
  import org.apache.myrmidon.api.TaskException;
  
  /**
   * This task is responsible for loading that OS-specific environment
   * variables and adding them as propertys to the context with a specified
   * prefix.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @ant.task name="load-environment"
   */
  public class LoadEnvironment
      extends AbstractTask
  {
      private static final Resources REZ =
          ResourceManager.getPackageResources( LoadEnvironment.class );
  
      private String m_prefix;
  
      public void setPrefix( final String prefix )
      {
          m_prefix = prefix;
      }
  
      public void execute()
          throws TaskException
      {
          if( null == m_prefix )
          {
              final String message = REZ.getString( "loadenv.no-prefix.error" );
              throw new TaskException( message );
          }
  
          //Make sure prefix ends with a '.'
          if( !m_prefix.endsWith( "." ) )
          {
              m_prefix += ".";
          }
  
          if( getContext().isDebugEnabled() )
          {
              final String displayPrefix =
                  m_prefix.substring( 0, m_prefix.length() - 1 );
              final String message =
                  REZ.getString( "loadenv.prefix.notice", displayPrefix );
              getContext().debug( message );
          }
  
          final Properties environment = loadNativeEnvironment();
          final Iterator keys = environment.keySet().iterator();
          while( keys.hasNext() )
          {
              final String key = (String)keys.next();
              final String value = environment.getProperty( key );
  
              if( value.equals( "" ) )
              {
                  final String message = REZ.getString( "loadenv.ignoring-empty.warn", key );
                  getContext().warn( message );
              }
              else
              {
                  getContext().setProperty( m_prefix + key, value );
              }
          }
      }
  
      /**
       * Utility method to load the native environment variables.
       */
      private Properties loadNativeEnvironment()
          throws TaskException
      {
          try
          {
              final ExecManager manager = (ExecManager)getService( ExecManager.class );
              return manager.getNativeEnvironment();
          }
          catch( final ExecException ee )
          {
              throw new TaskException( ee.getMessage(), ee );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/nativelib/OsCondition.java
  
  Index: OsCondition.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.txt file.
   */
  package org.apache.antlib.nativelib;
  
  import org.apache.aut.nativelib.Os;
  import org.apache.myrmidon.api.TaskContext;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.framework.conditions.Condition;
  
  /**
   * Condition to check the current OS.</p>
   *
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @version $Revision: 1.1 $
   *
   * @ant.type type="condition" name="os"
   */
  public class OsCondition
      implements Condition
  {
      private String m_family;
      private String m_name;
      private String m_version;
      private String m_arch;
  
      /**
       * Sets the desired OS family type
       *
       * @param family The OS family type desired.
       */
      public void setFamily( final String family )
      {
          m_family = family;
      }
  
      /**
       * Sets the desired OS name
       *
       * @param name   The OS name
       */
      public void setName( final String name )
      {
          m_name = name;
      }
  
      /**
       * Sets the desired OS architecture
       *
       * @param arch   The OS architecture
       */
      public void setArch( final String arch )
      {
          m_arch = arch;
      }
  
      /**
       * Sets the desired OS version
       *
       * @param version   The OS version
       */
      public void setVersion( final String version )
      {
          m_version = version;
      }
  
      /**
       * Evaluates this condition.
       */
      public boolean evaluate( final TaskContext context )
          throws TaskException
      {
          return Os.isOs( m_family, m_name, m_arch, m_version );
      }
  }
  
  
  
  1.1                  jakarta-ant-myrmidon/antlib/src/java/org/apache/antlib/nativelib/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  loadenv.no-prefix.error=No prefix specified for environment data.
  loadenv.prefix.notice=Loading Environment with prefix {0}.
  loadenv.ignoring-empty.warn=Key {0} in native OS environment is empty - ignoring key.
  
  
  

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


Mime
View raw message