Major changes include * making convertion API context-sensitive * the simplification of all the interfaces. The simplification is achived by applying IOC. Now AntEngine is responsible for creating and instantiating shared components via a ComponentManager. * Moved most of startup code to AntEngine so that alternate front ends can be added in simply. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268409 13f79535-47bb-0310-9956-ffa450edef68master
@@ -4,11 +4,14 @@ echo. | |||||
echo Ant Build System | echo Ant Build System | ||||
echo ---------------- | echo ---------------- | ||||
set ANT_HOME=. | |||||
set ANT_HOME=tools | |||||
set CLASSPATH= | |||||
set LOCALCLASSPATH= | |||||
for %%i in (lib\*.jar) do call tools\bin\lcp.bat %%i | |||||
set CLASSPATH=%LOCALCLASSPATH% | |||||
set LOCALCLASSPATH= | |||||
%ANT_HOME%\bin\ant.bat -emacs %1 %2 %3 %4 %5 %6 %7 %8 | |||||
%ANT_HOME%\bin\ant.bat -logger org.apache.tools.ant.NoBannerLogger -emacs %1 %2 %3 %4 %5 %6 %7 %8 | |||||
goto cleanup | goto cleanup | ||||
:cleanup | :cleanup | ||||
@@ -154,7 +154,9 @@ Legal: | |||||
destdir="${build.classes}" | destdir="${build.classes}" | ||||
debug="${debug}" | debug="${debug}" | ||||
optimize="${optimize}" | optimize="${optimize}" | ||||
deprecation="${deprecation}" /> | |||||
deprecation="${deprecation}"> | |||||
<exclude name="org/apache/ant/gui/**"/> | |||||
</javac> | |||||
<!-- | <!-- | ||||
<copy todir="${build.classes}"> | <copy todir="${build.classes}"> | ||||
@@ -0,0 +1,48 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant; | |||||
import java.util.Properties; | |||||
import org.apache.ant.project.ProjectBuilder; | |||||
import org.apache.ant.project.ProjectEngine; | |||||
import org.apache.avalon.Component; | |||||
import org.apache.avalon.Disposable; | |||||
import org.apache.avalon.Initializable; | |||||
/** | |||||
* Interface to the Ant runtime. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface AntEngine | |||||
extends Component, Initializable, Disposable | |||||
{ | |||||
/** | |||||
* Setup basic properties of engine. | |||||
* Called before init() and can be used to specify alternate components in system. | |||||
* | |||||
* @param properties the properties | |||||
*/ | |||||
void setProperties( Properties properties ); | |||||
/** | |||||
* Retrieve builder for runtime. | |||||
* Valid after init() call | |||||
* | |||||
* @return the ProjectBuilder | |||||
*/ | |||||
ProjectBuilder getProjectBuilder(); | |||||
/** | |||||
* Retrieve project engine for runtime. | |||||
* Valid after init() call | |||||
* | |||||
* @return the ProjectBuilder | |||||
*/ | |||||
ProjectEngine getProjectEngine(); | |||||
} |
@@ -0,0 +1,410 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant; | |||||
import java.io.File; | |||||
import java.util.Properties; | |||||
import org.apache.ant.configuration.Configurer; | |||||
import org.apache.ant.convert.ConverterEngine; | |||||
import org.apache.ant.datatypes.DataTypeEngine; | |||||
import org.apache.ant.project.ProjectBuilder; | |||||
import org.apache.ant.project.ProjectEngine; | |||||
import org.apache.ant.tasklet.JavaVersion; | |||||
import org.apache.ant.tasklet.engine.TaskletEngine; | |||||
import org.apache.ant.tasklet.engine.TskDeployer; | |||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.Component; | |||||
import org.apache.avalon.Composer; | |||||
import org.apache.avalon.DefaultComponentManager; | |||||
import org.apache.avalon.Initializable; | |||||
import org.apache.avalon.camelot.CamelotUtil; | |||||
import org.apache.avalon.camelot.DefaultFactory; | |||||
import org.apache.avalon.camelot.Deployer; | |||||
import org.apache.avalon.camelot.Factory; | |||||
import org.apache.avalon.util.ObjectUtil; | |||||
import org.apache.avalon.util.io.FileUtil; | |||||
/** | |||||
* Default implementation of Ant runtime. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultAntEngine | |||||
extends AbstractLoggable | |||||
implements AntEngine, Initializable | |||||
{ | |||||
protected ConverterEngine m_converterEngine; | |||||
protected DataTypeEngine m_dataTypeEngine; | |||||
protected TaskletEngine m_taskletEngine; | |||||
protected ProjectEngine m_projectEngine; | |||||
protected ProjectBuilder m_builder; | |||||
protected TskDeployer m_deployer; | |||||
protected Configurer m_configurer; | |||||
protected Factory m_factory; | |||||
protected DefaultComponentManager m_componentManager; | |||||
protected Properties m_properties; | |||||
protected Properties m_defaults; | |||||
protected File m_homeDir; | |||||
protected File m_binDir; | |||||
protected File m_libDir; | |||||
protected File m_taskLibDir; | |||||
/** | |||||
* Setup basic properties of engine. | |||||
* Called before init() and can be used to specify alternate components in system. | |||||
* | |||||
* @param properties the properties | |||||
*/ | |||||
public void setProperties( final Properties properties ) | |||||
{ | |||||
m_properties = properties; | |||||
} | |||||
/** | |||||
* Retrieve builder for runtime. | |||||
* Valid after init() call | |||||
* | |||||
* @return the ProjectBuilder | |||||
*/ | |||||
public ProjectBuilder getProjectBuilder() | |||||
{ | |||||
return m_builder; | |||||
} | |||||
/** | |||||
* Retrieve project engine for runtime. | |||||
* Valid after init() call | |||||
* | |||||
* @return the ProjectBuilder | |||||
*/ | |||||
public ProjectEngine getProjectEngine() | |||||
{ | |||||
return m_projectEngine; | |||||
} | |||||
/** | |||||
* Initialize the system. | |||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
public void init() | |||||
throws Exception | |||||
{ | |||||
//setup default properties | |||||
m_defaults = createDefaultProperties(); | |||||
//create all the components | |||||
m_factory = new DefaultFactory(); | |||||
createComponents(); | |||||
//setup the component manager | |||||
m_componentManager = createComponentManager(); | |||||
setupComponents(); | |||||
setupFiles(); | |||||
CamelotUtil.deployFromDirectory( m_deployer, m_taskLibDir, ".tsk" ); | |||||
} | |||||
/** | |||||
* Dispose engine. | |||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
public void dispose() | |||||
throws Exception | |||||
{ | |||||
m_converterEngine = null; | |||||
m_dataTypeEngine = null; | |||||
m_taskletEngine = null; | |||||
m_projectEngine = null; | |||||
m_builder = null; | |||||
m_deployer = null; | |||||
m_configurer = null; | |||||
m_factory = null; | |||||
m_componentManager = null; | |||||
m_properties = null; | |||||
m_defaults = null; | |||||
m_homeDir = null; | |||||
m_binDir = null; | |||||
m_libDir = null; | |||||
m_taskLibDir = null; | |||||
} | |||||
/** | |||||
* Create default properties which includes default names of all components. | |||||
* Overide this in sub-classes to change values. | |||||
* | |||||
* @return the Properties | |||||
*/ | |||||
protected Properties createDefaultProperties() | |||||
{ | |||||
final Properties defaults = new Properties(); | |||||
//create all the default properties for files/directories | |||||
defaults.setProperty( "ant.path.bin", "bin" ); | |||||
defaults.setProperty( "ant.path.lib", "lib" ); | |||||
defaults.setProperty( "ant.path.task-lib", "lib" ); | |||||
//create all the default properties for components | |||||
defaults.setProperty( "ant.comp.converter", | |||||
"org.apache.ant.convert.DefaultConverterEngine" ); | |||||
defaults.setProperty( "ant.comp.datatype", | |||||
"org.apache.ant.datatypes.DefaultDataTypeEngine" ); | |||||
defaults.setProperty( "ant.comp.tasklet", | |||||
"org.apache.ant.tasklet.engine.DefaultTaskletEngine" ); | |||||
defaults.setProperty( "ant.comp.project", | |||||
"org.apache.ant.project.DefaultProjectEngine" ); | |||||
defaults.setProperty( "ant.comp.builder", | |||||
"org.apache.ant.project.DefaultProjectBuilder" ); | |||||
defaults.setProperty( "ant.comp.deployer", | |||||
"org.apache.ant.tasklet.engine.DefaultTskDeployer" ); | |||||
defaults.setProperty( "ant.comp.configurer", | |||||
"org.apache.ant.configuration.DefaultConfigurer" ); | |||||
return defaults; | |||||
} | |||||
/** | |||||
* Create a ComponentManager containing all components in engine. | |||||
* | |||||
* @return the ComponentManager | |||||
*/ | |||||
protected DefaultComponentManager createComponentManager() | |||||
{ | |||||
final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||||
componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", m_taskletEngine ); | |||||
componentManager.put( "org.apache.ant.project.ProjectEngine", m_projectEngine ); | |||||
componentManager.put( "org.apache.ant.convert.ConverterEngine", m_converterEngine ); | |||||
componentManager.put( "org.apache.ant.convert.Converter", m_converterEngine ); | |||||
componentManager.put( "org.apache.ant.datatypes.DataTypeEngine", m_dataTypeEngine ); | |||||
componentManager.put( "org.apache.ant.project.ProjectBuilder", m_builder ); | |||||
componentManager.put( "org.apache.ant.tasklet.engine.TskDeployer", m_deployer ); | |||||
componentManager.put( "org.apache.avalon.camelot.Factory", m_factory ); | |||||
componentManager.put( "org.apache.ant.configuration.Configurer", m_configurer ); | |||||
return componentManager; | |||||
} | |||||
/** | |||||
* Create all required components. | |||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
protected void createComponents() | |||||
throws Exception | |||||
{ | |||||
String component = null; | |||||
component = getProperty( "ant.comp.converter" ); | |||||
m_converterEngine = (ConverterEngine)createComponent( component, ConverterEngine.class ); | |||||
component = getProperty( "ant.comp.datatype" ); | |||||
m_dataTypeEngine = (DataTypeEngine)createComponent( component, DataTypeEngine.class ); | |||||
component = getProperty( "ant.comp.tasklet" ); | |||||
m_taskletEngine = (TaskletEngine)createComponent( component, TaskletEngine.class ); | |||||
component = getProperty( "ant.comp.project" ); | |||||
m_projectEngine = (ProjectEngine)createComponent( component, ProjectEngine.class ); | |||||
component = getProperty( "ant.comp.builder" ); | |||||
m_builder =(ProjectBuilder)createComponent( component, ProjectBuilder.class ); | |||||
component = getProperty( "ant.comp.deployer" ); | |||||
m_deployer = (TskDeployer)createComponent( component, TskDeployer.class ); | |||||
component = getProperty( "ant.comp.configurer" ); | |||||
m_configurer = (Configurer)createComponent( component, Configurer.class ); | |||||
} | |||||
/** | |||||
* Setup all the components. (ir run all required lifecycle methods). | |||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
protected void setupComponents() | |||||
throws Exception | |||||
{ | |||||
setupComponent( m_factory ); | |||||
setupComponent( m_converterEngine ); | |||||
setupComponent( m_dataTypeEngine ); | |||||
setupComponent( m_taskletEngine ); | |||||
setupComponent( m_projectEngine ); | |||||
setupComponent( m_builder ); | |||||
setupComponent( m_deployer ); | |||||
setupComponent( m_configurer ); | |||||
} | |||||
/** | |||||
* Setup an individual component. | |||||
* | |||||
* @param component the component | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
protected void setupComponent( final Component component ) | |||||
throws Exception | |||||
{ | |||||
setupLogger( component ); | |||||
if( component instanceof Composer ) | |||||
{ | |||||
((Composer)component).compose( m_componentManager ); | |||||
} | |||||
if( component instanceof Initializable ) | |||||
{ | |||||
((Initializable)component).init(); | |||||
} | |||||
} | |||||
/** | |||||
* Setup all the files attributes. | |||||
*/ | |||||
protected void setupFiles() | |||||
{ | |||||
String filepath = null; | |||||
filepath = getProperty( "ant.home" ); | |||||
m_homeDir = (new File( filepath )).getAbsoluteFile(); | |||||
checkDirectory( m_homeDir, "ant-home" ); | |||||
filepath = getProperty( "ant.path.bin" ); | |||||
m_binDir = resolveDirectory( filepath, "bin-dir" ); | |||||
filepath = getProperty( "ant.path.lib" ); | |||||
m_libDir = resolveDirectory( filepath, "lib-dir" ); | |||||
filepath = getProperty( "ant.path.task-lib" ); | |||||
m_taskLibDir = resolveDirectory( filepath, "task-lib-dir" ); | |||||
} | |||||
/** | |||||
* Retrieve value of named property. | |||||
* First access passed in properties and then the default properties. | |||||
* | |||||
* @param name the name of property | |||||
* @return the value of property or null | |||||
*/ | |||||
protected String getProperty( final String name ) | |||||
{ | |||||
String value = m_properties.getProperty( name ); | |||||
if( null == value ) | |||||
{ | |||||
value = m_defaults.getProperty( name ); | |||||
} | |||||
return value; | |||||
} | |||||
/** | |||||
* Resolve a directory relative to another base directory. | |||||
* | |||||
* @param dir the base directory | |||||
* @param name the relative directory | |||||
* @return the created File | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected File resolveDirectory( final String dir, final String name ) | |||||
throws AntException | |||||
{ | |||||
final File file = FileUtil.resolveFile( m_homeDir, dir ); | |||||
checkDirectory( file, name ); | |||||
return file; | |||||
} | |||||
/** | |||||
* Verify file is a directory else throw an exception. | |||||
* | |||||
* @param file the File | |||||
* @param name the name of file type (used in error messages) | |||||
*/ | |||||
protected void checkDirectory( final File file, final String name ) | |||||
throws AntException | |||||
{ | |||||
if( !file.exists() ) | |||||
{ | |||||
throw new AntException( name + " (" + file + ") does not exist" ); | |||||
} | |||||
else if( !file.isDirectory() ) | |||||
{ | |||||
throw new AntException( name + " (" + file + ") is not a directory" ); | |||||
} | |||||
} | |||||
/** | |||||
* Helper method to retrieve current JVM version. | |||||
* Basically stolen from original Ant sources. | |||||
* | |||||
* @return the current JVM version | |||||
*/ | |||||
protected JavaVersion getJavaVersion() | |||||
{ | |||||
JavaVersion version = JavaVersion.JAVA1_0; | |||||
try | |||||
{ | |||||
Class.forName( "java.lang.Void" ); | |||||
version = JavaVersion.JAVA1_1; | |||||
Class.forName( "java.lang.ThreadLocal" ); | |||||
version = JavaVersion.JAVA1_2; | |||||
Class.forName( "java.lang.StrictMath" ); | |||||
version = JavaVersion.JAVA1_3; | |||||
} | |||||
catch( final ClassNotFoundException cnfe ) {} | |||||
return version; | |||||
} | |||||
/** | |||||
* Create a component that implements an interface. | |||||
* | |||||
* @param component the name of the component | |||||
* @param clazz the name of interface/type | |||||
* @return the created object | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected Object createComponent( final String component, final Class clazz ) | |||||
throws AntException | |||||
{ | |||||
try | |||||
{ | |||||
final Object object = ObjectUtil.createObject( component ); | |||||
if( !clazz.isInstance( object ) ) | |||||
{ | |||||
throw new AntException( "Object " + component + " is not an instance of " + | |||||
clazz ); | |||||
} | |||||
return object; | |||||
} | |||||
catch( final IllegalAccessException iae ) | |||||
{ | |||||
throw new AntException( "Non-public constructor for " + clazz + " " + component, | |||||
iae ); | |||||
} | |||||
catch( final InstantiationException ie ) | |||||
{ | |||||
throw new AntException( "Error instantiating class for " + clazz + " " + component, | |||||
ie ); | |||||
} | |||||
catch( final ClassNotFoundException cnfe ) | |||||
{ | |||||
throw new AntException( "Could not find the class for " + clazz + | |||||
" (" + component + ")", cnfe ); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant; | |||||
/** | |||||
* Interface for front end. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
* @author James Duncan Davidson (duncan@apache.org) | |||||
*/ | |||||
public interface FrontEnd | |||||
{ | |||||
} |
@@ -15,25 +15,26 @@ import java.io.InputStream; | |||||
import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
import java.net.URL; | import java.net.URL; | ||||
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 java.util.Map; | |||||
import java.util.Properties; | |||||
import org.apache.ant.launcher.AntClassLoader; | |||||
import org.apache.ant.launcher.AntLoader; | import org.apache.ant.launcher.AntLoader; | ||||
import org.apache.ant.project.DefaultProjectEngine; | |||||
import org.apache.ant.project.LogTargetToListenerAdapter; | |||||
import org.apache.ant.project.Project; | import org.apache.ant.project.Project; | ||||
import org.apache.ant.project.ProjectBuilder; | import org.apache.ant.project.ProjectBuilder; | ||||
import org.apache.ant.project.ProjectEngine; | import org.apache.ant.project.ProjectEngine; | ||||
import org.apache.ant.project.ProjectListener; | import org.apache.ant.project.ProjectListener; | ||||
import org.apache.ant.project.LogTargetToListenerAdapter; | |||||
import org.apache.ant.tasklet.JavaVersion; | import org.apache.ant.tasklet.JavaVersion; | ||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.ant.tasklet.engine.TskDeployer; | |||||
import org.apache.avalon.Disposable; | import org.apache.avalon.Disposable; | ||||
import org.apache.avalon.Initializable; | import org.apache.avalon.Initializable; | ||||
import org.apache.avalon.camelot.CamelotUtil; | |||||
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.ObjectUtil; | ||||
import org.apache.avalon.util.StringUtil; | import org.apache.avalon.util.StringUtil; | ||||
@@ -41,7 +42,6 @@ import org.apache.avalon.util.cli.AbstractMain; | |||||
import org.apache.avalon.util.cli.CLOption; | import org.apache.avalon.util.cli.CLOption; | ||||
import org.apache.avalon.util.cli.CLOptionDescriptor; | import org.apache.avalon.util.cli.CLOptionDescriptor; | ||||
import org.apache.avalon.util.io.ExtensionFileFilter; | import org.apache.avalon.util.io.ExtensionFileFilter; | ||||
import org.apache.avalon.util.io.FileUtil; | |||||
import org.apache.log.Category; | import org.apache.log.Category; | ||||
import org.apache.log.LogKit; | import org.apache.log.LogKit; | ||||
import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
@@ -67,21 +67,11 @@ public class Main | |||||
protected final static String DEFAULT_LOGLEVEL = "WARN"; | protected final static String DEFAULT_LOGLEVEL = "WARN"; | ||||
//Some defaults for file locations/names | //Some defaults for file locations/names | ||||
protected final static String DEFAULT_LIB_DIRECTORY = "lib"; | |||||
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 = | |||||
"org.apache.ant.project.DefaultProjectEngine"; | |||||
protected final static String DEFAULT_LISTENER = | protected final static String DEFAULT_LISTENER = | ||||
"org.apache.ant.project.DefaultProjectListener"; | "org.apache.ant.project.DefaultProjectListener"; | ||||
protected final static String DEFAULT_BUILDER = | |||||
"org.apache.ant.project.DefaultProjectBuilder"; | |||||
//defines for the Command Line options | //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'; | ||||
@@ -91,8 +81,6 @@ public class Main | |||||
private static final int DEFINE_OPT = 'D'; | private static final int DEFINE_OPT = 'D'; | ||||
private static final int VERSION_OPT = 1; | private static final int VERSION_OPT = 1; | ||||
private static final int LISTENER_OPT = 2; | private static final int LISTENER_OPT = 2; | ||||
private static final int BIN_DIR_OPT = 3; | |||||
private static final int LIB_DIR_OPT = 4; | |||||
private static final int TASKLIB_DIR_OPT = 5; | private static final int TASKLIB_DIR_OPT = 5; | ||||
private static final int INCREMENTAL_OPT = 6; | private static final int INCREMENTAL_OPT = 6; | ||||
private static final int HOME_DIR_OPT = 7; | private static final int HOME_DIR_OPT = 7; | ||||
@@ -102,8 +90,7 @@ public class Main | |||||
{ | { | ||||
HELP_OPT, QUIET_OPT, VERBOSE_OPT, FILE_OPT, | HELP_OPT, QUIET_OPT, VERBOSE_OPT, FILE_OPT, | ||||
LOG_LEVEL_OPT, VERSION_OPT, LISTENER_OPT, | LOG_LEVEL_OPT, VERSION_OPT, LISTENER_OPT, | ||||
DEFINE_OPT | |||||
//BIN_DIR_OPT, LIB_DIR_OPT, TASKLIB_DIR_OPT, HOME_DIR_OPT | |||||
DEFINE_OPT //TASKLIB_DIR_OPT, HOME_DIR_OPT | |||||
}; | }; | ||||
//incompatable options for other logging options | //incompatable options for other logging options | ||||
@@ -112,15 +99,8 @@ public class Main | |||||
QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT | QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT | ||||
}; | }; | ||||
protected Logger m_logger; | |||||
protected ProjectListener m_listener; | protected ProjectListener m_listener; | ||||
protected File m_binDir; | |||||
protected File m_homeDir; | protected File m_homeDir; | ||||
protected File m_libDir; | |||||
protected File m_taskLibDir; | |||||
protected File m_buildFile; | |||||
protected File m_userDir; | |||||
/** | /** | ||||
* Main entry point called to run standard Ant. | * Main entry point called to run standard Ant. | ||||
@@ -134,13 +114,13 @@ public class Main | |||||
try { main.execute( args ); } | try { main.execute( args ); } | ||||
catch( final AntException ae ) | catch( final AntException ae ) | ||||
{ | { | ||||
main.m_logger.error( "Error: " + ae.getMessage() ); | |||||
main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( ae ) ); | |||||
main.getLogger().error( "Error: " + ae.getMessage() ); | |||||
main.getLogger().debug( "Exception..." + StringUtil.printStackTrace( ae ) ); | |||||
} | } | ||||
catch( final Throwable throwable ) | catch( final Throwable throwable ) | ||||
{ | { | ||||
main.m_logger.error( "Error: " + throwable ); | |||||
main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( throwable ) ); | |||||
main.getLogger().error( "Error: " + throwable ); | |||||
main.getLogger().debug( "Exception..." + StringUtil.printStackTrace( throwable ) ); | |||||
} | } | ||||
} | } | ||||
@@ -151,7 +131,7 @@ public class Main | |||||
protected CLOptionDescriptor[] createCLOptions() | protected CLOptionDescriptor[] createCLOptions() | ||||
{ | { | ||||
//TODO: localise | //TODO: localise | ||||
final CLOptionDescriptor[] options = new CLOptionDescriptor[ 13 ]; | |||||
final CLOptionDescriptor[] options = new CLOptionDescriptor[ 11 ]; | |||||
options[0] = | options[0] = | ||||
new CLOptionDescriptor( "help", | new CLOptionDescriptor( "help", | ||||
@@ -202,33 +182,21 @@ public class Main | |||||
INFO_OPT_INCOMPAT ); | INFO_OPT_INCOMPAT ); | ||||
options[7] = | options[7] = | ||||
new CLOptionDescriptor( "bin-dir", | |||||
CLOptionDescriptor.ARGUMENT_REQUIRED, | |||||
BIN_DIR_OPT, | |||||
"the listener for log events." ); | |||||
options[8] = | |||||
new CLOptionDescriptor( "lib-dir", | |||||
CLOptionDescriptor.ARGUMENT_REQUIRED, | |||||
LIB_DIR_OPT, | |||||
"the lib directory to scan for jars/zip files." ); | |||||
options[9] = | |||||
new CLOptionDescriptor( "task-lib-dir", | new CLOptionDescriptor( "task-lib-dir", | ||||
CLOptionDescriptor.ARGUMENT_REQUIRED, | CLOptionDescriptor.ARGUMENT_REQUIRED, | ||||
TASKLIB_DIR_OPT, | TASKLIB_DIR_OPT, | ||||
"the task lib directory to scan for .tsk files." ); | "the task lib directory to scan for .tsk files." ); | ||||
options[10] = | |||||
options[8] = | |||||
new CLOptionDescriptor( "incremental", | new CLOptionDescriptor( "incremental", | ||||
CLOptionDescriptor.ARGUMENT_DISALLOWED, | CLOptionDescriptor.ARGUMENT_DISALLOWED, | ||||
INCREMENTAL_OPT, | INCREMENTAL_OPT, | ||||
"Run in incremental mode" ); | "Run in incremental mode" ); | ||||
options[11] = | |||||
options[9] = | |||||
new CLOptionDescriptor( "ant-home", | new CLOptionDescriptor( "ant-home", | ||||
CLOptionDescriptor.ARGUMENT_REQUIRED, | CLOptionDescriptor.ARGUMENT_REQUIRED, | ||||
HOME_DIR_OPT, | HOME_DIR_OPT, | ||||
"Specify ant home directory" ); | "Specify ant home directory" ); | ||||
options[12] = | |||||
options[10] = | |||||
new CLOptionDescriptor( "define", | new CLOptionDescriptor( "define", | ||||
CLOptionDescriptor.ARGUMENTS_REQUIRED_2, | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, | ||||
DEFINE_OPT, | DEFINE_OPT, | ||||
@@ -249,11 +217,8 @@ public class Main | |||||
final ArrayList targets = new ArrayList(); | final ArrayList targets = new ArrayList(); | ||||
String filename = null; | String filename = null; | ||||
String listenerName = null; | String listenerName = null; | ||||
String builderName = null; | |||||
String logLevel = null; | String logLevel = null; | ||||
String binDir = null; | |||||
String homeDir = null; | String homeDir = null; | ||||
String libDir = null; | |||||
String taskLibDir = null; | String taskLibDir = null; | ||||
boolean incremental = false; | boolean incremental = false; | ||||
HashMap defines = new HashMap(); | HashMap defines = new HashMap(); | ||||
@@ -268,8 +233,6 @@ public class Main | |||||
case HELP_OPT: usage(); return; | case HELP_OPT: usage(); return; | ||||
case VERSION_OPT: System.out.println( VERSION ); return; | case VERSION_OPT: System.out.println( VERSION ); return; | ||||
case FILE_OPT: filename = option.getArgument(); break; | case FILE_OPT: filename = option.getArgument(); break; | ||||
case BIN_DIR_OPT: binDir = option.getArgument(); break; | |||||
case LIB_DIR_OPT: libDir = option.getArgument(); break; | |||||
case HOME_DIR_OPT: homeDir = option.getArgument(); break; | case HOME_DIR_OPT: homeDir = option.getArgument(); break; | ||||
case TASKLIB_DIR_OPT: taskLibDir = option.getArgument(); break; | case TASKLIB_DIR_OPT: taskLibDir = option.getArgument(); break; | ||||
case VERBOSE_OPT: logLevel = "INFO"; break; | case VERBOSE_OPT: logLevel = "INFO"; break; | ||||
@@ -284,64 +247,63 @@ public class Main | |||||
} | } | ||||
} | } | ||||
if( null == logLevel ) logLevel = getDefaultLogLevel(); | |||||
if( null == listenerName ) listenerName = getDefaultListener(); | |||||
if( null == filename ) filename = getDefaultFilename(); | |||||
if( null == libDir ) libDir = getDefaultLibDir(); | |||||
if( null == taskLibDir ) taskLibDir = getDefaultTaskLibDir(); | |||||
if( null == builderName ) builderName = getBuilderNameFor( filename ); | |||||
setupLogger( logLevel ); //handle logging... | |||||
setupListener( listenerName ); //handle listener.. | |||||
setupDefaultAntDirs(); | |||||
//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 ) | |||||
{ | |||||
m_homeDir = getDefaultHomeDir(); | |||||
m_binDir = m_homeDir.getParentFile(); | |||||
} | |||||
else if( null == binDir ) // && null != homeDir | |||||
{ | |||||
m_homeDir = getHomeDir( homeDir ); | |||||
m_binDir = new File( m_homeDir, "bin" ); | |||||
} | |||||
else | |||||
if( null == logLevel ) logLevel = DEFAULT_LOGLEVEL; | |||||
if( null == listenerName ) listenerName = DEFAULT_LISTENER; | |||||
if( null == filename ) filename = DEFAULT_FILENAME; | |||||
//handle logging... | |||||
setLogger( createLogger( logLevel ) ); | |||||
//if ant home not set then use system property ant.home | |||||
//that was set up by launcher. | |||||
if( null == homeDir ) homeDir = System.getProperty( "ant.home" ); | |||||
final Properties properties = new Properties(); | |||||
properties.setProperty( "ant.home", homeDir ); | |||||
if( null != taskLibDir ) properties.setProperty( "ant.path.task-lib", taskLibDir ); | |||||
m_homeDir = (new File( homeDir )).getAbsoluteFile(); | |||||
if( !m_homeDir.isDirectory() ) | |||||
{ | { | ||||
m_binDir = getBinDir( binDir ); | |||||
m_homeDir = m_binDir.getParentFile(); | |||||
throw new AntException( "ant-home (" + m_homeDir + ") is not a directory" ); | |||||
} | } | ||||
m_libDir = getLibDir( m_homeDir, libDir ); | |||||
m_taskLibDir = getTaskLibDir( m_homeDir, taskLibDir ); | |||||
m_buildFile = getFile( filename ); | |||||
m_logger.warn( "Ant Build File: " + m_buildFile ); | |||||
m_logger.info( "Ant Home Directory: " + m_homeDir ); | |||||
m_logger.info( "Ant Bin Directory: " + m_binDir ); | |||||
m_logger.debug( "Ant Lib Directory: " + m_libDir ); | |||||
m_logger.debug( "Ant Task Lib Directory: " + m_taskLibDir ); | |||||
final File libDir = new File( m_homeDir, "lib" ); | |||||
final File buildFile = (new File( filename )).getCanonicalFile(); | |||||
if( !buildFile.isFile() ) | |||||
{ | |||||
throw new AntException( "File " + buildFile + " is not a file or doesn't exist" ); | |||||
} | |||||
//setup classloader so that it will correctly load | //setup classloader so that it will correctly load | ||||
//the Project/ProjectBuilder/ProjectEngine and all dependencies | //the Project/ProjectBuilder/ProjectEngine and all dependencies | ||||
setupContextClassLoader( m_libDir ); | |||||
final ClassLoader classLoader = createClassLoader( libDir ); | |||||
Thread.currentThread().setContextClassLoader( classLoader ); | |||||
final Project project = getProject( builderName, m_buildFile ); | |||||
setupProjectContext( project, defines ); | |||||
//handle listener.. | |||||
final ProjectListener listener = createListener( listenerName ); | |||||
final ProjectEngine engine = getProjectEngine(); | |||||
getLogger().warn( "Ant Build File: " + buildFile ); | |||||
getLogger().info( "Ant Home Directory: " + m_homeDir ); | |||||
//getLogger().info( "Ant Bin Directory: " + m_binDir ); | |||||
//getLogger().debug( "Ant Lib Directory: " + m_libDir ); | |||||
//getLogger().debug( "Ant Task Lib Directory: " + m_taskLibDir ); | |||||
//make sure Engine is sweet... | |||||
if( engine instanceof Initializable ) | |||||
{ | |||||
((Initializable)engine).init(); | |||||
} | |||||
final AntEngine antEngine = new DefaultAntEngine(); | |||||
setupLogger( antEngine ); | |||||
antEngine.setProperties( properties ); | |||||
antEngine.init(); | |||||
engine.addProjectListener( m_listener ); | |||||
final ProjectBuilder builder = antEngine.getProjectBuilder(); | |||||
//create the project | |||||
final Project project = builder.build( buildFile ); | |||||
setupProjectContext( project, defines ); | |||||
deployDefaultTaskLibs( engine, m_taskLibDir ); | |||||
final ProjectEngine engine = antEngine.getProjectEngine(); | |||||
engine.addProjectListener( listener ); | |||||
BufferedReader reader = null; | BufferedReader reader = null; | ||||
@@ -366,44 +328,7 @@ public class Main | |||||
} | } | ||||
//shutdown engine gracefully if needed | |||||
if( engine instanceof Disposable ) | |||||
{ | |||||
((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, | |||||
final File taskLibDirectory ) | |||||
{ | |||||
final ExtensionFileFilter filter = new ExtensionFileFilter( ".tsk" ); | |||||
final File[] files = taskLibDirectory.listFiles( filter ); | |||||
final TskDeployer deployer = engine.getTaskletEngine().getTskDeployer(); | |||||
for( int i = 0; i < files.length; i++ ) | |||||
{ | |||||
final String name = files[ i ].getName(); | |||||
try | |||||
{ | |||||
deployer.deploy( name.substring( 0, name.length() - 4 ), | |||||
files[ i ].toURL() ); | |||||
} | |||||
catch( final MalformedURLException mue ) {} | |||||
catch( final DeploymentException de ) | |||||
{ | |||||
throw new AntException( "Failed to deploy task library " + files[ i ], | |||||
de ); | |||||
} | |||||
} | |||||
antEngine.dispose(); | |||||
} | } | ||||
/** | /** | ||||
@@ -436,22 +361,11 @@ public class Main | |||||
} | } | ||||
catch( final AntException ae ) | catch( final AntException ae ) | ||||
{ | { | ||||
m_logger.error( "BUILD FAILED" ); | |||||
m_logger.error( "Reason:\n" + StringUtil.printStackTrace( ae, 5, true ) ); | |||||
getLogger().error( "BUILD FAILED" ); | |||||
getLogger().error( "Reason:\n" + StringUtil.printStackTrace( ae, 5, true ) ); | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 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 ) | |||||
{ | |||||
m_logger = createLogger( logLevel ); | |||||
} | |||||
/** | /** | ||||
* Create Logger of appropriate log-level. | * Create Logger of appropriate log-level. | ||||
* | * | ||||
@@ -479,39 +393,47 @@ public class Main | |||||
* | * | ||||
* @param listenerName the name of project listener | * @param listenerName the name of project listener | ||||
*/ | */ | ||||
protected void setupListener( final String listenerName ) | |||||
protected ProjectListener createListener( final String listenerName ) | |||||
throws AntException | |||||
{ | { | ||||
m_listener = createListener( listenerName ); | |||||
m_logger.addLogTarget( new LogTargetToListenerAdapter( m_listener ) ); | |||||
} | |||||
ProjectListener result = null; | |||||
/** | |||||
* 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 ) | |||||
{ | |||||
setupClassLoader( libDir ); | |||||
Thread.currentThread().setContextClassLoader( AntLoader.getLoader() ); | |||||
try { result = (ProjectListener)ObjectUtil.createObject( listenerName ); } | |||||
catch( final Throwable t ) | |||||
{ | |||||
throw new AntException( "Error creating the listener " + listenerName + | |||||
" due to " + StringUtil.printStackTrace( t, 5, true ), | |||||
t ); | |||||
} | |||||
getLogger().addLogTarget( new LogTargetToListenerAdapter( result ) ); | |||||
return result; | |||||
} | } | ||||
/** | /** | ||||
* 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. | |||||
* Try to load all extra zipz/jars from lib directory into CURRENT classloader. | |||||
* | * | ||||
* @param libDir the directory of lib files to add | * @param libDir the directory of lib files to add | ||||
*/ | */ | ||||
protected void setupClassLoader( final File libDir ) | |||||
protected ClassLoader createClassLoader( final File libDir ) | |||||
{ | { | ||||
final ClassLoader candidate = getClass().getClassLoader(); | |||||
if( !(candidate instanceof AntClassLoader) ) | |||||
{ | |||||
getLogger().warn( "Warning: Unable to add entries from " + | |||||
"lib-path to classloader" ); | |||||
return candidate; | |||||
} | |||||
final AntClassLoader classLoader = (AntClassLoader)candidate; | |||||
final ExtensionFileFilter filter = | final ExtensionFileFilter filter = | ||||
new ExtensionFileFilter( new String[] { ".jar", ".zip" } ); | new ExtensionFileFilter( new String[] { ".jar", ".zip" } ); | ||||
final File[] files = libDir.listFiles( filter ); | final File[] files = libDir.listFiles( filter ); | ||||
final AntLoader classLoader = AntLoader.getLoader(); | |||||
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 | //except for a few *special* files add all the | ||||
@@ -524,28 +446,8 @@ public class Main | |||||
catch( final MalformedURLException mue ) {} | catch( final MalformedURLException mue ) {} | ||||
} | } | ||||
} | } | ||||
} | |||||
/** | |||||
* 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 ) | |||||
throws AntException, IOException | |||||
{ | |||||
m_logger.debug( "Ant Project Builder: " + builderName ); | |||||
final ProjectBuilder builder = createBuilder( builderName ); | |||||
builder.setLogger( m_logger ); | |||||
//create the project | |||||
final Project project = builder.build( file ); | |||||
return project; | |||||
return classLoader; | |||||
} | } | ||||
/** | /** | ||||
@@ -562,12 +464,11 @@ public class Main | |||||
{ | { | ||||
//put these values into defines so that they overide | //put these values into defines so that they overide | ||||
//user-defined proeprties | //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.JAVA_VERSION, getJavaVersion() ); | |||||
//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( TaskletContext.JAVA_VERSION, getJavaVersion() ); | |||||
final TaskletContext context = project.getContext(); | final TaskletContext context = project.getContext(); | ||||
addToContext( context, defines ); | addToContext( context, defines ); | ||||
@@ -593,330 +494,5 @@ public class Main | |||||
context.setProperty( key, value ); | context.setProperty( key, value ); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Helper method to retrieve current JVM version. | |||||
* Basically stolen from original Ant sources. | |||||
* | |||||
* @return the current JVM version | |||||
*/ | |||||
protected JavaVersion getJavaVersion() | |||||
{ | |||||
JavaVersion version = JavaVersion.JAVA1_0; | |||||
try | |||||
{ | |||||
Class.forName( "java.lang.Void" ); | |||||
version = JavaVersion.JAVA1_1; | |||||
Class.forName( "java.lang.ThreadLocal" ); | |||||
version = JavaVersion.JAVA1_2; | |||||
Class.forName( "java.lang.StrictMath" ); | |||||
version = JavaVersion.JAVA1_3; | |||||
} | |||||
catch( final ClassNotFoundException cnfe ) {} | |||||
return version; | |||||
} | |||||
/** | |||||
* Create and configure project engine | |||||
* | |||||
* @return the ProjectEngine | |||||
*/ | |||||
protected ProjectEngine getProjectEngine() | |||||
{ | |||||
final ProjectEngine engine = createProjectEngine(); | |||||
engine.setLogger( m_logger ); | |||||
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() | |||||
{ | |||||
return (ProjectEngine)createObject( DEFAULT_ENGINE, "project-engine" ); | |||||
} | |||||
protected File getHomeDir( final String homeDir ) | |||||
throws AntException | |||||
{ | |||||
final File file = (new File( homeDir )).getAbsoluteFile(); | |||||
checkDirectory( file, "ant-home" ); | |||||
return file; | |||||
} | |||||
protected File getBinDir( final String binDir ) | |||||
throws AntException | |||||
{ | |||||
File file = (new File( binDir )).getAbsoluteFile(); | |||||
if( !file.isDirectory() ) file = file.getParentFile(); | |||||
checkDirectory( file, "bin-dir" ); | |||||
return file; | |||||
} | |||||
protected File getLibDir( final File antHome, String libDir ) | |||||
throws AntException | |||||
{ | |||||
return resolveDirectory( antHome, libDir, "lib-dir" ); | |||||
} | |||||
protected File getTaskLibDir( final File antHome, final String taskLibDir ) | |||||
throws AntException | |||||
{ | |||||
return resolveDirectory( antHome, taskLibDir, "task-lib-dir" ); | |||||
} | |||||
protected File resolveDirectory( final File antHome, final String dir, final String name ) | |||||
throws AntException | |||||
{ | |||||
final File file = FileUtil.resolveFile( antHome, dir ); | |||||
checkDirectory( file, name ); | |||||
return file; | |||||
} | |||||
protected void checkDirectory( final File file, final String name ) | |||||
{ | |||||
if( !file.exists() ) | |||||
{ | |||||
throw new AntException( name + " (" + file + ") does not exist" ); | |||||
} | |||||
else if( !file.isDirectory() ) | |||||
{ | |||||
throw new AntException( name + " (" + file + ") is not a directory" ); | |||||
} | |||||
} | |||||
protected ProjectListener createListener( final String listenerName ) | |||||
throws AntException | |||||
{ | |||||
try { return (ProjectListener)createObject( listenerName, "listener" ); } | |||||
catch( final ClassCastException cce ) | |||||
{ | |||||
throw new AntException( "Aparently the listener named " + listenerName + | |||||
" does not implement the ProjectListener interface", | |||||
cce ); | |||||
} | |||||
} | |||||
protected void setupDefaultAntDirs() | |||||
{ | |||||
final String os = System.getProperty( "os.name" ); | |||||
final String userDir = System.getProperty( "user.home" ); | |||||
m_userDir = | |||||
(new File( getUserLocationFor( os, userDir ) )).getAbsoluteFile(); | |||||
} | |||||
/** | |||||
* Retrieve default bin-dir value if possible (Otherwise throw an exception). | |||||
* | |||||
* Lookup OS specific places for ant to be. | |||||
* /opt/ant on *BSD ? | |||||
* /usr/local/ant on linux ? | |||||
* /Program Files/Ant on Win32 ? | |||||
* | |||||
* @return bin directory | |||||
*/ | |||||
protected File getDefaultHomeDir() | |||||
throws AntException | |||||
{ | |||||
if( null != m_userDir ) | |||||
{ | |||||
try | |||||
{ | |||||
checkDirectory( m_userDir, null ); | |||||
return m_userDir; | |||||
} | |||||
catch( final AntException ae ) {} | |||||
} | |||||
final String os = System.getProperty( "os.name" ); | |||||
final File candidate = | |||||
(new File( getSystemLocationFor( os ) )).getAbsoluteFile(); | |||||
checkDirectory( candidate, "ant-home" ); | |||||
return candidate; | |||||
} | |||||
/** | |||||
* This determins a mapping from an OS specific place to ants home directory. | |||||
* In later versions the mapping should be read from configuration file. | |||||
* | |||||
* @param os the name of OS | |||||
* @return the location of directory | |||||
*/ | |||||
protected String getUserLocationFor( final String os, final String userDir ) | |||||
{ | |||||
if( os.startsWith( "Windows" ) ) | |||||
{ | |||||
return userDir + "\\Ant"; | |||||
} | |||||
else if( '/' == File.separatorChar ) | |||||
{ | |||||
if( os.startsWith( "Linux" ) ) return userDir + "/ant"; | |||||
else return userDir + "/opt/ant"; | |||||
} | |||||
else | |||||
{ | |||||
return userDir + File.separator + "ant"; | |||||
} | |||||
} | |||||
/** | |||||
* This determins a mapping from an OS specific place to ants home directory. | |||||
* In later versions the mapping should be read from configuration file. | |||||
* | |||||
* @param os the name of OS | |||||
* @return the location of directory | |||||
*/ | |||||
protected String getSystemLocationFor( final String os ) | |||||
{ | |||||
if( os.startsWith( "Windows" ) ) | |||||
{ | |||||
return "\\Program Files\\Ant"; | |||||
} | |||||
else if( '/' == File.separatorChar ) | |||||
{ | |||||
if( os.startsWith( "Linux" ) ) return "/usr/local/ant"; | |||||
else return "/opt/ant"; | |||||
} | |||||
else | |||||
{ | |||||
return File.separator + "ant"; | |||||
} | |||||
} | |||||
protected String getDefaultLibDir() | |||||
{ | |||||
return DEFAULT_LIB_DIRECTORY; | |||||
} | |||||
protected String getDefaultTaskLibDir() | |||||
{ | |||||
return DEFAULT_TASKLIB_DIRECTORY; | |||||
} | |||||
/** | |||||
* Retrieve default filename. Overide this in base classes to change default. | |||||
* | |||||
* @return the default filename | |||||
*/ | |||||
protected String getDefaultFilename() | |||||
{ | |||||
return DEFAULT_FILENAME; | |||||
} | |||||
/** | |||||
* Retrieve default logelevel. Overide this in base classes to change default. | |||||
* | |||||
* @return the default loglevel | |||||
*/ | |||||
protected String getDefaultLogLevel() | |||||
{ | |||||
return DEFAULT_LOGLEVEL; | |||||
} | |||||
/** | |||||
* Retrieve default listener. Overide this in base classes to change default. | |||||
* | |||||
* @return the default listener | |||||
*/ | |||||
protected String getDefaultListener() | |||||
{ | |||||
return DEFAULT_LISTENER; | |||||
} | |||||
/** | |||||
* Get File object for filename. | |||||
* Check that file exists and is not a directory. | |||||
* | |||||
* @param filename the filename | |||||
* @return the file object | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected File getFile( final String filename ) | |||||
throws AntException, IOException | |||||
{ | |||||
final File file = (new File( filename )).getCanonicalFile(); | |||||
if( !file.exists() ) | |||||
{ | |||||
throw new AntException( "File " + file + " does not exist." ); | |||||
} | |||||
if( file.isDirectory() ) | |||||
{ | |||||
throw new AntException( "File " + file + " is a directory." ); | |||||
} | |||||
return file; | |||||
} | |||||
/** | |||||
* Create instance of Builder based on classname. | |||||
* | |||||
* @param builderName builder class name | |||||
* @return the ProjectBuilder | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected ProjectBuilder createBuilder( final String builderName ) | |||||
throws AntException | |||||
{ | |||||
try { return (ProjectBuilder)createObject( builderName, "builder" ); } | |||||
catch( final ClassCastException cce ) | |||||
{ | |||||
throw new AntException( "Aparently the builder named " + builderName + | |||||
" does not implement the ProjectBuilder interface", | |||||
cce ); | |||||
} | |||||
} | |||||
/** | |||||
* Helper method to create object and throw an apporpriate AntException if creation failed. | |||||
* | |||||
* @param objectName the classname of object | |||||
* @param type the type of object being created (ie builder|listener) | |||||
* @return the created object | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected Object createObject( final String objectName, final String type ) | |||||
throws AntException | |||||
{ | |||||
try | |||||
{ | |||||
return ObjectUtil.createObject( objectName ); | |||||
} | |||||
catch( final IllegalAccessException iae ) | |||||
{ | |||||
throw new AntException( "Non-public constructor for " + type + " " + objectName, | |||||
iae ); | |||||
} | |||||
catch( final InstantiationException ie ) | |||||
{ | |||||
throw new AntException( "Error instantiating class for " + type + " " + objectName, | |||||
ie ); | |||||
} | |||||
catch( final ClassNotFoundException cnfe ) | |||||
{ | |||||
throw new AntException( "Could not find the class for " + type + " " + objectName, | |||||
cnfe ); | |||||
} | |||||
} | |||||
/** | |||||
* Retrieve class name of builder for file. | |||||
* Eventually this will look in a registry of file extentions to BuilderNames. | |||||
* | |||||
* @param filename the filename | |||||
* @return the name of Class for Builder | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected String getBuilderNameFor( final String filename ) | |||||
throws AntException | |||||
{ | |||||
return DEFAULT_BUILDER; | |||||
} | |||||
} | } | ||||
@@ -18,12 +18,6 @@ import org.xml.sax.SAXException; | |||||
public class ConfigurationBuilder | public class ConfigurationBuilder | ||||
extends org.apache.avalon.DefaultConfigurationBuilder | extends org.apache.avalon.DefaultConfigurationBuilder | ||||
{ | { | ||||
public ConfigurationBuilder() | |||||
throws SAXException | |||||
{ | |||||
super(); | |||||
} | |||||
protected org.apache.avalon.SAXConfigurationHandler getHandler() | protected org.apache.avalon.SAXConfigurationHandler getHandler() | ||||
{ | { | ||||
return new SAXConfigurationHandler(); | return new SAXConfigurationHandler(); | ||||
@@ -13,9 +13,9 @@ import java.util.ArrayList; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import org.apache.ant.convert.Converter; | import org.apache.ant.convert.Converter; | ||||
import org.apache.ant.convert.ConverterException; | import org.apache.ant.convert.ConverterException; | ||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.ConfigurationException; | import org.apache.avalon.ConfigurationException; | ||||
import org.apache.avalon.Context; | import org.apache.avalon.Context; | ||||
@@ -30,6 +30,7 @@ import org.apache.log.Logger; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public class DefaultConfigurer | public class DefaultConfigurer | ||||
extends AbstractLoggable | |||||
implements Configurer, Composer, Loggable | implements Configurer, Composer, Loggable | ||||
{ | { | ||||
protected final static String RESERVED_ATTRIBUTES[] = | protected final static String RESERVED_ATTRIBUTES[] = | ||||
@@ -44,15 +45,9 @@ public class DefaultConfigurer | |||||
protected final static boolean DEBUG = false; | protected final static boolean DEBUG = false; | ||||
protected Converter m_converter; | protected Converter m_converter; | ||||
protected Logger m_logger; | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_converter = (Converter)componentManager.lookup( "org.apache.ant.convert.Converter" ); | m_converter = (Converter)componentManager.lookup( "org.apache.ant.convert.Converter" ); | ||||
} | } | ||||
@@ -206,7 +201,7 @@ public class DefaultConfigurer | |||||
final Object objectValue = | final Object objectValue = | ||||
PropertyUtil.resolveProperty( value, context, false ); | PropertyUtil.resolveProperty( value, context, false ); | ||||
setValue( object, objectValue, methods ); | |||||
setValue( object, objectValue, methods, context ); | |||||
} | } | ||||
catch( final PropertyException pe ) | catch( final PropertyException pe ) | ||||
{ | { | ||||
@@ -215,7 +210,10 @@ public class DefaultConfigurer | |||||
} | } | ||||
} | } | ||||
protected void setValue( final Object object, Object value, final Method methods[] ) | |||||
protected void setValue( final Object object, | |||||
Object value, | |||||
final Method methods[], | |||||
final Context context ) | |||||
throws ConfigurationException | throws ConfigurationException | ||||
{ | { | ||||
final Class sourceClass = value.getClass(); | final Class sourceClass = value.getClass(); | ||||
@@ -223,7 +221,7 @@ public class DefaultConfigurer | |||||
for( int i = 0; i < methods.length; i++ ) | for( int i = 0; i < methods.length; i++ ) | ||||
{ | { | ||||
if( setValue( object, value, methods[ i ], sourceClass, source ) ) | |||||
if( setValue( object, value, methods[ i ], sourceClass, source, context ) ) | |||||
{ | { | ||||
return; | return; | ||||
} | } | ||||
@@ -238,7 +236,8 @@ public class DefaultConfigurer | |||||
Object value, | Object value, | ||||
final Method method, | final Method method, | ||||
final Class sourceClass, | final Class sourceClass, | ||||
final String source ) | |||||
final String source, | |||||
final Context context ) | |||||
throws ConfigurationException | throws ConfigurationException | ||||
{ | { | ||||
Class parameterType = method.getParameterTypes()[ 0 ]; | Class parameterType = method.getParameterTypes()[ 0 ]; | ||||
@@ -249,7 +248,7 @@ public class DefaultConfigurer | |||||
try | try | ||||
{ | { | ||||
value = m_converter.convert( parameterType, value ); | |||||
value = m_converter.convert( parameterType, value, context ); | |||||
} | } | ||||
catch( final ConverterException ce ) | catch( final ConverterException ce ) | ||||
{ | { | ||||
@@ -359,7 +358,7 @@ public class DefaultConfigurer | |||||
protected String getMethodNameFor( final String attribute ) | protected String getMethodNameFor( final String attribute ) | ||||
{ | { | ||||
return "set" + getJavaNameFor( attribute ); | |||||
return "set" + getJavaNameFor( attribute.toLowerCase() ); | |||||
} | } | ||||
protected String getJavaNameFor( final String name ) | protected String getJavaNameFor( final String name ) | ||||
@@ -7,6 +7,8 @@ | |||||
*/ | */ | ||||
package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* Instances of this interface are used to convert between different types. | * Instances of this interface are used to convert between different types. | ||||
* | * | ||||
@@ -35,10 +37,11 @@ public abstract class AbstractConverter | |||||
* | * | ||||
* @param destination the destination type | * @param destination the destination type | ||||
* @param original the original Object | * @param original the original Object | ||||
* @param context the context in which to convert | |||||
* @return the converted object | * @return the converted object | ||||
* @exception Exception if an error occurs | * @exception Exception if an error occurs | ||||
*/ | */ | ||||
public Object convert( final Class destination, final Object original ) | |||||
public Object convert( final Class destination, final Object original, Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
if( m_destination != destination ) | if( m_destination != destination ) | ||||
@@ -53,17 +56,18 @@ public abstract class AbstractConverter | |||||
"instance of " + m_source.getName() ); | "instance of " + m_source.getName() ); | ||||
} | } | ||||
return convert( original ); | |||||
return convert( original, context ); | |||||
} | } | ||||
/** | /** | ||||
* Overide this in a particular converter to do the conversion. | * Overide this in a particular converter to do the conversion. | ||||
* | * | ||||
* @param original the original Object | * @param original the original Object | ||||
* @param context the context in which to convert | |||||
* @return the converted object | * @return the converted object | ||||
* @exception Exception if an error occurs | * @exception Exception if an error occurs | ||||
*/ | */ | ||||
protected abstract Object convert( Object original ) | |||||
protected abstract Object convert( Object original, Context context ) | |||||
throws Exception; | throws Exception; | ||||
} | } | ||||
@@ -7,6 +7,8 @@ | |||||
*/ | */ | ||||
package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* Instances of this interface are used to convert between different types. | * Instances of this interface are used to convert between different types. | ||||
* | * | ||||
@@ -21,9 +23,10 @@ public interface Converter | |||||
* | * | ||||
* @param destination the destinaiton type | * @param destination the destinaiton type | ||||
* @param original the original type | * @param original the original type | ||||
* @param context the context in which to convert | |||||
* @return the converted object | * @return the converted object | ||||
* @exception Exception if an error occurs | * @exception Exception if an error occurs | ||||
*/ | */ | ||||
Object convert( Class destination, Object original ) | |||||
Object convert( Class destination, Object original, Context context ) | |||||
throws ConverterException, Exception; | throws ConverterException, Exception; | ||||
} | } |
@@ -8,13 +8,27 @@ | |||||
package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
import org.apache.avalon.Loggable; | |||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
import org.apache.log.Logger; | |||||
/** | |||||
* Converter engine to handle converting between types. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface ConverterEngine | public interface ConverterEngine | ||||
extends Component, Converter, Loggable | |||||
extends Component, Converter | |||||
{ | { | ||||
/** | |||||
* Get registry used to locate converters. | |||||
* | |||||
* @return the LocatorRegistry | |||||
*/ | |||||
LocatorRegistry getRegistry(); | LocatorRegistry getRegistry(); | ||||
/** | |||||
* Get registry for converterInfo objects. | |||||
* | |||||
* @return the ConverterRegistry | |||||
*/ | |||||
ConverterRegistry getInfoRegistry(); | ConverterRegistry getInfoRegistry(); | ||||
} | } |
@@ -8,62 +8,74 @@ | |||||
package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
import org.apache.avalon.Component; | |||||
import org.apache.avalon.Initializable; | |||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.ComponentManager; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | |||||
import org.apache.avalon.Context; | |||||
import org.apache.avalon.camelot.DefaultFactory; | import org.apache.avalon.camelot.DefaultFactory; | ||||
import org.apache.avalon.camelot.DefaultLocatorRegistry; | import org.apache.avalon.camelot.DefaultLocatorRegistry; | ||||
import org.apache.avalon.camelot.Factory; | |||||
import org.apache.avalon.camelot.Locator; | import org.apache.avalon.camelot.Locator; | ||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
import org.apache.log.Logger; | |||||
/** | |||||
* Converter engine to handle converting between types. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultConverterEngine | public class DefaultConverterEngine | ||||
implements ConverterEngine, Initializable | |||||
extends AbstractLoggable | |||||
implements ConverterEngine, Composer | |||||
{ | { | ||||
protected final static boolean DEBUG = false; | protected final static boolean DEBUG = false; | ||||
protected DefaultFactory m_factory; | |||||
protected LocatorRegistry m_registry; | |||||
protected ConverterRegistry m_infoRegistry; | |||||
protected Logger m_logger; | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
protected Factory m_factory; | |||||
protected LocatorRegistry m_registry = new DefaultLocatorRegistry(); | |||||
protected ConverterRegistry m_infoRegistry = new DefaultConverterRegistry(); | |||||
/** | |||||
* Get registry used to locate converters. | |||||
* | |||||
* @return the LocatorRegistry | |||||
*/ | |||||
public LocatorRegistry getRegistry() | public LocatorRegistry getRegistry() | ||||
{ | { | ||||
return m_registry; | return m_registry; | ||||
} | } | ||||
/** | |||||
* Get registry for converterInfo objects. | |||||
* | |||||
* @return the ConverterRegistry | |||||
*/ | |||||
public ConverterRegistry getInfoRegistry() | public ConverterRegistry getInfoRegistry() | ||||
{ | { | ||||
return m_infoRegistry; | return m_infoRegistry; | ||||
} | } | ||||
public void init() | |||||
throws Exception | |||||
{ | |||||
m_infoRegistry = createInfoRegistry(); | |||||
m_registry = createRegistry(); | |||||
m_factory = createFactory(); | |||||
} | |||||
protected ConverterRegistry createInfoRegistry() | |||||
{ | |||||
return new DefaultConverterRegistry(); | |||||
} | |||||
protected LocatorRegistry createRegistry() | |||||
{ | |||||
return new DefaultLocatorRegistry(); | |||||
} | |||||
protected DefaultFactory createFactory() | |||||
/** | |||||
* Retrieve relevent services needed to deploy. | |||||
* | |||||
* @param componentManager the ComponentManager | |||||
* @exception ComponentManagerException if an error occurs | |||||
*/ | |||||
public void compose( final ComponentManager componentManager ) | |||||
throws ComponentManagerException | |||||
{ | { | ||||
return new DefaultFactory(); | |||||
m_factory = (Factory)componentManager.lookup( "org.apache.avalon.camelot.Factory" ); | |||||
} | } | ||||
public Object convert( Class destination, final Object original ) | |||||
/** | |||||
* Convert object to destination type. | |||||
* | |||||
* @param destination the destination type | |||||
* @param original the original object | |||||
* @param context the context in which to convert | |||||
* @return the converted object | |||||
* @exception Exception if an error occurs | |||||
*/ | |||||
public Object convert( Class destination, final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
final Class originalClass = original.getClass(); | final Class originalClass = original.getClass(); | ||||
@@ -79,6 +91,7 @@ public class DefaultConverterEngine | |||||
" to " + destination.getName() ); | " to " + destination.getName() ); | ||||
} | } | ||||
//TODO: Start searching inheritance hierarchy for converter | |||||
final String name = | final String name = | ||||
m_infoRegistry.getConverterInfoName( originalClass.getName(), | m_infoRegistry.getConverterInfoName( originalClass.getName(), | ||||
destination.getName() ); | destination.getName() ); | ||||
@@ -90,8 +103,9 @@ public class DefaultConverterEngine | |||||
destination.getName() + " conversion" ); | destination.getName() + " conversion" ); | ||||
} | } | ||||
//TODO: Start caching converters instead of repeatedly instantiating em. | |||||
final Locator locator = m_registry.getLocator( name ); | final Locator locator = m_registry.getLocator( name ); | ||||
final Converter converter = (Converter)m_factory.create( locator, Converter.class ); | final Converter converter = (Converter)m_factory.create( locator, Converter.class ); | ||||
return converter.convert( destination, original ); | |||||
return converter.convert( destination, original, context ); | |||||
} | } | ||||
} | } |
@@ -8,7 +8,7 @@ | |||||
package org.apache.ant.convert; | package org.apache.ant.convert; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import org.apache.avalon.camelot.AbstractRegistry; | |||||
import org.apache.avalon.camelot.DefaultRegistry; | |||||
import org.apache.avalon.camelot.Info; | import org.apache.avalon.camelot.Info; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
@@ -18,11 +18,16 @@ import org.apache.avalon.camelot.RegistryException; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public class DefaultConverterRegistry | public class DefaultConverterRegistry | ||||
extends AbstractRegistry | |||||
extends DefaultRegistry | |||||
implements ConverterRegistry | implements ConverterRegistry | ||||
{ | { | ||||
protected final HashMap m_mapping = new HashMap(); | protected final HashMap m_mapping = new HashMap(); | ||||
public DefaultConverterRegistry() | |||||
{ | |||||
super( ConverterInfo.class ); | |||||
} | |||||
/** | /** | ||||
* Retrieve ConverterInfo that describes converter that converts from source to destination. | * Retrieve ConverterInfo that describes converter that converts from source to destination. | ||||
* | * | ||||
@@ -37,6 +42,13 @@ public class DefaultConverterRegistry | |||||
return (String)map.get( destination ); | return (String)map.get( destination ); | ||||
} | } | ||||
/** | |||||
* Overidden method so can add info into mapping. | |||||
* | |||||
* @param name the name of info | |||||
* @param info the Info | |||||
* @exception RegistryException if an error occurs | |||||
*/ | |||||
protected void checkInfo( final String name, final Info info ) | protected void checkInfo( final String name, final Info info ) | ||||
throws RegistryException | throws RegistryException | ||||
{ | { | ||||
@@ -55,9 +67,4 @@ public class DefaultConverterRegistry | |||||
map.put( destination, name ); | map.put( destination, name ); | ||||
} | } | ||||
protected Class getInfoClass() | |||||
{ | |||||
return ConverterInfo.class; | |||||
} | |||||
} | } |
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to byte converter | * String to byte converter | ||||
@@ -22,7 +23,7 @@ public class StringToByteConverter | |||||
super( String.class, Byte.class ); | super( String.class, Byte.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Byte( (String)original ); | return new Byte( (String)original ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to class converter | * String to class converter | ||||
@@ -22,7 +23,7 @@ public class StringToClassConverter | |||||
super( String.class, Class.class ); | super( String.class, Class.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return Class.forName( (String)original ); | return Class.forName( (String)original ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to double converter | * String to double converter | ||||
@@ -22,7 +23,7 @@ public class StringToDoubleConverter | |||||
super( String.class, Double.class ); | super( String.class, Double.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Double( (String)original ); | return new Double( (String)original ); | ||||
@@ -0,0 +1,35 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant.convert.core; | |||||
import java.io.File; | |||||
import org.apache.ant.convert.AbstractConverter; | |||||
import org.apache.ant.tasklet.TaskletContext; | |||||
import org.apache.avalon.Context; | |||||
/** | |||||
* String to file converter | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class StringToFileConverter | |||||
extends AbstractConverter | |||||
{ | |||||
public StringToFileConverter() | |||||
{ | |||||
super( String.class, File.class ); | |||||
} | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | |||||
{ | |||||
final TaskletContext taskletContext = (TaskletContext)context; | |||||
return taskletContext.resolveFile( (String)original ); | |||||
} | |||||
} | |||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to float converter | * String to float converter | ||||
@@ -22,7 +23,7 @@ public class StringToFloatConverter | |||||
super( String.class, Float.class ); | super( String.class, Float.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Float( (String)original ); | return new Float( (String)original ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to integer converter. | * String to integer converter. | ||||
@@ -22,7 +23,7 @@ public class StringToIntegerConverter | |||||
super( String.class, Integer.class ); | super( String.class, Integer.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Integer( (String)original ); | return new Integer( (String)original ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to long converter | * String to long converter | ||||
@@ -22,7 +23,7 @@ public class StringToLongConverter | |||||
super( String.class, Long.class ); | super( String.class, Long.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Long( (String)original ); | return new Long( (String)original ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.convert.core; | package org.apache.ant.convert.core; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to short converter | * String to short converter | ||||
@@ -22,7 +23,7 @@ public class StringToShortConverter | |||||
super( String.class, Short.class ); | super( String.class, Short.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new Short( (String)original ); | return new Short( (String)original ); | ||||
@@ -9,6 +9,7 @@ package org.apache.ant.convert.core; | |||||
import java.net.URL; | import java.net.URL; | ||||
import org.apache.ant.convert.AbstractConverter; | import org.apache.ant.convert.AbstractConverter; | ||||
import org.apache.avalon.Context; | |||||
/** | /** | ||||
* String to url converter | * String to url converter | ||||
@@ -23,7 +24,7 @@ public class StringToURLConverter | |||||
super( String.class, URL.class ); | super( String.class, URL.class ); | ||||
} | } | ||||
public Object convert( final Object original ) | |||||
public Object convert( final Object original, final Context context ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
return new URL( (String)original ); | return new URL( (String)original ); | ||||
@@ -13,11 +13,31 @@ import org.apache.avalon.camelot.FactoryException; | |||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
/** | |||||
* This is basically a engine that can be used to access data-types. | |||||
* The engine acts as a repository and factory for these types. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface DataTypeEngine | public interface DataTypeEngine | ||||
extends Component, Loggable | |||||
extends Component | |||||
{ | { | ||||
/** | |||||
* Retrieve registry of data-types. | |||||
* This is used by deployer to add types into engine. | |||||
* | |||||
* @return the registry | |||||
*/ | |||||
LocatorRegistry getRegistry(); | LocatorRegistry getRegistry(); | ||||
/** | |||||
* Create a data-type of type registered under name. | |||||
* | |||||
* @param name the name of data type | |||||
* @return the DataType | |||||
* @exception RegistryException if an error occurs | |||||
* @exception FactoryException if an error occurs | |||||
*/ | |||||
DataType createDataType( String name ) | DataType createDataType( String name ) | ||||
throws RegistryException, FactoryException; | throws RegistryException, FactoryException; | ||||
} | } |
@@ -7,65 +7,62 @@ | |||||
*/ | */ | ||||
package org.apache.ant.datatypes; | package org.apache.ant.datatypes; | ||||
import org.apache.ant.AntException; | |||||
import org.apache.avalon.Initializable; | |||||
import org.apache.avalon.Loggable; | |||||
import org.apache.avalon.camelot.DefaultFactory; | |||||
import org.apache.avalon.Composer; | |||||
import org.apache.avalon.ComponentManager; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | |||||
import org.apache.avalon.camelot.DefaultLocatorRegistry; | import org.apache.avalon.camelot.DefaultLocatorRegistry; | ||||
import org.apache.avalon.camelot.Factory; | |||||
import org.apache.avalon.camelot.FactoryException; | |||||
import org.apache.avalon.camelot.Locator; | import org.apache.avalon.camelot.Locator; | ||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
import org.apache.avalon.camelot.FactoryException; | |||||
import org.apache.log.Logger; | |||||
/** | |||||
* This is basically a engine that can be used to access data-types. | |||||
* The engine acts as a repository and factory for these types. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultDataTypeEngine | public class DefaultDataTypeEngine | ||||
implements DataTypeEngine, Initializable | |||||
implements DataTypeEngine, Composer | |||||
{ | { | ||||
protected DefaultFactory m_factory; | |||||
protected LocatorRegistry m_registry; | |||||
protected Logger m_logger; | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
protected Factory m_factory; | |||||
protected LocatorRegistry m_registry = new DefaultLocatorRegistry(); | |||||
/** | |||||
* Retrieve registry of data-types. | |||||
* This is used by deployer to add types into engine. | |||||
* | |||||
* @return the registry | |||||
*/ | |||||
public LocatorRegistry getRegistry() | public LocatorRegistry getRegistry() | ||||
{ | { | ||||
return m_registry; | return m_registry; | ||||
} | } | ||||
public void init() | |||||
throws Exception | |||||
{ | |||||
m_registry = createRegistry(); | |||||
setupComponent( m_registry ); | |||||
m_factory = createFactory(); | |||||
setupComponent( m_factory ); | |||||
} | |||||
protected void setupComponent( final Object object ) | |||||
throws Exception | |||||
{ | |||||
if( object instanceof Loggable ) | |||||
{ | |||||
((Loggable)object).setLogger( m_logger ); | |||||
} | |||||
} | |||||
protected LocatorRegistry createRegistry() | |||||
{ | |||||
return new DefaultLocatorRegistry(); | |||||
} | |||||
protected DefaultFactory createFactory() | |||||
/** | |||||
* Retrieve relevent services needed to deploy. | |||||
* | |||||
* @param componentManager the ComponentManager | |||||
* @exception ComponentManagerException if an error occurs | |||||
*/ | |||||
public void compose( final ComponentManager componentManager ) | |||||
throws ComponentManagerException | |||||
{ | { | ||||
return new DefaultFactory(); | |||||
m_factory = (Factory)componentManager.lookup( "org.apache.avalon.camelot.Factory" ); | |||||
} | } | ||||
/** | |||||
* Create a data-type of type registered under name. | |||||
* | |||||
* @param name the name of data type | |||||
* @return the DataType | |||||
* @exception RegistryException if an error occurs | |||||
* @exception FactoryException if an error occurs | |||||
*/ | |||||
public DataType createDataType( final String name ) | public DataType createDataType( final String name ) | ||||
throws RegistryException, FactoryException | |||||
throws RegistryException, FactoryException | |||||
{ | { | ||||
final Locator locator = m_registry.getLocator( name ); | final Locator locator = m_registry.getLocator( name ); | ||||
return (DataType)m_factory.create( locator, DataType.class ); | return (DataType)m_factory.create( locator, DataType.class ); | ||||
@@ -8,6 +8,7 @@ | |||||
package org.apache.ant.datatypes; | package org.apache.ant.datatypes; | ||||
import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
import org.apache.ant.util.Condition; | |||||
/** | /** | ||||
* Basic data type for holding patterns. | * Basic data type for holding patterns. | ||||
@@ -20,21 +21,43 @@ public class Pattern | |||||
protected String m_name; | protected String m_name; | ||||
protected Condition m_condition; | protected Condition m_condition; | ||||
/** | |||||
* Retrieve name (aka value) of pattern. | |||||
* | |||||
* @return the name/value of pattern | |||||
*/ | |||||
public String getName() | public String getName() | ||||
{ | { | ||||
return m_name; | return m_name; | ||||
} | } | ||||
/** | |||||
* Get condition associated with pattern if any. | |||||
* | |||||
* @return the Condition | |||||
*/ | |||||
public Condition getCondition() | public Condition getCondition() | ||||
{ | { | ||||
return m_condition; | return m_condition; | ||||
} | } | ||||
/** | |||||
* Setter method for name/value of pattern. | |||||
* Conforms to ant setter patterns | |||||
* | |||||
* @param name the value | |||||
*/ | |||||
public void setName( final String name ) | public void setName( final String name ) | ||||
{ | { | ||||
m_name = name; | m_name = name; | ||||
} | } | ||||
/** | |||||
* Set if clause on pattern. | |||||
* | |||||
* @param condition the condition | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public void setIf( final String condition ) | public void setIf( final String condition ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
@@ -42,6 +65,12 @@ public class Pattern | |||||
m_condition = new Condition( true, condition ); | m_condition = new Condition( true, condition ); | ||||
} | } | ||||
/** | |||||
* Set unless clause of pattern. | |||||
* | |||||
* @param condition the unless clause | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public void setUnless( final String condition ) | public void setUnless( final String condition ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
@@ -49,6 +78,12 @@ public class Pattern | |||||
m_condition = new Condition( false, condition ); | m_condition = new Condition( false, condition ); | ||||
} | } | ||||
/** | |||||
* Utility method to make sure condition unset. | |||||
* Made so that it is not possible for both if and unless to be set. | |||||
* | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected void verifyConditionNull() | protected void verifyConditionNull() | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
@@ -0,0 +1,56 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant.launcher; | |||||
import java.io.File; | |||||
import java.lang.reflect.Method; | |||||
import java.net.URL; | |||||
import java.net.URLClassLoader; | |||||
import java.util.StringTokenizer; | |||||
/** | |||||
* Basic classloader that allows modification at runtime. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public final class AntClassLoader | |||||
extends URLClassLoader | |||||
{ | |||||
/** | |||||
* Basic constructor. | |||||
* | |||||
* @param urls the Starting URLS | |||||
*/ | |||||
public AntClassLoader( final URL[] urls ) | |||||
{ | |||||
super( urls ); | |||||
} | |||||
/** | |||||
* Add a URL to classloader | |||||
* | |||||
* @param url the url | |||||
*/ | |||||
public void addURL( final URL url ) | |||||
{ | |||||
super.addURL( url ); | |||||
} | |||||
/** | |||||
* Add an array of URLs to classloader | |||||
* | |||||
* @param url the url | |||||
*/ | |||||
public void addURLs( final URL[] urls ) | |||||
{ | |||||
for( int i = 0; i < urls.length; i++ ) | |||||
{ | |||||
addURL( urls[ i ] ); | |||||
} | |||||
} | |||||
} |
@@ -7,31 +7,22 @@ | |||||
*/ | */ | ||||
package org.apache.ant.launcher; | package org.apache.ant.launcher; | ||||
import java.io.File; | |||||
import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
import java.lang.reflect.InvocationTargetException; | |||||
import java.net.URL; | import java.net.URL; | ||||
import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||
import java.util.StringTokenizer; | |||||
/** | /** | ||||
* Basic Loader that is responsible for all the hackery to get classloader to work. | * 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. | * 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> | ||||
* @author <a href="mailto:mpfoemme@thoughtworks.com">Matthew Foemmel</a> | |||||
*/ | */ | ||||
public final class AntLoader | public final class AntLoader | ||||
extends URLClassLoader | |||||
{ | { | ||||
protected static AntLoader c_classLoader; | |||||
public static AntLoader getLoader() | |||||
{ | |||||
if( null == c_classLoader ) | |||||
{ | |||||
c_classLoader = new AntLoader( new URL[ 0 ] ); | |||||
} | |||||
return c_classLoader; | |||||
} | |||||
/** | /** | ||||
* Magic entry point. | * Magic entry point. | ||||
* | * | ||||
@@ -40,42 +31,67 @@ public final class AntLoader | |||||
*/ | */ | ||||
public final static void main( final String[] args ) | public final static void main( final String[] args ) | ||||
throws Exception | throws Exception | ||||
{ | |||||
final URL archive = new URL( "file:lib/myrmidon.jar" ); | |||||
c_classLoader = new AntLoader( new URL[] { archive } ); | |||||
{ | |||||
try | try | ||||
{ | { | ||||
//actually try to discover the install directory based on where | |||||
// the ant.jar is | |||||
final File installDirectory = findInstallDir(); | |||||
System.setProperty( "ant.home", installDirectory.toString() ); | |||||
//setup classloader appropriately for myrmidon jar | |||||
final File archive = | |||||
new File( installDirectory, "lib" + File.separator + "myrmidon.jar" ); | |||||
final AntClassLoader classLoader = | |||||
new AntClassLoader( new URL[] { archive.toURL() } ); | |||||
//load class and retrieve appropriate main method. | //load class and retrieve appropriate main method. | ||||
final Class clazz = c_classLoader.loadClass( "org.apache.ant.Main" ); | |||||
final Class clazz = classLoader.loadClass( "org.apache.ant.Main" ); | |||||
final Method method = clazz.getMethod( "main", new Class[] { args.getClass() } ); | final Method method = clazz.getMethod( "main", new Class[] { args.getClass() } ); | ||||
//kick the tires and light the fires.... | //kick the tires and light the fires.... | ||||
method.invoke( null, new Object[] { args } ); | method.invoke( null, new Object[] { args } ); | ||||
} | } | ||||
catch( final InvocationTargetException ite ) | |||||
{ | |||||
System.err.println( "Error: " + ite.getTargetException().getMessage() ); | |||||
ite.getTargetException().printStackTrace(); | |||||
} | |||||
catch( final Throwable throwable ) | catch( final Throwable throwable ) | ||||
{ | { | ||||
System.err.println( "Error: " + throwable.getMessage() ); | |||||
throwable.printStackTrace(); | throwable.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Basic constructor. | |||||
* | |||||
* @param urls the Starting URLS | |||||
* Finds the ant.jar file in the classpath. | |||||
*/ | */ | ||||
public AntLoader( final URL[] urls ) | |||||
protected final static File findInstallDir() | |||||
throws Exception | |||||
{ | { | ||||
super( urls ); | |||||
} | |||||
final String classpath = System.getProperty( "java.class.path" ); | |||||
final String pathSeparator = System.getProperty( "path.separator" ); | |||||
final StringTokenizer tokenizer = new StringTokenizer( classpath, pathSeparator ); | |||||
while( tokenizer.hasMoreTokens() ) | |||||
{ | |||||
final String element = tokenizer.nextToken(); | |||||
/** | |||||
* Add a URL to classloader | |||||
* | |||||
* @param url the url | |||||
*/ | |||||
public void addURL( final URL url ) | |||||
{ | |||||
super.addURL( url ); | |||||
if( element.endsWith( "ant.jar" ) ) | |||||
{ | |||||
File file = (new File( element )).getAbsoluteFile(); | |||||
file = file.getParentFile(); | |||||
if( null != file ) | |||||
{ | |||||
file = file.getParentFile(); | |||||
} | |||||
return file; | |||||
} | |||||
} | |||||
throw new Exception( "Unable to locate ant.jar in classpath" ); | |||||
} | } | ||||
} | } |
@@ -16,6 +16,11 @@ import org.apache.ant.AntException; | |||||
import org.apache.ant.tasklet.DefaultTaskletContext; | import org.apache.ant.tasklet.DefaultTaskletContext; | ||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
/** | |||||
* Default project implementation. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultProject | public class DefaultProject | ||||
implements Project | implements Project | ||||
{ | { | ||||
@@ -23,42 +28,87 @@ public class DefaultProject | |||||
protected final HashMap m_targets = new HashMap(); | protected final HashMap m_targets = new HashMap(); | ||||
protected Target m_implicitTarget; | protected Target m_implicitTarget; | ||||
protected String m_defaultTarget; | protected String m_defaultTarget; | ||||
/** | |||||
* Retrieve implicit target. | |||||
* The implicit target is top level tasks. | |||||
* Currently restricted to property tasks. | |||||
* | |||||
* @return the Target | |||||
*/ | |||||
public Target getImplicitTarget() | public Target getImplicitTarget() | ||||
{ | { | ||||
return m_implicitTarget; | return m_implicitTarget; | ||||
} | } | ||||
/** | |||||
* Set ImplicitTarget. | |||||
* | |||||
* @param target the implicit target | |||||
*/ | |||||
public void setImplicitTarget( final Target target ) | public void setImplicitTarget( final Target target ) | ||||
{ | { | ||||
m_implicitTarget = target; | m_implicitTarget = target; | ||||
} | } | ||||
/** | |||||
* Retrieve a target by name. | |||||
* | |||||
* @param name the name of target | |||||
* @return the Target or null if no target exists with name | |||||
*/ | |||||
public Target getTarget( final String targetName ) | public Target getTarget( final String targetName ) | ||||
{ | { | ||||
return (Target)m_targets.get( targetName ); | return (Target)m_targets.get( targetName ); | ||||
} | } | ||||
/** | |||||
* Get name of default target. | |||||
* | |||||
* @return the default target name | |||||
*/ | |||||
public String getDefaultTargetName() | public String getDefaultTargetName() | ||||
{ | { | ||||
return m_defaultTarget; | return m_defaultTarget; | ||||
} | } | ||||
/** | |||||
* Retrieve names of all targets in project. | |||||
* | |||||
* @return the iterator of project names | |||||
*/ | |||||
public Iterator getTargetNames() | public Iterator getTargetNames() | ||||
{ | { | ||||
return m_targets.keySet().iterator(); | return m_targets.keySet().iterator(); | ||||
} | } | ||||
/** | |||||
* Get project (top-level) context. | |||||
* | |||||
* @return the context | |||||
*/ | |||||
public TaskletContext getContext() | public TaskletContext getContext() | ||||
{ | { | ||||
return m_baseContext; | return m_baseContext; | ||||
} | } | ||||
/** | |||||
* Set DefaultTargetName. | |||||
* | |||||
* @param defaultTarget the default target name | |||||
*/ | |||||
public void setDefaultTargetName( final String defaultTarget ) | public void setDefaultTargetName( final String defaultTarget ) | ||||
{ | { | ||||
m_defaultTarget = defaultTarget; | m_defaultTarget = defaultTarget; | ||||
} | } | ||||
/** | |||||
* Add a target to project. | |||||
* | |||||
* @param name the name of target | |||||
* @param target the Target | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public void addTarget( final String name, final Target target ) | public void addTarget( final String name, final Target target ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
@@ -13,54 +13,87 @@ import java.util.Iterator; | |||||
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.configuration.ConfigurationBuilder; | import org.apache.ant.configuration.ConfigurationBuilder; | ||||
import org.apache.ant.datatypes.Condition; | |||||
import org.apache.ant.util.Condition; | |||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.ConfigurationException; | import org.apache.avalon.ConfigurationException; | ||||
import org.apache.avalon.util.StringUtil; | |||||
import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
import org.xml.sax.InputSource; | import org.xml.sax.InputSource; | ||||
import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
/** | |||||
* Default implementation to construct project from a build file. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultProjectBuilder | public class DefaultProjectBuilder | ||||
extends AbstractLoggable | |||||
implements ProjectBuilder | implements ProjectBuilder | ||||
{ | { | ||||
protected final ConfigurationBuilder m_configurationBuilder; | |||||
protected Logger m_logger; | |||||
protected ConfigurationBuilder m_builder; | |||||
public DefaultProjectBuilder() | public DefaultProjectBuilder() | ||||
{ | { | ||||
ConfigurationBuilder builder = null; | |||||
try { builder = new ConfigurationBuilder(); } | |||||
catch( final SAXException se ) {} | |||||
m_configurationBuilder = builder; | |||||
} | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
m_builder = new ConfigurationBuilder(); | |||||
} | } | ||||
/** | |||||
* build a project from file. | |||||
* | |||||
* @param source the source | |||||
* @return the constructed Project | |||||
* @exception IOException if an error occurs | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public Project build( final File projectFile ) | public Project build( final File projectFile ) | ||||
throws IOException, AntException | throws IOException, AntException | ||||
{ | { | ||||
try | try | ||||
{ | { | ||||
final String location = projectFile.getCanonicalFile().toURL().toString(); | |||||
final InputSource inputSource = new InputSource( location ); | |||||
final Configuration configuration = | |||||
(Configuration)m_configurationBuilder.build( inputSource ); | |||||
final String location = projectFile.getCanonicalFile().toString(); | |||||
final Configuration configuration = buildConfiguration( location ); | |||||
return build( projectFile, configuration ); | return build( projectFile, configuration ); | ||||
} | } | ||||
catch( final SAXException se ) | |||||
{ | |||||
throw new AntException( "SAXEception: " + se.getMessage(), se ); | |||||
} | |||||
catch( final ConfigurationException ce ) | catch( final ConfigurationException ce ) | ||||
{ | { | ||||
throw new AntException( "ConfigurationException: " + ce.getMessage(), ce ); | throw new AntException( "ConfigurationException: " + ce.getMessage(), ce ); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Utility method to build a Configuration tree from a source. | |||||
* Overide this in sub-classes if you want to provide extra | |||||
* functionality (ie xslt/css). | |||||
* | |||||
* @param location the location | |||||
* @return the created Configuration | |||||
* @exception AntException if an error occurs | |||||
* @exception IOException if an error occurs | |||||
*/ | |||||
protected Configuration buildConfiguration( final String location ) | |||||
throws AntException, IOException, ConfigurationException | |||||
{ | |||||
try | |||||
{ | |||||
return (Configuration)m_builder.build( location ); | |||||
} | |||||
catch( final SAXException se ) | |||||
{ | |||||
throw new AntException( "SAXEception: " + se.getMessage(), se ); | |||||
} | |||||
} | |||||
/** | |||||
* build project from configuration. | |||||
* | |||||
* @param file the file from which configuration was loaded | |||||
* @param configuration the configuration loaded | |||||
* @return the created Project | |||||
* @exception IOException if an error occurs | |||||
* @exception AntException if an error occurs | |||||
* @exception ConfigurationException if an error occurs | |||||
*/ | |||||
protected Project build( final File file, final Configuration configuration ) | protected Project build( final File file, final Configuration configuration ) | ||||
throws IOException, AntException, ConfigurationException | throws IOException, AntException, ConfigurationException | ||||
{ | { | ||||
@@ -68,29 +101,41 @@ public class DefaultProjectBuilder | |||||
{ | { | ||||
throw new AntException( "Project file must be enclosed in project element" ); | throw new AntException( "Project file must be enclosed in project element" ); | ||||
} | } | ||||
//get project-level attributes | |||||
final String baseDirectoryName = configuration.getAttribute( "basedir" ); | final String baseDirectoryName = configuration.getAttribute( "basedir" ); | ||||
final String defaultTarget = configuration.getAttribute( "default" ); | final String defaultTarget = configuration.getAttribute( "default" ); | ||||
final String projectName = configuration.getAttribute( "name" ); | final String projectName = configuration.getAttribute( "name" ); | ||||
final DefaultProject project = new DefaultProject(); | |||||
project.setDefaultTargetName( defaultTarget ); | |||||
//determine base directory for project | |||||
final File baseDirectory = | final File baseDirectory = | ||||
(new File( file.getParentFile(), baseDirectoryName )).getAbsoluteFile(); | (new File( file.getParentFile(), baseDirectoryName )).getAbsoluteFile(); | ||||
m_logger.debug( "Project " + projectName + " base directory: " + baseDirectory ); | |||||
getLogger().debug( "Project " + projectName + " base directory: " + baseDirectory ); | |||||
//create project and ... | |||||
final DefaultProject project = new DefaultProject(); | |||||
project.setDefaultTargetName( defaultTarget ); | |||||
//setup basic context of project | |||||
final TaskletContext context = project.getContext(); | final TaskletContext context = project.getContext(); | ||||
context.setProperty( TaskletContext.BASE_DIRECTORY, baseDirectory ); | context.setProperty( TaskletContext.BASE_DIRECTORY, baseDirectory ); | ||||
context.setProperty( Project.PROJECT_FILE, file ); | context.setProperty( Project.PROJECT_FILE, file ); | ||||
context.setProperty( Project.PROJECT, projectName ); | context.setProperty( Project.PROJECT, projectName ); | ||||
//build using all top-level attributes | |||||
buildTopLevelProject( project, configuration ); | buildTopLevelProject( project, configuration ); | ||||
return project; | return project; | ||||
} | } | ||||
/** | |||||
* Handle all top level elements in configuration. | |||||
* | |||||
* @param project the project | |||||
* @param configuration the Configuration | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected void buildTopLevelProject( final DefaultProject project, | protected void buildTopLevelProject( final DefaultProject project, | ||||
final Configuration configuration ) | final Configuration configuration ) | ||||
throws AntException | throws AntException | ||||
@@ -102,8 +147,9 @@ public class DefaultProjectBuilder | |||||
final Configuration element = (Configuration)elements.next(); | final Configuration element = (Configuration)elements.next(); | ||||
final String name = element.getName(); | final String name = element.getName(); | ||||
//handle individual elements | |||||
if( name.equals( "target" ) ) buildTarget( project, element ); | if( name.equals( "target" ) ) buildTarget( project, element ); | ||||
else if( name.equals( "property" ) ) buildProperty( project, element ); | |||||
else if( name.equals( "property" ) ) buildImplicitTask( project, element ); | |||||
else | else | ||||
{ | { | ||||
throw new AntException( "Unknown top-level element " + name + | throw new AntException( "Unknown top-level element " + name + | ||||
@@ -112,95 +158,88 @@ public class DefaultProjectBuilder | |||||
} | } | ||||
} | } | ||||
protected void buildTarget( final DefaultProject project, | |||||
final Configuration configuration ) | |||||
/** | |||||
* Build a target from configuration. | |||||
* | |||||
* @param project the project | |||||
* @param task the Configuration | |||||
*/ | |||||
protected void buildTarget( final DefaultProject project, final Configuration target ) | |||||
{ | { | ||||
final String name = configuration.getAttribute( "name", null ); | |||||
final String depends = configuration.getAttribute( "depends", null ); | |||||
final String ifCondition = configuration.getAttribute( "if", null ); | |||||
final String unlessCondition = configuration.getAttribute( "unless", null ); | |||||
final String name = target.getAttribute( "name", null ); | |||||
final String depends = target.getAttribute( "depends", null ); | |||||
final String ifCondition = target.getAttribute( "if", null ); | |||||
final String unlessCondition = target.getAttribute( "unless", null ); | |||||
if( null == name ) | if( null == name ) | ||||
{ | { | ||||
throw new AntException( "Discovered un-named target at " + | throw new AntException( "Discovered un-named target at " + | ||||
configuration.getLocation() ); | |||||
target.getLocation() ); | |||||
} | } | ||||
m_logger.debug( "Parsing target: " + name ); | |||||
getLogger().debug( "Parsing target: " + name ); | |||||
if( null != ifCondition && null != unlessCondition ) | if( null != ifCondition && null != unlessCondition ) | ||||
{ | { | ||||
throw new AntException( "Discovered invalid target that has both a if and " + | throw new AntException( "Discovered invalid target that has both a if and " + | ||||
"unless condition at " + configuration.getLocation() ); | |||||
"unless condition at " + target.getLocation() ); | |||||
} | } | ||||
Condition condition = null; | Condition condition = null; | ||||
if( null != ifCondition ) | if( null != ifCondition ) | ||||
{ | { | ||||
m_logger.debug( "Target if condition: " + ifCondition ); | |||||
getLogger().debug( "Target if condition: " + ifCondition ); | |||||
condition = new Condition( true, ifCondition ); | condition = new Condition( true, ifCondition ); | ||||
} | } | ||||
else if( null != unlessCondition ) | else if( null != unlessCondition ) | ||||
{ | { | ||||
m_logger.debug( "Target unless condition: " + unlessCondition ); | |||||
getLogger().debug( "Target unless condition: " + unlessCondition ); | |||||
condition = new Condition( false, unlessCondition ); | condition = new Condition( false, unlessCondition ); | ||||
} | } | ||||
final DefaultTarget target = new DefaultTarget( condition ); | |||||
final DefaultTarget defaultTarget = new DefaultTarget( condition ); | |||||
//apply depends attribute | |||||
if( null != depends ) | if( null != depends ) | ||||
{ | { | ||||
int start = 0; | |||||
int end = depends.indexOf( ',' ); | |||||
final String[] elements = StringUtil.splitString( depends, "," ); | |||||
while( -1 != end ) | |||||
for( int i = 0; i < elements.length; i++ ) | |||||
{ | { | ||||
final String dependency = | |||||
parseDependency( configuration, depends.substring( start, end ) ); | |||||
target.addDependency( dependency ); | |||||
start = end++; | |||||
end = depends.indexOf( ',', start ); | |||||
} | |||||
final String dependency = elements[ i ].trim(); | |||||
final String dependency = | |||||
parseDependency( configuration, depends.substring( start ) ); | |||||
if( 0 == dependency.length() ) | |||||
{ | |||||
throw new AntException( "Discovered empty dependency in target " + | |||||
target.getName() + " at " + target.getLocation() ); | |||||
} | |||||
target.addDependency( dependency ); | |||||
getLogger().debug( "Target dependency: " + dependency ); | |||||
defaultTarget.addDependency( dependency ); | |||||
} | |||||
} | } | ||||
final Iterator tasks = configuration.getChildren(); | |||||
//add all the targets from element | |||||
final Iterator tasks = target.getChildren(); | |||||
while( tasks.hasNext() ) | while( tasks.hasNext() ) | ||||
{ | { | ||||
final Configuration task = (Configuration)tasks.next(); | final Configuration task = (Configuration)tasks.next(); | ||||
m_logger.debug( "Parsed task: " + task.getName() ); | |||||
target.addTask( task ); | |||||
} | |||||
project.addTarget( name, target ); | |||||
} | |||||
protected String parseDependency( final Configuration configuration, | |||||
String dependency ) | |||||
throws AntException | |||||
{ | |||||
dependency = dependency.trim(); | |||||
if( 0 == dependency.length() ) | |||||
{ | |||||
throw new AntException( "Discovered empty dependency in target " + | |||||
configuration.getName() + " at " + | |||||
configuration.getLocation() ); | |||||
getLogger().debug( "Parsed task: " + task.getName() ); | |||||
defaultTarget.addTask( task ); | |||||
} | } | ||||
m_logger.debug( "Target dependency: " + dependency ); | |||||
return dependency; | |||||
//add target to project | |||||
project.addTarget( name, defaultTarget ); | |||||
} | } | ||||
protected void buildProperty( final DefaultProject project, | |||||
final Configuration configuration ) | |||||
/** | |||||
* Create an implict task from configuration | |||||
* | |||||
* @param project the project | |||||
* @param task the configuration | |||||
*/ | |||||
protected void buildImplicitTask( final DefaultProject project, final Configuration task ) | |||||
{ | { | ||||
DefaultTarget target = (DefaultTarget)project.getImplicitTarget(); | DefaultTarget target = (DefaultTarget)project.getImplicitTarget(); | ||||
@@ -210,7 +249,7 @@ public class DefaultProjectBuilder | |||||
project.setImplicitTarget( target ); | project.setImplicitTarget( target ); | ||||
} | } | ||||
m_logger.debug( "Parsed implicit task: " + configuration.getName() ); | |||||
target.addTask( configuration ); | |||||
getLogger().debug( "Parsed implicit task: " + task.getName() ); | |||||
target.addTask( task ); | |||||
} | } | ||||
} | } |
@@ -11,88 +11,80 @@ import java.util.ArrayList; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
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.datatypes.Condition; | |||||
import org.apache.ant.tasklet.DefaultTaskletContext; | import org.apache.ant.tasklet.DefaultTaskletContext; | ||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.ant.tasklet.engine.DefaultTaskletEngine; | import org.apache.ant.tasklet.engine.DefaultTaskletEngine; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.ant.util.Condition; | |||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.ComponentManager; | |||||
import org.apache.avalon.DefaultComponentManager; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
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; | ||||
import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
/** | |||||
* This is the default implementation of ProjectEngine. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultProjectEngine | public class DefaultProjectEngine | ||||
implements ProjectEngine, Initializable, Disposable | |||||
extends AbstractLoggable | |||||
implements ProjectEngine, Composer | |||||
{ | { | ||||
protected TaskletEngine m_taskletEngine; | protected TaskletEngine m_taskletEngine; | ||||
protected Logger m_logger; | |||||
protected ProjectListenerSupport m_listenerSupport; | |||||
protected ProjectListenerSupport m_listenerSupport = new ProjectListenerSupport(); | |||||
protected DefaultComponentManager m_componentManager; | protected DefaultComponentManager m_componentManager; | ||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
/** | |||||
* Add a listener to project events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
public void addProjectListener( final ProjectListener listener ) | public void addProjectListener( final ProjectListener listener ) | ||||
{ | { | ||||
m_listenerSupport.addProjectListener( listener ); | m_listenerSupport.addProjectListener( listener ); | ||||
} | } | ||||
/** | |||||
* Remove a listener from project events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
public void removeProjectListener( final ProjectListener listener ) | public void removeProjectListener( final ProjectListener listener ) | ||||
{ | { | ||||
m_listenerSupport.removeProjectListener( listener ); | m_listenerSupport.removeProjectListener( listener ); | ||||
} | } | ||||
public void init() | |||||
throws Exception | |||||
{ | |||||
m_listenerSupport = new ProjectListenerSupport(); | |||||
setupTaskletEngine(); | |||||
m_componentManager = new DefaultComponentManager(); | |||||
m_componentManager.put( "org.apache.ant.project.ProjectEngine", this ); | |||||
m_componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", m_taskletEngine ); | |||||
m_componentManager.put( "org.apache.ant.convert.ConverterEngine", | |||||
m_taskletEngine.getConverterEngine() ); | |||||
} | |||||
public void dispose() | |||||
throws Exception | |||||
{ | |||||
if( m_taskletEngine instanceof Disposable ) | |||||
{ | |||||
((Disposable)m_taskletEngine).dispose(); | |||||
} | |||||
} | |||||
public TaskletEngine getTaskletEngine() | |||||
/** | |||||
* Retrieve relevent services needed for engine. | |||||
* | |||||
* @param componentManager the ComponentManager | |||||
* @exception ComponentManagerException if an error occurs | |||||
*/ | |||||
public void compose( final ComponentManager componentManager ) | |||||
throws ComponentManagerException | |||||
{ | { | ||||
return m_taskletEngine; | |||||
m_componentManager = (DefaultComponentManager)componentManager; | |||||
m_taskletEngine = (TaskletEngine)componentManager. | |||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | |||||
} | } | ||||
protected void setupTaskletEngine() | |||||
throws Exception | |||||
{ | |||||
m_taskletEngine = createTaskletEngine(); | |||||
m_taskletEngine.setLogger( m_logger ); | |||||
if( m_taskletEngine instanceof Initializable ) | |||||
{ | |||||
((Initializable)m_taskletEngine).init(); | |||||
} | |||||
} | |||||
protected TaskletEngine createTaskletEngine() | |||||
{ | |||||
return new DefaultTaskletEngine(); | |||||
} | |||||
/** | |||||
* Execute a target in a particular project. | |||||
* Execute in the project context. | |||||
* | |||||
* @param project the Project | |||||
* @param target the name of the target | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public void execute( final Project project, final String target ) | public void execute( final Project project, final String target ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
//HACK: should do this a better way !!!!!! | |||||
m_componentManager.put( "org.apache.ant.project.Project", project ); | m_componentManager.put( "org.apache.ant.project.Project", project ); | ||||
final TaskletContext context = project.getContext(); | final TaskletContext context = project.getContext(); | ||||
@@ -110,12 +102,29 @@ public class DefaultProjectEngine | |||||
m_listenerSupport.projectFinished(); | m_listenerSupport.projectFinished(); | ||||
} | } | ||||
/** | |||||
* Execute a target in a particular project, in a particular context. | |||||
* | |||||
* @param project the Project | |||||
* @param target the name of the target | |||||
* @param context the context | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
public void execute( Project project, String target, TaskletContext context ) | public void execute( Project project, String target, TaskletContext context ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
execute( project, target, context, new ArrayList() ); | execute( project, target, context, new ArrayList() ); | ||||
} | } | ||||
/** | |||||
* Helper method to execute a target. | |||||
* | |||||
* @param project the Project | |||||
* @param target the name of the target | |||||
* @param context the context | |||||
* @param done the list of targets already executed in current run | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected void execute( final Project project, | protected void execute( final Project project, | ||||
final String targetName, | final String targetName, | ||||
final TaskletContext context, | final TaskletContext context, | ||||
@@ -128,9 +137,11 @@ public class DefaultProjectEngine | |||||
{ | { | ||||
throw new AntException( "Unable to find target " + targetName ); | throw new AntException( "Unable to find target " + targetName ); | ||||
} | } | ||||
//add target to list of targets executed | |||||
done.add( targetName ); | done.add( targetName ); | ||||
//execute all dependencies | |||||
final Iterator dependencies = target.getDependencies(); | final Iterator dependencies = target.getDependencies(); | ||||
while( dependencies.hasNext() ) | while( dependencies.hasNext() ) | ||||
{ | { | ||||
@@ -144,41 +155,65 @@ public class DefaultProjectEngine | |||||
executeTarget( targetName, target, context ); | executeTarget( targetName, target, context ); | ||||
} | } | ||||
/** | |||||
* Method to execute a particular target instance. | |||||
* | |||||
* @param targetName the name of target | |||||
* @param target the target | |||||
* @param context the context in which to execute | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected void executeTarget( final String targetName, | protected void executeTarget( final String targetName, | ||||
final Target target, | final Target target, | ||||
final TaskletContext context ) | final TaskletContext context ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
m_componentManager.put( "org.apache.ant.project.Target", target ); | |||||
//is this necessary ? I think not but .... | |||||
// NO it isn't because you set target name and project has already been provided | |||||
//m_componentManager.put( "org.apache.ant.project.Target", target ); | |||||
//create project context and set target name | |||||
final TaskletContext targetContext = new DefaultTaskletContext( context ); | final TaskletContext targetContext = new DefaultTaskletContext( context ); | ||||
targetContext.setProperty( Project.TARGET, targetName ); | targetContext.setProperty( Project.TARGET, targetName ); | ||||
//notify listeners | |||||
m_listenerSupport.targetStarted( targetName ); | m_listenerSupport.targetStarted( targetName ); | ||||
//actually do the execution work | |||||
executeTargetWork( targetName, target, targetContext ); | executeTargetWork( targetName, target, targetContext ); | ||||
//notify listeners | |||||
m_listenerSupport.targetFinished(); | m_listenerSupport.targetFinished(); | ||||
} | } | ||||
/** | |||||
* Do the work associated with target. | |||||
* ie execute all tasks | |||||
* | |||||
* @param name the name of target | |||||
* @param target the target | |||||
* @param context the context | |||||
*/ | |||||
protected void executeTargetWork( final String name, | protected void executeTargetWork( final String name, | ||||
final Target target, | final Target target, | ||||
final TaskletContext context ) | final TaskletContext context ) | ||||
{ | { | ||||
//check the condition associated with target. | |||||
//if it is not satisfied then skip target | |||||
final Condition condition = target.getCondition(); | final Condition condition = target.getCondition(); | ||||
if( null != condition ) | if( null != condition ) | ||||
{ | { | ||||
if( false == condition.evaluate( context ) ) | if( false == condition.evaluate( context ) ) | ||||
{ | { | ||||
m_logger.debug( "Skipping target " + name + | |||||
" as it does not satisfy condition" ); | |||||
getLogger().debug( "Skipping target " + name + | |||||
" as it does not satisfy condition" ); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
m_logger.debug( "Executing target " + name ); | |||||
getLogger().debug( "Executing target " + name ); | |||||
//execute all tasks assciated with target | |||||
final Iterator tasks = target.getTasks(); | final Iterator tasks = target.getTasks(); | ||||
while( tasks.hasNext() ) | while( tasks.hasNext() ) | ||||
{ | { | ||||
@@ -187,24 +222,32 @@ public class DefaultProjectEngine | |||||
} | } | ||||
} | } | ||||
protected void executeTask( final Configuration configuration, | |||||
final TaskletContext context ) | |||||
/** | |||||
* Execute a task. | |||||
* | |||||
* @param task the task definition | |||||
* @param context the context | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
protected void executeTask( final Configuration task, final TaskletContext context ) | |||||
throws AntException | throws AntException | ||||
{ | { | ||||
final String name = configuration.getName(); | |||||
m_logger.debug( "Executing task " + name ); | |||||
final String name = task.getName(); | |||||
getLogger().debug( "Executing task " + name ); | |||||
//Set up context for task... | //Set up context for task... | ||||
//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 ); | ||||
//is setting name even necessary ??? | |||||
context.setProperty( TaskletContext.NAME, name ); | 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, context, m_componentManager ); | |||||
m_taskletEngine.execute( task, context ); | |||||
//notify listeners task has ended | //notify listeners task has ended | ||||
m_listenerSupport.taskletFinished(); | m_listenerSupport.taskletFinished(); | ||||
@@ -9,49 +9,95 @@ package org.apache.ant.project; | |||||
import org.apache.avalon.util.StringUtil; | import org.apache.avalon.util.StringUtil; | ||||
/** | |||||
* Default listener that emulates the old ant listener notifications. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultProjectListener | public class DefaultProjectListener | ||||
implements ProjectListener | implements ProjectListener | ||||
{ | { | ||||
protected String m_prefix; | protected String m_prefix; | ||||
/** | |||||
* Notify listener of projectStarted event. | |||||
* | |||||
* @param projectName the projectName | |||||
*/ | |||||
public void projectStarted( final String projectName ) | public void projectStarted( final String projectName ) | ||||
{ | { | ||||
output( "Starting project " + projectName + "\n" ); | output( "Starting project " + projectName + "\n" ); | ||||
} | } | ||||
/** | |||||
* Notify listener of projectFinished event. | |||||
*/ | |||||
public void projectFinished() | public void projectFinished() | ||||
{ | { | ||||
} | } | ||||
/** | |||||
* Notify listener of targetStarted event. | |||||
* | |||||
* @param targetName the name of target | |||||
*/ | |||||
public void targetStarted( final String targetName ) | public void targetStarted( final String targetName ) | ||||
{ | { | ||||
output( targetName + ":\n" ); | output( targetName + ":\n" ); | ||||
} | } | ||||
/** | |||||
* Notify listener of targetFinished event. | |||||
*/ | |||||
public void targetFinished() | public void targetFinished() | ||||
{ | { | ||||
} | } | ||||
/** | |||||
* Notify listener of taskletStarted event. | |||||
* | |||||
* @param taskletName the name of tasklet | |||||
*/ | |||||
public void taskletStarted( final String taskletName ) | public void taskletStarted( final String taskletName ) | ||||
{ | { | ||||
m_prefix = taskletName; | m_prefix = taskletName; | ||||
} | } | ||||
/** | |||||
* Notify listener of taskletFinished event. | |||||
*/ | |||||
public void taskletFinished() | public void taskletFinished() | ||||
{ | { | ||||
m_prefix = null; | m_prefix = null; | ||||
} | } | ||||
/** | |||||
* Notify listener of log message event. | |||||
* | |||||
* @param message the message | |||||
*/ | |||||
public void log( String message ) | public void log( String message ) | ||||
{ | { | ||||
output( message ); | output( message ); | ||||
} | } | ||||
/** | |||||
* Notify listener of log message event. | |||||
* | |||||
* @param message the message | |||||
* @param throwable the throwable | |||||
*/ | |||||
public void log( String message, Throwable throwable ) | public void log( String message, Throwable throwable ) | ||||
{ | { | ||||
output( message + "\n" + StringUtil.printStackTrace( throwable, 5, true ) ); | output( message + "\n" + StringUtil.printStackTrace( throwable, 5, true ) ); | ||||
} | } | ||||
/** | |||||
* Utility class to output data. | |||||
* Overide in sub-classes to direct to a different destination. | |||||
* | |||||
* @param data the data | |||||
*/ | |||||
protected void output( final String data ) | protected void output( final String data ) | ||||
{ | { | ||||
if( null != m_prefix ) System.out.println( "\t[" + m_prefix + "] " + data ); | if( null != m_prefix ) System.out.println( "\t[" + m_prefix + "] " + data ); | ||||
@@ -10,8 +10,13 @@ package org.apache.ant.project; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import org.apache.ant.configuration.Configuration; | import org.apache.ant.configuration.Configuration; | ||||
import org.apache.ant.datatypes.Condition; | |||||
import org.apache.ant.util.Condition; | |||||
/** | |||||
* Default implementation of target. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class DefaultTarget | public class DefaultTarget | ||||
implements Target | implements Target | ||||
{ | { | ||||
@@ -19,36 +24,68 @@ public class DefaultTarget | |||||
protected final ArrayList m_tasks = new ArrayList(); | protected final ArrayList m_tasks = new ArrayList(); | ||||
protected final Condition m_condition; | protected final Condition m_condition; | ||||
/** | |||||
* Constructor taking condition for target. | |||||
* | |||||
* @param condition the condition | |||||
*/ | |||||
public DefaultTarget( final Condition condition ) | public DefaultTarget( final Condition condition ) | ||||
{ | { | ||||
m_condition = condition; | m_condition = condition; | ||||
} | } | ||||
/** | |||||
* Constructor for target with no condition. | |||||
*/ | |||||
public DefaultTarget() | public DefaultTarget() | ||||
{ | { | ||||
this( null ); | this( null ); | ||||
} | } | ||||
/** | |||||
* Get condition under which target is executed. | |||||
* | |||||
* @return the condition for target or null | |||||
*/ | |||||
public Condition getCondition() | public Condition getCondition() | ||||
{ | { | ||||
return m_condition; | return m_condition; | ||||
} | } | ||||
/** | |||||
* Get dependencies of target | |||||
* | |||||
* @return the dependency list | |||||
*/ | |||||
public Iterator getDependencies() | public Iterator getDependencies() | ||||
{ | { | ||||
return m_dependencies.iterator(); | return m_dependencies.iterator(); | ||||
} | } | ||||
/** | |||||
* Get tasks in target | |||||
* | |||||
* @return the target list | |||||
*/ | |||||
public Iterator getTasks() | public Iterator getTasks() | ||||
{ | { | ||||
return m_tasks.iterator(); | return m_tasks.iterator(); | ||||
} | } | ||||
/** | |||||
* Add a dependency to target. | |||||
* | |||||
* @param dependency the dependency | |||||
*/ | |||||
public void addDependency( final String dependency ) | public void addDependency( final String dependency ) | ||||
{ | { | ||||
m_dependencies.add( dependency ); | m_dependencies.add( dependency ); | ||||
} | } | ||||
/** | |||||
* Add task to target. | |||||
* | |||||
* @param taskConfiguration the task representation | |||||
*/ | |||||
public void addTask( final Configuration taskConfiguration ) | public void addTask( final Configuration taskConfiguration ) | ||||
{ | { | ||||
m_tasks.add( taskConfiguration ); | m_tasks.add( taskConfiguration ); | ||||
@@ -10,12 +10,21 @@ package org.apache.ant.project; | |||||
import org.apache.log.LogEntry; | import org.apache.log.LogEntry; | ||||
import org.apache.log.LogTarget; | import org.apache.log.LogTarget; | ||||
/** | |||||
* Adapter between Avalon LogKit and Project listener interfaces. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class LogTargetToListenerAdapter | public class LogTargetToListenerAdapter | ||||
implements LogTarget | implements LogTarget | ||||
{ | { | ||||
protected final ProjectListener m_listener; | protected final ProjectListener m_listener; | ||||
/** | |||||
* Constructor taking listener to convert to. | |||||
* | |||||
* @param listener the ProjectListener | |||||
*/ | |||||
public LogTargetToListenerAdapter( final ProjectListener listener ) | public LogTargetToListenerAdapter( final ProjectListener listener ) | ||||
{ | { | ||||
m_listener = listener; | m_listener = listener; | ||||
@@ -12,6 +12,11 @@ import org.apache.ant.AntException; | |||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
/** | |||||
* Interface through which to interact with projects. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface Project | public interface Project | ||||
extends Component | extends Component | ||||
{ | { | ||||
@@ -24,9 +29,41 @@ public interface Project | |||||
// the name of currently executing target | // the name of currently executing target | ||||
String TARGET = "ant.target.name"; | String TARGET = "ant.target.name"; | ||||
/** | |||||
* Get name of default target. | |||||
* | |||||
* @return the default target name | |||||
*/ | |||||
String getDefaultTargetName(); | String getDefaultTargetName(); | ||||
/** | |||||
* Retrieve implicit target. | |||||
* The implicit target is top level tasks. | |||||
* Currently restricted to property tasks. | |||||
* | |||||
* @return the Target | |||||
*/ | |||||
Target getImplicitTarget(); | Target getImplicitTarget(); | ||||
/** | |||||
* Retrieve a target by name. | |||||
* | |||||
* @param name the name of target | |||||
* @return the Target or null if no target exists with name | |||||
*/ | |||||
Target getTarget( String name ); | Target getTarget( String name ); | ||||
/** | |||||
* Retrieve names of all targets in project. | |||||
* | |||||
* @return the iterator of project names | |||||
*/ | |||||
Iterator getTargetNames(); | Iterator getTargetNames(); | ||||
/** | |||||
* Get project (top-level) context. | |||||
* | |||||
* @return the context | |||||
*/ | |||||
TaskletContext getContext(); | TaskletContext getContext(); | ||||
} | } |
@@ -10,13 +10,25 @@ package org.apache.ant.project; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
import org.apache.log.Logger; | |||||
import org.apache.avalon.Component; | |||||
/** | |||||
* Interface implemented by components that build projects from sources. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface ProjectBuilder | public interface ProjectBuilder | ||||
extends Component | |||||
{ | { | ||||
void setLogger( Logger logger ); | |||||
Project build( File projectFile ) | |||||
/** | |||||
* build a project from source. | |||||
* | |||||
* @param source the source | |||||
* @return the constructed Project | |||||
* @exception IOException if an error occurs | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
Project build( File source ) | |||||
throws IOException, AntException; | throws IOException, AntException; | ||||
} | } | ||||
@@ -11,21 +11,50 @@ import org.apache.ant.AntException; | |||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
import org.apache.log.Logger; | |||||
/** | |||||
* This is the interface between ProjectEngine and rest of the system. | |||||
* This is the interface that tasks/frontends must use to interact with | |||||
* project execution. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface ProjectEngine | public interface ProjectEngine | ||||
extends Component | extends Component | ||||
{ | { | ||||
void setLogger( Logger logger ); | |||||
TaskletEngine getTaskletEngine(); | |||||
/** | |||||
* Add a listener to project events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
void addProjectListener( ProjectListener listener ); | void addProjectListener( ProjectListener listener ); | ||||
/** | |||||
* Remove a listener from project events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
void removeProjectListener( ProjectListener listener ); | void removeProjectListener( ProjectListener listener ); | ||||
/** | |||||
* Execute a target in a particular project. | |||||
* Execute in the project context. | |||||
* | |||||
* @param project the Project | |||||
* @param target the name of the target | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
void execute( Project project, String target ) | void execute( Project project, String target ) | ||||
throws AntException; | throws AntException; | ||||
/** | |||||
* Execute a target in a particular project, in a particular context. | |||||
* | |||||
* @param project the Project | |||||
* @param target the name of the target | |||||
* @param context the context | |||||
* @exception AntException if an error occurs | |||||
*/ | |||||
void execute( Project project, String target, TaskletContext context ) | void execute( Project project, String target, TaskletContext context ) | ||||
throws AntException; | throws AntException; | ||||
} | } |
@@ -7,17 +7,62 @@ | |||||
*/ | */ | ||||
package org.apache.ant.project; | package org.apache.ant.project; | ||||
/** | |||||
* The interface to implement if you want to receive | |||||
* notification of project status. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface ProjectListener | public interface ProjectListener | ||||
{ | { | ||||
/** | |||||
* Notify listener of projectStarted event. | |||||
* | |||||
* @param projectName the projectName | |||||
*/ | |||||
void projectStarted( String projectName ); | void projectStarted( String projectName ); | ||||
/** | |||||
* Notify listener of projectFinished event. | |||||
*/ | |||||
void projectFinished(); | void projectFinished(); | ||||
/** | |||||
* Notify listener of targetStarted event. | |||||
* | |||||
* @param targetName the name of target | |||||
*/ | |||||
void targetStarted( String targetName ); | void targetStarted( String targetName ); | ||||
/** | |||||
* Notify listener of targetFinished event. | |||||
*/ | |||||
void targetFinished(); | void targetFinished(); | ||||
/** | |||||
* Notify listener of taskletStarted event. | |||||
* | |||||
* @param taskletName the name of tasklet | |||||
*/ | |||||
void taskletStarted( String taskletName ); | void taskletStarted( String taskletName ); | ||||
/** | |||||
* Notify listener of taskletFinished event. | |||||
*/ | |||||
void taskletFinished(); | void taskletFinished(); | ||||
/** | |||||
* Notify listener of log message event. | |||||
* | |||||
* @param message the message | |||||
*/ | |||||
void log( String message ); | void log( String message ); | ||||
/** | |||||
* Notify listener of log message event. | |||||
* | |||||
* @param message the message | |||||
* @param throwable the throwable | |||||
*/ | |||||
void log( String message, Throwable throwable ); | void log( String message, Throwable throwable ); | ||||
} | } |
@@ -7,11 +7,21 @@ | |||||
*/ | */ | ||||
package org.apache.ant.project; | package org.apache.ant.project; | ||||
/** | |||||
* Support for the project listener event dispatching. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public class ProjectListenerSupport | public class ProjectListenerSupport | ||||
implements ProjectListener | implements ProjectListener | ||||
{ | { | ||||
protected ProjectListener[] m_listeners = new ProjectListener[ 0 ]; | protected ProjectListener[] m_listeners = new ProjectListener[ 0 ]; | ||||
/** | |||||
* Add an extra project listener that wants to receive notification of listener events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
public void addProjectListener( final ProjectListener listener ) | public void addProjectListener( final ProjectListener listener ) | ||||
{ | { | ||||
final ProjectListener[] listeners = new ProjectListener[ m_listeners.length + 1 ]; | final ProjectListener[] listeners = new ProjectListener[ m_listeners.length + 1 ]; | ||||
@@ -20,6 +30,11 @@ public class ProjectListenerSupport | |||||
m_listeners = listeners; | m_listeners = listeners; | ||||
} | } | ||||
/** | |||||
* Remove a project listener that wants to receive notification of listener events. | |||||
* | |||||
* @param listener the listener | |||||
*/ | |||||
public void removeProjectListener( final ProjectListener listener ) | public void removeProjectListener( final ProjectListener listener ) | ||||
{ | { | ||||
int found = -1; | int found = -1; | ||||
@@ -44,6 +59,11 @@ public class ProjectListenerSupport | |||||
m_listeners = listeners; | m_listeners = listeners; | ||||
} | } | ||||
/** | |||||
* Fire a projectStarted event. | |||||
* | |||||
* @param projectName the projectName | |||||
*/ | |||||
public void projectStarted( final String projectName ) | public void projectStarted( final String projectName ) | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -52,6 +72,9 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a projectFinished event. | |||||
*/ | |||||
public void projectFinished() | public void projectFinished() | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -60,6 +83,11 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a targetStarted event. | |||||
* | |||||
* @param targetName the name of target | |||||
*/ | |||||
public void targetStarted( String targetName ) | public void targetStarted( String targetName ) | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -68,6 +96,9 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a targetFinished event. | |||||
*/ | |||||
public void targetFinished() | public void targetFinished() | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -76,6 +107,11 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a targetStarted event. | |||||
* | |||||
* @param targetName the name of target | |||||
*/ | |||||
public void taskletStarted( String taskletName ) | public void taskletStarted( String taskletName ) | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -84,6 +120,9 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a taskletFinished event. | |||||
*/ | |||||
public void taskletFinished() | public void taskletFinished() | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -92,6 +131,11 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a log event. | |||||
* | |||||
* @param message the log message | |||||
*/ | |||||
public void log( String message ) | public void log( String message ) | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -100,6 +144,12 @@ public class ProjectListenerSupport | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Fire a log event. | |||||
* | |||||
* @param message the log message | |||||
* @param throwable the throwable to be logged | |||||
*/ | |||||
public void log( String message, Throwable throwable ) | public void log( String message, Throwable throwable ) | ||||
{ | { | ||||
for( int i = 0; i < m_listeners.length; i++ ) | for( int i = 0; i < m_listeners.length; i++ ) | ||||
@@ -8,14 +8,36 @@ | |||||
package org.apache.ant.project; | package org.apache.ant.project; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import org.apache.ant.util.Condition; | |||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
import org.apache.ant.datatypes.Condition; | |||||
/** | |||||
* Interface to represent targets in build file. | |||||
* | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
*/ | |||||
public interface Target | public interface Target | ||||
extends Component | extends Component | ||||
{ | { | ||||
/** | |||||
* Get dependencies of target | |||||
* | |||||
* @return the dependency list | |||||
*/ | |||||
Iterator getDependencies(); | Iterator getDependencies(); | ||||
/** | |||||
* Get tasks in target | |||||
* | |||||
* @return the target list | |||||
*/ | |||||
Iterator getTasks(); | Iterator getTasks(); | ||||
/** | |||||
* Get condition under which target is executed. | |||||
* | |||||
* @return the condition for target or null | |||||
*/ | |||||
Condition getCondition(); | Condition getCondition(); | ||||
} | } | ||||
@@ -8,9 +8,9 @@ | |||||
package org.apache.ant.tasklet; | package org.apache.ant.tasklet; | ||||
import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.Context; | import org.apache.avalon.Context; | ||||
import org.apache.avalon.Initializable; | import org.apache.avalon.Initializable; | ||||
import org.apache.log.Logger; | |||||
/** | /** | ||||
* This is abstract base class for tasklets. | * This is abstract base class for tasklets. | ||||
@@ -18,23 +18,13 @@ import org.apache.log.Logger; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public abstract class AbstractTasklet | public abstract class AbstractTasklet | ||||
extends AbstractLoggable | |||||
implements Tasklet, Initializable | implements Tasklet, Initializable | ||||
{ | { | ||||
//the user should set this in constructors of sub-classes | //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; | ||||
private Logger m_logger; | |||||
/** | |||||
* Receive logger from container. | |||||
* | |||||
* @param logger the logger | |||||
*/ | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
/** | /** | ||||
* Retrieve context from container. | * Retrieve context from container. | ||||
@@ -79,14 +69,4 @@ public abstract class AbstractTasklet | |||||
{ | { | ||||
return m_context; | return m_context; | ||||
} | } | ||||
/** | |||||
* Convenience method for subclass to get logger. | |||||
* | |||||
* @return the Logger | |||||
*/ | |||||
protected Logger getLogger() | |||||
{ | |||||
return m_logger; | |||||
} | |||||
} | } |
@@ -87,10 +87,10 @@ public class DefaultTaskletContext | |||||
* @param filename the filename to resolve | * @param filename the filename to resolve | ||||
* @return the resolved filename | * @return the resolved filename | ||||
*/ | */ | ||||
public String resolveFilename( final String filename ) | |||||
public File resolveFile( final String filename ) | |||||
{ | { | ||||
final File result = FileUtil.resolveFile( m_baseDirectory, filename ); | final File result = FileUtil.resolveFile( m_baseDirectory, filename ); | ||||
if( null != result ) return result.toString(); | |||||
if( null != result ) return result; | |||||
else return null; | else return null; | ||||
} | } | ||||
@@ -106,7 +106,7 @@ public class DefaultTaskletContext | |||||
try { return PropertyUtil.resolveProperty( property, this, false ); } | try { return PropertyUtil.resolveProperty( property, this, false ); } | ||||
catch( final PropertyException pe ) | catch( final PropertyException pe ) | ||||
{ | { | ||||
throw new AntException( "Error resolving " + property + " due to " +pe.getMessage(), | |||||
throw new AntException( "Error resolving " + property + " due to " + pe.getMessage(), | |||||
pe ); | pe ); | ||||
} | } | ||||
} | } | ||||
@@ -173,6 +173,14 @@ public class DefaultTaskletContext | |||||
} | } | ||||
} | } | ||||
/** | |||||
* put a value in context. | |||||
* This put method is overidden so new baseDirectory can be saved | |||||
* in member variable. | |||||
* | |||||
* @param key the key | |||||
* @param value the value | |||||
*/ | |||||
public void put( final Object key, final Object value ) | public void put( final Object key, final Object value ) | ||||
{ | { | ||||
if( key.equals( BASE_DIRECTORY ) ) | if( key.equals( BASE_DIRECTORY ) ) | ||||
@@ -24,6 +24,6 @@ import org.apache.avalon.Loggable; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public interface Tasklet | public interface Tasklet | ||||
extends Component, Contextualizable, Runnable, Loggable | |||||
extends Component, Loggable, Contextualizable, Runnable | |||||
{ | { | ||||
} | } |
@@ -60,9 +60,9 @@ public interface TaskletContext | |||||
* different volumes, file conventions etc) | * different volumes, file conventions etc) | ||||
* | * | ||||
* @param filename the filename to resolve | * @param filename the filename to resolve | ||||
* @return the resolved filename | |||||
* @return the resolved file | |||||
*/ | */ | ||||
String resolveFilename( String filename ); | |||||
File resolveFile( String filename ); | |||||
/** | /** | ||||
* Resolve property. | * Resolve property. | ||||
@@ -17,8 +17,11 @@ import org.apache.ant.convert.ConverterEngine; | |||||
import org.apache.ant.datatypes.DataTypeEngine; | import org.apache.ant.datatypes.DataTypeEngine; | ||||
import org.apache.ant.tasklet.Tasklet; | import org.apache.ant.tasklet.Tasklet; | ||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.avalon.AbstractLoggable; | |||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.DefaultComponentManager; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.Context; | import org.apache.avalon.Context; | ||||
import org.apache.avalon.Contextualizable; | import org.apache.avalon.Contextualizable; | ||||
@@ -28,6 +31,7 @@ import org.apache.avalon.Initializable; | |||||
import org.apache.avalon.Loggable; | import org.apache.avalon.Loggable; | ||||
import org.apache.avalon.camelot.DefaultFactory; | import org.apache.avalon.camelot.DefaultFactory; | ||||
import org.apache.avalon.camelot.DefaultLocatorRegistry; | import org.apache.avalon.camelot.DefaultLocatorRegistry; | ||||
import org.apache.avalon.camelot.Factory; | |||||
import org.apache.avalon.camelot.FactoryException; | import org.apache.avalon.camelot.FactoryException; | ||||
import org.apache.avalon.camelot.Locator; | import org.apache.avalon.camelot.Locator; | ||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
@@ -35,20 +39,17 @@ 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 | |||||
extends AbstractLoggable | |||||
implements TaskletEngine, Composer | |||||
{ | { | ||||
protected TskDeployer m_tskDeployer; | protected TskDeployer m_tskDeployer; | ||||
protected DefaultFactory m_factory; | |||||
protected LocatorRegistry m_locatorRegistry; | |||||
protected Factory m_factory; | |||||
protected LocatorRegistry m_locatorRegistry = new DefaultLocatorRegistry(); | |||||
protected Configurer m_configurer; | protected Configurer m_configurer; | ||||
protected Logger m_logger; | |||||
protected DataTypeEngine m_dataTypeEngine; | protected DataTypeEngine m_dataTypeEngine; | ||||
protected ConverterEngine m_converterEngine; | protected ConverterEngine m_converterEngine; | ||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
} | |||||
protected ComponentManager m_componentManager; | |||||
public TskDeployer getTskDeployer() | public TskDeployer getTskDeployer() | ||||
{ | { | ||||
@@ -74,120 +75,74 @@ public class DefaultTaskletEngine | |||||
{ | { | ||||
return m_dataTypeEngine; | return m_dataTypeEngine; | ||||
} | } | ||||
public void init() | |||||
throws Exception | |||||
{ | |||||
//converter must be created before configurerer | |||||
//so that it gets placed in configurers componentManager | |||||
m_converterEngine = createConverterEngine(); | |||||
setupSubComponent( m_converterEngine ); | |||||
m_configurer = createConfigurer(); | |||||
setupSubComponent( m_configurer ); | |||||
m_locatorRegistry = createLocatorRegistry(); | |||||
m_factory = createFactory(); | |||||
setupSubComponent( m_factory ); | |||||
m_dataTypeEngine = createDataTypeEngine(); | |||||
setupSubComponent( m_dataTypeEngine ); | |||||
m_tskDeployer = createTskDeployer(); | |||||
setupSubComponent( m_tskDeployer ); | |||||
} | |||||
protected void setupSubComponent( final Component component ) | |||||
throws Exception | |||||
{ | |||||
if( component instanceof Loggable ) | |||||
{ | |||||
((Loggable)component).setLogger( m_logger ); | |||||
} | |||||
if( component instanceof Composer ) | |||||
{ | |||||
final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||||
componentManager.put( "org.apache.ant.convert.Converter", | |||||
getConverterEngine() ); | |||||
componentManager.put( "org.apache.ant.configuration.Configurer", | |||||
m_configurer ); | |||||
componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", | |||||
this ); | |||||
((Composer)component).compose( componentManager ); | |||||
} | |||||
if( component instanceof Initializable ) | |||||
{ | |||||
((Initializable)component).init(); | |||||
} | |||||
} | |||||
protected DataTypeEngine createDataTypeEngine() | |||||
{ | |||||
final TaskletDataTypeEngine engine = new TaskletDataTypeEngine(); | |||||
engine.setFactory( m_factory ); | |||||
return engine; | |||||
} | |||||
protected TskDeployer createTskDeployer() | |||||
/** | |||||
* Retrieve relevent services needed to deploy. | |||||
* | |||||
* @param componentManager the ComponentManager | |||||
* @exception ComponentManagerException if an error occurs | |||||
*/ | |||||
public void compose( final ComponentManager componentManager ) | |||||
throws ComponentManagerException | |||||
{ | { | ||||
return new DefaultTskDeployer(); | |||||
} | |||||
//cache CM so it can be used while executing tasks | |||||
m_componentManager = componentManager; | |||||
protected Configurer createConfigurer() | |||||
{ | |||||
return new DefaultConfigurer(); | |||||
} | |||||
protected LocatorRegistry createLocatorRegistry() | |||||
{ | |||||
return new DefaultLocatorRegistry(); | |||||
} | |||||
protected DefaultFactory createFactory() | |||||
{ | |||||
return new DefaultFactory(); | |||||
} | |||||
protected ConverterEngine createConverterEngine() | |||||
{ | |||||
//this is done so that the loaders are shared | |||||
//which results in much less overhead | |||||
final TaskletConverterEngine engine = new TaskletConverterEngine(); | |||||
engine.setFactory( m_factory ); | |||||
return engine; | |||||
m_factory = (Factory)componentManager.lookup( "org.apache.avalon.camelot.Factory" ); | |||||
m_tskDeployer = | |||||
(TskDeployer)componentManager.lookup( "org.apache.ant.tasklet.engine.TskDeployer" ); | |||||
m_configurer = | |||||
(Configurer)componentManager.lookup( "org.apache.ant.configuration.Configurer" ); | |||||
m_dataTypeEngine = | |||||
(DataTypeEngine)componentManager.lookup( "org.apache.ant.datatypes.DataTypeEngine" ); | |||||
m_converterEngine = | |||||
(ConverterEngine)componentManager.lookup( "org.apache.ant.convert.ConverterEngine" ); | |||||
} | } | ||||
public void execute( final Configuration task, | public void execute( final Configuration task, | ||||
final TaskletContext context, | |||||
final ComponentManager componentManager ) | |||||
final TaskletContext context ) | |||||
throws AntException | throws AntException | ||||
{ | { | ||||
m_logger.debug( "Creating" ); | |||||
getLogger().debug( "Creating" ); | |||||
final Tasklet tasklet = createTasklet( task.getName() ); | final Tasklet tasklet = createTasklet( task.getName() ); | ||||
tasklet.setLogger( m_logger ); | |||||
setupLogger( tasklet ); | |||||
m_logger.debug( "Contextualizing" ); | |||||
getLogger().debug( "Contextualizing" ); | |||||
doContextualize( tasklet, task, context ); | doContextualize( tasklet, task, context ); | ||||
m_logger.debug( "Composing" ); | |||||
doCompose( tasklet, task, componentManager ); | |||||
getLogger().debug( "Composing" ); | |||||
doCompose( tasklet, task ); | |||||
m_logger.debug( "Configuring" ); | |||||
getLogger().debug( "Configuring" ); | |||||
doConfigure( tasklet, task, context ); | doConfigure( tasklet, task, context ); | ||||
m_logger.debug( "Initializing" ); | |||||
getLogger().debug( "Initializing" ); | |||||
doInitialize( tasklet, task ); | doInitialize( tasklet, task ); | ||||
m_logger.debug( "Running" ); | |||||
getLogger().debug( "Running" ); | |||||
tasklet.run(); | tasklet.run(); | ||||
m_logger.debug( "Disposing" ); | |||||
getLogger().debug( "Disposing" ); | |||||
doDispose( tasklet, task ); | doDispose( tasklet, task ); | ||||
} | } | ||||
protected Tasklet createTasklet( final String name ) | |||||
throws AntException | |||||
{ | |||||
try | |||||
{ | |||||
final Locator locator = m_locatorRegistry.getLocator( name ); | |||||
return (Tasklet)m_factory.create( locator, Tasklet.class ); | |||||
} | |||||
catch( final RegistryException re ) | |||||
{ | |||||
throw new AntException( "Unable to locate task " + name, re ); | |||||
} | |||||
catch( final FactoryException fe ) | |||||
{ | |||||
throw new AntException( "Unable to create task " + name, fe ); | |||||
} | |||||
} | |||||
protected void doConfigure( final Tasklet tasklet, | protected void doConfigure( final Tasklet tasklet, | ||||
final Configuration task, | final Configuration task, | ||||
@@ -203,20 +158,12 @@ public class DefaultTaskletEngine | |||||
} | } | ||||
} | } | ||||
protected void doCompose( final Tasklet tasklet, | |||||
final Configuration task, | |||||
final ComponentManager componentManager ) | |||||
protected void doCompose( final Tasklet tasklet, final Configuration task ) | |||||
throws AntException | throws AntException | ||||
{ | { | ||||
final DefaultComponentManager subComponentManager = | |||||
new DefaultComponentManager( componentManager ); | |||||
subComponentManager.put( "org.apache.ant.configuration.Configurer", m_configurer ); | |||||
if( tasklet instanceof Composer ) | if( tasklet instanceof Composer ) | ||||
{ | { | ||||
try { ((Composer)tasklet).compose( subComponentManager ); } | |||||
try { ((Composer)tasklet).compose( m_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 " + | ||||
@@ -231,9 +178,6 @@ public class DefaultTaskletEngine | |||||
final TaskletContext context ) | final TaskletContext context ) | ||||
throws AntException | throws AntException | ||||
{ | { | ||||
// 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 ) | ||||
{ | { | ||||
@@ -272,22 +216,4 @@ public class DefaultTaskletEngine | |||||
} | } | ||||
} | } | ||||
} | } | ||||
protected Tasklet createTasklet( final String name ) | |||||
throws AntException | |||||
{ | |||||
try | |||||
{ | |||||
final Locator locator = m_locatorRegistry.getLocator( name ); | |||||
return (Tasklet)m_factory.create( locator, Tasklet.class ); | |||||
} | |||||
catch( final RegistryException re ) | |||||
{ | |||||
throw new AntException( "Unable to locate task " + name, re ); | |||||
} | |||||
catch( final FactoryException fe ) | |||||
{ | |||||
throw new AntException( "Unable to create task " + name, fe ); | |||||
} | |||||
} | |||||
} | } |
@@ -15,13 +15,13 @@ import java.util.Iterator; | |||||
import java.util.zip.ZipEntry; | import java.util.zip.ZipEntry; | ||||
import java.util.zip.ZipException; | import java.util.zip.ZipException; | ||||
import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||
import org.apache.ant.datatypes.DataTypeEngine; | |||||
import org.apache.ant.convert.ConverterEngine; | import org.apache.ant.convert.ConverterEngine; | ||||
import org.apache.ant.convert.ConverterRegistry; | import org.apache.ant.convert.ConverterRegistry; | ||||
import org.apache.ant.convert.DefaultConverterInfo; | import org.apache.ant.convert.DefaultConverterInfo; | ||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.Configuration; | import org.apache.avalon.Configuration; | ||||
import org.apache.avalon.ConfigurationException; | import org.apache.avalon.ConfigurationException; | ||||
@@ -29,6 +29,7 @@ import org.apache.avalon.camelot.AbstractZipDeployer; | |||||
import org.apache.avalon.camelot.DefaultLocator; | import org.apache.avalon.camelot.DefaultLocator; | ||||
import org.apache.avalon.camelot.DefaultLocatorRegistry; | import org.apache.avalon.camelot.DefaultLocatorRegistry; | ||||
import org.apache.avalon.camelot.DeploymentException; | import org.apache.avalon.camelot.DeploymentException; | ||||
import org.apache.avalon.camelot.DeployerUtil; | |||||
import org.apache.avalon.camelot.Loader; | import org.apache.avalon.camelot.Loader; | ||||
import org.apache.avalon.camelot.LocatorRegistry; | import org.apache.avalon.camelot.LocatorRegistry; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
@@ -55,7 +56,7 @@ public class DefaultTskDeployer | |||||
*/ | */ | ||||
public DefaultTskDeployer() | public DefaultTskDeployer() | ||||
{ | { | ||||
super( false ); | |||||
super(); | |||||
m_autoUndeploy = true; | m_autoUndeploy = true; | ||||
m_type = "Tasklet"; | m_type = "Tasklet"; | ||||
} | } | ||||
@@ -64,34 +65,32 @@ public class DefaultTskDeployer | |||||
* Retrieve relevent services needed to deploy. | * Retrieve relevent services needed to deploy. | ||||
* | * | ||||
* @param componentManager the ComponentManager | * @param componentManager the ComponentManager | ||||
* @exception ComponentNotFoundException if an error occurs | |||||
* @exception ComponentNotAccessibleException if an error occurs | |||||
* @exception ComponentManagerException if an error occurs | |||||
*/ | */ | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
final TaskletEngine taskletEngine = (TaskletEngine)componentManager. | final TaskletEngine taskletEngine = (TaskletEngine)componentManager. | ||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | ||||
final ConverterEngine converterEngine = taskletEngine.getConverterEngine(); | |||||
m_taskletRegistry = taskletEngine.getRegistry(); | |||||
final ConverterEngine converterEngine = (ConverterEngine)componentManager. | |||||
lookup( "org.apache.ant.convert.ConverterEngine" ); | |||||
m_converterInfoRegistry = converterEngine.getInfoRegistry(); | m_converterInfoRegistry = converterEngine.getInfoRegistry(); | ||||
m_converterRegistry = converterEngine.getRegistry(); | m_converterRegistry = converterEngine.getRegistry(); | ||||
m_taskletRegistry = taskletEngine.getRegistry(); | |||||
final DataTypeEngine dataTypeEngine = (DataTypeEngine)componentManager. | |||||
lookup( "org.apache.ant.datatypes.DataTypeEngine" ); | |||||
m_dataTypeRegistry = taskletEngine.getDataTypeEngine().getRegistry(); | |||||
} | |||||
public void setLogger( final Logger logger ) | |||||
{ | |||||
m_logger = logger; | |||||
m_dataTypeRegistry = dataTypeEngine.getRegistry(); | |||||
} | } | ||||
protected void loadResources( final ZipFile zipFile, final String location, final URL url ) | protected void loadResources( final ZipFile zipFile, final String location, final URL url ) | ||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
final Configuration taskdefs = loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
final Configuration taskdefs = DeployerUtil.loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
try | try | ||||
{ | { | ||||
@@ -126,8 +125,8 @@ public class DefaultTskDeployer | |||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
checkDeployment( location, url ); | checkDeployment( location, url ); | ||||
final ZipFile zipFile = getZipFileFor( url ); | |||||
final Configuration taskdefs = loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
final ZipFile zipFile = DeployerUtil.getZipFileFor( getFileFor( url ) ); | |||||
final Configuration taskdefs = DeployerUtil.loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
try | try | ||||
{ | { | ||||
@@ -152,8 +151,9 @@ public class DefaultTskDeployer | |||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
checkDeployment( location, url ); | checkDeployment( location, url ); | ||||
final ZipFile zipFile = getZipFileFor( url ); | |||||
final Configuration datatypedefs = loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
final ZipFile zipFile = DeployerUtil.getZipFileFor( getFileFor( url ) ); | |||||
final Configuration datatypedefs = | |||||
DeployerUtil.loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
try | try | ||||
{ | { | ||||
@@ -178,8 +178,8 @@ public class DefaultTskDeployer | |||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
checkDeployment( location, url ); | checkDeployment( location, url ); | ||||
final ZipFile zipFile = getZipFileFor( url ); | |||||
final Configuration taskdefs = loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
final ZipFile zipFile = DeployerUtil.getZipFileFor( getFileFor( url ) ); | |||||
final Configuration taskdefs = DeployerUtil.loadConfiguration( zipFile, TSKDEF_FILE ); | |||||
try | try | ||||
{ | { | ||||
@@ -1,29 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant.tasklet.engine; | |||||
import org.apache.ant.convert.DefaultConverterEngine; | |||||
import org.apache.avalon.camelot.DefaultFactory; | |||||
public class TaskletConverterEngine | |||||
extends DefaultConverterEngine | |||||
{ | |||||
/** | |||||
* Set the ConverterFactory. | |||||
* Package access intended. | |||||
*/ | |||||
void setFactory( final DefaultFactory factory ) | |||||
{ | |||||
m_factory = factory; | |||||
} | |||||
protected DefaultFactory createFactory() | |||||
{ | |||||
return m_factory; | |||||
} | |||||
} |
@@ -1,29 +0,0 @@ | |||||
/* | |||||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
* | |||||
* This software is published under the terms of the Apache Software License | |||||
* version 1.1, a copy of which has been included with this distribution in | |||||
* the LICENSE file. | |||||
*/ | |||||
package org.apache.ant.tasklet.engine; | |||||
import org.apache.ant.datatypes.DefaultDataTypeEngine; | |||||
import org.apache.avalon.camelot.DefaultFactory; | |||||
public class TaskletDataTypeEngine | |||||
extends DefaultDataTypeEngine | |||||
{ | |||||
/** | |||||
* Set the DataTypeFactory. | |||||
* Package access intended. | |||||
*/ | |||||
void setFactory( final DefaultFactory factory ) | |||||
{ | |||||
m_factory = factory; | |||||
} | |||||
protected DefaultFactory createFactory() | |||||
{ | |||||
return m_factory; | |||||
} | |||||
} |
@@ -24,7 +24,7 @@ import org.apache.log.Logger; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public interface TaskletEngine | public interface TaskletEngine | ||||
extends Component, Loggable | |||||
extends Component | |||||
{ | { | ||||
/** | /** | ||||
* Retrieve deployer for engine. | * Retrieve deployer for engine. | ||||
@@ -60,8 +60,6 @@ public interface TaskletEngine | |||||
* @param task the configruation data for task | * @param task the configruation data for task | ||||
* @exception AntException if an error occurs | * @exception AntException if an error occurs | ||||
*/ | */ | ||||
void execute( Configuration task, | |||||
TaskletContext context, | |||||
ComponentManager componentManager ) | |||||
void execute( Configuration task, TaskletContext context ) | |||||
throws AntException; | throws AntException; | ||||
} | } |
@@ -14,8 +14,7 @@ import org.apache.ant.AntException; | |||||
import org.apache.ant.tasklet.AbstractTasklet; | import org.apache.ant.tasklet.AbstractTasklet; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
@@ -34,7 +33,7 @@ public abstract class AbstractResourceRegisterer | |||||
protected TaskletEngine m_engine; | protected TaskletEngine m_engine; | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_engine = (TaskletEngine)componentManager. | m_engine = (TaskletEngine)componentManager. | ||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | ||||
@@ -84,7 +83,7 @@ public abstract class AbstractResourceRegisterer | |||||
{ | { | ||||
if( null != libName ) | if( null != libName ) | ||||
{ | { | ||||
final File lib = new File( getContext().resolveFilename( libName ) ); | |||||
final File lib = getContext().resolveFile( libName ); | |||||
try { return lib.toURL(); } | try { return lib.toURL(); } | ||||
catch( final MalformedURLException mue ) | catch( final MalformedURLException mue ) | ||||
{ | { | ||||
@@ -16,8 +16,7 @@ import org.apache.ant.tasklet.DefaultTaskletContext; | |||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.Context; | import org.apache.avalon.Context; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
/** | /** | ||||
@@ -43,7 +42,7 @@ public class AntCall | |||||
} | } | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_componentManager = componentManager; | m_componentManager = componentManager; | ||||
m_projectEngine = (ProjectEngine)componentManager. | m_projectEngine = (ProjectEngine)componentManager. | ||||
@@ -19,8 +19,7 @@ import org.apache.ant.tasklet.AbstractTasklet; | |||||
import org.apache.ant.tasklet.TaskletContext; | import org.apache.ant.tasklet.TaskletContext; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.ConfigurationException; | import org.apache.avalon.ConfigurationException; | ||||
import org.apache.avalon.Resolvable; | import org.apache.avalon.Resolvable; | ||||
@@ -40,16 +39,15 @@ public class Property | |||||
protected Configurer m_configurer; | protected Configurer m_configurer; | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_configurer = (Configurer)componentManager. | m_configurer = (Configurer)componentManager. | ||||
lookup( "org.apache.ant.configuration.Configurer" ); | lookup( "org.apache.ant.configuration.Configurer" ); | ||||
final TaskletEngine taskletEngine = (TaskletEngine)componentManager. | |||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | |||||
m_engine = taskletEngine.getDataTypeEngine(); | |||||
m_converter = taskletEngine.getConverterEngine(); | |||||
m_engine = (DataTypeEngine)componentManager. | |||||
lookup( "org.apache.ant.datatypes.DataTypeEngine" ); | |||||
m_converter = (Converter)componentManager.lookup( "org.apache.ant.convert.Converter" ); | |||||
} | } | ||||
public void configure( final Configuration configuration ) | public void configure( final Configuration configuration ) | ||||
@@ -71,7 +69,12 @@ public class Property | |||||
if( name.equals( "name" ) ) | if( name.equals( "name" ) ) | ||||
{ | { | ||||
try { setName( (String)m_converter.convert( String.class, object ) ); } | |||||
try | |||||
{ | |||||
final String convertedValue = | |||||
(String)m_converter.convert( String.class, object, getContext() ); | |||||
setName( convertedValue ); | |||||
} | |||||
catch( final Exception e ) | catch( final Exception e ) | ||||
{ | { | ||||
throw new ConfigurationException( "Error converting value", e ); | throw new ConfigurationException( "Error converting value", e ); | ||||
@@ -86,7 +89,7 @@ public class Property | |||||
try | try | ||||
{ | { | ||||
final Boolean localScope = | final Boolean localScope = | ||||
(Boolean)m_converter.convert( Boolean.class, object ); | |||||
(Boolean)m_converter.convert( Boolean.class, object, getContext() ); | |||||
setLocalScope( Boolean.TRUE == localScope ); | setLocalScope( Boolean.TRUE == localScope ); | ||||
} | } | ||||
catch( final Exception e ) | catch( final Exception e ) | ||||
@@ -17,8 +17,7 @@ import org.apache.ant.convert.DefaultConverterInfo; | |||||
import org.apache.ant.tasklet.AbstractTasklet; | import org.apache.ant.tasklet.AbstractTasklet; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.camelot.DeploymentException; | import org.apache.avalon.camelot.DeploymentException; | ||||
import org.apache.avalon.camelot.RegistryException; | import org.apache.avalon.camelot.RegistryException; | ||||
@@ -39,7 +38,7 @@ public class RegisterConverter | |||||
protected TaskletEngine m_engine; | protected TaskletEngine m_engine; | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_engine = (TaskletEngine)componentManager. | m_engine = (TaskletEngine)componentManager. | ||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | ||||
@@ -90,7 +89,7 @@ public class RegisterConverter | |||||
if( !isFullyDefined && null == url ) | if( !isFullyDefined && null == url ) | ||||
{ | { | ||||
throw new AntException( "Must supply parameter if not fully specifying converter" ); | throw new AntException( "Must supply parameter if not fully specifying converter" ); | ||||
} | |||||
} | |||||
if( !isFullyDefined ) | if( !isFullyDefined ) | ||||
{ | { | ||||
@@ -126,7 +125,7 @@ public class RegisterConverter | |||||
{ | { | ||||
if( null != libName ) | if( null != libName ) | ||||
{ | { | ||||
final File lib = new File( getContext().resolveFilename( libName ) ); | |||||
final File lib = getContext().resolveFile( libName ); | |||||
try { return lib.toURL(); } | try { return lib.toURL(); } | ||||
catch( final MalformedURLException mue ) | catch( final MalformedURLException mue ) | ||||
{ | { | ||||
@@ -14,8 +14,7 @@ import org.apache.ant.AntException; | |||||
import org.apache.ant.tasklet.AbstractTasklet; | import org.apache.ant.tasklet.AbstractTasklet; | ||||
import org.apache.ant.tasklet.engine.TaskletEngine; | import org.apache.ant.tasklet.engine.TaskletEngine; | ||||
import org.apache.avalon.ComponentManager; | import org.apache.avalon.ComponentManager; | ||||
import org.apache.avalon.ComponentNotAccessibleException; | |||||
import org.apache.avalon.ComponentNotFoundException; | |||||
import org.apache.avalon.ComponentManagerException; | |||||
import org.apache.avalon.Composer; | import org.apache.avalon.Composer; | ||||
import org.apache.avalon.camelot.DeploymentException; | import org.apache.avalon.camelot.DeploymentException; | ||||
@@ -32,7 +31,7 @@ public class RegisterTasklib | |||||
protected TaskletEngine m_engine; | protected TaskletEngine m_engine; | ||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentNotFoundException, ComponentNotAccessibleException | |||||
throws ComponentManagerException | |||||
{ | { | ||||
m_engine = (TaskletEngine)componentManager. | m_engine = (TaskletEngine)componentManager. | ||||
lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); | ||||
@@ -53,7 +52,7 @@ public class RegisterTasklib | |||||
URL url = null; | URL url = null; | ||||
final File lib = new File( getContext().resolveFilename( m_lib ) ); | |||||
final File lib = getContext().resolveFile( m_lib ); | |||||
try { url = lib.toURL(); } | try { url = lib.toURL(); } | ||||
catch( final MalformedURLException mue ) | catch( final MalformedURLException mue ) | ||||
{ | { | ||||
@@ -5,7 +5,7 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE file. | * the LICENSE file. | ||||
*/ | */ | ||||
package org.apache.ant.datatypes; | |||||
package org.apache.ant.util; | |||||
import org.apache.ant.AntException; | import org.apache.ant.AntException; | ||||
import org.apache.avalon.Component; | import org.apache.avalon.Component; |
@@ -25,7 +25,7 @@ while [ -h "$PRG" ] ; do | |||||
fi | fi | ||||
done | done | ||||
MYRMIDON_HOME=`dirname "$PRG"`/.. | |||||
ANT_HOME=`dirname "$PRG"`/.. | |||||
if [ "$JAVA_HOME" == "" ] ; then | if [ "$JAVA_HOME" == "" ] ; then | ||||
@@ -42,4 +42,4 @@ else | |||||
fi | fi | ||||
fi | fi | ||||
$JAVACMD $ANT_OPTS -jar ant.jar --ant-home=${MYRMIDON_HOME} $@ | |||||
$JAVACMD $ANT_OPTS -jar $ANT_HOME/lib/ant.jar $@ |
@@ -2,6 +2,30 @@ | |||||
if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat" | if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat" | ||||
if not "%OS%"=="Windows_NT" goto start | |||||
rem %~dp0 is name of current script under NT | |||||
set DEFAULT_ANT_HOME=%~dp0 | |||||
rem : operator works similar to make : operator | |||||
set DEFAULT_ANT_HOME=%DEFAULT_ANT_HOME:\bin\=% | |||||
if "%ANT_HOME%"=="" set ANT_HOME=%DEFAULT_ANT_HOME% | |||||
set DEFAULT_ANT_HOME= | |||||
:start | |||||
if not "%ANT_HOME%" == "" goto ant_home_found | |||||
echo. | |||||
echo Warning: ANT_HOME environment variable is not set. | |||||
echo This needs to be set for Win9x as it's command prompt | |||||
echo scripting bites | |||||
echo. | |||||
goto end | |||||
:ant_home_found | |||||
if not "%JAVA_HOME%" == "" goto javaCmdSetup | if not "%JAVA_HOME%" == "" goto javaCmdSetup | ||||
echo. | echo. | ||||
@@ -10,7 +34,6 @@ echo If build fails because sun.* classes could not be found | |||||
echo you will need to set the JAVA_HOME environment variable | echo you will need to set the JAVA_HOME environment variable | ||||
echo to the installation directory of java. | echo to the installation directory of java. | ||||
echo. | echo. | ||||
goto end | |||||
rem hope that there is java command in path | rem hope that there is java command in path | ||||
if "%JAVACMD%" == "" set JAVACMD=java | if "%JAVACMD%" == "" set JAVACMD=java | ||||
@@ -22,7 +45,6 @@ if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java | |||||
:argSetup | :argSetup | ||||
set THIS_FILE=%0 | |||||
set ANT_CMD_LINE_ARGS= | set ANT_CMD_LINE_ARGS= | ||||
rem Slurp all args... | rem Slurp all args... | ||||
@@ -35,9 +57,8 @@ goto setupArgs | |||||
:doneArgs | :doneArgs | ||||
rem Mmmmmm tasty - finished slurping args | rem Mmmmmm tasty - finished slurping args | ||||
%JAVACMD% %ANT_OPTS% -jar lib\ant.jar "--bin-dir=%THIS_FILE%" %ANT_CMD_LINE_ARGS% | |||||
%JAVACMD% %ANT_OPTS% -jar %ANT_HOME%\lib\ant.jar %ANT_CMD_LINE_ARGS% | |||||
:end | :end | ||||
if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat" | if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat" | ||||
set THIS_FILE= | |||||
set ANT_CMD_LINE_ARGS= | set ANT_CMD_LINE_ARGS= |
@@ -0,0 +1,224 @@ | |||||
<html> | |||||
<head> | |||||
<title>Myrmidon: The Ant2.0 Proposal</title> | |||||
</head> | |||||
<body BGCOLOR="#ffffff"> | |||||
<center> | |||||
<h1>Myrmidon: The Ant2.0 Proposal</h1> | |||||
<i>by Peter Donald <a href="mailto:donaldp@apache.org"><donaldp@apache.org></a></i> | |||||
</center> | |||||
<br /> | |||||
<div align="center"> | |||||
<table border="0" width="60%"> | |||||
<tr> | |||||
<td width="100%"> | |||||
<i>Myrmidon is a proposal for <a href="http://jakarta.apache.org/ant">Ant</a> 2.0, a | |||||
java based build tool. Unlike other proposals it was specifically designed as | |||||
both a tool a an API library that can be reused in other domains.</i> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
<br /> | |||||
<h3>To do and what not to do</h3> | |||||
<blockquote> | |||||
<p> | |||||
There is a number of issues that this proposal addresses and a number of issues that | |||||
have been deliberately elided. The focus is currently at the lower levels - namely | |||||
the task execution engine, the notion of contexts/scopes, loading of tasklets, | |||||
datatypes and converters etc. While it does implement a Project engine API is still | |||||
being discussed on ant-dev and this proposal just adopts Ant1.x's model until a better | |||||
understanding is gained of what is required. | |||||
</p> | |||||
<p> | |||||
Neither this document nor the proposal is intended to be a vision statement. Rather it | |||||
is a description of how it could be implemented based on commonly accepted needs | |||||
requested on ant lists and discussed by ant-dev. The vision statement is more | |||||
strongly associated with the Project API and extentions (CJAN, import project trees, | |||||
preprocessing via xslt/css/whatever, templating etc). And thus is not addressed here. | |||||
</p> | |||||
</blockquote> | |||||
<h3>The Prime Directive: Execute tasks</h3> | |||||
<blockquote> | |||||
<p> | |||||
One of the primary concerns of ant is providing a task execution environment (TEE). | |||||
The TEE provides a number of services to tasks. The TEE manages the lifecycle of | |||||
the tasks. This includes providing the tasks with a logger instance, context | |||||
information and access to peer components. The lifecycle also involves executing | |||||
init(), run() and dispose() methods at appropriate times. | |||||
</p> | |||||
<p> | |||||
Instead of reinventing the wheel this proposal instead reuses the Avalon framework | |||||
that already provides facilities for many of the concepts required. It already has | |||||
interfaces/classes to model concepts of context, logger, containers etc. | |||||
</p> | |||||
<p> | |||||
One of the requirements identified was the need for dynamic interpretation and | |||||
instantiation of tasks. To implement this there needs to be an abstraction layer | |||||
between task object instances and the objects that are manipulated by projects | |||||
and tools outside tasklet API. This abstraction has the same requirements as | |||||
Configuration objects in Avalon and thus the task proxies are represented by | |||||
Avalons Configuration object. | |||||
</p> | |||||
</blockquote> | |||||
<h3>SOC, IOC and the alphabet soup</h3> | |||||
<blockquote> | |||||
<p> | |||||
The design of Myrmidon follows many of the design patterns found in Avalon. The strongest | |||||
influence cna be seen from the meta-patterns; Separation of Concerns (SOC) and Inversion of | |||||
Control (IOC). | |||||
</p> | |||||
<p> | |||||
SOC essentially is a design pattern used to separate the system accroding to relevent | |||||
dimensions. (SOC is often called multi-dimensional SOC). The definition of "relevent" | |||||
is domain specific and in our case there is a number of dimensions. For instance you | |||||
will notice that there is a separation between project, tasklet, conversion and datatype | |||||
functionality. Where in Ant1.x these were only partially separated or tightly coupled | |||||
there is now decoupling. This separation allows easy reuse of parts in other projects. ie | |||||
It is now extremely easy to reuse the tasklet api in other tools (such as Installshield | |||||
type apps or Cron-like deamons etc). | |||||
</p> | |||||
<p> | |||||
Another dimension in which myrmidon is separated is by users. For instance there is | |||||
a separation between engine code and client code. The client code is the code used by | |||||
those who implement the components. For instance tasklet developers only have to | |||||
look at client code for tasklets and never look at implementation of engine. | |||||
</p> | |||||
<p> | |||||
Inversion of Control (IOC) aka the Holywood Principle (Don't call us - we'll call you) is | |||||
another pattern applied within Myrmidon. In this pattern it is the container that provides | |||||
facilities and executes lifecycle by calling methods of child components. So instead of the | |||||
component calling methods to lookup or create peer components or method managing it's | |||||
own lifecycle the container is responsible for these functions. | |||||
</p> | |||||
<p> | |||||
These approach should be familiar to a servlet or EJB developer as they are also based on | |||||
SOC and IOC except they do it at a lower resolution. For more detailed explanation of | |||||
these design approaches have a look at <a | |||||
href="http://java.apache.org/framework/developer/index.html"> | |||||
http://java.apache.org/framework/developer/index.html</a>. | |||||
</p> | |||||
<p> | |||||
The result of these design choices is a more flexable and reusable components. | |||||
</p> | |||||
</blockquote> | |||||
<h3>Enough theory - give me Nuts and Bolts</h3> | |||||
<blockquote> | |||||
<p> | |||||
The code is separated into 5 different sections. These are the project, tastlet, | |||||
converter, datatype and frontend APIs. The project API is concerned with building | |||||
and representing a project. The tasklet API is concerned with executing tasks in a | |||||
particular environment. The converter API is concerned with converting instances of one | |||||
type into another type. The datatype API is used to register, load and instantiate | |||||
instances of named datatypes. The frontend API involves instantiating and managing | |||||
all the other components and making it easy to build different frontends (CLI, GUI, | |||||
Servlet). | |||||
</p> | |||||
<p> | |||||
When Myrmidon is started it interacts with FrontEnd API. It aquires a ProjectBuilder | |||||
instance from FrontEnd API and uses it to build a project. It then aquires a | |||||
ProjectEngine instance from FrontEnd again and uses it to execute the created project. | |||||
This project will first execute the implicit target (which includes all of properties | |||||
outside target element). And then execute the default or specified target. Each target | |||||
executes it's dependencies first and then checks it's condition to see if it should | |||||
execute itself. Each target contains a list of tasks (in the form of Configuraiton | |||||
objects). These are passed to the tasklet API that instantiates and executes the tasks. | |||||
The tasklet API instantiates the relevent task and then applies rules to use the | |||||
Configuration object to configure the task. In some cases this involves resolving | |||||
properties and converting values to the correct type required by task. The convertion | |||||
is done by Converter API. Properties are associations between a name and a value, the | |||||
types of the value aremanaged by the DataType API and accessed via the Property task. | |||||
</p> | |||||
<p> | |||||
Now if you wanted to change a certain component of the system - lets say the ProjectBuilder | |||||
component. You instead want to use a component that you wrote yourself that builds a project | |||||
with the result of a xslt + xml -> xml process so that you can use static templating. The | |||||
way to do this would be to set the property "ant.comp.builder" to | |||||
"com.biz.ant.MyXSLTProjectBuilder" before handing the properties to the FrontEnd API. The | |||||
FrontEnd API would then wire together the components appropriately and the same process as | |||||
documented above would be used. Other components can be replaced in a similar manner. For | |||||
a full list of properties that can be set see the default FrontEnd implementation. | |||||
</p> | |||||
<p> | |||||
Now instead of replacing a component in the system say you wanted to add an extra task. In | |||||
this case you would create a task "com.biz.ant.tasks.ProcessFile" that extends | |||||
"org.apache.ant.tasklet.AbstractTasklet". You would then implement run() method to do the | |||||
work and and setter methods to accept parameters. The run method can throw AntException if | |||||
the task fails for any reason. The setter methods are in format of Ant1.x setters with one | |||||
extention. The extention allows '-' characters to appear in xml names and these will be | |||||
transferred into capitalisation of next character in java names. ie file-permission | |||||
attribute --> setFilePermission() method. After implementing this task you would have | |||||
to define it in taskdef.xml of it's archive or else define it with a taskdef construct. | |||||
</p> | |||||
<p> | |||||
In a similar method new converters and datatypes can be added to the system. For example | |||||
if you needed to add a TestSet datatype that held a list of test names then this would | |||||
be possible. You could also add a converter that converted a list of comma separated | |||||
strings into a TestSet. | |||||
</p> | |||||
<p> | |||||
The one thing that this proposal does not address is validation concerns. You will notice | |||||
that the above is mainly aimed to reduce the complexity for task developers. Where in 1.x | |||||
you had to manage convertion manually (depending on version of Ant) and also had to explcitly | |||||
incorporate support for datatypes manually. The one other concern that was coded into every | |||||
task was validation. ie Were the correct parameters set ? It would be desirable to be able to | |||||
associate meta-information with the task that indicated the required parameters. This would | |||||
reduce the workload on task developers even more and encourage better task structure. This | |||||
is a future TODO. | |||||
</p> | |||||
</blockquote> | |||||
<h3>A Rose by any other name ...</h3> | |||||
<blockquote> | |||||
<p> | |||||
The name Myrmidon is a derivation of a mythological name for some anst that were turned | |||||
into soldiers by the god Zeus. It came to mean "a subordinate who executes orders | |||||
unquestioningly" which seemed suitable for a task execution/build tool. A more complete | |||||
description stolen from <a href="http://bondi-blue.parlez.com/previous_words/myrmidon.txt"> | |||||
http://bondi-blue.parlez.com/previous_words/myrmidon.txt</a>. | |||||
</p> | |||||
<quote> | |||||
<i>The appellation Myrmidon was derived from the Greek word "myrmex", | |||||
meaning ant. According to Greek mythology, the Myrmidons were | |||||
transformed into humans by the god Zeus as an act of kindness to his | |||||
son Aeacus. King Aeacus, captivated by a colony of ants, prayed | |||||
that he should receive an increase in population equal to the | |||||
number of ants before him. When he awoke the next day, the ants | |||||
were his human subjects. Thereafter, they were known as the | |||||
Myrmidons. See "The Iliad" for Homers' account of the Myrmidons | |||||
during the Trojan War.</i> | |||||
</quote> | |||||
</blockquote> | |||||
</body> | |||||
</html> |
@@ -40,7 +40,7 @@ fi | |||||
LOCALCLASSPATH=`echo $ANT_HOME/lib/*.jar | tr ' ' ':'` | LOCALCLASSPATH=`echo $ANT_HOME/lib/*.jar | tr ' ' ':'` | ||||
if [ "$CLASSPATH" != "" ] ; then | if [ "$CLASSPATH" != "" ] ; then | ||||
LOCALCLASSPATH=$CLASSPATH:$LOCALCLASSPATH | |||||
LOCALCLASSPATH=$LOCALCLASSPATH:$CLASSPATH | |||||
fi | fi | ||||
if [ "$JAVA_HOME" != "" ] ; then | if [ "$JAVA_HOME" != "" ] ; then |
@@ -1,4 +1,4 @@ | |||||
rem @echo off | |||||
@echo off | |||||
rem find ANT_HOME | rem find ANT_HOME | ||||
if not "%ANT_HOME%"=="" goto checkJava | if not "%ANT_HOME%"=="" goto checkJava | ||||
@@ -2,7 +2,7 @@ | |||||
cd %1 | cd %1 | ||||
set ANT_RUN_CMD=%2 | set ANT_RUN_CMD=%2 | ||||
shift | |||||
shift | |||||
shift | shift | ||||
%ANT_RUN_CMD% %1 %2 %3 %4 %5 %6 %7 %8 %9 | %ANT_RUN_CMD% %1 %2 %3 %4 %5 %6 %7 %8 %9 |
@@ -1 +1,2 @@ | |||||
set LOCALCLASSPATH=%LOCALCLASSPATH%;%1 | set LOCALCLASSPATH=%LOCALCLASSPATH%;%1 | ||||