git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268292 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1 @@ | |||||
| build.compiler=jikes | |||||
| @@ -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= | |||||
| @@ -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 | |||||
| @@ -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> | |||||
| @@ -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") | |||||
| @@ -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"; | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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() ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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(); | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| { | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| @@ -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> | |||||
| @@ -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} $@ | |||||
| @@ -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= | |||||
| @@ -0,0 +1,9 @@ | |||||
| #! /bin/sh | |||||
| # Args: DIR command | |||||
| cd "$1" | |||||
| CMD="$2" | |||||
| shift | |||||
| shift | |||||
| exec $CMD "$@" | |||||
| @@ -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% | |||||