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 ); | ||||