You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by do...@locus.apache.org on 2000/12/04 14:37:33 UTC

cvs commit: jakarta-ant/proposal/myrmidon/src/script ant ant.bat antRun antRun.bat

donaldp     00/12/04 05:37:33

  Added:       proposal/myrmidon .ant.properties build.bat build.sh
                        build.xml emacs-jprj.el
               proposal/myrmidon/lib ant.jar avalonapi.jar xerces.jar
               proposal/myrmidon/src/java/org/apache/ant
                        AntContextResources.java AntException.java
                        Main.java
               proposal/myrmidon/src/java/org/apache/ant/configuration
                        Configurable.java Configuration.java
                        ConfigurationBuilder.java DefaultConfiguration.java
                        SAXConfigurationHandler.java
               proposal/myrmidon/src/java/org/apache/ant/convert
                        AbstractConverter.java Converter.java
                        ConverterEntry.java ConverterFactory.java
                        ConverterInfo.java ConverterLoader.java
                        ConverterRegistry.java DefaultConverterFactory.java
                        DefaultConverterInfo.java
                        DefaultConverterLoader.java
                        DefaultConverterRegistry.java
               proposal/myrmidon/src/java/org/apache/ant/convert/core
                        StringToByteConverter.java
                        StringToDoubleConverter.java
                        StringToFloatConverter.java
                        StringToIntegerConverter.java
                        StringToLongConverter.java
                        StringToShortConverter.java converters.properties
               proposal/myrmidon/src/java/org/apache/ant/project
                        DefaultProject.java DefaultProjectBuilder.java
                        DefaultProjectEngine.java
                        DefaultProjectListener.java DefaultTarget.java
                        Project.java ProjectBuilder.java ProjectEngine.java
                        ProjectListener.java Target.java
               proposal/myrmidon/src/java/org/apache/ant/tasklet
                        AbstractTasklet.java DefaultTaskletContext.java
                        JavaVersion.java Tasklet.java TaskletContext.java
               proposal/myrmidon/src/java/org/apache/ant/tasklet/engine
                        DefaultTaskletConfigurer.java
                        DefaultTaskletEngine.java
                        DefaultTaskletFactory.java DefaultTaskletInfo.java
                        DefaultTaskletLoader.java
                        DefaultTaskletRegistry.java TaskletConfigurer.java
                        TaskletEngine.java TaskletEntry.java
                        TaskletFactory.java TaskletInfo.java
                        TaskletLoader.java TaskletRegistry.java
                        TskDeployer.java
               proposal/myrmidon/src/java/org/apache/ant/tasks/core
                        ConfigurationTest.java ContentTest.java Echo.java
                        PrimitiveTypesTest.java Property.java
                        SubElementTest.java taskdefs.properties
               proposal/myrmidon/src/make sample.xmk
               proposal/myrmidon/src/script ant ant.bat antRun antRun.bat
  Log:
  Initiall checkin of myrmidon proposal
  
  Revision  Changes    Path
  1.1                  jakarta-ant/proposal/myrmidon/.ant.properties
  
  Index: .ant.properties
  ===================================================================
  build.compiler=jikes
  
  
  1.1                  jakarta-ant/proposal/myrmidon/build.bat
  
  Index: build.bat
  ===================================================================
  @echo off
  
  echo.
  echo Ant Build System
  echo ----------------
  
  set ANT_HOME=.
  
  set CLASSPATH=
  
  %ANT_HOME%\bin\ant.bat -emacs %1 %2 %3 %4 %5 %6 %7 %8
  goto cleanup
  
  :cleanup
  set ANT_HOME=
  set CLASSPATH=
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/build.sh
  
  Index: build.sh
  ===================================================================
  #!/bin/sh
  
  echo
  echo "Ant Build System"
  echo "----------------"
  
  chmod u+x $PWD/bin/antRun
  chmod u+x $PWD/bin/ant
  #export ANT_OPTS="-Djava.compiler="
  
  $PWD/bin/ant -emacs $@ | awk -f $PWD/bin/fixPath.awk
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
  ==============================================================================
  
   Ant build file
  
  Authors:
   Peter Donald <do...@apache.org>
  
  Legal:
    Copyright (c) 2000 The Apache Software Foundation. All Rights Reserved.
  
  ==============================================================================
  -->
  
  <project default="main" basedir=".">
  
    <!--
      Give user a chance to override without editing this file
      (and without typing -D each time he compiles it)
    -->
    <property file=".ant.properties"/>
    <property file="${user.home}/.ant.properties"/>
  
    <property name="name" value="ant"/>
    <property name="Name" value="Ant"/>
    <property name="version" value="0.01-myrmidon"/>
    <property name="year" value="2000"/>
  
    <!-- 
      these are here only for those who use jikes compiler. For other 
      developers this part makes no difference.
    -->
    <property name="build.compiler.emacs" value="on"/>
    <property name="build.compiler.warnings" value="true"/>
    <property name="build.compiler.pedantic" value="true"/>
    <property name="build.compiler.depend" value="true"/>
  
    <property name="debug" value="on"/>
    <property name="optimize" value="off"/>
    <property name="deprecation" value="on"/>
  
    <property name="build.dir" value="build"/>
    <property name="build.lib" value="${build.dir}/lib"/>
    <property name="build.src" value="${build.dir}/src"/>
    <property name="build.classes" value="${build.dir}/classes"/>
    <property name="build.javadocs" value="${build.dir}/javadocs"/>
    <property name="build.docs" value="${build.dir}/docs"/>
  
    <property name="src.base" value="src"/>
    <property name="manifest.dir" value="${src.base}/manifest"/>
    <property name="xdocs.dir" value="${src.base}/xdocs"/>
    <property name="src.dir" value="${src.base}/java"/>
    <property name="skins.dir" value="${src.base}/skins"/>
    <property name="script.dir" value="${src.base}/script"/>
    <property name="lib.dir" value="lib"/>
  
    <property name="dist.name" value="${Name}-${version}"/>
    <!--   <property name="dist.dir" value="${dist.name}"/> -->
    <property name="dist.dir" value="dist"/>
    <property name="dist.bin" value="${dist.dir}/bin"/>
    <property name="dist.blocks" value="${dist.dir}/bin/blocks"/>
    <property name="dist.lib" value="${dist.dir}/lib"/>
    <property name="dist.docs" value="${dist.dir}/docs"/>
    <property name="dist.javadocs" value="${dist.dir}/docs/api"/>
    <property name="dist.src.base" value="${dist.dir}/src"/>
    <property name="dist.conf" value="${dist.dir}/conf"/>
    <property name="dist.log" value="${dist.dir}/logs"/>
  
    <property name="constants.file" value="org/apache/ant/Main.java"/>
  
    <!--
         ===================================================================
                                    Main target
         ===================================================================
    -->
    <target name="main" depends="dist" />
  
    <!--
         ===================================================================
                                    Help on usage
         ===================================================================
    -->
    <target name="usage">
      <echo message=""/>
      <echo message="${Name} Build file"/>
      <echo message="-------------------------------------------------------------"/>
      <echo message=""/>
      <echo message=" available targets are:"/>
      <echo message=""/>
      <echo message="   jar        -> generates the ${Name} jar files"/>
      <echo message="   compile    -> compiles the source code"/>
      <echo message="   dist       -> generates the ${Name} distribution (default)"/>
      <echo message="   clean      -> cleans up the created directories"/>
      <echo message="   real-clean -> cleans up all genereated files and directories"/>
  <!--
      <echo message="   test       -> perform unit tests"/>
      <echo message="   javadocs   -> generates the API documentation (java 1.2+ only)"/>
      <echo message="   docs       -> generates the ${Name} documentation"/> 
  -->
      <echo message=""/>
      <echo message="-------------------------------------------------------------"/>
      <echo message=""/>
    </target>
  
    <target name="help" depends="usage"/>
  
    <!--
         ===================================================================
                           Prepares the build directory
         ===================================================================
    -->
    <target name="prepare">
      <tstamp/>
      <mkdir dir="${build.dir}"/>
    </target>
  
    <!--
         ===================================================================
                             Prepares the library code
         ===================================================================
     -->
    <target name="prepare-lib" depends="prepare">
      <mkdir dir="${build.lib}"/>
      <copy file="${lib.dir}/xerces.jar" todir="${build.lib}"/>
      <copy file="${lib.dir}/avalonapi.jar" todir="${build.lib}"/>
    </target>
  
    <!--
         ===================================================================
                             Prepares the source code
         ===================================================================
     -->
    <target name="prepare-src" depends="prepare">
      <mkdir dir="${build.src}"/>
      <copy todir="${build.src}">
        <fileset dir="${src.dir}"/>
      </copy>
   
      <replace file="${build.src}/${constants.file}" token="@@VERSION@@" value="${version}" />
      <replace file="${build.src}/${constants.file}" token="@@DATE@@" value="${TODAY}" />
    </target>
   
    <!--
         ===================================================================
                          Compiles the source code
         ===================================================================
    -->
    <target name="compile" depends="prepare-src,prepare-lib">
  
      <mkdir dir="${build.classes}"/>
      <javac srcdir="${build.src}"
             destdir="${build.classes}"
             debug="${debug}"
             optimize="${optimize}"
             deprecation="${deprecation}" />
  
      <copy todir="${build.classes}">
        <fileset dir="${build.src}">
          <exclude name="**/*.properties"/>
        </fileset>
      </copy>
  
      <mkdir dir="${build.classes}/TASK-LIB"/>
      <copy file="${build.src}/org/apache/ant/tasks/core/taskdefs.properties" 
            todir="${build.classes}/TASK-LIB"/>
      <copy file="${build.src}/org/apache/ant/convert/core/converters.properties" 
            todir="${build.classes}/TASK-LIB"/>
    </target>
  
    <!--
         ===================================================================
                            Creates the ant.jar file
         ===================================================================
    -->
    <target name="jar-ant" depends="compile">
      <jar jarfile="${build.lib}/ant.jar" basedir="${build.classes}">
        <include name="org/apache/ant/**" />
        <exclude name="org/apache/ant/tasks/**" />
        <exclude name="org/apache/ant/convert/core/**" />
      </jar>
    </target>
  
    <!--
         ===================================================================
                            Creates the ant.jar file
         ===================================================================
    -->
    <target name="jar-core" depends="compile">
      <jar jarfile="${build.lib}/core.tsk" basedir="${build.classes}">
        <include name="org/apache/ant/tasks/core/**" />
        <include name="org/apache/ant/convert/core/**" />
        <include name="TASK-LIB/*" />
      </jar>
    </target>
  
    <!--
         ===================================================================
                            Creates the distribution
         ===================================================================
    -->
    <target name="dist" depends="jar-ant,jar-core">
      <mkdir dir="${dist.dir}"/>
      <mkdir dir="${dist.bin}"/>
      <mkdir dir="${dist.lib}"/>
  
      <copy todir="${dist.lib}">
        <fileset dir="${build.lib}">
          <exclude name="xalan*" />
          <exclude name="StyleBook*" />
        </fileset>
      </copy>
  
      <copy todir="${dist.bin}">
        <fileset dir="${script.dir}"/>
      </copy>
  
      <chmod dir="${dist.dir}" perm="go-rwx" />
      <chmod file="${dist.bin}/ant" perm="u+x"/>
      <fixcrlf srcdir="${dist.bin}" cr="add" includes="**/*.bat" />
      <fixcrlf srcdir="${dist.bin}" cr="remove" includes="**/*.sh" />
      <fixcrlf srcdir="${dist.bin}" cr="remove" includes="ant" />
  
    </target>
  
    <!-- 
         ===================================================================
         Performs unit tests
         =================================================================== 
    -->
    <target name="test" depends="jar-ant" if="test-task.present">
      <ant antfile="build-test.xml" dir="src/make" target="test" />
    </target>
  
    <!--
         ===================================================================
                   Cleans up build and distribution directories
         ===================================================================
    -->
    <target name="clean">
      <delete dir="${build.dir}"/>
      <delete dir="${dist.dir}"/>
      <delete>
        <fileset dir="." includes="**/*~" defaultexcludes="no"/>
      </delete>
    </target>
  
    <!--
         ===================================================================
                        Cleans absolutely everything up
         ===================================================================
    -->
    <target name="real-clean" depends="clean">
      <delete file="${dist.name}.tar.gz"/>
      <delete file="${dist.name}.zip"/>
      <delete dir="${javadocs.dir}"/>
    </target>
  
  </project>
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/emacs-jprj.el
  
  Index: emacs-jprj.el
  ===================================================================
  (setq jprj-base-path (message "%s/" (expand-file-name (substitute-in-file-name "."))) )
  (setq jprj-src-path (message "%ssrc/java/" jprj-base-path) )
  (setq jprj-compile-command "./build.bat")
  (setq jprj-run-command "./build.bat&");; cd dist; bin/ant.bat -f ../src/make/sample.xmk&")
  ;(setq tab-expansion-size 4)
  
  (load "update-prj")
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/lib/ant.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-ant/proposal/myrmidon/lib/avalonapi.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-ant/proposal/myrmidon/lib/xerces.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/AntContextResources.java
  
  Index: AntContextResources.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant;
  
  public interface AntContextResources
  {
      // the directory of ant
      String HOME_DIR     = "ant.install.dir"; 
      
      // the bin directory of ant
      String BIN_DIR      = "ant.install.bin"; 
  
      // the lib directory of ant
      String LIB_DIR      = "ant.install.lib"; 
      
      // the tasklib directory of ant
      String TASKLIB_DIR  = "ant.install.task-lib"; 
  
      // the directory to look for per user ant information
      String USER_DIR     = "ant.user.dir"; 
      
      // the directory to look for per project ant information
      String PROJECT_DIR  = "ant.project.dir";
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/AntException.java
  
  Index: AntException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant;
  
  import org.apache.avalon.CascadingRuntimeException;
  
  public class AntException
      extends CascadingRuntimeException
  {
      public AntException( final String message )
      {
          this( message, null );
      }
  
      public AntException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/Main.java
  
  Index: Main.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Iterator;
  import org.apache.ant.project.DefaultProjectEngine;
  import org.apache.ant.project.Project;
  import org.apache.ant.project.ProjectBuilder;
  import org.apache.ant.project.ProjectEngine;
  import org.apache.ant.project.ProjectListener;
  import org.apache.ant.tasklet.JavaVersion;
  import org.apache.ant.tasklet.TaskletContext;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.camelot.Deployer;
  import org.apache.avalon.camelot.DeploymentException;
  import org.apache.avalon.util.StringUtil;
  import org.apache.avalon.util.cli.AbstractMain;
  import org.apache.avalon.util.cli.CLOption;
  import org.apache.avalon.util.cli.CLOptionDescriptor;
  import org.apache.avalon.util.io.ExtensionFileFilter;
  import org.apache.avalon.util.io.FileUtil;
  import org.apache.log.Category;
  import org.apache.log.LogKit;
  import org.apache.log.Logger;
  import org.apache.log.Priority;
  
  /**
   * The class to kick the tires and light the fires.
   * Starts ant, loads ProjectBuilder, builds project then uses ProjectEngine
   * to run project.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class Main
      extends AbstractMain
  {
      public final static String     BUILD_DATE                = "@@DATE@@";
      public final static String     BUILD_VERSION             = "@@VERSION@@";
      public final static String     VERSION                   = 
          "Ant " + BUILD_VERSION + " compiled on " + BUILD_DATE;
  
      protected final static String  DEFAULT_LOGLEVEL          = "INFO";
      protected final static String  DEFAULT_LIB_DIRECTORY     = ".." + File.separator + "lib";
      protected final static String  DEFAULT_TASKLIB_DIRECTORY = DEFAULT_LIB_DIRECTORY;
      protected final static String  DEFAULT_FILENAME          = "build.xmk";
      protected final static String  DEFAULT_LISTENER          = 
          "org.apache.ant.project.DefaultProjectListener";
  
      protected final static String  DEFAULT_BUILDER           =  
          "org.apache.ant.project.DefaultProjectBuilder";
  
      private static final int       HELP_OPT                  = 'h';
      private static final int       QUIET_OPT                 = 'q';
      private static final int       VERBOSE_OPT               = 'v';
      private static final int       FILE_OPT                  = 'f';
      private static final int       LOG_LEVEL_OPT             = 'l';
      private static final int       DEFINE_OPT                = 'D';
      private static final int       VERSION_OPT               = 1;
      private static final int       LISTENER_OPT              = 2;
      private static final int       BIN_DIR_OPT               = 3;
      private static final int       LIB_DIR_OPT               = 4;
      private static final int       TASKLIB_DIR_OPT           = 5;
      private static final int       INCREMENTAL_OPT           = 6;
      private static final int       HOME_DIR_OPT              = 7;
      
      //incompatable options for info options
      private static final int       INFO_OPT_INCOMPAT[]       = new int[] 
      { 
          HELP_OPT, QUIET_OPT, VERBOSE_OPT, FILE_OPT, 
          LOG_LEVEL_OPT, VERSION_OPT, LISTENER_OPT,
          DEFINE_OPT
          //BIN_DIR_OPT, LIB_DIR_OPT, TASKLIB_DIR_OPT, HOME_DIR_OPT
      };
      
      //incompatable options for other logging options
      private static final int       LOG_OPT_INCOMPAT[]        = new int[] 
      {
          QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT
      };
  
      protected Logger               m_logger;
  
      protected File                 m_binDir;
      protected File                 m_homeDir;
      protected File                 m_libDir;
      protected File                 m_taskLibDir;
      protected File                 m_buildFile;
      protected File                 m_userDir;
  
      public static void main( final String args[] )
      {
          final Main main = new Main();
  
          try { main.execute( args ); }
          catch( final AntException ae )
          {
              main.m_logger.error( "Error: " + ae.getMessage() );
              main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( ae ) );
          }
          catch( final Throwable throwable )
          {
              main.m_logger.error( "Error: " + throwable );
              main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( throwable ) );
          }
      }
  
      /**
       * Initialise the options for command line parser.
       */
      protected CLOptionDescriptor[] createCLOptions()
      {
          //TODO: localise
          final CLOptionDescriptor options[] = new CLOptionDescriptor[ 13 ];
  
          options[0] =
              new CLOptionDescriptor( "help",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      HELP_OPT,
                                      "display this help message",
                                      INFO_OPT_INCOMPAT );
          
          options[1] =
              new CLOptionDescriptor( "file",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      FILE_OPT,
                                      "the build file." );
  
          options[2] =
              new CLOptionDescriptor( "log-level",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      LOG_LEVEL_OPT,
                                      "the verbosity level at which to log messages. " +
                                      "(DEBUG|INFO|WARN|ERROR|FATAL_ERROR)",
                                      LOG_OPT_INCOMPAT );
  
          options[3] =
              new CLOptionDescriptor( "quiet",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      QUIET_OPT,
                                      "equivelent to --log-level=FATAL_ERROR",
                                      LOG_OPT_INCOMPAT );
  
          options[4] =
              new CLOptionDescriptor( "verbose",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      VERBOSE_OPT,
                                      "equivelent to --log-level=INFO",
                                      LOG_OPT_INCOMPAT );
  
          options[5] =
              new CLOptionDescriptor( "listener",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      LISTENER_OPT,
                                      "the listener for log events." );
  
          options[6] =
              new CLOptionDescriptor( "version",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      VERSION_OPT,
                                      "display version",
                                      INFO_OPT_INCOMPAT );
  
          options[7] =
              new CLOptionDescriptor( "bin-dir",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      BIN_DIR_OPT,
                                      "the listener for log events." );
  
          options[8] =
              new CLOptionDescriptor( "lib-dir",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      LIB_DIR_OPT,
                                      "the lib directory to scan for jars/zip files." );
  
          options[9] =
              new CLOptionDescriptor( "task-lib-dir",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      TASKLIB_DIR_OPT,
                                      "the task lib directory to scan for .tsk files." );
          options[10] =
              new CLOptionDescriptor( "incremental",
                                      CLOptionDescriptor.ARGUMENT_DISALLOWED,
                                      INCREMENTAL_OPT,
                                      "Run in incremental mode" );
          options[11] =
              new CLOptionDescriptor( "ant-home",
                                      CLOptionDescriptor.ARGUMENT_REQUIRED,
                                      HOME_DIR_OPT,
                                      "Specify ant home directory" );
          options[12] =
              new CLOptionDescriptor( "define",
                                      CLOptionDescriptor.ARGUMENTS_REQUIRED_2,
                                      DEFINE_OPT,
                                      "Define a variable (ie -Dfoo=var)" );
          return options;
      }
  
      /**
       * Entry point for standard ant.
       *
       * @param clOptions the list of command line options
       */
      protected void execute( final List clOptions )
          throws Throwable
      {
          final int size = clOptions.size();
          final ArrayList targets = new ArrayList();
          String filename = null;
          String listenerName = null;
          String builderName = null;
          String logLevel = null;
          String binDir = null;
          String homeDir = null;
          String libDir = null;
          String taskLibDir = null;
          boolean incremental = false;
          HashMap defines = new HashMap();
  
          for( int i = 0; i < size; i++ ) 
          {
              final CLOption option = (CLOption)clOptions.get( i );
                  
              switch( option.getId() )
              {
              case 0: targets.add( option.getArgument() ); break;
              case HELP_OPT: usage(); return;
              case VERSION_OPT: System.out.println( VERSION ); return;
              case FILE_OPT: filename = option.getArgument(); break;
              case BIN_DIR_OPT: binDir = option.getArgument(); break;
              case LIB_DIR_OPT: libDir = option.getArgument(); break;
              case HOME_DIR_OPT: homeDir = option.getArgument(); break;
              case TASKLIB_DIR_OPT: taskLibDir = option.getArgument(); break;
              case VERBOSE_OPT: logLevel = "INFO"; break;
              case QUIET_OPT: logLevel = "ERROR"; break;
              case LOG_LEVEL_OPT: logLevel = option.getArgument(); break; 
              case LISTENER_OPT: listenerName = option.getArgument(); break;
              case INCREMENTAL_OPT: incremental = true; break;
  
              case DEFINE_OPT: 
                  defines.put( option.getArgument( 0 ), option.getArgument( 1 ) );
                  break;
              }
          }
  
          if( null == logLevel ) logLevel = getDefaultLogLevel();
          if( null == listenerName ) listenerName = getDefaultListener();
          if( null == filename ) filename = getDefaultFilename();
          if( null == libDir ) libDir = getDefaultLibDir();
          if( null == taskLibDir ) taskLibDir = getDefaultTaskLibDir();
          if( null == builderName ) builderName = getBuilderNameFor( filename );
  
          setupLogger( logLevel ); //handle logging...
          setupListener( listenerName ); //handle listener..
          setupDefaultAntDirs();        
  
          if( null == binDir && null == homeDir ) 
          {
              m_homeDir = getDefaultHomeDir();
              m_binDir = m_homeDir.getParentFile();
          }
          else if( null == binDir ) // && null != homeDir
          {
              m_homeDir = getHomeDir( homeDir );
              m_binDir = new File( m_homeDir, "bin" );
          }
          else
          {
              m_binDir = getBinDir( binDir );
              m_homeDir = m_binDir.getParentFile();
          }
  
          m_libDir = getLibDir( m_homeDir, libDir );
          m_taskLibDir = getTaskLibDir( m_homeDir, taskLibDir );
          m_buildFile = getFile( filename );
  
          m_logger.info( "Ant Base Directory: " + m_homeDir );
          m_logger.info( "Ant Bin Directory: " + m_binDir );
          m_logger.info( "Ant Build File: " + m_buildFile );
          m_logger.debug( "Ant Lib Directory: " + m_libDir );
          m_logger.debug( "Ant Task Lib Directory: " + m_taskLibDir );
  
          setupContextClassLoader( m_libDir );
  
          final Project project = getProject( builderName, m_buildFile );
          setupProjectContext( project, defines );
  
          final ProjectEngine engine = getProjectEngine();
  
          //make sure Engine is sweet...
          if( engine instanceof Initializable )
          {
              ((Initializable)engine).init();
          }
  
          deployDefaultTaskLibs( engine, m_taskLibDir );
  
          BufferedReader reader = null;
  
          while( true )
          {
              doBuild( engine, project, targets );
  
              if( !incremental ) break;
  
              System.out.println( "Continue ? (Enter no to stop)" );
  
              if( null == reader )
              {
                  reader = new BufferedReader( new InputStreamReader( System.in ) );
              }
  
              String line = reader.readLine();
              
              if( line.equalsIgnoreCase( "no" ) ) break;
              
          }
          
          if( engine instanceof Disposable )
          {
              ((Disposable)engine).dispose();
          }
      }
  
      protected void deployDefaultTaskLibs( final ProjectEngine engine, 
                                            final File taskLibDirectory )
      
      {
          final ExtensionFileFilter filter = 
              new ExtensionFileFilter( new String[] { ".tsk" } );
  
          final File files[] = taskLibDirectory.listFiles( filter );
          final Deployer deployer = engine.getDeployer();
  
          for( int i = 0; i < files.length; i++ )
          {
              final String name = files[ i ].getName();
  
              try
              { 
                  deployer.deploy( name.substring( 0, name.length() - 4 ), 
                                   files[ i ].toURL() );
              }
              catch( final MalformedURLException mue ) {}
              catch( final DeploymentException de )
              {
                  throw new AntException( "Failed to deploy task library " + files[ i ], 
                                          de );
              }
          }
      }
  
      protected void doBuild( final ProjectEngine engine, 
                              final Project project, 
                              final ArrayList targets )
      {
          try
          {
              final int targetCount = targets.size();
          
              if( 0 == targetCount )
              {
                  engine.execute( project, project.getDefaultTargetName() );
              }
              else
              {
                  for( int i = 0; i < targetCount; i++ )
                  {
                      engine.execute( project, (String)targets.get( i ) );
                  }
              }
          }
          catch( final AntException ae )
          {
              m_logger.error( "BUILD FAILED" );
              m_logger.error( "Reason:\n" + StringUtil.printStackTrace( ae, 5, true ) );
          }
      } 
      
      protected void setupLogger( final String logLevel )
      {
          m_logger = createLogger( logLevel );
      }
  
      protected void setupListener( final String listenerName )
      {
          final ProjectListener listener = createListener( listenerName );
          m_logger.addLogTarget( listener );
      }
  
      protected void setupContextClassLoader( final File libDir )
      {
          final ClassLoader classLoader = createClassLoader( libDir );
          Thread.currentThread().setContextClassLoader( classLoader );
      }
  
      protected ClassLoader createClassLoader( final File libDir )
      {
          final ExtensionFileFilter filter = 
              new ExtensionFileFilter( new String[] { ".jar", ".zip" } );
  
          final ArrayList urlList = new ArrayList();
          toURLS( urlList, libDir.listFiles( filter ) );
          
          final URL urls[] = (URL[])urlList.toArray( new URL[0] );
  
          return new URLClassLoader( urls, ClassLoader.getSystemClassLoader() );
      }
  
      protected void toURLS( final ArrayList urls, final File files[] )
      {
          for( int i = 0; i < files.length; i++ )
          {
              try { urls.add( files[ i ].toURL() ); }
              catch( final MalformedURLException mue ) {}
          }
      }
  
      protected Project getProject( final String builderName, final File file )
          throws AntException, IOException
      {
          m_logger.debug( "Ant Project Builder: " + builderName );
          final ProjectBuilder builder = createBuilder( builderName );
          builder.setLogger( m_logger );
  
          //create the project
          final Project project = builder.build( file );
  
          return project;
      }
  
      protected void setupProjectContext( final Project project, final HashMap defines )
          throws AntException
      {
          final TaskletContext context = project.getContext();
          
          final Iterator keys = defines.keySet().iterator();
          //make sure these come before following so they get overidden if user tries to 
          //confuse the system
          while( keys.hasNext() )
          {
              final String key = (String)keys.next();
              final String value = (String)defines.get( key );
              context.setProperty( key, value );
          }
          
          context.setProperty( AntContextResources.HOME_DIR, m_homeDir );
          context.setProperty( AntContextResources.BIN_DIR, m_binDir );
          context.setProperty( AntContextResources.LIB_DIR, m_libDir );
          context.setProperty( AntContextResources.TASKLIB_DIR, m_taskLibDir );
          //context.put( AntContextResources.USER_DIR, m_userDir );
          context.setProperty( TaskletContext.LOGGER, m_logger );
          context.setProperty( TaskletContext.JAVA_VERSION, getJavaVersion() );
      }
  
      protected JavaVersion getJavaVersion()
      {
          JavaVersion version = JavaVersion.JAVA1_0;
  
          try
          {
              Class.forName( "java.lang.Void" );
              version = JavaVersion.JAVA1_1;
              Class.forName( "java.lang.ThreadLocal" );
              version = JavaVersion.JAVA1_2;
              Class.forName( "java.lang.StrictMath" );
              version = JavaVersion.JAVA1_3;
          } 
          catch( final ClassNotFoundException cnfe ) {}
  
          return version;
      }
  
      protected ProjectEngine getProjectEngine()
      {
          final ProjectEngine engine = createProjectEngine();
          engine.setLogger( m_logger );
          return engine;
      }
  
      protected ProjectEngine createProjectEngine()
      {
          return new DefaultProjectEngine();
      }
  
      protected File getHomeDir( final String homeDir )
          throws AntException
      {
          final File file = new File( homeDir );
          checkDirectory( file, "ant-home" );
          return file;
      }
  
      protected File getBinDir( final String binDir )
          throws AntException
      {
          File file = (new File( binDir )).getAbsoluteFile();
          if( !file.isDirectory() ) file = file.getParentFile();
          checkDirectory( file, "bin-dir" );
          return file;
      }
  
      protected File getLibDir( final File antHome, String libDir )
          throws AntException
      {
          return resolveDirectory( antHome, libDir, "lib-dir" );
      }
  
      protected File getTaskLibDir( final File antHome, final String taskLibDir )
          throws AntException
      {
          return resolveDirectory( antHome, taskLibDir, "task-lib-dir" );
      }
  
      protected File resolveDirectory( final File antHome, final String dir, final String name )
          throws AntException
      {
          final File file = FileUtil.resolveFile( antHome, dir );
          checkDirectory( file, name );
          return file;
      }
  
      protected void checkDirectory( final File file, final String name )
      { 
          if( !file.exists() )
          {
              throw new AntException( name + " (" + file + ") does not exist" );
          }
          else if( !file.isDirectory() )
          {
              throw new AntException( name + " (" + file + ") is not a directory" );
          }
      }
  
      protected ProjectListener createListener( final String listenerName )
          throws AntException
      {
          try { return (ProjectListener)createObject( listenerName, "listener" ); }
          catch( final ClassCastException cce )
          {
              throw new AntException( "Aparently the listener named " + listenerName +
                                      " does not implement the ProjectListener interface",
                                      cce );
          }
      }
  
      protected Logger createLogger( final String logLevel )
          throws AntException
      {
          final String logLevelCapitalized = logLevel.toUpperCase();
          final Priority.Enum priority = LogKit.getPriorityForName( logLevelCapitalized );
  
          if( !priority.getName().equals( logLevelCapitalized ) )
          {
              throw new AntException( "Unknown log level - " + logLevel );
          }
          
          final Category category = LogKit.createCategory( "ant", priority );
          return LogKit.createLogger( category );
      }
  
      protected void setupDefaultAntDirs()
      {
          final String os = System.getProperty( "os.name" );
          final String userDir = System.getProperty( "user.home" );
          m_userDir = 
              (new File( getUserLocationFor( os, userDir ) )).getAbsoluteFile();
      }
  
      /**
       * Retrieve default bin-dir value if possible (Otherwise throw an exception).
       *
       * Lookup OS specific places for ant to be. 
       * /opt/ant on *BSD ?
       * /usr/local/ant on linux ?
       * /Program Files/Ant on Win32 ?
       *
       * @return bin directory
       */
      protected File getDefaultHomeDir()
          throws AntException
      {
          if( null != m_userDir )
          {
              try 
              {
                  checkDirectory( m_userDir, null );
                  return m_userDir;
              }
              catch( final AntException ae ) {}
          }
  
          final String os = System.getProperty( "os.name" );
          final File candidate = 
              (new File( getSystemLocationFor( os ) )).getAbsoluteFile();
          checkDirectory( candidate, "ant-home" );
          return candidate;
      }
  
      /**
       * This determins a mapping from an OS specific place to ants home directory.
       * In later versions the mapping should be read from configuration file.
       *
       * @param os the name of OS
       * @return the location of directory
       */
      protected String getUserLocationFor( final String os, final String userDir )
      {
          if( os.startsWith( "Windows" ) )
          {
              return userDir + "\\Ant";
          }
          else if( '/' == File.separatorChar )
          {
              if( os.startsWith( "Linux" ) ) return userDir + "/ant";
              else return userDir + "/opt/ant";
          }
          else
          {
              return userDir + File.separator + "ant";
          }
      }
  
      /**
       * This determins a mapping from an OS specific place to ants home directory.
       * In later versions the mapping should be read from configuration file.
       *
       * @param os the name of OS
       * @return the location of directory
       */
      protected String getSystemLocationFor( final String os )
      {
          if( os.startsWith( "Windows" ) )
          {
              return "\\Program Files\\Ant";
          }
          else if( '/' == File.separatorChar )
          {
              if( os.startsWith( "Linux" ) ) return "/usr/local/ant";
              else return "/opt/ant";
          }
          else
          {
              return File.separator + "ant";
          }
      }
  
      protected String getDefaultLibDir()
      {
          return DEFAULT_LIB_DIRECTORY;
      }
  
      protected String getDefaultTaskLibDir()
      {
          return DEFAULT_TASKLIB_DIRECTORY;
      }
  
      /**
       * Retrieve default filename. Overide this in base classes to change default.
       *
       * @return the default filename
       */
      protected String getDefaultFilename()
      {
          return DEFAULT_FILENAME;
      }
   
      /**
       * Retrieve default logelevel. Overide this in base classes to change default.
       *
       * @return the default loglevel
       */
      protected String getDefaultLogLevel()
      {
          return DEFAULT_LOGLEVEL;
      }
     
      /**
       * Retrieve default listener. Overide this in base classes to change default.
       *
       * @return the default listener
       */
      protected String getDefaultListener()
      {
          return DEFAULT_LISTENER;
      }
  
      /**
       * Get File object for filename.
       * Check that file exists and is not a directory.
       *
       * @param filename the filename
       * @return the file object
       * @exception AntException if an error occurs
       */
      protected File getFile( final String filename )
          throws AntException, IOException
      {
          final File file = (new File( filename )).getCanonicalFile();
              
          if( !file.exists() )
          {
              throw new AntException( "File " + file + " does not exist." );
          }
          
          if( file.isDirectory() )
          {
              throw new AntException( "File " + file + " is a directory." );
          }
  
          return file;
      }
  
      /**
       * Create instance of Builder based on classname.
       *
       * @param builderName builder class name
       * @return the ProjectBuilder
       * @exception AntException if an error occurs
       */
      protected ProjectBuilder createBuilder( final String builderName )
          throws AntException
      {
          try { return (ProjectBuilder)createObject( builderName, "builder" ); }
          catch( final ClassCastException cce )
          {
              throw new AntException( "Aparently the builder named " + builderName +
                                      " does not implement the ProjectBuilder interface",
                                      cce );
          }
      }
  
      /**
       * Helper method to create object and throw an apporpriate AntException if creation failed.
       *
       * @param objectName the classname of object
       * @param type the type of object being created (ie builder|listener)
       * @return the created object
       * @exception AntException if an error occurs
       */
      protected Object createObject( final String objectName, final String type )
          throws AntException
      {
          try
          {
              final Class clazz = Class.forName( objectName );
              return clazz.newInstance();
          }
          catch( final IllegalAccessException iae )
          {
              throw new AntException( "Non-public constructor for " + type + " " + objectName, 
                                      iae );
          }
          catch( final InstantiationException ie )
          {
              throw new AntException( "Error instantiating class for " + type + " " + objectName, 
                                      ie );
          }
          catch( final ClassNotFoundException cnfe )
          {
              throw new AntException( "Could not find the class for " + type + " " + objectName, 
                                      cnfe );
          }
      }
  
      /**
       * Retrieve class name of builder for file.
       * Eventually this will look in a registry of file extentions to BuilderNames.
       *
       * @param filename the filename
       * @return the name of Class for Builder
       * @exception AntException if an error occurs
       */
      protected String getBuilderNameFor( final String filename )
          throws AntException
      {
          return DEFAULT_BUILDER;
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/Configurable.java
  
  Index: Configurable.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.configuration;
  
  import org.apache.avalon.ConfigurationException;
  
  /**
   * This interface should be implemented by classes that need to be
   * configured with custom parameters before initialization.
   * <br />
   *
   * The contract surrounding a <code>Configurable</code> is that the
   * instantiating entity must call the <code>configure</code>
   * method before it is valid.  The <code>configure</code> method
   * must be called after the constructor, and before any other method.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Configurable
  {
      /**
       * Pass the <code>Configuration</code> to the <code>Configurable</code>
       * class. This method must always be called after the constructor
       * and before any other method.
       *
       * @param configuration the class configurations.
       */
      void configure( Configuration configuration ) 
          throws ConfigurationException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/Configuration.java
  
  Index: Configuration.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.configuration;
  
  import java.util.Iterator;
  
  /**
   * Hostile fork till Avalon gets equivelent functionality ;)
   */
  public interface Configuration
      extends org.apache.avalon.Configuration
  {
      /**
       * Retrieve a list of all child names.
       *
       * @return the child names
       */
      Iterator getChildren();
  
      /**
       * Retrieve a list of all attribute names.
       *
       * @return the attribute names
       */
      Iterator getAttributeNames();
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/ConfigurationBuilder.java
  
  Index: ConfigurationBuilder.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.configuration;
  
  import org.xml.sax.SAXException;
  
  /**
   * Hostile fork till Avalon gets equivelent functionality ;)
   */
  public class ConfigurationBuilder
      extends org.apache.avalon.DefaultConfigurationBuilder
  {
      public ConfigurationBuilder()
          throws SAXException
      {
          super();
      }
  
      protected org.apache.avalon.SAXConfigurationHandler getHandler()
      {
          return new SAXConfigurationHandler();
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfiguration.java
  
  Index: DefaultConfiguration.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.configuration;
  
  import java.util.Iterator;
  
  /**
   * Hostile fork till Avalon gets equivelent functionality ;)
   */
  public class DefaultConfiguration
      extends org.apache.avalon.DefaultConfiguration
      implements Configuration
  {
      public DefaultConfiguration( final String localname, final String location )
      {
          super( localname, location );
      }
  
      /**
       * Retrieve a list of all child names.
       *
       * @return the child names
       */
      public Iterator getChildren()
      {
          if( null == m_children ) return EMPTY_ITERATOR;
          else return m_children.iterator();
      }
      
      /**
       * Retrieve a list of all attribute names.
       *
       * @return the attribute names
       */
      public Iterator getAttributeNames()
      {
          if( null == m_attributes ) return EMPTY_ITERATOR;
          else return m_attributes.keySet().iterator();
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/SAXConfigurationHandler.java
  
  Index: SAXConfigurationHandler.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.configuration;
  
  /**
   * Hostile fork till Avalon gets equivelent functionality ;)
   */
  public class SAXConfigurationHandler
      extends org.apache.avalon.SAXConfigurationHandler
  {
      protected org.apache.avalon.DefaultConfiguration 
          createConfiguration( final String localName, final String location )
      {
          return new DefaultConfiguration( localName, location );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/AbstractConverter.java
  
  Index: AbstractConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  /**
   * Instances of this interface are used to convert between different types.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractConverter
      implements Converter
  {
      protected final Class         m_source;
      protected final Class         m_destination;
  
      public AbstractConverter( final Class source, final Class destination )
      {
          m_source = source;
          m_destination = destination;
      }
  
      public Object convert( final Class destination, final Object original )
          throws Exception
      {
          if( m_destination != destination )
          {
              throw new IllegalArgumentException( "Destination type " + destination.getName() +
                                                  " is not equal to " + m_destination );
          }
  
          if( !m_source.isInstance( original ) )
          {
              throw new IllegalArgumentException( "Object '" + original + "' is not an " + 
                                                  "instance of " + m_source.getName() );
          }
              
          return convert( original );
      }
  
      protected abstract Object convert( Object original )
          throws Exception;
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/Converter.java
  
  Index: Converter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  /**
   * Instances of this interface are used to convert between different types.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Converter
  {
      Object convert( Class destination, Object original )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEntry.java
  
  Index: ConverterEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import org.apache.ant.convert.Converter;
  import org.apache.avalon.camelot.AbstractEntry;
  
  public class ConverterEntry
      extends AbstractEntry
  {
      public ConverterEntry( final ConverterInfo info, final Converter converter )
      {
          super( info, converter );
      }
      
      /**
       * Retrieve instance of converter.
       *
       * @return the component instance
       */
      public Converter getConverter()
      {
          return (Converter)getInstance();
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterFactory.java
  
  Index: ConverterFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import org.apache.avalon.camelot.Factory;
  import org.apache.avalon.camelot.FactoryException;
  
  /**
   * Facility used to load Converters.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ConverterFactory
      extends Factory
  {
      ConverterEntry create( ConverterInfo info ) 
          throws FactoryException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterInfo.java
  
  Index: ConverterInfo.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import java.net.URL;
  import org.apache.avalon.camelot.Info;
  
  /**
   * This info represents meta-information about a converter.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ConverterInfo
      extends Info
  {
      /**
       * Retrieve the source type from which it can convert.
       * NB: Should this be an array ????
       *
       * @return the classname from which object produced
       */
      String getSource();
  
      /**
       * Retrieve the type to which the converter converts.
       * NB: Should this be an array ????
       *
       * @return the classname of the produced object
       */
      String getDestination();
  
      /**
       * Retrieve classname for concerter.
       *
       * @return the taskname
       */
      String getClassname();
  
      /**
       * Retrieve location of task library where task is contained.
       *
       * @return the location of task library
       */
      URL getLocation();
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterLoader.java
  
  Index: ConverterLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import org.apache.avalon.camelot.Loader;
  
  /**
   * Class used to load converters et al from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ConverterLoader
      extends Loader
  {
      Converter loadConverter( String converter )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterRegistry.java
  
  Index: ConverterRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import org.apache.avalon.camelot.Registry;
  
  public interface ConverterRegistry
      extends Registry
  {
      ConverterInfo getConverterInfo( String source, String destination );
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterFactory.java
  
  Index: DefaultConverterFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.HashMap;
  import org.apache.ant.convert.Converter;
  import org.apache.avalon.camelot.Entry;
  import org.apache.avalon.camelot.Factory;
  import org.apache.avalon.camelot.Loader;
  import org.apache.avalon.camelot.FactoryException;
  import org.apache.avalon.camelot.Info;
  
  /**
   * Facility used to load Converters.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultConverterFactory
      implements ConverterFactory
  {
      protected final HashMap         m_loaders        = new HashMap();
      
      public Entry create( final Info info )
          throws FactoryException
      {
          if( info.getClass().equals( ConverterInfo.class ) )
          {
              throw new IllegalArgumentException( "Passed incorrect Info type to factory" );
          }
          return create( (ConverterInfo)info );
      }
      
      public ConverterEntry create( final ConverterInfo info )
          throws FactoryException
      {
          final ConverterLoader loader = getLoader( info.getLocation() );
          
          Object object = null;
          
          try { object = loader.load( info.getClassname() ); }
          catch( final Exception e )
          {
              throw new FactoryException( "Failed loading converter from " + info.getLocation() +
                                          " due to " + e, e );
          }
          
          return new ConverterEntry( info, (Converter)object );        
      }
      
      protected ConverterLoader getLoader( final URL location )
      {
          ConverterLoader loader = (ConverterLoader)m_loaders.get( location );
          
          if( null == loader )
          {
              loader = createLoader( location );
              m_loaders.put( location, loader );
          }
          
          return loader;
      }
      
      protected ConverterLoader createLoader( final URL location )
      {
          if( null != location ) return new DefaultConverterLoader( location );
          else return new DefaultConverterLoader();
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterInfo.java
  
  Index: DefaultConverterInfo.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import java.net.URL;
  
  /**
   * This info represents meta-information about a converter.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultConverterInfo
      implements ConverterInfo
  {
      protected final String            m_source;
      protected final String            m_destination;
      protected final String            m_classname;
      protected final URL               m_location;
  
      public DefaultConverterInfo( final String source, 
                                   final String destination,
                                   final String classname,
                                   final URL location )
      {
          m_source = source;
          m_destination = destination;
          m_classname = classname;
          m_location = location;
      } 
  
      /**
       * Retrieve the source type from which it can convert.
       * NB: Should this be an array ????
       *
       * @return the classname from which object produced
       */
      public String getSource()
      {
          return m_source;
      }
      
      /**
       * Retrieve the type to which the converter converts.
       * NB: Should this be an array ????
       *
       * @return the classname of the produced object
       */
      public String getDestination()
      {
          return m_destination;
      }
      
      /**
       * Retrieve classname for concerter.
       *
       * @return the taskname
       */
      public String getClassname()
      {
          return m_classname;
      }
  
      /**
       * Retrieve location of task library where task is contained.
       *
       * @return the location of task library
       */
      public URL getLocation()
      {
          return m_location;
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterLoader.java
  
  Index: DefaultConverterLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import org.apache.avalon.camelot.AbstractLoader;
  
  /**
   * Class used to load converters et al from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultConverterLoader
      extends AbstractLoader
      implements ConverterLoader
  {
      public DefaultConverterLoader()
      {
          super( new URLClassLoader( new URL[0], 
                                     Thread.currentThread().getContextClassLoader() ) );
      }
      
      public DefaultConverterLoader( final URL location )
      {
          super( new URLClassLoader( new URL[] { location } ) );
      }
      
      public Converter loadConverter( final String converter )
          throws Exception
      {
          return (Converter)load( converter );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterRegistry.java
  
  Index: DefaultConverterRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert;
  
  import java.util.HashMap;
  import org.apache.avalon.camelot.AbstractRegistry;
  import org.apache.avalon.camelot.Info;
  import org.apache.avalon.camelot.RegistryException;
  
  public class DefaultConverterRegistry
      extends AbstractRegistry
      implements ConverterRegistry
  {
      protected final HashMap         m_mapping        = new HashMap();
  
      public ConverterInfo getConverterInfo( final String source, final String destination )
      {
          final HashMap map = (HashMap)m_mapping.get( source );
          if( null == map ) return null;
          return (ConverterInfo)map.get( destination );
      }
  
      protected void checkInfo( final String name, final Info info )
          throws RegistryException
      {
          super.checkInfo( name, info );
  
          final ConverterInfo converterInfo = (ConverterInfo)info;
          final String source = converterInfo.getSource();
          final String destination = converterInfo.getDestination();
  
          HashMap map = (HashMap)m_mapping.get( source );
          if( null == map )
          {
              map = new HashMap();
              m_mapping.put( source, map );
          }
          
          map.put( destination, info );        
      }
  
      protected Class getInfoClass()
      {
          return ConverterInfo.class;
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToByteConverter.java
  
  Index: StringToByteConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to byte converter
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToByteConverter
      extends AbstractConverter
  {
      public StringToByteConverter()
      {
          super( String.class, Byte.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Byte( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToDoubleConverter.java
  
  Index: StringToDoubleConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to double converter
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToDoubleConverter
      extends AbstractConverter
  {
      public StringToDoubleConverter()
      {
          super( String.class, Double.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Double( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToFloatConverter.java
  
  Index: StringToFloatConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to float converter
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToFloatConverter
      extends AbstractConverter
  {
      public StringToFloatConverter()
      {
          super( String.class, Float.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Float( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToIntegerConverter.java
  
  Index: StringToIntegerConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to integer converter.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToIntegerConverter
      extends AbstractConverter
  {
      public StringToIntegerConverter()
      {
          super( String.class, Integer.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Integer( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToLongConverter.java
  
  Index: StringToLongConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to long converter
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToLongConverter
      extends AbstractConverter
  {
      public StringToLongConverter()
      {
          super( String.class, Long.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Long( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToShortConverter.java
  
  Index: StringToShortConverter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.convert.core;
  
  import org.apache.ant.convert.AbstractConverter;
  
  /**
   * String to short converter
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class StringToShortConverter
      extends AbstractConverter
  {
      public StringToShortConverter()
      {
          super( String.class, Short.class );
      }
  
      public Object convert( final Object original )
          throws Exception
      {
          return new Short( (String)original );
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/converters.properties
  
  Index: converters.properties
  ===================================================================
  org.apache.ant.convert.core.StringToLongConverter=java.lang.String, java.lang.Long
  org.apache.ant.convert.core.StringToIntegerConverter=java.lang.String, java.lang.Integer
  org.apache.ant.convert.core.StringToShortConverter=java.lang.String, java.lang.Short
  org.apache.ant.convert.core.StringToByteConverter=java.lang.String, java.lang.Byte
  org.apache.ant.convert.core.StringToDoubleConverter=java.lang.String, java.lang.Double
  org.apache.ant.convert.core.StringToFloatConverter=java.lang.String, java.lang.Float
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProject.java
  
  Index: DefaultProject.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.DefaultTaskletContext;
  import org.apache.ant.tasklet.TaskletContext;
  
  public class DefaultProject
      implements Project
  {
      protected final TaskletContext       m_baseContext     = new DefaultTaskletContext();
      protected final HashMap              m_targets         = new HashMap();
      protected Target                     m_implicitTarget;
      protected String                     m_defaultTarget;
  
      public Target getImplicitTarget()
      {
          return m_implicitTarget;
      }
  
      public void setImplicitTarget( final Target target )
      {
          m_implicitTarget = target;
      }
  
      public Target getTarget( final String targetName )
      {
          return (Target)m_targets.get( targetName );
      }
  
      public String getDefaultTargetName()
      {
          return m_defaultTarget;
      }
  
      public Iterator getTargetNames()
      {
          return m_targets.keySet().iterator();
      }
      
      public TaskletContext getContext()
      {
          return m_baseContext;
      }
  
      public void setDefaultTargetName( final String defaultTarget )
      {
          m_defaultTarget = defaultTarget;
      }
  
      public void addTarget( final String name, final Target target )
          throws AntException
      {
          if( null != m_targets.get( name ) )
          {
              throw new AntException( "Can not have two targets in a file with the name " +
                                      name );
          }
          else
          {
              m_targets.put( name, target );
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java
  
  Index: DefaultProjectBuilder.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.Iterator;
  import org.apache.ant.AntException;
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.configuration.ConfigurationBuilder;
  import org.apache.ant.tasklet.TaskletContext;
  import org.apache.avalon.ConfigurationException;
  import org.apache.log.Logger;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  public class DefaultProjectBuilder
      implements ProjectBuilder
  {
      protected final ConfigurationBuilder  m_configurationBuilder;
      protected Logger                      m_logger;
  
      public DefaultProjectBuilder()
      {
          ConfigurationBuilder builder = null;
          try { builder = new ConfigurationBuilder(); }
          catch( final SAXException se ) {}
  
          m_configurationBuilder = builder;
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      public Project build( final File projectFile )
          throws IOException, AntException
      {
          try
          {
              final String location = projectFile.getCanonicalFile().toURL().toString();
              final InputSource inputSource = new InputSource( location );
              final Configuration configuration = 
                  (Configuration)m_configurationBuilder.build( inputSource );
              return build( projectFile, configuration );
          }
          catch( final SAXException se )
          {
              throw new AntException( "SAXEception: " + se.getMessage(), se );
          }
          catch( final ConfigurationException ce )
          {
              throw new AntException( "ConfigurationException: " + ce.getMessage(), ce );
          }
      }
  
      protected Project build( final File file, final Configuration configuration )
          throws IOException, AntException, ConfigurationException
      {
          if( !configuration.getName().equals("project") )
          {
              throw new AntException( "Project file must be enclosed in project element" );
          }
          
          final String baseDirectoryName = configuration.getAttribute( "basedir" );
          final String defaultTarget = configuration.getAttribute( "default" );
          final String projectName = configuration.getAttribute( "name" );
  
          final DefaultProject project = new DefaultProject();
          project.setDefaultTargetName( defaultTarget );
  
          final File baseDirectory = 
              (new File( file.getParentFile(), baseDirectoryName )).getAbsoluteFile();
  
          m_logger.debug( "Project " + projectName + " base directory: " + baseDirectory );
          
          final TaskletContext context = project.getContext();
          context.setProperty( TaskletContext.BASE_DIRECTORY, baseDirectory );
          context.setProperty( Project.PROJECT_FILE, file );
          context.setProperty( Project.PROJECT, projectName );
  
          buildTopLevelProject( project, configuration );
  
          return project;
      }
  
      protected void buildTopLevelProject( final DefaultProject project, 
                                           final Configuration configuration )
          throws AntException
      {
          final Iterator elements = configuration.getChildren();
  
          while( elements.hasNext() )
          {
              final Configuration element = (Configuration)elements.next();
              final String name = element.getName();
  
              if( name.equals( "target" ) ) buildTarget( project, element );
              else if( name.equals( "property" ) ) buildProperty( project, element );
              else
              {
                  throw new AntException( "Unknown top-level element " + name + 
                                          " at " + element.getLocation() );
              }
          }
      }
  
      protected void buildTarget( final DefaultProject project, 
                                  final Configuration configuration )
      {
          final String name = configuration.getAttribute( "name", null );
          final String depends = configuration.getAttribute( "depends", null );
          final String ifCondition = configuration.getAttribute( "if", null );
          final String unlessCondition = configuration.getAttribute( "unless", null );
  
          if( null == name )
          {
              throw new AntException( "Discovered un-named target at " + 
                                      configuration.getLocation() );
          } 
  
          m_logger.debug( "Parsing target: " + name );
  
          if( null != ifCondition && null != unlessCondition )
          {
              throw new AntException( "Discovered invalid target that has both a if and " +
                                      "unless condition at " + configuration.getLocation() );    
          }
  
          final DefaultTarget target = new DefaultTarget();
          
          if( null != ifCondition )
          {
              m_logger.debug( "Target if condition: " + ifCondition );
              target.setIfCondition( true );
              target.setCondition( ifCondition );
          }
          else if( null != unlessCondition )
          {
              m_logger.debug( "Target unless condition: " + unlessCondition );
              target.setIfCondition( false );
              target.setCondition( unlessCondition );
          }
  
          if( null != depends )
          {
              int start = 0;
              int end = depends.indexOf( ',' );
  
              while( -1 != end )
              {
                  final String dependency = 
                      parseDependency( configuration, depends.substring( start, end ) );
  
                  target.addDependency( dependency );
                  start = end++;
                  end = depends.indexOf( ',', start );
              }    
  
              final String dependency = 
                  parseDependency( configuration, depends.substring( start ) );
  
              target.addDependency( dependency );
          }
  
          final Iterator tasks = configuration.getChildren();
          while( tasks.hasNext() )
          {
              final Configuration task = (Configuration)tasks.next();
              m_logger.debug( "Parsed task: " + task.getName() );
              target.addTask( task );
          }
  
          project.addTarget( name, target );
      }
  
      protected String parseDependency( final Configuration configuration, 
                                        String dependency ) 
          throws AntException
      {
          dependency = dependency.trim();
          
          if( 0 == dependency.length() )
          {
              throw new AntException( "Discovered empty dependency in target " + 
                                      configuration.getName() + " at " + 
                                      configuration.getLocation() ); 
          }
          
          m_logger.debug( "Target dependency: " + dependency );
  
          return dependency;
      }
  
      protected void buildProperty( final DefaultProject project, 
                                    final Configuration configuration )
      {       
          DefaultTarget target = (DefaultTarget)project.getImplicitTarget();
          
          if( null == target )
          {
              target = new DefaultTarget();
              project.setImplicitTarget( target );
          }
  
          m_logger.debug( "Parsed implicit task: " + configuration.getName() );
          target.addTask( configuration );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java
  
  Index: DefaultProjectEngine.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import org.apache.ant.AntException;
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.convert.ConverterRegistry;
  import org.apache.ant.convert.DefaultConverterRegistry;
  import org.apache.ant.tasklet.DefaultTaskletContext;
  import org.apache.ant.tasklet.TaskletContext;
  import org.apache.ant.tasklet.engine.DefaultTaskletEngine;
  import org.apache.ant.tasklet.engine.DefaultTaskletInfo;
  import org.apache.ant.tasklet.engine.DefaultTaskletRegistry;
  import org.apache.ant.tasklet.engine.TaskletEngine;
  import org.apache.ant.tasklet.engine.TaskletRegistry;
  import org.apache.ant.tasklet.engine.TskDeployer;
  import org.apache.avalon.DefaultComponentManager;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.camelot.Deployer;
  import org.apache.avalon.camelot.DeploymentException;
  import org.apache.avalon.camelot.RegistryException;
  import org.apache.log.Logger;
  
  public class DefaultProjectEngine
      implements ProjectEngine, Initializable, Disposable
  {
      protected Deployer              m_deployer;
      protected TaskletRegistry       m_taskletRegistry;
      protected ConverterRegistry     m_converterRegistry;
      protected TaskletEngine         m_taskletEngine;
      protected Logger                m_logger;
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      public void init()
          throws Exception
      {
          m_taskletEngine = createTaskletEngine();
  
          m_taskletRegistry = createTaskletRegistry();
          m_converterRegistry = createConverterRegistry();
          m_deployer = createDeployer();
  
          //final DefaultTaskletContext context = new DefaultTaskletContext();
          //m_taskletEngine.contextualize( context );
  
          final DefaultComponentManager componentManager = new DefaultComponentManager();
          componentManager.put( "org.apache.ant.tasklet.engine.TaskletRegistry", 
                                m_taskletRegistry );
  
          componentManager.put( "org.apache.ant.convert.ConverterRegistry", 
                                m_converterRegistry );
  
          componentManager.put( "org.apache.avalon.camelot.Deployer", m_deployer );
         
          m_taskletEngine.compose( componentManager );
          
          if( m_taskletEngine instanceof Initializable )
          {
              ((Initializable)m_taskletEngine).init();
          }
      }
  
      public void dispose()
          throws Exception
      {
          if( m_taskletEngine instanceof Disposable )
          {
              ((Disposable)m_taskletEngine).dispose();
          }
      }
  
      public Deployer getDeployer()
      {
          return m_deployer;
      }
  
      protected TaskletEngine createTaskletEngine()
      {
          return new DefaultTaskletEngine();
      }    
      
      protected TaskletRegistry createTaskletRegistry()
      {
          return new DefaultTaskletRegistry();
      }
      
      protected ConverterRegistry createConverterRegistry()
      {
          return new DefaultConverterRegistry();
      }
         
      protected Deployer createDeployer()
      {
          final TskDeployer deployer = 
              new TskDeployer( m_taskletRegistry, m_converterRegistry );
          deployer.setLogger( m_logger );
          return deployer;
      }
          
      public void execute( final Project project, final String target )
          throws AntException
      {
          m_taskletEngine.contextualize( project.getContext() );
          executeTarget( "<init>", project.getImplicitTarget() );
  
          final ArrayList done = new ArrayList();
          execute( project, target, done );
      }
  
      protected void execute( final Project project, 
                              final String targetName, 
                              final ArrayList done )
          throws AntException
      {
          final Target target = project.getTarget( targetName );
  
          if( null == target )
          {
              throw new AntException( "Unable to find target " + targetName );
          }
  
          done.add( targetName );
  
          final Iterator dependencies = target.getDependencies();
          while( dependencies.hasNext() )
          {
              final String dependency = (String)dependencies.next();
              if( !done.contains( dependency ) )
              {
                  execute( project, dependency, done );
              }
          }
  
          final TaskletContext context = getContextFor( project, targetName );
          m_taskletEngine.contextualize( context );
          executeTarget( targetName, target );
      }
  
      protected TaskletContext getContextFor( final Project project, final String targetName )
      {
          final DefaultTaskletContext context = 
              new DefaultTaskletContext( project.getContext() );
  
          context.setProperty( Project.TARGET, targetName );
          context.put( TaskletContext.LOGGER, m_logger );
  
          return context;
      }
  
      protected void executeTarget( final String targetName, final Target target )
          throws AntException
      {
          m_logger.debug( "Executing target " + targetName );
          
          final Iterator tasks = target.getTasks();
          while( tasks.hasNext() )
          {
              final Configuration task = (Configuration)tasks.next();
              executeTask( task );
          }
      }
  
      protected void executeTask( final Configuration configuration )
          throws AntException
      {
          final String name = configuration.getName();
          m_logger.debug( "Executing task " + name );
  
          m_taskletEngine.execute( configuration );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectListener.java
  
  Index: DefaultProjectListener.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import org.apache.log.format.PatternFormatter;
  import org.apache.log.output.DefaultOutputLogTarget;
  
  public class DefaultProjectListener
      extends DefaultOutputLogTarget
      implements ProjectListener
  {
      protected String        m_prefix;
  
      /**
       * Initialize the default pattern.
       */
      protected void initPattern()
      {
          final PatternFormatter formatrer = new PatternFormatter();
          formatrer.setFormat( "%{message}\\n%{throwable}" );
          m_formatter = formatrer;
      }
  
      public void projectStarted( final String projectName )
      {
          output( "Starting project " + projectName + "\n" );
      }
  
      public void projectFinished()
      {
      }
      
      public void targetStarted( final String targetName )
      {
          output( targetName + ":\n" );
      }
  
      public void targetFinished()
      {
      }
      
      public void taskletStarted( final String taskletName )
      {
          m_prefix = taskletName;
      }
  
      public void taskletFinished()
      {
          m_prefix = null;
      }
  
      protected void output( final String data )
      {
          if( null != m_prefix ) super.output( "[" + m_prefix + "] " + data );
          else super.output( data );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java
  
  Index: DefaultTarget.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import org.apache.ant.configuration.Configuration;
  
  public class DefaultTarget
      implements Target
  {
      protected ArrayList         m_dependencies     = new ArrayList();
      protected ArrayList         m_tasks            = new ArrayList();
      protected String            m_condition;
      protected boolean           m_isIfCondition;
  
      public Iterator getDependencies()
      {
          return m_dependencies.iterator();
      }
  
      public Iterator getTasks()
      {
          return m_tasks.iterator();
      }
  
      public String getCondition()
      {
          return m_condition;
      }
  
      public void setCondition( final String condition )
      {
          m_condition = condition;
      }
  
      public boolean isIfCondition()
      {
          return m_isIfCondition;
      }
  
      public void setIfCondition( final boolean isIfCondition )
      {
          m_isIfCondition = isIfCondition;
      }
  
      public void addDependency( final String dependency )
      {
          m_dependencies.add( dependency );
      }
  
      public void addTask( final Configuration taskConfiguration )
      {
          m_tasks.add( taskConfiguration );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/Project.java
  
  Index: Project.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.util.Iterator;
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.TaskletContext;
  
  public interface Project
  {
      // the name of currently executing project
      String PROJECT          = "ant.project.name"; 
  
      // the name of currently executing project
      String PROJECT_FILE     = "ant.project.file"; 
  
      // the name of currently executing target
      String TARGET           = "ant.target.name"; 
  
      String getDefaultTargetName();
      Target getImplicitTarget();
      Target getTarget( String name );
      Iterator getTargetNames();
      TaskletContext getContext();
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectBuilder.java
  
  Index: ProjectBuilder.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.io.File;
  import java.io.IOException;
  import org.apache.ant.AntException;
  import org.apache.log.Logger;
  
  public interface ProjectBuilder
  {
      void setLogger( Logger logger );
  
      Project build( File projectFile )
          throws IOException, AntException;
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectEngine.java
  
  Index: ProjectEngine.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import org.apache.ant.AntException;
  import org.apache.avalon.camelot.Deployer;
  import org.apache.avalon.camelot.Registry;
  import org.apache.log.Logger;
  
  public interface ProjectEngine
  {
      Deployer getDeployer();
      void setLogger( Logger logger );
      void execute( Project project, String target )
          throws AntException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectListener.java
  
  Index: ProjectListener.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import org.apache.log.LogTarget;
  
  public interface ProjectListener
      extends LogTarget
  {
      void projectStarted( String projectName );
      void projectFinished();
  
      void targetStarted( String targetName );
      void targetFinished();
  
      void taskletStarted( String taskletName );
      void taskletFinished();
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/Target.java
  
  Index: Target.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.project;
  
  import java.util.Iterator;
  
  public interface Target
  {
      Iterator getDependencies();
      Iterator getTasks();
      String getCondition();
      boolean isIfCondition();
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java
  
  Index: AbstractTasklet.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet;
  
  import org.apache.ant.AntException;
  import org.apache.avalon.Context;
  import org.apache.avalon.Initializable;
  import org.apache.log.Logger;
  
  /**
   * This is abstract base class for tasklets.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractTasklet
      implements Tasklet, Initializable
  {
      protected JavaVersion             m_requiredJavaVersion;
  
      private TaskletContext            m_context;
      private Logger                    m_logger;
  
      /**
       * Retrieve context from container.
       *
       * @param context the context
       */
      public void contextualize( final Context context )
      {
          m_context = (TaskletContext)context;
          m_logger = (Logger)m_context.getLogger();
      }
  
      /**
       * This will be called before run() method and checks any preconditions.
       *
       * Intially preconditions just include JVM version but in future it 
       * will automagically also check if all required parameters are present.
       *
       * @exception AntException if an error occurs
       */
      public void init()
          throws AntException
      {
          if( null != m_requiredJavaVersion )
          {
              final JavaVersion suppliedVersion = m_context.getJavaVersion();
  
              if( m_requiredJavaVersion.isLessThan( suppliedVersion ) )
              {
                  throw new AntException( "Task requires a JavaVersion of at least " + 
                                          m_requiredJavaVersion + " but current version is " +
                                          suppliedVersion );
              }
          }
      }
  
      /**
       * Convenience method for sub-class to retrieve context.
       *
       * @return the context
       */
      protected TaskletContext getContext()
      {
          return m_context;
      }
  
      /**
       * Convenience method for subclass to get logger.
       *
       * @return the Logger
       */
      protected Logger getLogger()
      {
          return m_logger;
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java
  
  Index: DefaultTaskletContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet;
  
  import java.io.File;
  import org.apache.ant.AntException;
  import org.apache.avalon.DefaultContext;
  import org.apache.avalon.util.PropertyException;
  import org.apache.avalon.util.PropertyUtil; 
  import org.apache.avalon.util.io.FileUtil;
  import org.apache.log.Logger;
  
  /**
   * This represents the *Context* in which a task can be executed.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultTaskletContext
      extends DefaultContext
      implements TaskletContext
  {
      protected File     m_baseDirectory;
  
      /**
       * Constructor for Context with no parent contexts.
       */
      public DefaultTaskletContext()
      {
          this( null );
      }
      /**
       * Constructor.
       */
      public DefaultTaskletContext( final TaskletContext parent )
      {
          super( parent );
  
          if( null != parent )
          {
              m_baseDirectory = (File)parent.get( BASE_DIRECTORY );
          }
      }
  
      /**
       * Retrieve JavaVersion running under.
       *
       * @return the version of JVM
       */
      public JavaVersion getJavaVersion()
      {
          return (JavaVersion)get( JAVA_VERSION );
      }
  
      
      /**
       * Retrieve Name of tasklet.
       *
       * @return the name
       */
      public String getName()
      {
          return (String)get( NAME );
      }
  
      /**
       * Retrieve Logger associated with task.
       *
       * @return the logger
       */
      public Logger getLogger()
      {
          return (Logger)get( LOGGER );
      }
      
      /**
       * Retrieve base directory.
       *
       * @return the base directory
       */
      public File getBaseDirectory()
      {
          return m_baseDirectory;
      }
  
      /**
       * Resolve filename. 
       * This involves resolving it against baseDirectory and
       * removing ../ and ./ references. It also means formatting 
       * it appropriately for the particular OS (ie different OS have 
       * different volumes, file conventions etc)
       *
       * @param filename the filename to resolve
       * @return the resolved filename
       */
      public String resolveFilename( final String filename )
      {
          final File result = FileUtil.resolveFile( m_baseDirectory, filename );
          if( null != result ) return result.toString();
          else return null;
      }
  
      /**
       * Resolve property. 
       * This evaluates all property substitutions based on current context.
       *
       * @param property the property to resolve
       * @return the resolved property
       */
      public Object resolveValue( final String property )
      {
          try { return PropertyUtil.resolveProperty( property, this, false ); }
          catch( final PropertyException pe )
          {
              throw new AntException( "Error resolving " + property + " due to " +pe.getMessage(),
                                      pe );
          }
      }
  
      /**
       * Retrieve property for name.
       *
       * @param name the name of property
       * @return the value of the property
       */
      public Object getProperty( final String name )
      {
          return get( name );
      }
  
      /**
       * Set property value in current context.
       *
       * @param name the name of property
       * @param value the value of property
       */
      public void setProperty( final String name, final Object value )
      {
          setProperty( name, value, CURRENT );
      }
      
      /**
       * Set property value.
       *
       * @param property the property
       */
      public void setProperty(  final String name, final Object value, final ScopeEnum scope  )
      {
          checkPropertyValid( name, value );
  
          if( CURRENT == scope ) put( name, value );
          else if( PARENT == scope )
          {
              if( null == m_parent ) 
              {
                  throw new AntException( "Can't set a property with parent scope when context " +
                                          " has no parent" );   
              }
              else
              {
                  ((DefaultTaskletContext)m_parent).put( name, value );
              }
          }
          else if( TOP_LEVEL == scope )
          {
              DefaultTaskletContext context = this;
  
              while( null != context.m_parent )
              {
                  context = (DefaultTaskletContext)context.m_parent;
              }
  
              context.put( name, value );
          }
          else
          {
              throw new AntException( "Can't set a property with an unknown " +
                                      "property context! (" + scope + ")" );
          }
      }
  
      public void put( final Object key, final Object value  )
      {
          if( key.equals( BASE_DIRECTORY ) )
          {
              try { m_baseDirectory = (File)value; }
              catch( final ClassCastException cce )
              {
                  throw new AntException( "Can not set baseDirectory to a non-file value.",
                                          cce );
              }
          }
  
          super.put( key, value );
      }
  
      /**
       * Make sure property is valid if it is one of the "magic" properties.
       *
       * @param name the name of property
       * @param value the value of proeprty
       * @exception AntException if an error occurs
       */
      protected void checkPropertyValid( final String name, final Object value )
          throws AntException
      {
          if( LOGGER.equals( name ) && !( value instanceof Logger ) )
          {
              throw new AntException( "property " + LOGGER +
                                      " must have a value of type " + 
                                      Logger.class.getName() );
          }
          else if( BASE_DIRECTORY.equals( name ) && !( value instanceof File ) )
          {
              throw new AntException( "Property " + BASE_DIRECTORY +
                                      " must have a value of type " + 
                                      File.class.getName() );
          }
          else if( NAME.equals( name ) && !( value instanceof String ) )
          {
              throw new AntException( "Property " + NAME +
                                      " must have a value of type " + 
                                      String.class.getName() );
          }
          else if( JAVA_VERSION.equals( name ) && !( value instanceof JavaVersion ) )
          {
              throw new AntException( "property " + JAVA_VERSION +
                                      " must have a value of type " + 
                                      JavaVersion.class.getName() );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/JavaVersion.java
  
  Index: JavaVersion.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet;
  
  import org.apache.avalon.util.ValuedEnum;
  
  /**
   * Type safe wrapper class for Java Version enums.
   */
  public final class JavaVersion
      extends ValuedEnum
  {
      //standard enums for version of JVM
      public final static JavaVersion  JAVA1_0  = new JavaVersion( "Java 1.0", 100 );
      public final static JavaVersion  JAVA1_1  = new JavaVersion( "Java 1.1", 110 );
      public final static JavaVersion  JAVA1_2  = new JavaVersion( "Java 1.2", 120 );
      public final static JavaVersion  JAVA1_3  = new JavaVersion( "Java 1.3", 130 );
  
      private JavaVersion( final String name, final int value )
      {
          super( name, value );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java
  
  Index: Tasklet.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet;
  
  import org.apache.avalon.Component;
  import org.apache.avalon.Contextualizable;
  
  /**
   * This represents the individual tasks.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Tasklet
      extends Component, Contextualizable, Runnable
  {
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java
  
  Index: TaskletContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet;
  
  import java.io.File;
  import org.apache.avalon.Context;
  import org.apache.avalon.util.Enum;
  import org.apache.avalon.util.ValuedEnum;
  import org.apache.log.Logger;
  
  /**
   * This represents the *Context* in which a task can be executed.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface TaskletContext
      extends Context
  {
      //these values are used when setting properties to indicate the scope at
      //which properties are set
      ScopeEnum       CURRENT            = new ScopeEnum( "Current" );
      ScopeEnum       PARENT             = new ScopeEnum( "Parent" );
      ScopeEnum       TOP_LEVEL          = new ScopeEnum( "TopLevel" );
  
      //these are the names of properties that every TaskContext must contain
      String          JAVA_VERSION       = "ant.java.version";
      String          BASE_DIRECTORY     = "ant.base.directory";
      String          LOGGER             = "ant.logger";
      String          NAME               = "ant.task.name";
  
      /**
       * Retrieve JavaVersion running under.
       *
       * @return the version of JVM
       */
      JavaVersion getJavaVersion();
      
      /**
       * Retrieve Name of tasklet.
       *
       * @return the name
       */
      String getName();
  
      /**
       * Retrieve Logger associated with task.
       *
       * @return the logger
       */
      Logger getLogger();
      
      /**
       * Retrieve base directory.
       *
       * @return the base directory
       */
      File getBaseDirectory();
  
      /**
       * Resolve filename. 
       * This involves resolving it against baseDirectory and
       * removing ../ and ./ references. It also means formatting 
       * it appropriately for the particular OS (ie different OS have 
       * different volumes, file conventions etc)
       *
       * @param filename the filename to resolve
       * @return the resolved filename
       */
      String resolveFilename( String filename );
  
      /**
       * Resolve property. 
       * This evaluates all property substitutions based on current context.
       *
       * @param property the property to resolve
       * @return the resolved property
       */
      Object resolveValue( String property );
  
      /**
       * Retrieve property for name.
       *
       * @param name the name of property
       * @return the value of property
       */
      Object getProperty( String name );
  
      /**
       * Set property value in current context.
       *
       * @param name the name of property
       * @param value the value of property
       */
      void setProperty( String name, Object value );
      
      /**
       * Set property value.
       *
       * @param name the name of property
       * @param value the value of property
       * @param scope the scope at which to set property
       */
      void setProperty( String name, Object value, ScopeEnum scope  );
  
      /**
       * Safe wrapper class for Scope enums.
       */
      final class ScopeEnum
          extends Enum
      {
          ScopeEnum( final String name )
          {
              super( name );
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletConfigurer.java
  
  Index: DefaultTaskletConfigurer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.Iterator;
  import org.apache.ant.configuration.Configurable;
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.convert.Converter;
  import org.apache.ant.convert.ConverterEntry;
  import org.apache.ant.convert.ConverterFactory;
  import org.apache.ant.convert.ConverterInfo;
  import org.apache.ant.convert.ConverterRegistry;
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.avalon.ComponentManager;
  import org.apache.avalon.ComponentNotAccessibleException;
  import org.apache.avalon.ComponentNotFoundException;
  import org.apache.avalon.Composer;
  import org.apache.avalon.ConfigurationException;
  import org.apache.avalon.Context;
  import org.apache.avalon.camelot.FactoryException;
  import org.apache.avalon.util.PropertyException;
  import org.apache.avalon.util.PropertyUtil;
  
  /**
   * Class used to configure tasks.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultTaskletConfigurer
      implements TaskletConfigurer, Composer
  {
      protected final static String  RESERVED_ATTRIBUTES[] = 
      {
          "id"
      };
  
      protected final static String  RESERVED_ELEMENTS[] = 
      {
          "content"
      };
  
      protected ConverterRegistry    m_converterRegistry;
      protected ConverterFactory     m_converterFactory;
  
      public void compose( final ComponentManager componentManager )
          throws ComponentNotFoundException, ComponentNotAccessibleException
      {
          m_converterRegistry = (ConverterRegistry)componentManager.
              lookup( "org.apache.ant.convert.ConverterRegistry" );
          m_converterFactory = (ConverterFactory)componentManager.
              lookup( "org.apache.ant.convert.ConverterFactory" );
      }
  
      public void configure( final Tasklet tasklet, 
                             final Configuration configuration,
                             final Context context )
          throws ConfigurationException
      {
          configure( (Object)tasklet, configuration, context );
      }
  
      public void configure( final Object object, 
                             final Configuration configuration,
                             final Context context )
          throws ConfigurationException
      {
          if( object instanceof Configurable )
          {
              ((Configurable)object).configure( configuration );
          }
          else
          {
              final Iterator attributes = configuration.getAttributeNames();
  
              while( attributes.hasNext() )
              {
                  final String name = (String)attributes.next();
                  final String value = configuration.getAttribute( name );
                  configureAttribute( object, name, value, context );
              }
  
              final Iterator elements = configuration.getChildren();
              
              while( elements.hasNext() )
              {
                  final Configuration element = (Configuration)elements.next();
                  configureElement( object, element, context );
              }
  
              final String content = configuration.getValue( null );
  
              if( null != content )
              {
                  if( !content.trim().equals( "" ) )
                  {
                      configureContent( object, content, context );
                  }
              }
          }
      }
  
      protected void configureContent( final Object object, 
                                       final String content,
                                       final Context context )
          throws ConfigurationException
      {
          setValue( object, "addContent", content, context );
      }
  
      protected void configureAttribute( final Object object, 
                                         final String name, 
                                         final String value,
                                         final Context context )
          throws ConfigurationException
      {
          for( int i = 0; i < RESERVED_ATTRIBUTES.length; i++ )
          {
              if( RESERVED_ATTRIBUTES[ i ].equals( name ) ) return;
          }
  
          final String methodName = getMethodNameFor( name );
          setValue( object, methodName, value, context );
      }
  
      protected void setValue( final Object object, 
                               final String methodName,
                               final String value,
                               final Context context )
          throws ConfigurationException
      {
          // OMFG the rest of this is soooooooooooooooooooooooooooooooo
          // slow. Need to cache results per class etc.
  
          final Class clazz = object.getClass();
          final Method methods[] = getMethodsFor( clazz, methodName );
  
          if( 0 == methods.length )
          {
              throw new ConfigurationException( "Unable to set attribute via " + methodName + 
                                                " due to not finding any appropriate " + 
                                                "accessor method" );
          }
  
          setValue( object, value, context, methods );
      }
  
      protected void setValue( final Object object,
                               final String value,
                               final Context context,
                               final Method methods[] )
          throws ConfigurationException
      {
          try
          {
              final Object objectValue = 
                  PropertyUtil.resolveProperty( value, context, false );
  
              setValue( object, objectValue, methods );
          }
          catch( final PropertyException pe )
          {
              throw new ConfigurationException( "Error resolving property " + value,
                                                pe );
          }
      }
  
      protected void setValue( final Object object, Object value, final Method methods[] )
          throws ConfigurationException
      {
          final Class sourceClass = value.getClass();
          final String source = sourceClass.getName();
  
          for( int i = 0; i < methods.length; i++ )
          {
              if( setValue( object, value, methods[ i ], sourceClass, source ) )
              {
                  return;
              }
          }
          
          throw new ConfigurationException( "Unable to set attribute via " + 
                                            methods[ 0 ].getName() + " as could not convert " + 
                                            source + " to a matching type" );
      }
  
      protected boolean setValue( final Object object, 
                                  Object value, 
                                  final Method method,
                                  final Class sourceClass,
                                  final String source )
          throws ConfigurationException
      {
          Class parameterType = method.getParameterTypes()[ 0 ];
          if( parameterType.isPrimitive() )
          {
              parameterType = getComplexTypeFor( parameterType );
          }
          
          if( !parameterType.isAssignableFrom( sourceClass ) )
          {
              final String destination = parameterType.getName();
              
              try
              {
                  final ConverterInfo info = m_converterRegistry.
                      getConverterInfo( source, destination );
                  
                  if( null == info ) return false;
                
                  final ConverterEntry entry = m_converterFactory.create( info );
                  final Converter converter = entry.getConverter();
                  value = converter.convert( parameterType, value );
              }
              catch( final FactoryException fe )
              {
                  throw new ConfigurationException( "Badly configured ConverterFactory ",
                                                    fe );
              }
              catch( final Exception e )
              {
                  throw new ConfigurationException( "Error converting attribute for " + 
                                                    method.getName(),
                                                    e );
              }
          }
          
          try
          {
              method.invoke( object, new Object[] { value } );
          }
          catch( final IllegalAccessException iae )
          {
              //should never happen ....
              throw new ConfigurationException( "Error retrieving methods with " + 
                                                "correct access specifiers",
                                                iae );
          }
          catch( final InvocationTargetException ite )
          {
              throw new ConfigurationException( "Error calling method attribute " + 
                                                method.getName(),
                                                ite );
          }
  
          return true;
      }
  
      protected Class getComplexTypeFor( final Class clazz )
      {
          if( String.class == clazz ) return String.class;
          else if( Integer.TYPE.equals( clazz ) ) return Integer.class;
          else if( Long.TYPE.equals( clazz ) ) return Long.class;
          else if( Short.TYPE.equals( clazz ) ) return Short.class;
          else if( Byte.TYPE.equals( clazz ) ) return Byte.class;
          else if( Boolean.TYPE.equals( clazz ) ) return Boolean.class;
          else if( Float.TYPE.equals( clazz ) ) return Float.class;
          else if( Double.TYPE.equals( clazz ) ) return Double.class;
          else
          {
              throw new IllegalArgumentException( "Can not get complex type for non-primitive " +
                                                  "type " + clazz.getName() );
          }
      }
  
      protected Method[] getMethodsFor( final Class clazz, final String methodName )
      {
          final Method methods[] = clazz.getMethods();
          final ArrayList matches = new ArrayList();
          
          for( int i = 0; i < methods.length; i++ )
          {
              final Method method = methods[ i ];
              if( methodName.equals( method.getName() ) && 
                  Method.PUBLIC == (method.getModifiers() & Method.PUBLIC) )
              {
                  if( method.getReturnType().equals( Void.TYPE ) )
                  {
                      final Class parameters[] = method.getParameterTypes();
                      if( 1 == parameters.length )
                      {
                          matches.add( method );
                      }
                  }
              }
          }
  
          return (Method[])matches.toArray( new Method[0] );
      }
  
      protected Method[] getCreateMethodsFor( final Class clazz, final String methodName )
      {
          final Method methods[] = clazz.getMethods();
          final ArrayList matches = new ArrayList();
          
          for( int i = 0; i < methods.length; i++ )
          {
              final Method method = methods[ i ];
              if( methodName.equals( method.getName() ) && 
                  Method.PUBLIC == (method.getModifiers() & Method.PUBLIC) )
              {
                  final Class returnType = method.getReturnType();
                  if( !returnType.equals( Void.TYPE ) &&
                      !returnType.isPrimitive() )
                  {
                      final Class parameters[] = method.getParameterTypes();
                      if( 0 == parameters.length )
                      {
                          matches.add( method );
                      }
                  }
              }
          }
  
          return (Method[])matches.toArray( new Method[0] );
      }
  
      protected String getMethodNameFor( final String attribute )
      {
          return "set" + getJavaNameFor( attribute );
      }
  
      protected String getJavaNameFor( final String name )
      {
          final StringBuffer sb = new StringBuffer();
          
          int index = name.indexOf( '-' );
          int last = 0;
          
          while( -1 != index )
          {
              final String word = name.substring( last, index ).toLowerCase();
              sb.append( Character.toUpperCase( word.charAt( 0 ) ) );
              sb.append( word.substring( 1, word.length() ) );
              last = index + 1;
              index = name.indexOf( '-', last );
          }
          
          index = name.length();
          final String word = name.substring( last, index ).toLowerCase();
          sb.append( Character.toUpperCase( word.charAt( 0 ) ) );
          sb.append( word.substring( 1, word.length() ) );
          
          return sb.toString();
      }    
  
      protected void configureElement( final Object object, 
                                       final Configuration configuration,
                                       final Context context )
          throws ConfigurationException
      {
          final String name = configuration.getName();
  
          for( int i = 0; i < RESERVED_ELEMENTS.length; i++ )
          {
              if( RESERVED_ATTRIBUTES[ i ].equals( name ) ) return;
          }
  
          final String javaName = getJavaNameFor( name );
  
          // OMFG the rest of this is soooooooooooooooooooooooooooooooo
          // slow. Need to cache results per class etc.
          final Class clazz = object.getClass();
          Method methods[] = getMethodsFor( clazz, "add" + javaName );
          
          if( 0 != methods.length )
          {
              //guess it is first method ????
              addElement( object, methods[ 0 ], configuration, context );
          }
          else
          {
              methods = getCreateMethodsFor( clazz, "create" + javaName );
  
              if( 0 == methods.length )
              {
                  throw new ConfigurationException( "Unable to set attribute " + javaName + 
                                                    " due to not finding any appropriate " + 
                                                    "accessor method" );
              }
  
              //guess it is first method ????
              createElement( object, methods[ 0 ], configuration, context );
          }
      }
  
      protected void createElement( final Object object, 
                                    final Method method,
                                    final Configuration configuration,
                                    final Context context )
          throws ConfigurationException
      {
          try
          {
              final Object created = method.invoke( object, new Object[ 0 ] );
              configure( created, configuration, context );
          }
          catch( final ConfigurationException ce )
          {
              throw ce;
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Error creating sub-element", e );
          }
      }
  
      protected void addElement( final Object object, 
                                 final Method method,
                                 final Configuration configuration,
                                 final Context context )
          throws ConfigurationException
      {
          try
          {
              final Class clazz = method.getParameterTypes()[ 0 ];
              final Object created = clazz.newInstance();
  
              configure( created, configuration, context );
              method.invoke( object, new Object[] { created } );
          }
          catch( final ConfigurationException ce )
          {
              throw ce;
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Error creating sub-element", e );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java
  
  Index: DefaultTaskletEngine.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.util.HashMap;
  import org.apache.ant.AntException;
  import org.apache.ant.configuration.Configurable;
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.convert.ConverterFactory;
  import org.apache.ant.convert.ConverterRegistry;
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.ant.tasklet.TaskletContext;
  import org.apache.avalon.ComponentManager;
  import org.apache.avalon.ComponentNotAccessibleException;
  import org.apache.avalon.ComponentNotFoundException;
  import org.apache.avalon.Composer;
  import org.apache.avalon.Context;
  import org.apache.avalon.Contextualizable;
  import org.apache.avalon.DefaultComponentManager;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.camelot.FactoryException;
  import org.apache.avalon.camelot.RegistryException;
  import org.apache.log.Logger;
  
  public class DefaultTaskletEngine
      implements TaskletEngine, Initializable
  {
      protected ComponentManager     m_componentManager;
      protected TaskletContext       m_context;
      protected TaskletFactory       m_taskletFactory;
      protected ConverterFactory     m_converterFactory;
      protected TaskletRegistry      m_taskletRegistry;
      protected ConverterRegistry    m_converterRegistry;
      protected TaskletConfigurer    m_configurer;
      protected Logger               m_logger;
  
      public void contextualize( final Context context )
      {
          m_context = (TaskletContext)context;
          m_logger = m_context.getLogger();
      }
  
      public void compose( final ComponentManager componentManager )
          throws ComponentNotFoundException, ComponentNotAccessibleException
      {
          m_componentManager = componentManager;
          m_taskletRegistry = (TaskletRegistry)componentManager.
              lookup( "org.apache.ant.tasklet.engine.TaskletRegistry" );
          m_converterRegistry = (ConverterRegistry)componentManager.
              lookup( "org.apache.ant.convert.ConverterRegistry" );
      }
  
      public void init()
          throws Exception
      {
          m_taskletFactory = createTaskletFactory();
          m_converterFactory =  createConverterFactory();
          m_configurer = createTaskletConfigurer();
  
          if( m_configurer instanceof Composer )
          {
              final DefaultComponentManager componentManager = 
                  new DefaultComponentManager( m_componentManager );
              componentManager.put( "org.apache.ant.convert.ConverterFactory", 
                                    m_converterFactory );
  
              ((Composer)m_configurer).compose( componentManager );
          }
  
          if( m_configurer instanceof Initializable )
          {
              ((Initializable)m_configurer).init();
          }
      }
  
      protected TaskletConfigurer createTaskletConfigurer()
      {
          return new DefaultTaskletConfigurer();
      }
  
      protected TaskletFactory createTaskletFactory()
      {
          return new DefaultTaskletFactory();
      }
  
      protected ConverterFactory createConverterFactory()
      {
          return (ConverterFactory)m_taskletFactory;
      }
  
      public void execute( final Configuration task )
          throws AntException
      {
          final Tasklet tasklet = createTasklet( task );
  
          final String name = task.getName();
          m_logger.debug( "Created task " + name );
  
          doContextualize( tasklet, task );
          m_logger.debug( "Contextualized task " + name );
  
          doCompose( tasklet, task );
          m_logger.debug( "Composed task " + name );
  
          doConfigure( tasklet, task );
          m_logger.debug( "Configured task " + name );
  
          doInitialize( tasklet, task );
          m_logger.debug( "Initialize task " + name );
  
          tasklet.run();
          m_logger.debug( "Ran task " + name );
  
          doDispose( tasklet, task );
          m_logger.debug( "Dispose task " + name );
      }
  
      protected void doConfigure( final Tasklet tasklet, final Configuration task )
          throws AntException
      {
          try { m_configurer.configure( tasklet, task, m_context ); }
          catch( final Throwable throwable )
          {
              throw new AntException( "Error configuring task " +  task.getName() + " at " +
                                      task.getLocation() + "(Reason: " + 
                                      throwable.getMessage() + ")", throwable );
          }
      }
  
      protected TaskletContext getContextFor( final String name )
      {
          //If we are single threaded we really don't need to have a new object
          //for context ... if we are not single threaded then we need to create new 
          //context. Alternatively we could remove getName from TaskletContext        
  
          //final DefaultTaskletContext context = new DefaultTaskletContext( m_context );
          m_context.setProperty( TaskletContext.NAME, name );
          return m_context;
      }
      
      protected void doCompose( final Tasklet tasklet, final Configuration task )
          throws AntException
      {
          if( tasklet instanceof Composer )
          {
              try { ((Composer)tasklet).compose( m_componentManager ); }
              catch( final Throwable throwable )
              {
                  throw new AntException( "Error composing task " +  task.getName() + " at " +
                                          task.getLocation() + "(Reason: " + 
                                          throwable.getMessage() + ")", throwable );            
              }
          }
      }
  
      protected void doContextualize( final Tasklet tasklet, final Configuration task )
          throws AntException
      {
          final TaskletContext context = getContextFor( task.getName() );
  
          try { tasklet.contextualize( context ); }
          catch( final Throwable throwable )
          {
              throw new AntException( "Error contextualizing task " +  task.getName() + " at " +
                                      task.getLocation() + "(Reason: " + 
                                      throwable.getMessage() + ")", throwable );            
          }
      }
  
      protected void doDispose( final Tasklet tasklet, final Configuration task )
          throws AntException
      {
          if( tasklet instanceof Disposable )
          {
              try { ((Disposable)tasklet).dispose(); }
              catch( final Throwable throwable )
              {
                  throw new AntException( "Error disposing task " +  task.getName() + " at " +
                                          task.getLocation() + "(Reason: " + 
                                          throwable.getMessage() + ")", throwable );
              }
          }
      }
  
      protected void doInitialize( final Tasklet tasklet, final Configuration task )
          throws AntException
      {
          if( tasklet instanceof Initializable )
          {
              try { ((Initializable)tasklet).init(); }
              catch( final Throwable throwable )
              {
                  throw new AntException( "Error initializing task " +  task.getName() + " at " +
                                          task.getLocation() + "(Reason: " +
                                          throwable.getMessage() + ")", throwable );
              }
          }
      }
  
      protected Tasklet createTasklet( final Configuration configuration )
          throws AntException
      {
          final String name = configuration.getName();
          TaskletInfo info = null;
  
          try { info = (TaskletInfo)m_taskletRegistry.getInfo( name ); }
          catch( final RegistryException re )
          {
              throw new AntException( "Unable to locate task " + name, re );
          }
  
          TaskletEntry entry = null;
  
          try { entry = m_taskletFactory.create( info ); }
          catch( final FactoryException fe )
          {
              throw new AntException( "Unable to create task " + name + 
                                      " (of type " + info.getClassname() + " from " +
                                      info.getLocation() + ")",
                                      fe );
          }
          
          return entry.getTasklet();
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletFactory.java
  
  Index: DefaultTaskletFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.HashMap;
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.ant.convert.ConverterLoader;
  import org.apache.ant.convert.DefaultConverterFactory;
  import org.apache.avalon.camelot.Entry;
  import org.apache.avalon.camelot.Factory;
  import org.apache.avalon.camelot.FactoryException;
  import org.apache.avalon.camelot.Info;
  
  /**
   * Facility used to load Tasklets.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultTaskletFactory
      extends DefaultConverterFactory
      implements TaskletFactory
  {
      public Entry create( final Info info )
          throws FactoryException
      {
          if( !info.getClass().equals( TaskletInfo.class ) )
          {
              return super.create( info );
          }
          else
          {
              return create( (TaskletInfo)info );
          }
      }
  
      public TaskletEntry create( final TaskletInfo info )
          throws FactoryException
      {
          final TaskletLoader loader = (TaskletLoader)getLoader( info.getLocation() );
  
          Object object = null;
          
          try { object = loader.load( info.getClassname() ); }
          catch( final Exception e )
          {
              throw new FactoryException( "Failed loading tasklet from " + info.getLocation() +
                                          " due to " + e, e );
          }
          
          return new TaskletEntry( info, (Tasklet)object );        
      }
  
      protected ConverterLoader createLoader( final URL location )
      {
          if( null != location ) return new DefaultTaskletLoader( location );
          else return new DefaultTaskletLoader();
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletInfo.java
  
  Index: DefaultTaskletInfo.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.net.URL;
  import org.apache.avalon.camelot.Info;
  
  /**
   * This is default container of information about a task. 
   * A BeanInfo equivelent for a task. Eventually it will auto-magically
   * generate a schema via reflection for Validator/Editor tools.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultTaskletInfo
      implements TaskletInfo
  {
      protected final String        m_classname;
      protected final URL           m_location;
  
      /**
       * Constructor that takes classname and taskLibraryLocation.
       */
      public DefaultTaskletInfo( final String classname, final URL location )
      {
          m_location = location;
          m_classname = classname;
      }
  
      /**
       * Retrieve classname for task.
       *
       * @return the taskname
       */
      public String getClassname()
      {    
          return m_classname;
      }
  
      /**
       * Retrieve tasklib location from which task is loaded.
       *
       * @return the location
       */
      public URL getLocation()
      {
          return m_location;
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletLoader.java
  
  Index: DefaultTaskletLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.net.URL;
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.ant.convert.DefaultConverterLoader;
  
  /**
   * Class used to load tasks et al from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultTaskletLoader
      extends DefaultConverterLoader
      implements TaskletLoader
  {
      public DefaultTaskletLoader()
      {
      }
  
      public DefaultTaskletLoader( final URL location )
      {
          super( location );
      }
  
      public Tasklet loadTasklet( final String tasklet )
          throws Exception
      {
          return (Tasklet)load( tasklet );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletRegistry.java
  
  Index: DefaultTaskletRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.avalon.camelot.AbstractRegistry;
  
  public class DefaultTaskletRegistry
      extends AbstractRegistry
      implements TaskletRegistry
  {
      protected Class getInfoClass()
      {
          return TaskletInfo.class;
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletConfigurer.java
  
  Index: TaskletConfigurer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.avalon.ConfigurationException;
  import org.apache.avalon.Context;
  
  /**
   * Class used to configure tasks.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface TaskletConfigurer
  {
      void configure( Tasklet tasklet, Configuration configuration, Context context )
          throws ConfigurationException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java
  
  Index: TaskletEngine.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.ant.AntException;
  import org.apache.ant.configuration.Configuration;
  import org.apache.avalon.Composer;
  import org.apache.avalon.Contextualizable;
   
  public interface TaskletEngine
      extends Contextualizable, Composer
  {
      void execute( final Configuration task )
          throws AntException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEntry.java
  
  Index: TaskletEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.avalon.camelot.AbstractEntry;
  
  public class TaskletEntry
      extends AbstractEntry
  {
      public TaskletEntry( final TaskletInfo info, final Tasklet tasklet )
      {
          super( info, tasklet );
      }
  
      /**
       * Retrieve instance of tasklet.
       *
       * @return the component instance
       */
      public Tasklet getTasklet()
      {
          return (Tasklet)getInstance();
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletFactory.java
  
  Index: TaskletFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.avalon.camelot.Factory;
  import org.apache.avalon.camelot.FactoryException;
  
  /**
   * Facility used to load Tasklets.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface TaskletFactory
      extends Factory
  {
      TaskletEntry create( TaskletInfo info ) 
          throws FactoryException;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletInfo.java
  
  Index: TaskletInfo.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.net.URL;
  import org.apache.avalon.camelot.Info;
  
  /**
   * This is information about a task. 
   * A BeanInfo equivelent for a task. Eventually it will auto-magically
   * generate a schema via reflection for Validator/Editor tools.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface TaskletInfo
      extends Info
  {
      /**
       * Retrieve classname for task.
       *
       * @return the taskname
       */
      String getClassname();
  
      /**
       * Retrieve location of task library where task is contained.
       *
       * @return the location of task library
       */
      URL getLocation();
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletLoader.java
  
  Index: TaskletLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.ant.tasklet.Tasklet;
  import org.apache.avalon.camelot.Loader;
  
  /**
   * Class used to load tasks et al from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface TaskletLoader
      extends Loader
  {
      Tasklet loadTasklet( String tasklet )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletRegistry.java
  
  Index: TaskletRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import org.apache.avalon.camelot.Registry;
  
  public interface TaskletRegistry
      extends Registry
  {
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java
  
  Index: TskDeployer.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasklet.engine;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipException;
  import java.util.zip.ZipFile;
  import org.apache.ant.tasklet.engine.DefaultTaskletInfo;
  import org.apache.ant.convert.ConverterRegistry;
  import org.apache.ant.convert.DefaultConverterInfo;
  import org.apache.avalon.Component;
  import org.apache.avalon.camelot.AbstractDeployer;
  import org.apache.avalon.camelot.DeploymentException;
  import org.apache.avalon.camelot.RegistryException;
  import org.apache.log.Logger;
  
  /**
   * This class deploys a .tsk file into a registry.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class TskDeployer
      extends AbstractDeployer
  {
      protected final static String   TASKDEF_FILE     = "TASK-LIB/taskdefs.properties";
      protected final static String   CONVERTER_FILE   = "TASK-LIB/converters.properties";
  
      protected TaskletRegistry       m_taskletRegistry;
      protected ConverterRegistry     m_converterRegistry;
  
      public TskDeployer( final TaskletRegistry taskletRegistry, 
                          final ConverterRegistry converterRegistry )
      {
          m_taskletRegistry = taskletRegistry;
          m_converterRegistry = converterRegistry;
          m_autoUndeploy = true;
          m_type = "Tasklet";
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      protected boolean isValidLocation( final String location )
      {
          //TODO: Make sure it is valid JavaIdentifier 
          //that optionally has '-' embedded in it
          return true;
      }
      
      /**
       * Deploy Tasklets from a .tsk file.
       * Eventually this should be cached for performance reasons.
       *
       * @param location the location 
       * @param file the file
       * @exception DeploymentException if an error occurs
       */
      protected void deployFromFile( final String location, final File file )
          throws DeploymentException
      {
          m_logger.info( "Deploying .tsk file (" + file + ") as " + location );
  
          ZipFile zipFile = null;
  
          try { zipFile = new ZipFile( file ); }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error opening " + file + 
                                             " due to " + ioe.getMessage(),
                                             ioe );
          }
  
          try
          {
              final Properties taskdefs = loadProperties( zipFile, TASKDEF_FILE );
              final Properties converters = loadProperties( zipFile, CONVERTER_FILE );
  
              try { zipFile.close(); }
              catch( final IOException ioe ) {}
  
              URL url = null;
  
              try { url = file.toURL(); }
              catch( final MalformedURLException mue ) {}
  
              handleTaskdefs( taskdefs, url );
              handleConverters( converters, url );
          }
          catch( final DeploymentException de )
          {
              try { zipFile.close(); }
              catch( final IOException ioe ) {}
  
              throw de;
          }
      }
  
      protected void handleConverters( final Properties properties, final URL url )
          throws DeploymentException
      {
          final Enumeration enum = properties.propertyNames();
          
          while( enum.hasMoreElements() )
          {
              final String key = (String)enum.nextElement();
              final String value = (String)properties.get( key );
              final int index = value.indexOf( ',' );
  
              if( -1 == index )
              {
                  throw new DeploymentException( "Malformed converter definition (" + 
                                                 key + ")" );
              }
              
              final String source = value.substring( 0, index ).trim();
              final String destination = value.substring( index + 1 ).trim();
  
              final DefaultConverterInfo info = 
                  new DefaultConverterInfo( source, destination, key, url );
              
              try { m_converterRegistry.register( key, info ); }
              catch( final RegistryException re )
              {
                  throw new DeploymentException( "Error registering converter " + 
                                                 key + " due to " + re,
                                                 re );
              }
          }
      }   
       
      protected void handleTaskdefs( final Properties properties, final URL url )
          throws DeploymentException
      {
          final Enumeration enum = properties.propertyNames();
          
          while( enum.hasMoreElements() )
          {
              final String key = (String)enum.nextElement();
              final String value = (String)properties.get( key );
              final DefaultTaskletInfo info = new DefaultTaskletInfo( value, url );
                      
              try { m_taskletRegistry.register( key, info ); }
              catch( final RegistryException re )
              {
                  throw new DeploymentException( "Error registering " + key + " due to " + re,
                                                 re );
              }
          }
      }
  
      protected Properties loadProperties( final ZipFile zipFile, final String filename )
          throws DeploymentException
      {
          final ZipEntry entry = zipFile.getEntry( filename );
          if( null == entry )
          {
              throw new DeploymentException( "Unable to locate " + filename + 
                                             " in " + zipFile.getName() );
          }
          
          Properties properties = new Properties();
          
          try
          {
              properties.load( zipFile.getInputStream( entry ) );
          }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error reading " + filename + 
                                             " from " + zipFile.getName(),
                                             ioe );
          }
  
          return properties;
      }
      
      protected boolean canUndeploy( final Component component )
          throws DeploymentException
      {
          return true;
      }
      
      protected void shutdownDeployment( final Component component )
          throws DeploymentException
      {
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/ConfigurationTest.java
  
  Index: ConfigurationTest.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.configuration.Configurable;
  import org.apache.ant.configuration.Configuration;
  import org.apache.ant.tasklet.AbstractTasklet;
  import org.apache.avalon.ConfigurationException;
  
  /**
   * This is abstract base class for tasklets.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ConfigurationTest 
      extends AbstractTasklet
      implements Configurable
  {
      protected String              m_message;
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          String message = configuration.getAttribute( "message" );
          final Object object = getContext().resolveValue( message );
          if( object instanceof String )
          {
              m_message = (String)object;
          }
          else
          {
              m_message = object.toString();
          }
      }
  
      public void run()
          throws AntException
      {
          getLogger().info( m_message );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/ContentTest.java
  
  Index: ContentTest.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.AbstractTasklet;
  
  /**
   * This is abstract base class for tasklets.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ContentTest 
      extends AbstractTasklet
  {
      public void addContent( final Integer value )
      {
          getLogger().info( "Integer content: " + value );
      }
  
      /*
        public void addContent( final String blah )
        {
        System.out.println( "String: " + blah );
        }
      */
  
      public void run()
          throws AntException
      {
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Echo.java
  
  Index: Echo.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.AbstractTasklet;
  
  /**
   * This is abstract base class for tasklets.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class Echo 
      extends AbstractTasklet
  {
      protected String              m_message;
  
      public void setMessage( final String message )
      {
          m_message = message;
      }
  
      public void run()
          throws AntException
      {
          getLogger().info( m_message );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/PrimitiveTypesTest.java
  
  Index: PrimitiveTypesTest.java
  ===================================================================
  
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.AbstractTasklet;
  
  /**
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class PrimitiveTypesTest 
      extends AbstractTasklet
  {
      public void setInteger( final Integer value )
      {
          getLogger().info( "setInteger( " + value + " );" );
      }
      
      public void setInteger2( final int value )
      {
          getLogger().info( "setInteger2( " + value + " );" );
      }
  
      public void setShort( final Short value )
      {
          getLogger().info( "setShort( " + value + " );" );
      }
      
      public void setShort2( final short value )
      {
          getLogger().info( "setShort2( " + value + " );" );
      }
  
      public void setByte( final Byte value )
      {
          getLogger().info( "setByte( " + value + " );" );
      }
      
      public void setByte2( final byte value )
      {
          getLogger().info( "setByte2( " + value + " );" );
      }
  
      public void setLong( final Long value )
      {
          getLogger().info( "setLong( " + value + " );" );
      }
      
      public void setLong2( final long value )
      {
          getLogger().info( "setLong2( " + value + " );" );
      }
      
      public void setFloat( final Float value )
      {
          getLogger().info( "setFloat( " + value + " );" );
      }
      
      public void setFloat2( final float value )
      {
          getLogger().info( "setFloat2( " + value + " );" );
      }
      
      public void setDouble( final Double value )
      {
          getLogger().info( "setDouble( " + value + " );" );
      }
      
      public void setDouble2( final double value )
      {
          getLogger().info( "setDouble2( " + value + " );" );
      }
  
      public void setString( final String value )
      {
          getLogger().info( "setString( " + value + " );" );
      }
  
      public void run()
          throws AntException
      {
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java
  
  Index: Property.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.AbstractTasklet;
  import org.apache.ant.tasklet.TaskletContext;
  
  /**
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class Property 
      extends AbstractTasklet
  {
      protected String              m_name;
      protected String              m_value;
      protected boolean             m_localScope     = true;
  
      public void setName( final String name )
      {
          m_name = name;
      }
      
      public void setValue( final String value )
      {
          m_value = value;
      }
      
      public void setLocalScope( final boolean localScope )
      {
          m_localScope = localScope;
      }
  
      public void run()
          throws AntException
      {
          if( null == m_name )
          {
              throw new AntException( "Name must be specified" );
          }
  
          if( null == m_value )
          {
              throw new AntException( "Value must be specified" );
          }
  
          final TaskletContext context = getContext();
          final Object value = context.resolveValue( m_value );
  
          if( m_localScope )
          {
              context.setProperty( m_name, value );
          }
          else
          {
              context.setProperty( m_name, value, TaskletContext.PARENT );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/SubElementTest.java
  
  Index: SubElementTest.java
  ===================================================================
  
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.ant.tasks.core;
  
  import org.apache.ant.AntException;
  import org.apache.ant.tasklet.AbstractTasklet;
  
  /**
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class SubElementTest 
      extends AbstractTasklet
  {
      public static final class Beep
      {
          public void setMessage( final String string )
          {
              System.out.println( string );
          }
      }
  
      public Beep createCreateBeep()
      {
          System.out.println( "createCreateBeep()" );
          return new Beep();
      }
  
      public void addAddBeep( final Beep beep )
      {
          System.out.println( "addBeeper(" + beep + ");" );
      }
  
      public void run()
          throws AntException
      {
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/taskdefs.properties
  
  Index: taskdefs.properties
  ===================================================================
  # TASK-LIB/taskdefs.properties
  echo=org.apache.ant.tasks.core.Echo
  prim-test=org.apache.ant.tasks.core.PrimitiveTypesTest
  sub-elements-test=org.apache.ant.tasks.core.SubElementTest
  conf-test=org.apache.ant.tasks.core.ConfigurationTest
  content-test=org.apache.ant.tasks.core.ContentTest
  property=org.apache.ant.tasks.core.Property
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/make/sample.xmk
  
  Index: sample.xmk
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
  ==============================================================================
  
   Sample build file
  
  Authors:
   Peter Donald <do...@apache.org>
  
  Legal:
    Copyright (c) 2000 The Apache Software Foundation. All Rights Reserved.
  
  ==============================================================================
  -->
  
  <project name="MySample" default="main" basedir=".">
  
    <property name="year" value="2000"/>
  
    <target name="main" depends="property-test" />
  
    <!--
         ===================================================================
                                    Help on usage
         ===================================================================
    -->
    <target name="option-test">
  
      <prim-test
          integer="1"
          integer2="2"
          short="3"
          short2="4"
          long="5"
          long2="6"
          byte="7"
          byte2="8"
          string="aString"
          float="1.0"
          float2="2.0"
          double="3.0"
          double2="4.0"
       />
  
      <sub-elements-test>
        <create-beep message="Evaluation of ant.install.dir=${ant.install.dir}" />
        <add-beep message="Evaluation of ant.install.lib=${ant.install.lib}" />
      </sub-elements-test>
  
      <conf-test message="Test of configuration=${ant.install.lib}" />
      
      <content-test>123</content-test>
      
    </target>
  
    <target name="property-test">
      <property name="blah" value="fred" />
      <property name="${blah}" value="barney" />
  
      <echo message="Doing the funky Echo with ${blah} ${fred} Year=${year}!"/>
    </target>
  
    <target name="property-test2">
      <echo message="This should fail ...."/>
      <echo message="${blah}"/>
    </target>
  
  </project>
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/script/ant
  
  Index: ant
  ===================================================================
  #!/bin/sh
  
  if [ -f $HOME/.antrc ] ; then 
    . $HOME/.antrc
  fi
  
  # Cygwin support.
  if [ "$OSTYPE" == "cygwin32" ] || [ "$OSTYPE" = "cygwin" ]; then
  
    if [ ! "$JAVA_HOME" = "" ]; then
      JAVA_HOME=`cygpath --path --unix $JAVA_HOME`
    fi
  fi
  
  ## resolve links - $0 may be a link to ant's home
  PRG=$0
  progname=`basename $0`
    
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '.*/.*' > /dev/null; then
      PRG="$link"
    else
      PRG="`dirname $PRG`/$link"
    fi
  done
    
  ANT_HOME=`dirname "$PRG"`/..
  
  # Allow .antrc to specifiy flags to java cmd
  if [ "$JAVACMD" = "" ] ; then 
    JAVACMD=java
  fi
  
  LOCALCLASSPATH=`echo $ANT_HOME/lib/*.jar | tr ' ' ':'`
  
  if [ "$CLASSPATH" != "" ] ; then
    LOCALCLASSPATH=$CLASSPATH:$LOCALCLASSPATH
  fi
  
  if [ "$JAVA_HOME" != "" ] ; then
    if test -f $JAVA_HOME/lib/tools.jar ; then
      LOCALCLASSPATH=$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar
    fi
  else
    echo "Warning: JAVA_HOME environment variable is not set."
    echo "  If build fails because sun.* classes could not be found"
    echo "  you will need to set the JAVA_HOME environment variable"
    echo "  to the installation directory of java."
  fi
  
  # More Cygwin support
  if [ "$OSTYPE" == "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then
    LOCALCLASSPATH=`cygpath --path --windows "$LOCALCLASSPATH"`
  fi
  
  $JAVACMD -classpath $LOCALCLASSPATH $ANT_OPTS org.apache.ant.Main --ant-home=${ANT_HOME} $@
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/script/ant.bat
  
  Index: ant.bat
  ===================================================================
  @echo off
  
  :checkJava
  if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java
  if not "%JAVA_HOME%" == "" goto setupClasspath
  
  echo.
  echo Warning: JAVA_HOME environment variable is not set.
  echo   If build fails because sun.* classes could not be found
  echo   you will need to set the JAVA_HOME environment variable
  echo   to the installation directory of java.
  echo.
  goto end
  
  :setupClasspath
  set LOCALCLASSPATH=lib\xerces.jar;lib\ant.jar;lib\avalonapi.jar;%JAVA_HOME%\lib\tools.jar
  
  set THIS_FILE=%0
  
  set ANT_CMD_LINE_ARGS=
  
  rem Slurp all args...
  :setupArgs
  if "%0" == "" goto doneArgs
  set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
  shift
  goto setupArgs
  
  :doneArgs
  rem Mmmmmm tasty - finished slurping args
  
  %JAVACMD% -classpath "%LOCALCLASSPATH%" %ANT_OPTS% org.apache.ant.Main "--bin-dir=%THIS_FILE%" %ANT_CMD_LINE_ARGS%
  
  :end
  set LOCALCLASSPATH=
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/script/antRun
  
  Index: antRun
  ===================================================================
  #! /bin/sh
  
  # Args: DIR command
  cd "$1"
  CMD="$2"
  shift
  shift
  
  exec $CMD "$@"
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/script/antRun.bat
  
  Index: antRun.bat
  ===================================================================
  @echo off
  
  cd %1
  set ANT_RUN_CMD=%2
  shift
  shift
  
  set PARAMS=
  :loop
  if "%1" == "" goto runCommand
  set PARAMS=%PARAMS% %1
  shift
  goto loop
  
  :runCommand
  echo %ANT_RUN_CMD% %PARAMS%
  %ANT_RUN_CMD% %PARAMS%