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% | |||