Browse Source

Initiall checkin of myrmidon proposal

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268292 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 24 years ago
parent
commit
ed120ac805
75 changed files with 4886 additions and 0 deletions
  1. +1
    -0
      proposal/myrmidon/.ant.properties
  2. +16
    -0
      proposal/myrmidon/build.bat
  3. +11
    -0
      proposal/myrmidon/build.sh
  4. +260
    -0
      proposal/myrmidon/build.xml
  5. +7
    -0
      proposal/myrmidon/emacs-jprj.el
  6. BIN
      proposal/myrmidon/lib/ant.jar
  7. BIN
      proposal/myrmidon/lib/avalonapi.jar
  8. BIN
      proposal/myrmidon/lib/xerces.jar
  9. +29
    -0
      proposal/myrmidon/src/java/org/apache/ant/AntContextResources.java
  10. +25
    -0
      proposal/myrmidon/src/java/org/apache/ant/AntException.java
  11. +797
    -0
      proposal/myrmidon/src/java/org/apache/ant/Main.java
  12. +39
    -0
      proposal/myrmidon/src/java/org/apache/ant/configuration/Configurable.java
  13. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/configuration/Configuration.java
  14. +28
    -0
      proposal/myrmidon/src/java/org/apache/ant/configuration/ConfigurationBuilder.java
  15. +45
    -0
      proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfiguration.java
  16. +21
    -0
      proposal/myrmidon/src/java/org/apache/ant/configuration/SAXConfigurationHandler.java
  17. +48
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/AbstractConverter.java
  18. +19
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/Converter.java
  19. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEntry.java
  20. +23
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/ConverterFactory.java
  21. +51
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/ConverterInfo.java
  22. +22
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/ConverterLoader.java
  23. +16
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/ConverterRegistry.java
  24. +75
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterFactory.java
  25. +78
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterInfo.java
  26. +39
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterLoader.java
  27. +51
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterRegistry.java
  28. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToByteConverter.java
  29. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToDoubleConverter.java
  30. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToFloatConverter.java
  31. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToIntegerConverter.java
  32. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToLongConverter.java
  33. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToShortConverter.java
  34. +6
    -0
      proposal/myrmidon/src/java/org/apache/ant/convert/core/converters.properties
  35. +77
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/DefaultProject.java
  36. +215
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java
  37. +183
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java
  38. +62
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectListener.java
  39. +61
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java
  40. +30
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/Project.java
  41. +23
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/ProjectBuilder.java
  42. +21
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/ProjectEngine.java
  43. +23
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/ProjectListener.java
  44. +20
    -0
      proposal/myrmidon/src/java/org/apache/ant/project/Target.java
  45. +82
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java
  46. +236
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java
  47. +28
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/JavaVersion.java
  48. +21
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java
  49. +122
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java
  50. +438
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletConfigurer.java
  51. +231
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java
  52. +65
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletFactory.java
  53. +54
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletInfo.java
  54. +37
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletLoader.java
  55. +20
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletRegistry.java
  56. +24
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletConfigurer.java
  57. +20
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java
  58. +31
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEntry.java
  59. +23
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletFactory.java
  60. +36
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletInfo.java
  61. +23
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletLoader.java
  62. +15
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletRegistry.java
  63. +200
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java
  64. +47
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/ConfigurationTest.java
  65. +37
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/ContentTest.java
  66. +33
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/Echo.java
  67. +90
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/PrimitiveTypesTest.java
  68. +64
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java
  69. +43
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/SubElementTest.java
  70. +7
    -0
      proposal/myrmidon/src/java/org/apache/ant/tasks/core/taskdefs.properties
  71. +69
    -0
      proposal/myrmidon/src/make/sample.xmk
  72. +58
    -0
      proposal/myrmidon/src/script/ant
  73. +35
    -0
      proposal/myrmidon/src/script/ant.bat
  74. +9
    -0
      proposal/myrmidon/src/script/antRun
  75. +18
    -0
      proposal/myrmidon/src/script/antRun.bat

+ 1
- 0
proposal/myrmidon/.ant.properties View File

@@ -0,0 +1 @@
build.compiler=jikes

+ 16
- 0
proposal/myrmidon/build.bat View File

@@ -0,0 +1,16 @@
@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=

+ 11
- 0
proposal/myrmidon/build.sh View File

@@ -0,0 +1,11 @@
#!/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

