git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268313 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -7,6 +7,11 @@ | |||||
| */ | */ | ||||
| package org.apache.ant; | package org.apache.ant; | ||||
| /** | |||||
| * Interface that holds constants used to access variables from context. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public interface AntContextResources | public interface AntContextResources | ||||
| { | { | ||||
| // the directory of ant | // the directory of ant | ||||
| @@ -9,14 +9,34 @@ package org.apache.ant; | |||||
| import org.apache.avalon.CascadingRuntimeException; | import org.apache.avalon.CascadingRuntimeException; | ||||
| /** | |||||
| * AntException thrown when a problem with tasks etc. | |||||
| * It is cascading so that further embedded information can be contained. | |||||
| * ie ANtException was caused by IOException etc. | |||||
| * It is RuntimeException as it has to pass through a number of Java-defined | |||||
| * interfaces - ala Runnable and also to aid in ease of indicating an error. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public class AntException | public class AntException | ||||
| extends CascadingRuntimeException | extends CascadingRuntimeException | ||||
| { | { | ||||
| /** | |||||
| * Basic constructor with a message | |||||
| * | |||||
| * @param message the message | |||||
| */ | |||||
| public AntException( final String message ) | public AntException( final String message ) | ||||
| { | { | ||||
| this( message, null ); | this( message, null ); | ||||
| } | } | ||||
| /** | |||||
| * Constructor that builds cascade so that other exception information can be retained. | |||||
| * | |||||
| * @param message the message | |||||
| * @param throwable the throwable | |||||
| */ | |||||
| public AntException( final String message, final Throwable throwable ) | public AntException( final String message, final Throwable throwable ) | ||||
| { | { | ||||
| super( message, throwable ); | super( message, throwable ); | ||||
| @@ -18,6 +18,7 @@ import java.net.URL; | |||||
| import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| import java.util.Map; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.List; | import java.util.List; | ||||
| import org.apache.ant.launcher.AntLoader; | import org.apache.ant.launcher.AntLoader; | ||||
| @@ -33,6 +34,7 @@ import org.apache.avalon.Disposable; | |||||
| import org.apache.avalon.Initializable; | import org.apache.avalon.Initializable; | ||||
| import org.apache.avalon.camelot.Deployer; | import org.apache.avalon.camelot.Deployer; | ||||
| import org.apache.avalon.camelot.DeploymentException; | import org.apache.avalon.camelot.DeploymentException; | ||||
| import org.apache.avalon.util.ObjectUtil; | |||||
| import org.apache.avalon.util.StringUtil; | import org.apache.avalon.util.StringUtil; | ||||
| import org.apache.avalon.util.cli.AbstractMain; | import org.apache.avalon.util.cli.AbstractMain; | ||||
| import org.apache.avalon.util.cli.CLOption; | import org.apache.avalon.util.cli.CLOption; | ||||
| @@ -54,16 +56,22 @@ import org.apache.log.Priority; | |||||
| public class Main | public class Main | ||||
| extends AbstractMain | extends AbstractMain | ||||
| { | { | ||||
| //Constants to indicate the build of Ant/Myrmidon | |||||
| public final static String BUILD_DATE = "@@DATE@@"; | public final static String BUILD_DATE = "@@DATE@@"; | ||||
| public final static String BUILD_VERSION = "@@VERSION@@"; | public final static String BUILD_VERSION = "@@VERSION@@"; | ||||
| public final static String VERSION = | public final static String VERSION = | ||||
| "Ant " + BUILD_VERSION + " compiled on " + BUILD_DATE; | "Ant " + BUILD_VERSION + " compiled on " + BUILD_DATE; | ||||
| //default log level | |||||
| protected final static String DEFAULT_LOGLEVEL = "WARN"; | protected final static String DEFAULT_LOGLEVEL = "WARN"; | ||||
| //Some defaults for file locations/names | |||||
| protected final static String DEFAULT_LIB_DIRECTORY = "lib"; | protected final static String DEFAULT_LIB_DIRECTORY = "lib"; | ||||
| protected final static String DEFAULT_TASKLIB_DIRECTORY = DEFAULT_LIB_DIRECTORY; | protected final static String DEFAULT_TASKLIB_DIRECTORY = DEFAULT_LIB_DIRECTORY; | ||||
| protected final static String DEFAULT_FILENAME = "build.xmk"; | protected final static String DEFAULT_FILENAME = "build.xmk"; | ||||
| //some constants that define the classes to be loaded to perform | |||||
| //particular services | |||||
| protected final static String DEFAULT_ENGINE = | protected final static String DEFAULT_ENGINE = | ||||
| "org.apache.ant.project.DefaultProjectEngine"; | "org.apache.ant.project.DefaultProjectEngine"; | ||||
| @@ -73,6 +81,7 @@ public class Main | |||||
| protected final static String DEFAULT_BUILDER = | protected final static String DEFAULT_BUILDER = | ||||
| "org.apache.ant.project.DefaultProjectBuilder"; | "org.apache.ant.project.DefaultProjectBuilder"; | ||||
| //defines for the Command Line options | |||||
| private static final int HELP_OPT = 'h'; | private static final int HELP_OPT = 'h'; | ||||
| private static final int QUIET_OPT = 'q'; | private static final int QUIET_OPT = 'q'; | ||||
| private static final int VERBOSE_OPT = 'v'; | private static final int VERBOSE_OPT = 'v'; | ||||
| @@ -102,8 +111,8 @@ public class Main | |||||
| QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT | QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT | ||||
| }; | }; | ||||
| protected Logger m_logger; | |||||
| protected Logger m_logger; | |||||
| protected ProjectListener m_listener; | protected ProjectListener m_listener; | ||||
| protected File m_binDir; | protected File m_binDir; | ||||
| protected File m_homeDir; | protected File m_homeDir; | ||||
| @@ -112,6 +121,11 @@ public class Main | |||||
| protected File m_buildFile; | protected File m_buildFile; | ||||
| protected File m_userDir; | protected File m_userDir; | ||||
| /** | |||||
| * Main entry point called to run standard Ant. | |||||
| * | |||||
| * @param args the args | |||||
| */ | |||||
| public static void main( final String[] args ) | public static void main( final String[] args ) | ||||
| { | { | ||||
| final Main main = new Main(); | final Main main = new Main(); | ||||
| @@ -131,6 +145,7 @@ public class Main | |||||
| /** | /** | ||||
| * Initialise the options for command line parser. | * Initialise the options for command line parser. | ||||
| * This is called by super-class. | |||||
| */ | */ | ||||
| protected CLOptionDescriptor[] createCLOptions() | protected CLOptionDescriptor[] createCLOptions() | ||||
| { | { | ||||
| @@ -278,6 +293,9 @@ public class Main | |||||
| setupListener( listenerName ); //handle listener.. | setupListener( listenerName ); //handle listener.. | ||||
| setupDefaultAntDirs(); | setupDefaultAntDirs(); | ||||
| //try to auto-discover the location of ant so that | |||||
| //can populate classpath with libs/tasks and gain access | |||||
| //to antRun | |||||
| if( null == binDir && null == homeDir ) | if( null == binDir && null == homeDir ) | ||||
| { | { | ||||
| m_homeDir = getDefaultHomeDir(); | m_homeDir = getDefaultHomeDir(); | ||||
| @@ -304,6 +322,8 @@ public class Main | |||||
| m_logger.debug( "Ant Lib Directory: " + m_libDir ); | m_logger.debug( "Ant Lib Directory: " + m_libDir ); | ||||
| m_logger.debug( "Ant Task Lib Directory: " + m_taskLibDir ); | m_logger.debug( "Ant Task Lib Directory: " + m_taskLibDir ); | ||||
| //setup classloader so that it will correctly load | |||||
| //the Project/ProjectBuilder/ProjectEngine and all dependencies | |||||
| setupContextClassLoader( m_libDir ); | setupContextClassLoader( m_libDir ); | ||||
| final Project project = getProject( builderName, m_buildFile ); | final Project project = getProject( builderName, m_buildFile ); | ||||
| @@ -323,8 +343,10 @@ public class Main | |||||
| BufferedReader reader = null; | BufferedReader reader = null; | ||||
| //loop over build if we are in incremental mode.. | |||||
| while( true ) | while( true ) | ||||
| { | { | ||||
| //actually do the build ... | |||||
| doBuild( engine, project, targets ); | doBuild( engine, project, targets ); | ||||
| if( !incremental ) break; | if( !incremental ) break; | ||||
| @@ -341,13 +363,20 @@ public class Main | |||||
| if( line.equalsIgnoreCase( "no" ) ) break; | if( line.equalsIgnoreCase( "no" ) ) break; | ||||
| } | } | ||||
| //shutdown engine gracefully if needed | |||||
| if( engine instanceof Disposable ) | if( engine instanceof Disposable ) | ||||
| { | { | ||||
| ((Disposable)engine).dispose(); | ((Disposable)engine).dispose(); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Deploy all tasklibs in tasklib directory into ProjectEngine. | |||||
| * | |||||
| * @param engine the ProjectEngine | |||||
| * @param taskLibDirectory the directory to look for .tsk files | |||||
| */ | |||||
| protected void deployDefaultTaskLibs( final ProjectEngine engine, | protected void deployDefaultTaskLibs( final ProjectEngine engine, | ||||
| final File taskLibDirectory ) | final File taskLibDirectory ) | ||||
| @@ -375,6 +404,13 @@ public class Main | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Actually do the build. | |||||
| * | |||||
| * @param engine the engine | |||||
| * @param project the project | |||||
| * @param targets the targets to build as passed by CLI | |||||
| */ | |||||
| protected void doBuild( final ProjectEngine engine, | protected void doBuild( final ProjectEngine engine, | ||||
| final Project project, | final Project project, | ||||
| final ArrayList targets ) | final ArrayList targets ) | ||||
| @@ -383,6 +419,7 @@ public class Main | |||||
| { | { | ||||
| final int targetCount = targets.size(); | final int targetCount = targets.size(); | ||||
| //if we didn't specify a target on CLI then choose default | |||||
| if( 0 == targetCount ) | if( 0 == targetCount ) | ||||
| { | { | ||||
| engine.execute( project, project.getDefaultTargetName() ); | engine.execute( project, project.getDefaultTargetName() ); | ||||
| @@ -402,23 +439,68 @@ public class Main | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Setup Logger for a particular log-level. | |||||
| * This is in seperate method so it can be overidden if sub-classed. | |||||
| * | |||||
| * @param logLevel the log-level | |||||
| */ | |||||
| protected void setupLogger( final String logLevel ) | protected void setupLogger( final String logLevel ) | ||||
| { | { | ||||
| m_logger = createLogger( logLevel ); | m_logger = createLogger( logLevel ); | ||||
| } | } | ||||
| /** | |||||
| * Create Logger of appropriate log-level. | |||||
| * | |||||
| * @param logLevel the log-level | |||||
| * @return the logger | |||||
| * @exception AntException if an error occurs | |||||
| */ | |||||
| 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 ); | |||||
| } | |||||
| /** | |||||
| * Setup project listener. | |||||
| * | |||||
| * @param listenerName the name of project listener | |||||
| */ | |||||
| protected void setupListener( final String listenerName ) | protected void setupListener( final String listenerName ) | ||||
| { | { | ||||
| m_listener = createListener( listenerName ); | m_listener = createListener( listenerName ); | ||||
| m_logger.addLogTarget( new ProjectToListenerAdapter( m_listener ) ); | m_logger.addLogTarget( new ProjectToListenerAdapter( m_listener ) ); | ||||
| } | } | ||||
| /** | |||||
| * Make sure classloader is setup correctly so can do Class.forName safely | |||||
| * | |||||
| * @param libDir the directory to grab all the lib files from | |||||
| */ | |||||
| protected void setupContextClassLoader( final File libDir ) | protected void setupContextClassLoader( final File libDir ) | ||||
| { | { | ||||
| setupClassLoader( libDir ); | setupClassLoader( libDir ); | ||||
| Thread.currentThread().setContextClassLoader( AntLoader.getLoader() ); | Thread.currentThread().setContextClassLoader( AntLoader.getLoader() ); | ||||
| } | } | ||||
| /** | |||||
| * Setup classloader so that the *current* classloader has access to parsers etc. | |||||
| * This is a bit of a hack as it assumes that AntLoader was used to load this file | |||||
| * but it is the only way to add to current classloader safely. | |||||
| * | |||||
| * @param libDir the directory of lib files to add | |||||
| */ | |||||
| protected void setupClassLoader( final File libDir ) | protected void setupClassLoader( final File libDir ) | ||||
| { | { | ||||
| final ExtensionFileFilter filter = | final ExtensionFileFilter filter = | ||||
| @@ -430,6 +512,8 @@ public class Main | |||||
| for( int i = 0; i < files.length; i++ ) | for( int i = 0; i < files.length; i++ ) | ||||
| { | { | ||||
| //except for a few *special* files add all the | |||||
| //.zip/.jars to classloader | |||||
| if( !files[ i ].getName().equals( "ant.jar" ) && | if( !files[ i ].getName().equals( "ant.jar" ) && | ||||
| !files[ i ].getName().equals( "myrmidon.jar" ) && | !files[ i ].getName().equals( "myrmidon.jar" ) && | ||||
| !files[ i ].getName().equals( "avalonapi.jar" ) ) | !files[ i ].getName().equals( "avalonapi.jar" ) ) | ||||
| @@ -440,6 +524,15 @@ public class Main | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Using a specified builder create a project from a particular file. | |||||
| * | |||||
| * @param builderName the name of the builder class | |||||
| * @param file the file | |||||
| * @return the newly created Project | |||||
| * @exception AntException if an error occurs | |||||
| * @exception IOException if an error occurs | |||||
| */ | |||||
| protected Project getProject( final String builderName, final File file ) | protected Project getProject( final String builderName, final File file ) | ||||
| throws AntException, IOException | throws AntException, IOException | ||||
| { | { | ||||
| @@ -453,30 +546,59 @@ public class Main | |||||
| return project; | return project; | ||||
| } | } | ||||
| /** | |||||
| * Setup the projects context so all the "default" properties are defined. | |||||
| * This also takes a hashmap that is added to context. Usually these are the | |||||
| * ones defined on command line. | |||||
| * | |||||
| * @param project the project | |||||
| * @param defines the defines | |||||
| * @exception AntException if an error occurs | |||||
| */ | |||||
| protected void setupProjectContext( final Project project, final HashMap defines ) | protected void setupProjectContext( final Project project, final HashMap defines ) | ||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| //put these values into defines so that they overide | |||||
| //user-defined proeprties | |||||
| defines.put( AntContextResources.HOME_DIR, m_homeDir ); | |||||
| defines.put( AntContextResources.BIN_DIR, m_binDir ); | |||||
| defines.put( AntContextResources.LIB_DIR, m_libDir ); | |||||
| defines.put( AntContextResources.TASKLIB_DIR, m_taskLibDir ); | |||||
| //defines.put( AntContextResources.USER_DIR, m_userDir ); | |||||
| defines.put( TaskletContext.LOGGER, m_logger ); | |||||
| defines.put( TaskletContext.JAVA_VERSION, getJavaVersion() ); | |||||
| final TaskletContext context = project.getContext(); | 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 | |||||
| addToContext( context, defines ); | |||||
| //Add system properties second so that they overide user-defined properties | |||||
| addToContext( context, System.getProperties() ); | |||||
| } | |||||
| /** | |||||
| * Helper method to add values to a context | |||||
| * | |||||
| * @param context the context | |||||
| * @param map the map of names->values | |||||
| */ | |||||
| protected void addToContext( final TaskletContext context, final Map map ) | |||||
| { | |||||
| final Iterator keys = map.keySet().iterator(); | |||||
| while( keys.hasNext() ) | while( keys.hasNext() ) | ||||
| { | { | ||||
| final String key = (String)keys.next(); | final String key = (String)keys.next(); | ||||
| final String value = (String)defines.get( key ); | |||||
| final Object value = map.get( key ); | |||||
| context.setProperty( key, value ); | 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() ); | |||||
| } | } | ||||
| /** | |||||
| * Helper method to retrieve current JVM version. | |||||
| * Basically stolen from original Ant sources. | |||||
| * | |||||
| * @return the current JVM version | |||||
| */ | |||||
| protected JavaVersion getJavaVersion() | protected JavaVersion getJavaVersion() | ||||
| { | { | ||||
| JavaVersion version = JavaVersion.JAVA1_0; | JavaVersion version = JavaVersion.JAVA1_0; | ||||
| @@ -495,6 +617,11 @@ public class Main | |||||
| return version; | return version; | ||||
| } | } | ||||
| /** | |||||
| * Create and configure project engine | |||||
| * | |||||
| * @return the ProjectEngine | |||||
| */ | |||||
| protected ProjectEngine getProjectEngine() | protected ProjectEngine getProjectEngine() | ||||
| { | { | ||||
| final ProjectEngine engine = createProjectEngine(); | final ProjectEngine engine = createProjectEngine(); | ||||
| @@ -502,6 +629,12 @@ public class Main | |||||
| return engine; | return engine; | ||||
| } | } | ||||
| /** | |||||
| * Create the project engine. | |||||
| * This is seperate method so that it can be overidden in a sub-class. | |||||
| * | |||||
| * @return the new ProjectEngine | |||||
| */ | |||||
| protected ProjectEngine createProjectEngine() | protected ProjectEngine createProjectEngine() | ||||
| { | { | ||||
| return (ProjectEngine)createObject( DEFAULT_ENGINE, "project-engine" ); | return (ProjectEngine)createObject( DEFAULT_ENGINE, "project-engine" ); | ||||
| @@ -510,7 +643,7 @@ public class Main | |||||
| protected File getHomeDir( final String homeDir ) | protected File getHomeDir( final String homeDir ) | ||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| final File file = new File( homeDir ); | |||||
| final File file = (new File( homeDir )).getAbsoluteFile(); | |||||
| checkDirectory( file, "ant-home" ); | checkDirectory( file, "ant-home" ); | ||||
| return file; | return file; | ||||
| } | } | ||||
| @@ -568,21 +701,6 @@ public class Main | |||||
| } | } | ||||
| } | } | ||||
| 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() | protected void setupDefaultAntDirs() | ||||
| { | { | ||||
| final String os = System.getProperty( "os.name" ); | final String os = System.getProperty( "os.name" ); | ||||
| @@ -767,8 +885,7 @@ public class Main | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| final Class clazz = Class.forName( objectName ); | |||||
| return clazz.newInstance(); | |||||
| return ObjectUtil.createObject( objectName ); | |||||
| } | } | ||||
| catch( final IllegalAccessException iae ) | catch( final IllegalAccessException iae ) | ||||
| { | { | ||||
| @@ -10,7 +10,10 @@ package org.apache.ant.configuration; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| /** | /** | ||||
| * Hostile fork till Avalon gets equivelent functionality ;) | |||||
| * Fork of Avalon code that will be folded back when they get equivelent facilties. | |||||
| * Note that the code is different package so it should not cause any issues. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | */ | ||||
| public interface Configuration | public interface Configuration | ||||
| extends org.apache.avalon.Configuration | extends org.apache.avalon.Configuration | ||||
| @@ -10,7 +10,10 @@ package org.apache.ant.configuration; | |||||
| import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
| /** | /** | ||||
| * Hostile fork till Avalon gets equivelent functionality ;) | |||||
| * Fork of Avalon code that will be folded back when they get equivelent facilties. | |||||
| * Note that the code is different package so it should not cause any issues. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | */ | ||||
| public class ConfigurationBuilder | public class ConfigurationBuilder | ||||
| extends org.apache.avalon.DefaultConfigurationBuilder | extends org.apache.avalon.DefaultConfigurationBuilder | ||||
| @@ -10,7 +10,10 @@ package org.apache.ant.configuration; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| /** | /** | ||||
| * Hostile fork till Avalon gets equivelent functionality ;) | |||||
| * Fork of Avalon code that will be folded back when they get equivelent facilties. | |||||
| * Note that the code is different package so it should not cause any issues. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | */ | ||||
| public class DefaultConfiguration | public class DefaultConfiguration | ||||
| extends org.apache.avalon.DefaultConfiguration | extends org.apache.avalon.DefaultConfiguration | ||||
| @@ -8,7 +8,10 @@ | |||||
| package org.apache.ant.configuration; | package org.apache.ant.configuration; | ||||
| /** | /** | ||||
| * Hostile fork till Avalon gets equivelent functionality ;) | |||||
| * Fork of Avalon code that will be folded back when they get equivelent facilties. | |||||
| * Note that the code is different package so it should not cause any issues. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | */ | ||||
| public class SAXConfigurationHandler | public class SAXConfigurationHandler | ||||
| extends org.apache.avalon.SAXConfigurationHandler | extends org.apache.avalon.SAXConfigurationHandler | ||||
| @@ -18,12 +18,26 @@ public abstract class AbstractConverter | |||||
| protected final Class m_source; | protected final Class m_source; | ||||
| protected final Class m_destination; | protected final Class m_destination; | ||||
| /** | |||||
| * Constructor for a converter between types source and destination | |||||
| * | |||||
| * @param source the source type | |||||
| * @param destination the destination type | |||||
| */ | |||||
| public AbstractConverter( final Class source, final Class destination ) | public AbstractConverter( final Class source, final Class destination ) | ||||
| { | { | ||||
| m_source = source; | m_source = source; | ||||
| m_destination = destination; | m_destination = destination; | ||||
| } | } | ||||
| /** | |||||
| * Convert an object from original to destination types | |||||
| * | |||||
| * @param destination the destination type | |||||
| * @param original the original Object | |||||
| * @return the converted object | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| public Object convert( final Class destination, final Object original ) | public Object convert( final Class destination, final Object original ) | ||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| @@ -42,6 +56,13 @@ public abstract class AbstractConverter | |||||
| return convert( original ); | return convert( original ); | ||||
| } | } | ||||
| /** | |||||
| * Overide this in a particular converter to do the conversion. | |||||
| * | |||||
| * @param original the original Object | |||||
| * @return the converted object | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| protected abstract Object convert( Object original ) | protected abstract Object convert( Object original ) | ||||
| throws Exception; | throws Exception; | ||||
| } | } | ||||
| @@ -14,6 +14,16 @@ package org.apache.ant.convert; | |||||
| */ | */ | ||||
| public interface Converter | public interface Converter | ||||
| { | { | ||||
| /** | |||||
| * Convert original to destination type. | |||||
| * Destination is passed so that one converter can potentiall | |||||
| * convert to multiple different types. | |||||
| * | |||||
| * @param destination the destinaiton type | |||||
| * @param original the original type | |||||
| * @return the converted object | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| Object convert( Class destination, Object original ) | Object convert( Class destination, Object original ) | ||||
| throws Exception; | throws Exception; | ||||
| } | } | ||||
| @@ -10,6 +10,12 @@ package org.apache.ant.convert; | |||||
| import org.apache.ant.convert.Converter; | import org.apache.ant.convert.Converter; | ||||
| import org.apache.avalon.camelot.AbstractEntry; | import org.apache.avalon.camelot.AbstractEntry; | ||||
| /** | |||||
| * An entry representing an instance of Converter. | |||||
| * See Cameloy documentation for more details. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public class ConverterEntry | public class ConverterEntry | ||||
| extends AbstractEntry | extends AbstractEntry | ||||
| { | { | ||||
| @@ -18,6 +18,13 @@ import org.apache.avalon.camelot.FactoryException; | |||||
| public interface ConverterFactory | public interface ConverterFactory | ||||
| extends Factory | extends Factory | ||||
| { | { | ||||
| /** | |||||
| * Create entries (ie instances) from infos (ie types). | |||||
| * | |||||
| * @param info the info | |||||
| * @return the entry | |||||
| * @exception FactoryException if an error occurs | |||||
| */ | |||||
| ConverterEntry create( ConverterInfo info ) | ConverterEntry create( ConverterInfo info ) | ||||
| throws FactoryException; | throws FactoryException; | ||||
| } | } | ||||
| @@ -17,6 +17,13 @@ import org.apache.avalon.camelot.Loader; | |||||
| public interface ConverterLoader | public interface ConverterLoader | ||||
| extends Loader | extends Loader | ||||
| { | { | ||||
| /** | |||||
| * Load a particular converter. | |||||
| * | |||||
| * @param converter the converter name | |||||
| * @return the loaded Converter | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| Converter loadConverter( String converter ) | Converter loadConverter( String converter ) | ||||
| throws Exception; | throws Exception; | ||||
| } | } | ||||
| @@ -8,9 +8,20 @@ | |||||
| package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
| import org.apache.avalon.camelot.Registry; | import org.apache.avalon.camelot.Registry; | ||||
| /** | |||||
| * Interface for registry for ConverterInfos. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public interface ConverterRegistry | public interface ConverterRegistry | ||||
| extends Registry | extends Registry | ||||
| { | { | ||||
| /** | |||||
| * Retrieve ConverterInfo that describes converter that converts from source to destination. | |||||
| * | |||||
| * @param source the source classname | |||||
| * @param destination the destination classname | |||||
| * @return the converter-info or null if none available | |||||
| */ | |||||
| ConverterInfo getConverterInfo( String source, String destination ); | ConverterInfo getConverterInfo( String source, String destination ); | ||||
| } | } | ||||
| @@ -27,6 +27,13 @@ public class DefaultConverterFactory | |||||
| { | { | ||||
| protected final HashMap m_loaders = new HashMap(); | protected final HashMap m_loaders = new HashMap(); | ||||
| /** | |||||
| * Method for generic Factory. | |||||
| * | |||||
| * @param info generic info | |||||
| * @return the created entry | |||||
| * @exception FactoryException if an error occurs | |||||
| */ | |||||
| public Entry create( final Info info ) | public Entry create( final Info info ) | ||||
| throws FactoryException | throws FactoryException | ||||
| { | { | ||||
| @@ -37,6 +44,13 @@ public class DefaultConverterFactory | |||||
| return create( (ConverterInfo)info ); | return create( (ConverterInfo)info ); | ||||
| } | } | ||||
| /** | |||||
| * Non-generic factory method. | |||||
| * | |||||
| * @param info the info to create instance from | |||||
| * @return the created entry | |||||
| * @exception FactoryException if an error occurs | |||||
| */ | |||||
| public ConverterEntry create( final ConverterInfo info ) | public ConverterEntry create( final ConverterInfo info ) | ||||
| throws FactoryException | throws FactoryException | ||||
| { | { | ||||
| @@ -54,6 +68,12 @@ public class DefaultConverterFactory | |||||
| return new ConverterEntry( info, (Converter)object ); | return new ConverterEntry( info, (Converter)object ); | ||||
| } | } | ||||
| /** | |||||
| * Get a loader for a particular location | |||||
| * | |||||
| * @param locationthe location | |||||
| * @return the loader | |||||
| */ | |||||
| protected ConverterLoader getLoader( final URL location ) | protected ConverterLoader getLoader( final URL location ) | ||||
| { | { | ||||
| ConverterLoader loader = (ConverterLoader)m_loaders.get( location ); | ConverterLoader loader = (ConverterLoader)m_loaders.get( location ); | ||||
| @@ -67,6 +87,13 @@ public class DefaultConverterFactory | |||||
| return loader; | return loader; | ||||
| } | } | ||||
| /** | |||||
| * Create a new loader. | |||||
| * Put in another method so that it can be overridden. | |||||
| * | |||||
| * @param location the location the Loader will load from | |||||
| * @return the loader | |||||
| */ | |||||
| protected ConverterLoader createLoader( final URL location ) | protected ConverterLoader createLoader( final URL location ) | ||||
| { | { | ||||
| if( null != location ) return new DefaultConverterLoader( location ); | if( null != location ) return new DefaultConverterLoader( location ); | ||||
| @@ -32,6 +32,13 @@ public class DefaultConverterLoader | |||||
| Thread.currentThread().getContextClassLoader() ) ); | Thread.currentThread().getContextClassLoader() ) ); | ||||
| } | } | ||||
| /** | |||||
| * Load a Converter object. | |||||
| * | |||||
| * @param converter the converter classname | |||||
| * @return the converter instance | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| public Converter loadConverter( final String converter ) | public Converter loadConverter( final String converter ) | ||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| @@ -12,12 +12,24 @@ import org.apache.avalon.camelot.AbstractRegistry; | |||||
| import org.apache.avalon.camelot.Info; | import org.apache.avalon.camelot.Info; | ||||
| import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
| /** | |||||
| * Default implementation of ConverterInfo registry. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public class DefaultConverterRegistry | public class DefaultConverterRegistry | ||||
| extends AbstractRegistry | extends AbstractRegistry | ||||
| implements ConverterRegistry | implements ConverterRegistry | ||||
| { | { | ||||
| protected final HashMap m_mapping = new HashMap(); | protected final HashMap m_mapping = new HashMap(); | ||||
| /** | |||||
| * Retrieve ConverterInfo that describes converter that converts from source to destination. | |||||
| * | |||||
| * @param source the source classname | |||||
| * @param destination the destination classname | |||||
| * @return the converter-info or null if none available | |||||
| */ | |||||
| public ConverterInfo getConverterInfo( final String source, final String destination ) | public ConverterInfo getConverterInfo( final String source, final String destination ) | ||||
| { | { | ||||
| final HashMap map = (HashMap)m_mapping.get( source ); | final HashMap map = (HashMap)m_mapping.get( source ); | ||||
| @@ -12,7 +12,8 @@ import java.net.URL; | |||||
| import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||
| /** | /** | ||||
| * AvalonLoader is the class that bootstraps and installs the security manager. | |||||
| * Basic Loader that is responsible for all the hackery to get classloader to work. | |||||
| * Other classes can call AntLoader.getLoader() and add to their own classloader. | |||||
| * | * | ||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
| */ | */ | ||||
| @@ -31,7 +32,13 @@ public final class AntLoader | |||||
| return c_classLoader; | return c_classLoader; | ||||
| } | } | ||||
| public final static void main( final String args[] ) | |||||
| /** | |||||
| * Magic entry point. | |||||
| * | |||||
| * @param argsthe CLI arguments | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| public final static void main( final String[] args ) | |||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| final URL archive = new URL( "file:lib/myrmidon.jar" ); | final URL archive = new URL( "file:lib/myrmidon.jar" ); | ||||
| @@ -52,11 +59,21 @@ public final class AntLoader | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Basic constructor. | |||||
| * | |||||
| * @param urls the Starting URLS | |||||
| */ | |||||
| public AntLoader( final URL[] urls ) | public AntLoader( final URL[] urls ) | ||||
| { | { | ||||
| super( urls ); | super( urls ); | ||||
| } | } | ||||
| /** | |||||
| * Add a URL to classloader | |||||
| * | |||||
| * @param url the url | |||||
| */ | |||||
| public void addURL( final URL url ) | public void addURL( final URL url ) | ||||
| { | { | ||||
| super.addURL( url ); | super.addURL( url ); | ||||
| @@ -21,6 +21,7 @@ import org.apache.ant.tasklet.engine.DefaultTaskletRegistry; | |||||
| import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
| import org.apache.ant.tasklet.engine.TaskletRegistry; | import org.apache.ant.tasklet.engine.TaskletRegistry; | ||||
| import org.apache.ant.tasklet.engine.TskDeployer; | import org.apache.ant.tasklet.engine.TskDeployer; | ||||
| import org.apache.avalon.Composer; | |||||
| import org.apache.avalon.DefaultComponentManager; | import org.apache.avalon.DefaultComponentManager; | ||||
| import org.apache.avalon.Disposable; | import org.apache.avalon.Disposable; | ||||
| import org.apache.avalon.Initializable; | import org.apache.avalon.Initializable; | ||||
| @@ -60,29 +61,15 @@ public class DefaultProjectEngine | |||||
| { | { | ||||
| m_listenerSupport = new ProjectListenerSupport(); | m_listenerSupport = new ProjectListenerSupport(); | ||||
| m_taskletEngine = createTaskletEngine(); | |||||
| m_taskletEngine.setLogger( m_logger ); | |||||
| m_taskletRegistry = createTaskletRegistry(); | m_taskletRegistry = createTaskletRegistry(); | ||||
| m_converterRegistry = createConverterRegistry(); | m_converterRegistry = createConverterRegistry(); | ||||
| m_deployer = createDeployer(); | m_deployer = createDeployer(); | ||||
| setupTaskletEngine(); | |||||
| m_componentManager = new DefaultComponentManager(); | m_componentManager = new DefaultComponentManager(); | ||||
| m_componentManager.put( "org.apache.ant.project.ProjectEngine", this ); | m_componentManager.put( "org.apache.ant.project.ProjectEngine", this ); | ||||
| m_componentManager.put( "org.apache.ant.tasklet.engine.TaskletRegistry", | |||||
| m_taskletRegistry ); | |||||
| m_componentManager.put( "org.apache.ant.convert.ConverterRegistry", | |||||
| m_converterRegistry ); | |||||
| m_componentManager.put( "org.apache.avalon.camelot.Deployer", m_deployer ); | |||||
| m_taskletEngine.compose( m_componentManager ); | |||||
| if( m_taskletEngine instanceof Initializable ) | |||||
| { | |||||
| ((Initializable)m_taskletEngine).init(); | |||||
| } | |||||
| m_componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", m_taskletEngine ); | |||||
| } | } | ||||
| public void dispose() | public void dispose() | ||||
| @@ -99,6 +86,29 @@ public class DefaultProjectEngine | |||||
| return m_deployer; | return m_deployer; | ||||
| } | } | ||||
| protected void setupTaskletEngine() | |||||
| throws Exception | |||||
| { | |||||
| m_taskletEngine = createTaskletEngine(); | |||||
| m_taskletEngine.setLogger( m_logger ); | |||||
| if( m_taskletEngine instanceof Composer ) | |||||
| { | |||||
| final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||||
| componentManager.put( "org.apache.ant.tasklet.engine.TaskletRegistry", | |||||
| m_taskletRegistry ); | |||||
| componentManager.put( "org.apache.ant.convert.ConverterRegistry", | |||||
| m_converterRegistry ); | |||||
| ((Composer)m_taskletEngine).compose( componentManager ); | |||||
| } | |||||
| if( m_taskletEngine instanceof Initializable ) | |||||
| { | |||||
| ((Initializable)m_taskletEngine).init(); | |||||
| } | |||||
| } | |||||
| protected TaskletEngine createTaskletEngine() | protected TaskletEngine createTaskletEngine() | ||||
| { | { | ||||
| return new DefaultTaskletEngine(); | return new DefaultTaskletEngine(); | ||||
| @@ -219,19 +229,16 @@ public class DefaultProjectEngine | |||||
| m_logger.debug( "Executing task " + name ); | m_logger.debug( "Executing task " + name ); | ||||
| //Set up context for task... | //Set up context for task... | ||||
| final TaskletContext taskletContext = context; | |||||
| //is Only necessary if we are multi-threaded | //is Only necessary if we are multi-threaded | ||||
| //final TaskletContext targetContext = new DefaultTaskletContext( context ); | //final TaskletContext targetContext = new DefaultTaskletContext( context ); | ||||
| taskletContext.setProperty( TaskletContext.NAME, name ); | |||||
| m_taskletEngine.contextualize( taskletContext ); | |||||
| context.setProperty( TaskletContext.NAME, name ); | |||||
| //notify listeners | //notify listeners | ||||
| m_listenerSupport.taskletStarted( name ); | m_listenerSupport.taskletStarted( name ); | ||||
| //run task | //run task | ||||
| m_taskletEngine.execute( configuration ); | |||||
| m_taskletEngine.execute( configuration, context, m_componentManager ); | |||||
| //notify listeners task has ended | //notify listeners task has ended | ||||
| m_listenerSupport.taskletFinished(); | m_listenerSupport.taskletFinished(); | ||||
| @@ -20,6 +20,7 @@ import org.apache.log.Logger; | |||||
| public abstract class AbstractTasklet | public abstract class AbstractTasklet | ||||
| implements Tasklet, Initializable | implements Tasklet, Initializable | ||||
| { | { | ||||
| //the user should set this in constructors of sub-classes | |||||
| protected JavaVersion m_requiredJavaVersion; | protected JavaVersion m_requiredJavaVersion; | ||||
| private TaskletContext m_context; | private TaskletContext m_context; | ||||
| @@ -16,7 +16,8 @@ import org.apache.avalon.util.io.FileUtil; | |||||
| import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
| /** | /** | ||||
| * This represents the *Context* in which a task can be executed. | |||||
| * Default implementation of TaskletContext. | |||||
| * It represents the *Context* in which a task can be executed. | |||||
| * | * | ||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
| */ | */ | ||||
| @@ -11,6 +11,8 @@ import org.apache.avalon.util.ValuedEnum; | |||||
| /** | /** | ||||
| * Type safe wrapper class for Java Version enums. | * Type safe wrapper class for Java Version enums. | ||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | */ | ||||
| public final class JavaVersion | public final class JavaVersion | ||||
| extends ValuedEnum | extends ValuedEnum | ||||
| @@ -21,6 +23,12 @@ public final class JavaVersion | |||||
| public final static JavaVersion JAVA1_2 = new JavaVersion( "Java 1.2", 120 ); | public final static JavaVersion JAVA1_2 = new JavaVersion( "Java 1.2", 120 ); | ||||
| public final static JavaVersion JAVA1_3 = new JavaVersion( "Java 1.3", 130 ); | public final static JavaVersion JAVA1_3 = new JavaVersion( "Java 1.3", 130 ); | ||||
| /** | |||||
| * Private constructor so no instance except here can be defined. | |||||
| * | |||||
| * @param name the java version name | |||||
| * @param value the version * 100 | |||||
| */ | |||||
| private JavaVersion( final String name, final int value ) | private JavaVersion( final String name, final int value ) | ||||
| { | { | ||||
| super( name, value ); | super( name, value ); | ||||
| @@ -12,6 +12,13 @@ import org.apache.avalon.Contextualizable; | |||||
| /** | /** | ||||
| * This represents the individual tasks. | * This represents the individual tasks. | ||||
| * Particular instances can also implement Initializable | |||||
| * and/or Disposable, in which case init()/dispose() will | |||||
| * be called at appropriate time. | |||||
| * The task can also implement Composer in which case required | |||||
| * facilities will be passed via a ComponentManager. The actual | |||||
| * facilties is determined by particular task engine but will usually | |||||
| * include ProjectEngine and TaskEngine. | |||||
| * | * | ||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
| */ | */ | ||||
| @@ -58,7 +58,20 @@ public class DefaultTaskletConfigurer | |||||
| m_converterFactory = (ConverterFactory)componentManager. | m_converterFactory = (ConverterFactory)componentManager. | ||||
| lookup( "org.apache.ant.convert.ConverterFactory" ); | lookup( "org.apache.ant.convert.ConverterFactory" ); | ||||
| } | } | ||||
| /** | |||||
| * Configure a task based on a configuration in a particular context. | |||||
| * This configuring can be done in different ways for different | |||||
| * configurers. | |||||
| * This one does it by first checking if object implements Configurable | |||||
| * and if it does will pass the task the configuration - else it will use | |||||
| * ants rules to map configuration to types | |||||
| * | |||||
| * @param tasklet the tasklet | |||||
| * @param configuration the configuration | |||||
| * @param context the Context | |||||
| * @exception ConfigurationException if an error occurs | |||||
| */ | |||||
| public void configure( final Tasklet tasklet, | public void configure( final Tasklet tasklet, | ||||
| final Configuration configuration, | final Configuration configuration, | ||||
| final Context context ) | final Context context ) | ||||
| @@ -67,6 +80,19 @@ public class DefaultTaskletConfigurer | |||||
| configure( (Object)tasklet, configuration, context ); | configure( (Object)tasklet, configuration, context ); | ||||
| } | } | ||||
| /** | |||||
| * Configure a task based on a configuration in a particular context. | |||||
| * This configuring can be done in different ways for different | |||||
| * configurers. | |||||
| * This one does it by first checking if object implements Configurable | |||||
| * and if it does will pass the task the configuration - else it will use | |||||
| * ants rules to map configuration to types | |||||
| * | |||||
| * @param tasklet the tasklet | |||||
| * @param configuration the configuration | |||||
| * @param context the Context | |||||
| * @exception ConfigurationException if an error occurs | |||||
| */ | |||||
| public void configure( final Object object, | public void configure( final Object object, | ||||
| final Configuration configuration, | final Configuration configuration, | ||||
| final Context context ) | final Context context ) | ||||
| @@ -107,6 +133,14 @@ public class DefaultTaskletConfigurer | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Try to configure content of an object. | |||||
| * | |||||
| * @param object the object | |||||
| * @param content the content value to be set | |||||
| * @param context the Context | |||||
| * @exception ConfigurationException if an error occurs | |||||
| */ | |||||
| protected void configureContent( final Object object, | protected void configureContent( final Object object, | ||||
| final String content, | final String content, | ||||
| final Context context ) | final Context context ) | ||||
| @@ -318,7 +352,7 @@ public class DefaultTaskletConfigurer | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return (Method[])matches.toArray( new Method[0] ); | return (Method[])matches.toArray( new Method[0] ); | ||||
| } | } | ||||
| @@ -29,10 +29,8 @@ import org.apache.avalon.camelot.RegistryException; | |||||
| import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
| public class DefaultTaskletEngine | public class DefaultTaskletEngine | ||||
| implements TaskletEngine, Initializable | |||||
| implements TaskletEngine, Initializable, Composer | |||||
| { | { | ||||
| protected ComponentManager m_componentManager; | |||||
| protected TaskletContext m_context; | |||||
| protected TaskletFactory m_taskletFactory; | protected TaskletFactory m_taskletFactory; | ||||
| protected ConverterFactory m_converterFactory; | protected ConverterFactory m_converterFactory; | ||||
| protected TaskletRegistry m_taskletRegistry; | protected TaskletRegistry m_taskletRegistry; | ||||
| @@ -45,21 +43,25 @@ public class DefaultTaskletEngine | |||||
| m_logger = logger; | m_logger = logger; | ||||
| } | } | ||||
| public void contextualize( final Context context ) | |||||
| { | |||||
| m_context = (TaskletContext)context; | |||||
| } | |||||
| public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
| throws ComponentNotFoundException, ComponentNotAccessibleException | throws ComponentNotFoundException, ComponentNotAccessibleException | ||||
| { | { | ||||
| m_componentManager = componentManager; | |||||
| m_taskletRegistry = (TaskletRegistry)componentManager. | m_taskletRegistry = (TaskletRegistry)componentManager. | ||||
| lookup( "org.apache.ant.tasklet.engine.TaskletRegistry" ); | lookup( "org.apache.ant.tasklet.engine.TaskletRegistry" ); | ||||
| m_converterRegistry = (ConverterRegistry)componentManager. | m_converterRegistry = (ConverterRegistry)componentManager. | ||||
| lookup( "org.apache.ant.convert.ConverterRegistry" ); | lookup( "org.apache.ant.convert.ConverterRegistry" ); | ||||
| } | } | ||||
| public TaskletRegistry getTaskletRegistry() | |||||
| { | |||||
| return m_taskletRegistry; | |||||
| } | |||||
| public ConverterRegistry getConverterRegistry() | |||||
| { | |||||
| return m_converterRegistry; | |||||
| } | |||||
| public void init() | public void init() | ||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| @@ -69,10 +71,11 @@ public class DefaultTaskletEngine | |||||
| if( m_configurer instanceof Composer ) | if( m_configurer instanceof Composer ) | ||||
| { | { | ||||
| final DefaultComponentManager componentManager = | |||||
| new DefaultComponentManager( m_componentManager ); | |||||
| final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||||
| componentManager.put( "org.apache.ant.convert.ConverterFactory", | componentManager.put( "org.apache.ant.convert.ConverterFactory", | ||||
| m_converterFactory ); | m_converterFactory ); | ||||
| componentManager.put( "org.apache.ant.convert.ConverterRegistry", | |||||
| m_converterRegistry ); | |||||
| ((Composer)m_configurer).compose( componentManager ); | ((Composer)m_configurer).compose( componentManager ); | ||||
| } | } | ||||
| @@ -98,37 +101,40 @@ public class DefaultTaskletEngine | |||||
| return (ConverterFactory)m_taskletFactory; | return (ConverterFactory)m_taskletFactory; | ||||
| } | } | ||||
| public void execute( final Configuration task ) | |||||
| public void execute( final Configuration task, | |||||
| final TaskletContext context, | |||||
| final ComponentManager componentManager ) | |||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| final Tasklet tasklet = createTasklet( task ); | |||||
| final String name = task.getName(); | |||||
| m_logger.debug( "Created task " + name ); | |||||
| m_logger.debug( "Creating" ); | |||||
| final Tasklet tasklet = createTasklet( task ); | |||||
| doContextualize( tasklet, task ); | |||||
| m_logger.debug( "Contextualized task " + name ); | |||||
| m_logger.debug( "Contextualizing" ); | |||||
| doContextualize( tasklet, task, context ); | |||||
| doCompose( tasklet, task ); | |||||
| m_logger.debug( "Composed task " + name ); | |||||
| m_logger.debug( "Composing" ); | |||||
| doCompose( tasklet, task, componentManager ); | |||||
| doConfigure( tasklet, task ); | |||||
| m_logger.debug( "Configured task " + name ); | |||||
| m_logger.debug( "Configuring" ); | |||||
| doConfigure( tasklet, task, context ); | |||||
| m_logger.debug( "Initializing" ); | |||||
| doInitialize( tasklet, task ); | doInitialize( tasklet, task ); | ||||
| m_logger.debug( "Initialize task " + name ); | |||||
| m_logger.debug( "Running" ); | |||||
| tasklet.run(); | tasklet.run(); | ||||
| m_logger.debug( "Ran task " + name ); | |||||
| m_logger.debug( "Disposing" ); | |||||
| doDispose( tasklet, task ); | doDispose( tasklet, task ); | ||||
| m_logger.debug( "Dispose task " + name ); | |||||
| } | } | ||||
| protected void doConfigure( final Tasklet tasklet, final Configuration task ) | |||||
| protected void doConfigure( final Tasklet tasklet, | |||||
| final Configuration task, | |||||
| final TaskletContext context ) | |||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| try { m_configurer.configure( tasklet, task, m_context ); } | |||||
| try { m_configurer.configure( tasklet, task, context ); } | |||||
| catch( final Throwable throwable ) | catch( final Throwable throwable ) | ||||
| { | { | ||||
| throw new AntException( "Error configuring task " + task.getName() + " at " + | throw new AntException( "Error configuring task " + task.getName() + " at " + | ||||
| @@ -136,24 +142,15 @@ public class DefaultTaskletEngine | |||||
| throwable.getMessage() + ")", throwable ); | 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 ) | |||||
| protected void doCompose( final Tasklet tasklet, | |||||
| final Configuration task, | |||||
| final ComponentManager componentManager ) | |||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| if( tasklet instanceof Composer ) | if( tasklet instanceof Composer ) | ||||
| { | { | ||||
| try { ((Composer)tasklet).compose( m_componentManager ); } | |||||
| try { ((Composer)tasklet).compose( componentManager ); } | |||||
| catch( final Throwable throwable ) | catch( final Throwable throwable ) | ||||
| { | { | ||||
| throw new AntException( "Error composing task " + task.getName() + " at " + | throw new AntException( "Error composing task " + task.getName() + " at " + | ||||
| @@ -163,10 +160,13 @@ public class DefaultTaskletEngine | |||||
| } | } | ||||
| } | } | ||||
| protected void doContextualize( final Tasklet tasklet, final Configuration task ) | |||||
| protected void doContextualize( final Tasklet tasklet, | |||||
| final Configuration task, | |||||
| final TaskletContext context ) | |||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| final TaskletContext context = getContextFor( task.getName() ); | |||||
| // Already done in container ... | |||||
| //context.setProperty( TaskletContext.NAME, name ); | |||||
| try { tasklet.contextualize( context ); } | try { tasklet.contextualize( context ); } | ||||
| catch( final Throwable throwable ) | catch( final Throwable throwable ) | ||||
| @@ -8,8 +8,8 @@ | |||||
| package org.apache.ant.tasklet.engine; | package org.apache.ant.tasklet.engine; | ||||
| import java.net.URL; | import java.net.URL; | ||||
| import org.apache.ant.tasklet.Tasklet; | |||||
| import org.apache.ant.convert.DefaultConverterLoader; | import org.apache.ant.convert.DefaultConverterLoader; | ||||
| import org.apache.ant.tasklet.Tasklet; | |||||
| /** | /** | ||||
| * Class used to load tasks et al from a source. | * Class used to load tasks et al from a source. | ||||
| @@ -29,6 +29,13 @@ public class DefaultTaskletLoader | |||||
| super( location ); | super( location ); | ||||
| } | } | ||||
| /** | |||||
| * Load a tasklet with a particular classname. | |||||
| * | |||||
| * @param tasklet the tasklet classname | |||||
| * @return the tasklet | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| public Tasklet loadTasklet( final String tasklet ) | public Tasklet loadTasklet( final String tasklet ) | ||||
| throws Exception | throws Exception | ||||
| { | { | ||||
| @@ -19,6 +19,16 @@ import org.apache.avalon.Context; | |||||
| */ | */ | ||||
| public interface TaskletConfigurer | public interface TaskletConfigurer | ||||
| { | { | ||||
| /** | |||||
| * Configure a task based on a configuration in a particular context. | |||||
| * This configuring can be done in different ways for different | |||||
| * configurers. | |||||
| * | |||||
| * @param tasklet the tasklet | |||||
| * @param configuration the configuration | |||||
| * @param context the Context | |||||
| * @exception ConfigurationException if an error occurs | |||||
| */ | |||||
| void configure( Tasklet tasklet, Configuration configuration, Context context ) | void configure( Tasklet tasklet, Configuration configuration, Context context ) | ||||
| throws ConfigurationException; | throws ConfigurationException; | ||||
| } | } | ||||
| @@ -9,14 +9,46 @@ package org.apache.ant.tasklet.engine; | |||||
| import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
| import org.apache.ant.configuration.Configuration; | import org.apache.ant.configuration.Configuration; | ||||
| import org.apache.ant.convert.ConverterRegistry; | |||||
| import org.apache.ant.tasklet.TaskletContext; | |||||
| import org.apache.avalon.Component; | |||||
| import org.apache.avalon.ComponentManager; | |||||
| import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
| import org.apache.avalon.Contextualizable; | import org.apache.avalon.Contextualizable; | ||||
| import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
| /** | |||||
| * Engine inteface that should be implemented by all tasklet engines. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public interface TaskletEngine | public interface TaskletEngine | ||||
| extends Contextualizable, Composer | |||||
| extends Component | |||||
| { | { | ||||
| void setLogger( Logger logger ); | void setLogger( Logger logger ); | ||||
| void execute( final Configuration task ) | |||||
| /** | |||||
| * Retrieve tasklet registry associated with engine. | |||||
| * | |||||
| * @return the TaskletRegistry | |||||
| */ | |||||
| TaskletRegistry getTaskletRegistry(); | |||||
| /** | |||||
| * Retrieve converter registry associated with engine. | |||||
| * | |||||
| * @return the ConverterRegistry | |||||
| */ | |||||
| ConverterRegistry getConverterRegistry(); | |||||
| /** | |||||
| * execute a task. | |||||
| * | |||||
| * @param task the configruation data for task | |||||
| * @exception AntException if an error occurs | |||||
| */ | |||||
| void execute( Configuration task, | |||||
| TaskletContext context, | |||||
| ComponentManager componentManager ) | |||||
| throws AntException; | throws AntException; | ||||
| } | } | ||||
| @@ -18,6 +18,13 @@ import org.apache.avalon.camelot.Loader; | |||||
| public interface TaskletLoader | public interface TaskletLoader | ||||
| extends Loader | extends Loader | ||||
| { | { | ||||
| /** | |||||
| * Load a tasklet with a particular classname. | |||||
| * | |||||
| * @param tasklet the tasklet classname | |||||
| * @return the tasklet | |||||
| * @exception Exception if an error occurs | |||||
| */ | |||||
| Tasklet loadTasklet( String tasklet ) | Tasklet loadTasklet( String tasklet ) | ||||
| throws Exception; | throws Exception; | ||||
| } | } | ||||
| @@ -9,6 +9,11 @@ package org.apache.ant.tasklet.engine; | |||||
| import org.apache.avalon.camelot.Registry; | import org.apache.avalon.camelot.Registry; | ||||
| /** | |||||
| * The registry for tasklets | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public interface TaskletRegistry | public interface TaskletRegistry | ||||
| extends Registry | extends Registry | ||||
| { | { | ||||
| @@ -13,6 +13,7 @@ import java.net.URL; | |||||
| import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
| import org.apache.ant.tasklet.AbstractTasklet; | import org.apache.ant.tasklet.AbstractTasklet; | ||||
| import org.apache.ant.tasklet.engine.DefaultTaskletInfo; | import org.apache.ant.tasklet.engine.DefaultTaskletInfo; | ||||
| import org.apache.ant.tasklet.engine.TaskletEngine; | |||||
| import org.apache.ant.tasklet.engine.TaskletRegistry; | import org.apache.ant.tasklet.engine.TaskletRegistry; | ||||
| import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
| import org.apache.avalon.ComponentNotAccessibleException; | import org.apache.avalon.ComponentNotAccessibleException; | ||||
| @@ -37,8 +38,9 @@ public class RegisterTasklet | |||||
| public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
| throws ComponentNotFoundException, ComponentNotAccessibleException | throws ComponentNotFoundException, ComponentNotAccessibleException | ||||
| { | { | ||||
| m_taskletRegistry = (TaskletRegistry)componentManager. | |||||
| lookup( "org.apache.ant.tasklet.engine.TaskletRegistry" ); | |||||
| final TaskletEngine engine = (TaskletEngine)componentManager. | |||||
| lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | |||||
| m_taskletRegistry = engine.getTaskletRegistry(); | |||||
| } | } | ||||
| public void setTaskLib( final String tasklib ) | public void setTaskLib( final String tasklib ) | ||||
| @@ -59,14 +61,21 @@ public class RegisterTasklet | |||||
| public void run() | public void run() | ||||
| throws AntException | throws AntException | ||||
| { | { | ||||
| /* | |||||
| if( null == m_tasklib ) | if( null == m_tasklib ) | ||||
| { | { | ||||
| throw new AntException( "Must specify tasklib parameter" ); | throw new AntException( "Must specify tasklib parameter" ); | ||||
| } | } | ||||
| */ | |||||
| if( null == m_taskName ) | if( null == m_taskName ) | ||||
| { | { | ||||
| throw new AntException( "Must specify taskname parameter" ); | |||||
| throw new AntException( "Must specify taskname parameter" ); | |||||
| } | |||||
| if( null == m_tasklib && null == m_classname ) | |||||
| { | |||||
| throw new AntException( "Must specify classname if don't specify " + | |||||
| "tasklib parameter" ); | |||||
| } | } | ||||
| if( null == m_classname ) | if( null == m_classname ) | ||||
| @@ -76,8 +85,13 @@ public class RegisterTasklet | |||||
| try | try | ||||
| { | { | ||||
| final File tasklib = new File( getContext().resolveFilename( m_tasklib ) ); | |||||
| final URL url = tasklib.toURL(); | |||||
| URL url = null; | |||||
| if( null != m_tasklib ) | |||||
| { | |||||
| final File tasklib = new File( getContext().resolveFilename( m_tasklib ) ); | |||||
| url = tasklib.toURL(); | |||||
| } | |||||
| final DefaultTaskletInfo info = new DefaultTaskletInfo( m_classname, url ); | final DefaultTaskletInfo info = new DefaultTaskletInfo( m_classname, url ); | ||||