+ 260
- 0
proposal/myrmidon/build.xml View File

@@ -0,0 +1,260 @@
<?xml version="1.0"?>

<!--
==============================================================================

Ant build file

Authors:
Peter Donald <donaldp@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>

+ 7
- 0
proposal/myrmidon/emacs-jprj.el View File

@@ -0,0 +1,7 @@
(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")

BIN
proposal/myrmidon/lib/ant.jar View File


BIN
proposal/myrmidon/lib/avalonapi.jar View File


BIN
proposal/myrmidon/lib/xerces.jar View File


+ 29
- 0
proposal/myrmidon/src/java/org/apache/ant/AntContextResources.java View File

@@ -0,0 +1,29 @@
/*
* 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";
}

+ 25
- 0
proposal/myrmidon/src/java/org/apache/ant/AntException.java View File

@@ -0,0 +1,25 @@
/*
* 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 );
}
}


+ 797
- 0
proposal/myrmidon/src/java/org/apache/ant/Main.java View File

@@ -0,0 +1,797 @@
/*
* 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;
}
}


+ 39
- 0
proposal/myrmidon/src/java/org/apache/ant/configuration/Configurable.java View File

@@ -0,0 +1,39 @@
/*
* 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;
}

+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/configuration/Configuration.java View File

@@ -0,0 +1,31 @@
/*
* 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();
}

+ 28
- 0
proposal/myrmidon/src/java/org/apache/ant/configuration/ConfigurationBuilder.java View File

@@ -0,0 +1,28 @@
/*
* 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();
}
}

+ 45
- 0
proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfiguration.java View File

@@ -0,0 +1,45 @@
/*
* 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();
}
}

+ 21
- 0
proposal/myrmidon/src/java/org/apache/ant/configuration/SAXConfigurationHandler.java View File

@@ -0,0 +1,21 @@
/*
* 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 );
}
}

+ 48
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/AbstractConverter.java View File

@@ -0,0 +1,48 @@
/*
* 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;
}


+ 19
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/Converter.java View File

@@ -0,0 +1,19 @@
/*
* 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;
}

+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEntry.java View File

@@ -0,0 +1,31 @@
/*
* 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();
}
}


+ 23
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/ConverterFactory.java View File

@@ -0,0 +1,23 @@
/*
* 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;
}

+ 51
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/ConverterInfo.java View File

@@ -0,0 +1,51 @@
/*
* 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();
}


+ 22
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/ConverterLoader.java View File

@@ -0,0 +1,22 @@
/*
* 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;
}

+ 16
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/ConverterRegistry.java View File

@@ -0,0 +1,16 @@
/*
* 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 );
}

+ 75
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterFactory.java View File

@@ -0,0 +1,75 @@
/*
* 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();
}
}

+ 78
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterInfo.java View File

@@ -0,0 +1,78 @@
/*
* 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;
}
}


+ 39
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterLoader.java View File

@@ -0,0 +1,39 @@
/*
* 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 );
}
}

+ 51
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterRegistry.java View File

@@ -0,0 +1,51 @@
/*
* 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;
}
}

+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToByteConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToDoubleConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToFloatConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToIntegerConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToLongConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToShortConverter.java View File

@@ -0,0 +1,31 @@
/*
* 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 );
}
}


+ 6
- 0
proposal/myrmidon/src/java/org/apache/ant/convert/core/converters.properties View File

@@ -0,0 +1,6 @@
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

+ 77
- 0
proposal/myrmidon/src/java/org/apache/ant/project/DefaultProject.java View File

@@ -0,0 +1,77 @@
/*
* 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 );
}
}
}



+ 215
- 0
proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java View File

@@ -0,0 +1,215 @@
/*
* 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 );
}
}

+ 183
- 0
proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java View File

@@ -0,0 +1,183 @@
/*
* 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 );
}
}

+ 62
- 0
proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectListener.java View File

@@ -0,0 +1,62 @@
/*
* 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 );
}
}

+ 61
- 0
proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java View File

@@ -0,0 +1,61 @@
/*
* 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 );
}
}

+ 30
- 0
proposal/myrmidon/src/java/org/apache/ant/project/Project.java View File

@@ -0,0 +1,30 @@
/*
* 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();
}

+ 23
- 0
proposal/myrmidon/src/java/org/apache/ant/project/ProjectBuilder.java View File

@@ -0,0 +1,23 @@
/*
* 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;
}



+ 21
- 0
proposal/myrmidon/src/java/org/apache/ant/project/ProjectEngine.java View File

@@ -0,0 +1,21 @@
/*
* 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;
}

+ 23
- 0
proposal/myrmidon/src/java/org/apache/ant/project/ProjectListener.java View File

@@ -0,0 +1,23 @@
/*
* 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();
}

+ 20
- 0
proposal/myrmidon/src/java/org/apache/ant/project/Target.java View File

@@ -0,0 +1,20 @@
/*
* 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();
}



+ 82
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java View File

@@ -0,0 +1,82 @@
/*
* 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;
}
}

+ 236
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java View File

@@ -0,0 +1,236 @@
/*
* 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() );
}
}
}

+ 28
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/JavaVersion.java View File

@@ -0,0 +1,28 @@
/*
* 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 );
}
}

+ 21
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java View File

@@ -0,0 +1,21 @@
/*
* 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
{
}

+ 122
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java View File

@@ -0,0 +1,122 @@
/*
* 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 );
}
}
}


+ 438
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletConfigurer.java View File

@@ -0,0 +1,438 @@
/*
* 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 );
}
}
}

+ 231
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java View File

@@ -0,0 +1,231 @@
/*
* 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();
}
}

+ 65
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletFactory.java View File

@@ -0,0 +1,65 @@
/*
* 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();
}
}

+ 54
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletInfo.java View File

@@ -0,0 +1,54 @@
/*
* 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;
}
}

+ 37
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletLoader.java View File

@@ -0,0 +1,37 @@
/*
* 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 );
}
}

+ 20
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletRegistry.java View File

@@ -0,0 +1,20 @@
/*
* 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;
}
}

+ 24
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletConfigurer.java View File

@@ -0,0 +1,24 @@
/*
* 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;
}

+ 20
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java View File

@@ -0,0 +1,20 @@
/*
* 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;
}

+ 31
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEntry.java View File

@@ -0,0 +1,31 @@
/*
* 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();
}
}


+ 23
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletFactory.java View File

@@ -0,0 +1,23 @@
/*
* 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;
}

+ 36
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletInfo.java View File

@@ -0,0 +1,36 @@
/*
* 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();
}

+ 23
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletLoader.java View File

@@ -0,0 +1,23 @@
/*
* 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;
}

+ 15
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletRegistry.java View File

@@ -0,0 +1,15 @@
/*
* 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
{
}

+ 200
- 0
proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java View File

@@ -0,0 +1,200 @@
/*
* 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
{
}
}

+ 47
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/ConfigurationTest.java View File

@@ -0,0 +1,47 @@
/*
* 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 );
}
}

+ 37
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/ContentTest.java View File

@@ -0,0 +1,37 @@
/*
* 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
{
}
}

+ 33
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/Echo.java View File

@@ -0,0 +1,33 @@
/*
* 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 );
}
}

+ 90
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/PrimitiveTypesTest.java View File

@@ -0,0 +1,90 @@

/*
* 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
{
}
}

+ 64
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java View File

@@ -0,0 +1,64 @@
/*
* 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 );
}
}
}

+ 43
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/SubElementTest.java View File

@@ -0,0 +1,43 @@

/*
* 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
{
}
}

+ 7
- 0
proposal/myrmidon/src/java/org/apache/ant/tasks/core/taskdefs.properties View File

@@ -0,0 +1,7 @@
# 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

+ 69
- 0
proposal/myrmidon/src/make/sample.xmk View File

@@ -0,0 +1,69 @@
<?xml version="1.0"?>

<!--
==============================================================================

Sample build file

Authors:
Peter Donald <donaldp@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>

+ 58
- 0
proposal/myrmidon/src/script/ant View File

@@ -0,0 +1,58 @@
#!/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} $@

+ 35
- 0
proposal/myrmidon/src/script/ant.bat View File

@@ -0,0 +1,35 @@
@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=

+ 9
- 0
proposal/myrmidon/src/script/antRun View File

@@ -0,0 +1,9 @@
#! /bin/sh

# Args: DIR command
cd "$1"
CMD="$2"
shift
shift

exec $CMD "$@"

+ 18
- 0
proposal/myrmidon/src/script/antRun.bat View File

@@ -0,0 +1,18 @@
@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%


Loading…
Cancel
Save