Return-Path: Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 24585 invoked by uid 500); 4 Dec 2000 13:37:34 -0000 Delivered-To: apmail-jakarta-ant-cvs@apache.org Received: (qmail 24579 invoked by uid 1195); 4 Dec 2000 13:37:33 -0000 Date: 4 Dec 2000 13:37:33 -0000 Message-ID: <20001204133733.24578.qmail@locus.apache.org> From: donaldp@locus.apache.org To: jakarta-ant-cvs@apache.org Subject: cvs commit: jakarta-ant/proposal/myrmidon/src/script ant ant.bat antRun antRun.bat donaldp 00/12/04 05:37:33 Added: proposal/myrmidon .ant.properties build.bat build.sh build.xml emacs-jprj.el proposal/myrmidon/lib ant.jar avalonapi.jar xerces.jar proposal/myrmidon/src/java/org/apache/ant AntContextResources.java AntException.java Main.java proposal/myrmidon/src/java/org/apache/ant/configuration Configurable.java Configuration.java ConfigurationBuilder.java DefaultConfiguration.java SAXConfigurationHandler.java proposal/myrmidon/src/java/org/apache/ant/convert AbstractConverter.java Converter.java ConverterEntry.java ConverterFactory.java ConverterInfo.java ConverterLoader.java ConverterRegistry.java DefaultConverterFactory.java DefaultConverterInfo.java DefaultConverterLoader.java DefaultConverterRegistry.java proposal/myrmidon/src/java/org/apache/ant/convert/core StringToByteConverter.java StringToDoubleConverter.java StringToFloatConverter.java StringToIntegerConverter.java StringToLongConverter.java StringToShortConverter.java converters.properties proposal/myrmidon/src/java/org/apache/ant/project DefaultProject.java DefaultProjectBuilder.java DefaultProjectEngine.java DefaultProjectListener.java DefaultTarget.java Project.java ProjectBuilder.java ProjectEngine.java ProjectListener.java Target.java proposal/myrmidon/src/java/org/apache/ant/tasklet AbstractTasklet.java DefaultTaskletContext.java JavaVersion.java Tasklet.java TaskletContext.java proposal/myrmidon/src/java/org/apache/ant/tasklet/engine DefaultTaskletConfigurer.java DefaultTaskletEngine.java DefaultTaskletFactory.java DefaultTaskletInfo.java DefaultTaskletLoader.java DefaultTaskletRegistry.java TaskletConfigurer.java TaskletEngine.java TaskletEntry.java TaskletFactory.java TaskletInfo.java TaskletLoader.java TaskletRegistry.java TskDeployer.java proposal/myrmidon/src/java/org/apache/ant/tasks/core ConfigurationTest.java ContentTest.java Echo.java PrimitiveTypesTest.java Property.java SubElementTest.java taskdefs.properties proposal/myrmidon/src/make sample.xmk proposal/myrmidon/src/script ant ant.bat antRun antRun.bat Log: Initiall checkin of myrmidon proposal Revision Changes Path 1.1 jakarta-ant/proposal/myrmidon/.ant.properties Index: .ant.properties =================================================================== build.compiler=jikes 1.1 jakarta-ant/proposal/myrmidon/build.bat Index: build.bat =================================================================== @echo off echo. echo Ant Build System echo ---------------- set ANT_HOME=. set CLASSPATH= %ANT_HOME%\bin\ant.bat -emacs %1 %2 %3 %4 %5 %6 %7 %8 goto cleanup :cleanup set ANT_HOME= set CLASSPATH= 1.1 jakarta-ant/proposal/myrmidon/build.sh Index: build.sh =================================================================== #!/bin/sh echo echo "Ant Build System" echo "----------------" chmod u+x $PWD/bin/antRun chmod u+x $PWD/bin/ant #export ANT_OPTS="-Djava.compiler=" $PWD/bin/ant -emacs $@ | awk -f $PWD/bin/fixPath.awk 1.1 jakarta-ant/proposal/myrmidon/build.xml Index: build.xml =================================================================== 1.1 jakarta-ant/proposal/myrmidon/emacs-jprj.el Index: emacs-jprj.el =================================================================== (setq jprj-base-path (message "%s/" (expand-file-name (substitute-in-file-name "."))) ) (setq jprj-src-path (message "%ssrc/java/" jprj-base-path) ) (setq jprj-compile-command "./build.bat") (setq jprj-run-command "./build.bat&");; cd dist; bin/ant.bat -f ../src/make/sample.xmk&") ;(setq tab-expansion-size 4) (load "update-prj") 1.1 jakarta-ant/proposal/myrmidon/lib/ant.jar <> 1.1 jakarta-ant/proposal/myrmidon/lib/avalonapi.jar <> 1.1 jakarta-ant/proposal/myrmidon/lib/xerces.jar <> 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/AntContextResources.java Index: AntContextResources.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant; public interface AntContextResources { // the directory of ant String HOME_DIR = "ant.install.dir"; // the bin directory of ant String BIN_DIR = "ant.install.bin"; // the lib directory of ant String LIB_DIR = "ant.install.lib"; // the tasklib directory of ant String TASKLIB_DIR = "ant.install.task-lib"; // the directory to look for per user ant information String USER_DIR = "ant.user.dir"; // the directory to look for per project ant information String PROJECT_DIR = "ant.project.dir"; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/AntException.java Index: AntException.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant; import org.apache.avalon.CascadingRuntimeException; public class AntException extends CascadingRuntimeException { public AntException( final String message ) { this( message, null ); } public AntException( final String message, final Throwable throwable ) { super( message, throwable ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/Main.java Index: Main.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Iterator; import org.apache.ant.project.DefaultProjectEngine; import org.apache.ant.project.Project; import org.apache.ant.project.ProjectBuilder; import org.apache.ant.project.ProjectEngine; import org.apache.ant.project.ProjectListener; import org.apache.ant.tasklet.JavaVersion; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.Disposable; import org.apache.avalon.Initializable; import org.apache.avalon.camelot.Deployer; import org.apache.avalon.camelot.DeploymentException; import org.apache.avalon.util.StringUtil; import org.apache.avalon.util.cli.AbstractMain; import org.apache.avalon.util.cli.CLOption; import org.apache.avalon.util.cli.CLOptionDescriptor; import org.apache.avalon.util.io.ExtensionFileFilter; import org.apache.avalon.util.io.FileUtil; import org.apache.log.Category; import org.apache.log.LogKit; import org.apache.log.Logger; import org.apache.log.Priority; /** * The class to kick the tires and light the fires. * Starts ant, loads ProjectBuilder, builds project then uses ProjectEngine * to run project. * * @author Peter Donald */ public class Main extends AbstractMain { public final static String BUILD_DATE = "@@DATE@@"; public final static String BUILD_VERSION = "@@VERSION@@"; public final static String VERSION = "Ant " + BUILD_VERSION + " compiled on " + BUILD_DATE; protected final static String DEFAULT_LOGLEVEL = "INFO"; protected final static String DEFAULT_LIB_DIRECTORY = ".." + File.separator + "lib"; protected final static String DEFAULT_TASKLIB_DIRECTORY = DEFAULT_LIB_DIRECTORY; protected final static String DEFAULT_FILENAME = "build.xmk"; protected final static String DEFAULT_LISTENER = "org.apache.ant.project.DefaultProjectListener"; protected final static String DEFAULT_BUILDER = "org.apache.ant.project.DefaultProjectBuilder"; private static final int HELP_OPT = 'h'; private static final int QUIET_OPT = 'q'; private static final int VERBOSE_OPT = 'v'; private static final int FILE_OPT = 'f'; private static final int LOG_LEVEL_OPT = 'l'; private static final int DEFINE_OPT = 'D'; private static final int VERSION_OPT = 1; private static final int LISTENER_OPT = 2; private static final int BIN_DIR_OPT = 3; private static final int LIB_DIR_OPT = 4; private static final int TASKLIB_DIR_OPT = 5; private static final int INCREMENTAL_OPT = 6; private static final int HOME_DIR_OPT = 7; //incompatable options for info options private static final int INFO_OPT_INCOMPAT[] = new int[] { HELP_OPT, QUIET_OPT, VERBOSE_OPT, FILE_OPT, LOG_LEVEL_OPT, VERSION_OPT, LISTENER_OPT, DEFINE_OPT //BIN_DIR_OPT, LIB_DIR_OPT, TASKLIB_DIR_OPT, HOME_DIR_OPT }; //incompatable options for other logging options private static final int LOG_OPT_INCOMPAT[] = new int[] { QUIET_OPT, VERBOSE_OPT, LOG_LEVEL_OPT }; protected Logger m_logger; protected File m_binDir; protected File m_homeDir; protected File m_libDir; protected File m_taskLibDir; protected File m_buildFile; protected File m_userDir; public static void main( final String args[] ) { final Main main = new Main(); try { main.execute( args ); } catch( final AntException ae ) { main.m_logger.error( "Error: " + ae.getMessage() ); main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( ae ) ); } catch( final Throwable throwable ) { main.m_logger.error( "Error: " + throwable ); main.m_logger.debug( "Exception..." + StringUtil.printStackTrace( throwable ) ); } } /** * Initialise the options for command line parser. */ protected CLOptionDescriptor[] createCLOptions() { //TODO: localise final CLOptionDescriptor options[] = new CLOptionDescriptor[ 13 ]; options[0] = new CLOptionDescriptor( "help", CLOptionDescriptor.ARGUMENT_DISALLOWED, HELP_OPT, "display this help message", INFO_OPT_INCOMPAT ); options[1] = new CLOptionDescriptor( "file", CLOptionDescriptor.ARGUMENT_REQUIRED, FILE_OPT, "the build file." ); options[2] = new CLOptionDescriptor( "log-level", CLOptionDescriptor.ARGUMENT_REQUIRED, LOG_LEVEL_OPT, "the verbosity level at which to log messages. " + "(DEBUG|INFO|WARN|ERROR|FATAL_ERROR)", LOG_OPT_INCOMPAT ); options[3] = new CLOptionDescriptor( "quiet", CLOptionDescriptor.ARGUMENT_DISALLOWED, QUIET_OPT, "equivelent to --log-level=FATAL_ERROR", LOG_OPT_INCOMPAT ); options[4] = new CLOptionDescriptor( "verbose", CLOptionDescriptor.ARGUMENT_DISALLOWED, VERBOSE_OPT, "equivelent to --log-level=INFO", LOG_OPT_INCOMPAT ); options[5] = new CLOptionDescriptor( "listener", CLOptionDescriptor.ARGUMENT_REQUIRED, LISTENER_OPT, "the listener for log events." ); options[6] = new CLOptionDescriptor( "version", CLOptionDescriptor.ARGUMENT_DISALLOWED, VERSION_OPT, "display version", INFO_OPT_INCOMPAT ); options[7] = new CLOptionDescriptor( "bin-dir", CLOptionDescriptor.ARGUMENT_REQUIRED, BIN_DIR_OPT, "the listener for log events." ); options[8] = new CLOptionDescriptor( "lib-dir", CLOptionDescriptor.ARGUMENT_REQUIRED, LIB_DIR_OPT, "the lib directory to scan for jars/zip files." ); options[9] = new CLOptionDescriptor( "task-lib-dir", CLOptionDescriptor.ARGUMENT_REQUIRED, TASKLIB_DIR_OPT, "the task lib directory to scan for .tsk files." ); options[10] = new CLOptionDescriptor( "incremental", CLOptionDescriptor.ARGUMENT_DISALLOWED, INCREMENTAL_OPT, "Run in incremental mode" ); options[11] = new CLOptionDescriptor( "ant-home", CLOptionDescriptor.ARGUMENT_REQUIRED, HOME_DIR_OPT, "Specify ant home directory" ); options[12] = new CLOptionDescriptor( "define", CLOptionDescriptor.ARGUMENTS_REQUIRED_2, DEFINE_OPT, "Define a variable (ie -Dfoo=var)" ); return options; } /** * Entry point for standard ant. * * @param clOptions the list of command line options */ protected void execute( final List clOptions ) throws Throwable { final int size = clOptions.size(); final ArrayList targets = new ArrayList(); String filename = null; String listenerName = null; String builderName = null; String logLevel = null; String binDir = null; String homeDir = null; String libDir = null; String taskLibDir = null; boolean incremental = false; HashMap defines = new HashMap(); for( int i = 0; i < size; i++ ) { final CLOption option = (CLOption)clOptions.get( i ); switch( option.getId() ) { case 0: targets.add( option.getArgument() ); break; case HELP_OPT: usage(); return; case VERSION_OPT: System.out.println( VERSION ); return; case FILE_OPT: filename = option.getArgument(); break; case BIN_DIR_OPT: binDir = option.getArgument(); break; case LIB_DIR_OPT: libDir = option.getArgument(); break; case HOME_DIR_OPT: homeDir = option.getArgument(); break; case TASKLIB_DIR_OPT: taskLibDir = option.getArgument(); break; case VERBOSE_OPT: logLevel = "INFO"; break; case QUIET_OPT: logLevel = "ERROR"; break; case LOG_LEVEL_OPT: logLevel = option.getArgument(); break; case LISTENER_OPT: listenerName = option.getArgument(); break; case INCREMENTAL_OPT: incremental = true; break; case DEFINE_OPT: defines.put( option.getArgument( 0 ), option.getArgument( 1 ) ); break; } } if( null == logLevel ) logLevel = getDefaultLogLevel(); if( null == listenerName ) listenerName = getDefaultListener(); if( null == filename ) filename = getDefaultFilename(); if( null == libDir ) libDir = getDefaultLibDir(); if( null == taskLibDir ) taskLibDir = getDefaultTaskLibDir(); if( null == builderName ) builderName = getBuilderNameFor( filename ); setupLogger( logLevel ); //handle logging... setupListener( listenerName ); //handle listener.. setupDefaultAntDirs(); if( null == binDir && null == homeDir ) { m_homeDir = getDefaultHomeDir(); m_binDir = m_homeDir.getParentFile(); } else if( null == binDir ) // && null != homeDir { m_homeDir = getHomeDir( homeDir ); m_binDir = new File( m_homeDir, "bin" ); } else { m_binDir = getBinDir( binDir ); m_homeDir = m_binDir.getParentFile(); } m_libDir = getLibDir( m_homeDir, libDir ); m_taskLibDir = getTaskLibDir( m_homeDir, taskLibDir ); m_buildFile = getFile( filename ); m_logger.info( "Ant Base Directory: " + m_homeDir ); m_logger.info( "Ant Bin Directory: " + m_binDir ); m_logger.info( "Ant Build File: " + m_buildFile ); m_logger.debug( "Ant Lib Directory: " + m_libDir ); m_logger.debug( "Ant Task Lib Directory: " + m_taskLibDir ); setupContextClassLoader( m_libDir ); final Project project = getProject( builderName, m_buildFile ); setupProjectContext( project, defines ); final ProjectEngine engine = getProjectEngine(); //make sure Engine is sweet... if( engine instanceof Initializable ) { ((Initializable)engine).init(); } deployDefaultTaskLibs( engine, m_taskLibDir ); BufferedReader reader = null; while( true ) { doBuild( engine, project, targets ); if( !incremental ) break; System.out.println( "Continue ? (Enter no to stop)" ); if( null == reader ) { reader = new BufferedReader( new InputStreamReader( System.in ) ); } String line = reader.readLine(); if( line.equalsIgnoreCase( "no" ) ) break; } if( engine instanceof Disposable ) { ((Disposable)engine).dispose(); } } protected void deployDefaultTaskLibs( final ProjectEngine engine, final File taskLibDirectory ) { final ExtensionFileFilter filter = new ExtensionFileFilter( new String[] { ".tsk" } ); final File files[] = taskLibDirectory.listFiles( filter ); final Deployer deployer = engine.getDeployer(); for( int i = 0; i < files.length; i++ ) { final String name = files[ i ].getName(); try { deployer.deploy( name.substring( 0, name.length() - 4 ), files[ i ].toURL() ); } catch( final MalformedURLException mue ) {} catch( final DeploymentException de ) { throw new AntException( "Failed to deploy task library " + files[ i ], de ); } } } protected void doBuild( final ProjectEngine engine, final Project project, final ArrayList targets ) { try { final int targetCount = targets.size(); if( 0 == targetCount ) { engine.execute( project, project.getDefaultTargetName() ); } else { for( int i = 0; i < targetCount; i++ ) { engine.execute( project, (String)targets.get( i ) ); } } } catch( final AntException ae ) { m_logger.error( "BUILD FAILED" ); m_logger.error( "Reason:\n" + StringUtil.printStackTrace( ae, 5, true ) ); } } protected void setupLogger( final String logLevel ) { m_logger = createLogger( logLevel ); } protected void setupListener( final String listenerName ) { final ProjectListener listener = createListener( listenerName ); m_logger.addLogTarget( listener ); } protected void setupContextClassLoader( final File libDir ) { final ClassLoader classLoader = createClassLoader( libDir ); Thread.currentThread().setContextClassLoader( classLoader ); } protected ClassLoader createClassLoader( final File libDir ) { final ExtensionFileFilter filter = new ExtensionFileFilter( new String[] { ".jar", ".zip" } ); final ArrayList urlList = new ArrayList(); toURLS( urlList, libDir.listFiles( filter ) ); final URL urls[] = (URL[])urlList.toArray( new URL[0] ); return new URLClassLoader( urls, ClassLoader.getSystemClassLoader() ); } protected void toURLS( final ArrayList urls, final File files[] ) { for( int i = 0; i < files.length; i++ ) { try { urls.add( files[ i ].toURL() ); } catch( final MalformedURLException mue ) {} } } protected Project getProject( final String builderName, final File file ) throws AntException, IOException { m_logger.debug( "Ant Project Builder: " + builderName ); final ProjectBuilder builder = createBuilder( builderName ); builder.setLogger( m_logger ); //create the project final Project project = builder.build( file ); return project; } protected void setupProjectContext( final Project project, final HashMap defines ) throws AntException { final TaskletContext context = project.getContext(); final Iterator keys = defines.keySet().iterator(); //make sure these come before following so they get overidden if user tries to //confuse the system while( keys.hasNext() ) { final String key = (String)keys.next(); final String value = (String)defines.get( key ); context.setProperty( key, value ); } context.setProperty( AntContextResources.HOME_DIR, m_homeDir ); context.setProperty( AntContextResources.BIN_DIR, m_binDir ); context.setProperty( AntContextResources.LIB_DIR, m_libDir ); context.setProperty( AntContextResources.TASKLIB_DIR, m_taskLibDir ); //context.put( AntContextResources.USER_DIR, m_userDir ); context.setProperty( TaskletContext.LOGGER, m_logger ); context.setProperty( TaskletContext.JAVA_VERSION, getJavaVersion() ); } protected JavaVersion getJavaVersion() { JavaVersion version = JavaVersion.JAVA1_0; try { Class.forName( "java.lang.Void" ); version = JavaVersion.JAVA1_1; Class.forName( "java.lang.ThreadLocal" ); version = JavaVersion.JAVA1_2; Class.forName( "java.lang.StrictMath" ); version = JavaVersion.JAVA1_3; } catch( final ClassNotFoundException cnfe ) {} return version; } protected ProjectEngine getProjectEngine() { final ProjectEngine engine = createProjectEngine(); engine.setLogger( m_logger ); return engine; } protected ProjectEngine createProjectEngine() { return new DefaultProjectEngine(); } protected File getHomeDir( final String homeDir ) throws AntException { final File file = new File( homeDir ); checkDirectory( file, "ant-home" ); return file; } protected File getBinDir( final String binDir ) throws AntException { File file = (new File( binDir )).getAbsoluteFile(); if( !file.isDirectory() ) file = file.getParentFile(); checkDirectory( file, "bin-dir" ); return file; } protected File getLibDir( final File antHome, String libDir ) throws AntException { return resolveDirectory( antHome, libDir, "lib-dir" ); } protected File getTaskLibDir( final File antHome, final String taskLibDir ) throws AntException { return resolveDirectory( antHome, taskLibDir, "task-lib-dir" ); } protected File resolveDirectory( final File antHome, final String dir, final String name ) throws AntException { final File file = FileUtil.resolveFile( antHome, dir ); checkDirectory( file, name ); return file; } protected void checkDirectory( final File file, final String name ) { if( !file.exists() ) { throw new AntException( name + " (" + file + ") does not exist" ); } else if( !file.isDirectory() ) { throw new AntException( name + " (" + file + ") is not a directory" ); } } protected ProjectListener createListener( final String listenerName ) throws AntException { try { return (ProjectListener)createObject( listenerName, "listener" ); } catch( final ClassCastException cce ) { throw new AntException( "Aparently the listener named " + listenerName + " does not implement the ProjectListener interface", cce ); } } protected Logger createLogger( final String logLevel ) throws AntException { final String logLevelCapitalized = logLevel.toUpperCase(); final Priority.Enum priority = LogKit.getPriorityForName( logLevelCapitalized ); if( !priority.getName().equals( logLevelCapitalized ) ) { throw new AntException( "Unknown log level - " + logLevel ); } final Category category = LogKit.createCategory( "ant", priority ); return LogKit.createLogger( category ); } protected void setupDefaultAntDirs() { final String os = System.getProperty( "os.name" ); final String userDir = System.getProperty( "user.home" ); m_userDir = (new File( getUserLocationFor( os, userDir ) )).getAbsoluteFile(); } /** * Retrieve default bin-dir value if possible (Otherwise throw an exception). * * Lookup OS specific places for ant to be. * /opt/ant on *BSD ? * /usr/local/ant on linux ? * /Program Files/Ant on Win32 ? * * @return bin directory */ protected File getDefaultHomeDir() throws AntException { if( null != m_userDir ) { try { checkDirectory( m_userDir, null ); return m_userDir; } catch( final AntException ae ) {} } final String os = System.getProperty( "os.name" ); final File candidate = (new File( getSystemLocationFor( os ) )).getAbsoluteFile(); checkDirectory( candidate, "ant-home" ); return candidate; } /** * This determins a mapping from an OS specific place to ants home directory. * In later versions the mapping should be read from configuration file. * * @param os the name of OS * @return the location of directory */ protected String getUserLocationFor( final String os, final String userDir ) { if( os.startsWith( "Windows" ) ) { return userDir + "\\Ant"; } else if( '/' == File.separatorChar ) { if( os.startsWith( "Linux" ) ) return userDir + "/ant"; else return userDir + "/opt/ant"; } else { return userDir + File.separator + "ant"; } } /** * This determins a mapping from an OS specific place to ants home directory. * In later versions the mapping should be read from configuration file. * * @param os the name of OS * @return the location of directory */ protected String getSystemLocationFor( final String os ) { if( os.startsWith( "Windows" ) ) { return "\\Program Files\\Ant"; } else if( '/' == File.separatorChar ) { if( os.startsWith( "Linux" ) ) return "/usr/local/ant"; else return "/opt/ant"; } else { return File.separator + "ant"; } } protected String getDefaultLibDir() { return DEFAULT_LIB_DIRECTORY; } protected String getDefaultTaskLibDir() { return DEFAULT_TASKLIB_DIRECTORY; } /** * Retrieve default filename. Overide this in base classes to change default. * * @return the default filename */ protected String getDefaultFilename() { return DEFAULT_FILENAME; } /** * Retrieve default logelevel. Overide this in base classes to change default. * * @return the default loglevel */ protected String getDefaultLogLevel() { return DEFAULT_LOGLEVEL; } /** * Retrieve default listener. Overide this in base classes to change default. * * @return the default listener */ protected String getDefaultListener() { return DEFAULT_LISTENER; } /** * Get File object for filename. * Check that file exists and is not a directory. * * @param filename the filename * @return the file object * @exception AntException if an error occurs */ protected File getFile( final String filename ) throws AntException, IOException { final File file = (new File( filename )).getCanonicalFile(); if( !file.exists() ) { throw new AntException( "File " + file + " does not exist." ); } if( file.isDirectory() ) { throw new AntException( "File " + file + " is a directory." ); } return file; } /** * Create instance of Builder based on classname. * * @param builderName builder class name * @return the ProjectBuilder * @exception AntException if an error occurs */ protected ProjectBuilder createBuilder( final String builderName ) throws AntException { try { return (ProjectBuilder)createObject( builderName, "builder" ); } catch( final ClassCastException cce ) { throw new AntException( "Aparently the builder named " + builderName + " does not implement the ProjectBuilder interface", cce ); } } /** * Helper method to create object and throw an apporpriate AntException if creation failed. * * @param objectName the classname of object * @param type the type of object being created (ie builder|listener) * @return the created object * @exception AntException if an error occurs */ protected Object createObject( final String objectName, final String type ) throws AntException { try { final Class clazz = Class.forName( objectName ); return clazz.newInstance(); } catch( final IllegalAccessException iae ) { throw new AntException( "Non-public constructor for " + type + " " + objectName, iae ); } catch( final InstantiationException ie ) { throw new AntException( "Error instantiating class for " + type + " " + objectName, ie ); } catch( final ClassNotFoundException cnfe ) { throw new AntException( "Could not find the class for " + type + " " + objectName, cnfe ); } } /** * Retrieve class name of builder for file. * Eventually this will look in a registry of file extentions to BuilderNames. * * @param filename the filename * @return the name of Class for Builder * @exception AntException if an error occurs */ protected String getBuilderNameFor( final String filename ) throws AntException { return DEFAULT_BUILDER; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/Configurable.java Index: Configurable.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.configuration; import org.apache.avalon.ConfigurationException; /** * This interface should be implemented by classes that need to be * configured with custom parameters before initialization. *
* * The contract surrounding a Configurable is that the * instantiating entity must call the configure * method before it is valid. The configure method * must be called after the constructor, and before any other method. * * @author Federico Barbieri * @author Pierpaolo Fumagalli * @author Stefano Mazzocchi * @author Berin Loritsch * @author Peter Donald */ public interface Configurable { /** * Pass the Configuration to the Configurable * class. This method must always be called after the constructor * and before any other method. * * @param configuration the class configurations. */ void configure( Configuration configuration ) throws ConfigurationException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/Configuration.java Index: Configuration.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.configuration; import java.util.Iterator; /** * Hostile fork till Avalon gets equivelent functionality ;) */ public interface Configuration extends org.apache.avalon.Configuration { /** * Retrieve a list of all child names. * * @return the child names */ Iterator getChildren(); /** * Retrieve a list of all attribute names. * * @return the attribute names */ Iterator getAttributeNames(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/ConfigurationBuilder.java Index: ConfigurationBuilder.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.configuration; import org.xml.sax.SAXException; /** * Hostile fork till Avalon gets equivelent functionality ;) */ public class ConfigurationBuilder extends org.apache.avalon.DefaultConfigurationBuilder { public ConfigurationBuilder() throws SAXException { super(); } protected org.apache.avalon.SAXConfigurationHandler getHandler() { return new SAXConfigurationHandler(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfiguration.java Index: DefaultConfiguration.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.configuration; import java.util.Iterator; /** * Hostile fork till Avalon gets equivelent functionality ;) */ public class DefaultConfiguration extends org.apache.avalon.DefaultConfiguration implements Configuration { public DefaultConfiguration( final String localname, final String location ) { super( localname, location ); } /** * Retrieve a list of all child names. * * @return the child names */ public Iterator getChildren() { if( null == m_children ) return EMPTY_ITERATOR; else return m_children.iterator(); } /** * Retrieve a list of all attribute names. * * @return the attribute names */ public Iterator getAttributeNames() { if( null == m_attributes ) return EMPTY_ITERATOR; else return m_attributes.keySet().iterator(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/configuration/SAXConfigurationHandler.java Index: SAXConfigurationHandler.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.configuration; /** * Hostile fork till Avalon gets equivelent functionality ;) */ public class SAXConfigurationHandler extends org.apache.avalon.SAXConfigurationHandler { protected org.apache.avalon.DefaultConfiguration createConfiguration( final String localName, final String location ) { return new DefaultConfiguration( localName, location ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/AbstractConverter.java Index: AbstractConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; /** * Instances of this interface are used to convert between different types. * * @author Peter Donald */ public abstract class AbstractConverter implements Converter { protected final Class m_source; protected final Class m_destination; public AbstractConverter( final Class source, final Class destination ) { m_source = source; m_destination = destination; } public Object convert( final Class destination, final Object original ) throws Exception { if( m_destination != destination ) { throw new IllegalArgumentException( "Destination type " + destination.getName() + " is not equal to " + m_destination ); } if( !m_source.isInstance( original ) ) { throw new IllegalArgumentException( "Object '" + original + "' is not an " + "instance of " + m_source.getName() ); } return convert( original ); } protected abstract Object convert( Object original ) throws Exception; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/Converter.java Index: Converter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; /** * Instances of this interface are used to convert between different types. * * @author Peter Donald */ public interface Converter { Object convert( Class destination, Object original ) throws Exception; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEntry.java Index: ConverterEntry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import org.apache.ant.convert.Converter; import org.apache.avalon.camelot.AbstractEntry; public class ConverterEntry extends AbstractEntry { public ConverterEntry( final ConverterInfo info, final Converter converter ) { super( info, converter ); } /** * Retrieve instance of converter. * * @return the component instance */ public Converter getConverter() { return (Converter)getInstance(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterFactory.java Index: ConverterFactory.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import org.apache.avalon.camelot.Factory; import org.apache.avalon.camelot.FactoryException; /** * Facility used to load Converters. * * @author Peter Donald */ public interface ConverterFactory extends Factory { ConverterEntry create( ConverterInfo info ) throws FactoryException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterInfo.java Index: ConverterInfo.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import java.net.URL; import org.apache.avalon.camelot.Info; /** * This info represents meta-information about a converter. * * @author Peter Donald */ public interface ConverterInfo extends Info { /** * Retrieve the source type from which it can convert. * NB: Should this be an array ???? * * @return the classname from which object produced */ String getSource(); /** * Retrieve the type to which the converter converts. * NB: Should this be an array ???? * * @return the classname of the produced object */ String getDestination(); /** * Retrieve classname for concerter. * * @return the taskname */ String getClassname(); /** * Retrieve location of task library where task is contained. * * @return the location of task library */ URL getLocation(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterLoader.java Index: ConverterLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import org.apache.avalon.camelot.Loader; /** * Class used to load converters et al from a source. * * @author Peter Donald */ public interface ConverterLoader extends Loader { Converter loadConverter( String converter ) throws Exception; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterRegistry.java Index: ConverterRegistry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import org.apache.avalon.camelot.Registry; public interface ConverterRegistry extends Registry { ConverterInfo getConverterInfo( String source, String destination ); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterFactory.java Index: DefaultConverterFactory.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import org.apache.ant.convert.Converter; import org.apache.avalon.camelot.Entry; import org.apache.avalon.camelot.Factory; import org.apache.avalon.camelot.Loader; import org.apache.avalon.camelot.FactoryException; import org.apache.avalon.camelot.Info; /** * Facility used to load Converters. * * @author Peter Donald */ public class DefaultConverterFactory implements ConverterFactory { protected final HashMap m_loaders = new HashMap(); public Entry create( final Info info ) throws FactoryException { if( info.getClass().equals( ConverterInfo.class ) ) { throw new IllegalArgumentException( "Passed incorrect Info type to factory" ); } return create( (ConverterInfo)info ); } public ConverterEntry create( final ConverterInfo info ) throws FactoryException { final ConverterLoader loader = getLoader( info.getLocation() ); Object object = null; try { object = loader.load( info.getClassname() ); } catch( final Exception e ) { throw new FactoryException( "Failed loading converter from " + info.getLocation() + " due to " + e, e ); } return new ConverterEntry( info, (Converter)object ); } protected ConverterLoader getLoader( final URL location ) { ConverterLoader loader = (ConverterLoader)m_loaders.get( location ); if( null == loader ) { loader = createLoader( location ); m_loaders.put( location, loader ); } return loader; } protected ConverterLoader createLoader( final URL location ) { if( null != location ) return new DefaultConverterLoader( location ); else return new DefaultConverterLoader(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterInfo.java Index: DefaultConverterInfo.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import java.net.URL; /** * This info represents meta-information about a converter. * * @author Peter Donald */ public class DefaultConverterInfo implements ConverterInfo { protected final String m_source; protected final String m_destination; protected final String m_classname; protected final URL m_location; public DefaultConverterInfo( final String source, final String destination, final String classname, final URL location ) { m_source = source; m_destination = destination; m_classname = classname; m_location = location; } /** * Retrieve the source type from which it can convert. * NB: Should this be an array ???? * * @return the classname from which object produced */ public String getSource() { return m_source; } /** * Retrieve the type to which the converter converts. * NB: Should this be an array ???? * * @return the classname of the produced object */ public String getDestination() { return m_destination; } /** * Retrieve classname for concerter. * * @return the taskname */ public String getClassname() { return m_classname; } /** * Retrieve location of task library where task is contained. * * @return the location of task library */ public URL getLocation() { return m_location; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterLoader.java Index: DefaultConverterLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import java.net.URL; import java.net.URLClassLoader; import org.apache.avalon.camelot.AbstractLoader; /** * Class used to load converters et al from a source. * * @author Peter Donald */ public class DefaultConverterLoader extends AbstractLoader implements ConverterLoader { public DefaultConverterLoader() { super( new URLClassLoader( new URL[0], Thread.currentThread().getContextClassLoader() ) ); } public DefaultConverterLoader( final URL location ) { super( new URLClassLoader( new URL[] { location } ) ); } public Converter loadConverter( final String converter ) throws Exception { return (Converter)load( converter ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterRegistry.java Index: DefaultConverterRegistry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert; import java.util.HashMap; import org.apache.avalon.camelot.AbstractRegistry; import org.apache.avalon.camelot.Info; import org.apache.avalon.camelot.RegistryException; public class DefaultConverterRegistry extends AbstractRegistry implements ConverterRegistry { protected final HashMap m_mapping = new HashMap(); public ConverterInfo getConverterInfo( final String source, final String destination ) { final HashMap map = (HashMap)m_mapping.get( source ); if( null == map ) return null; return (ConverterInfo)map.get( destination ); } protected void checkInfo( final String name, final Info info ) throws RegistryException { super.checkInfo( name, info ); final ConverterInfo converterInfo = (ConverterInfo)info; final String source = converterInfo.getSource(); final String destination = converterInfo.getDestination(); HashMap map = (HashMap)m_mapping.get( source ); if( null == map ) { map = new HashMap(); m_mapping.put( source, map ); } map.put( destination, info ); } protected Class getInfoClass() { return ConverterInfo.class; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToByteConverter.java Index: StringToByteConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to byte converter * * @author Peter Donald */ public class StringToByteConverter extends AbstractConverter { public StringToByteConverter() { super( String.class, Byte.class ); } public Object convert( final Object original ) throws Exception { return new Byte( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToDoubleConverter.java Index: StringToDoubleConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to double converter * * @author Peter Donald */ public class StringToDoubleConverter extends AbstractConverter { public StringToDoubleConverter() { super( String.class, Double.class ); } public Object convert( final Object original ) throws Exception { return new Double( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToFloatConverter.java Index: StringToFloatConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to float converter * * @author Peter Donald */ public class StringToFloatConverter extends AbstractConverter { public StringToFloatConverter() { super( String.class, Float.class ); } public Object convert( final Object original ) throws Exception { return new Float( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToIntegerConverter.java Index: StringToIntegerConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to integer converter. * * @author Peter Donald */ public class StringToIntegerConverter extends AbstractConverter { public StringToIntegerConverter() { super( String.class, Integer.class ); } public Object convert( final Object original ) throws Exception { return new Integer( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToLongConverter.java Index: StringToLongConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to long converter * * @author Peter Donald */ public class StringToLongConverter extends AbstractConverter { public StringToLongConverter() { super( String.class, Long.class ); } public Object convert( final Object original ) throws Exception { return new Long( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/StringToShortConverter.java Index: StringToShortConverter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.convert.core; import org.apache.ant.convert.AbstractConverter; /** * String to short converter * * @author Peter Donald */ public class StringToShortConverter extends AbstractConverter { public StringToShortConverter() { super( String.class, Short.class ); } public Object convert( final Object original ) throws Exception { return new Short( (String)original ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/convert/core/converters.properties Index: converters.properties =================================================================== org.apache.ant.convert.core.StringToLongConverter=java.lang.String, java.lang.Long org.apache.ant.convert.core.StringToIntegerConverter=java.lang.String, java.lang.Integer org.apache.ant.convert.core.StringToShortConverter=java.lang.String, java.lang.Short org.apache.ant.convert.core.StringToByteConverter=java.lang.String, java.lang.Byte org.apache.ant.convert.core.StringToDoubleConverter=java.lang.String, java.lang.Double org.apache.ant.convert.core.StringToFloatConverter=java.lang.String, java.lang.Float 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProject.java Index: DefaultProject.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import org.apache.ant.AntException; import org.apache.ant.tasklet.DefaultTaskletContext; import org.apache.ant.tasklet.TaskletContext; public class DefaultProject implements Project { protected final TaskletContext m_baseContext = new DefaultTaskletContext(); protected final HashMap m_targets = new HashMap(); protected Target m_implicitTarget; protected String m_defaultTarget; public Target getImplicitTarget() { return m_implicitTarget; } public void setImplicitTarget( final Target target ) { m_implicitTarget = target; } public Target getTarget( final String targetName ) { return (Target)m_targets.get( targetName ); } public String getDefaultTargetName() { return m_defaultTarget; } public Iterator getTargetNames() { return m_targets.keySet().iterator(); } public TaskletContext getContext() { return m_baseContext; } public void setDefaultTargetName( final String defaultTarget ) { m_defaultTarget = defaultTarget; } public void addTarget( final String name, final Target target ) throws AntException { if( null != m_targets.get( name ) ) { throw new AntException( "Can not have two targets in a file with the name " + name ); } else { m_targets.put( name, target ); } } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java Index: DefaultProjectBuilder.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.io.File; import java.io.IOException; import java.util.Iterator; import org.apache.ant.AntException; import org.apache.ant.configuration.Configuration; import org.apache.ant.configuration.ConfigurationBuilder; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.ConfigurationException; import org.apache.log.Logger; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class DefaultProjectBuilder implements ProjectBuilder { protected final ConfigurationBuilder m_configurationBuilder; protected Logger m_logger; public DefaultProjectBuilder() { ConfigurationBuilder builder = null; try { builder = new ConfigurationBuilder(); } catch( final SAXException se ) {} m_configurationBuilder = builder; } public void setLogger( final Logger logger ) { m_logger = logger; } public Project build( final File projectFile ) throws IOException, AntException { try { final String location = projectFile.getCanonicalFile().toURL().toString(); final InputSource inputSource = new InputSource( location ); final Configuration configuration = (Configuration)m_configurationBuilder.build( inputSource ); return build( projectFile, configuration ); } catch( final SAXException se ) { throw new AntException( "SAXEception: " + se.getMessage(), se ); } catch( final ConfigurationException ce ) { throw new AntException( "ConfigurationException: " + ce.getMessage(), ce ); } } protected Project build( final File file, final Configuration configuration ) throws IOException, AntException, ConfigurationException { if( !configuration.getName().equals("project") ) { throw new AntException( "Project file must be enclosed in project element" ); } final String baseDirectoryName = configuration.getAttribute( "basedir" ); final String defaultTarget = configuration.getAttribute( "default" ); final String projectName = configuration.getAttribute( "name" ); final DefaultProject project = new DefaultProject(); project.setDefaultTargetName( defaultTarget ); final File baseDirectory = (new File( file.getParentFile(), baseDirectoryName )).getAbsoluteFile(); m_logger.debug( "Project " + projectName + " base directory: " + baseDirectory ); final TaskletContext context = project.getContext(); context.setProperty( TaskletContext.BASE_DIRECTORY, baseDirectory ); context.setProperty( Project.PROJECT_FILE, file ); context.setProperty( Project.PROJECT, projectName ); buildTopLevelProject( project, configuration ); return project; } protected void buildTopLevelProject( final DefaultProject project, final Configuration configuration ) throws AntException { final Iterator elements = configuration.getChildren(); while( elements.hasNext() ) { final Configuration element = (Configuration)elements.next(); final String name = element.getName(); if( name.equals( "target" ) ) buildTarget( project, element ); else if( name.equals( "property" ) ) buildProperty( project, element ); else { throw new AntException( "Unknown top-level element " + name + " at " + element.getLocation() ); } } } protected void buildTarget( final DefaultProject project, final Configuration configuration ) { final String name = configuration.getAttribute( "name", null ); final String depends = configuration.getAttribute( "depends", null ); final String ifCondition = configuration.getAttribute( "if", null ); final String unlessCondition = configuration.getAttribute( "unless", null ); if( null == name ) { throw new AntException( "Discovered un-named target at " + configuration.getLocation() ); } m_logger.debug( "Parsing target: " + name ); if( null != ifCondition && null != unlessCondition ) { throw new AntException( "Discovered invalid target that has both a if and " + "unless condition at " + configuration.getLocation() ); } final DefaultTarget target = new DefaultTarget(); if( null != ifCondition ) { m_logger.debug( "Target if condition: " + ifCondition ); target.setIfCondition( true ); target.setCondition( ifCondition ); } else if( null != unlessCondition ) { m_logger.debug( "Target unless condition: " + unlessCondition ); target.setIfCondition( false ); target.setCondition( unlessCondition ); } if( null != depends ) { int start = 0; int end = depends.indexOf( ',' ); while( -1 != end ) { final String dependency = parseDependency( configuration, depends.substring( start, end ) ); target.addDependency( dependency ); start = end++; end = depends.indexOf( ',', start ); } final String dependency = parseDependency( configuration, depends.substring( start ) ); target.addDependency( dependency ); } final Iterator tasks = configuration.getChildren(); while( tasks.hasNext() ) { final Configuration task = (Configuration)tasks.next(); m_logger.debug( "Parsed task: " + task.getName() ); target.addTask( task ); } project.addTarget( name, target ); } protected String parseDependency( final Configuration configuration, String dependency ) throws AntException { dependency = dependency.trim(); if( 0 == dependency.length() ) { throw new AntException( "Discovered empty dependency in target " + configuration.getName() + " at " + configuration.getLocation() ); } m_logger.debug( "Target dependency: " + dependency ); return dependency; } protected void buildProperty( final DefaultProject project, final Configuration configuration ) { DefaultTarget target = (DefaultTarget)project.getImplicitTarget(); if( null == target ) { target = new DefaultTarget(); project.setImplicitTarget( target ); } m_logger.debug( "Parsed implicit task: " + configuration.getName() ); target.addTask( configuration ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java Index: DefaultProjectEngine.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.util.ArrayList; import java.util.Iterator; import org.apache.ant.AntException; import org.apache.ant.configuration.Configuration; import org.apache.ant.convert.ConverterRegistry; import org.apache.ant.convert.DefaultConverterRegistry; import org.apache.ant.tasklet.DefaultTaskletContext; import org.apache.ant.tasklet.TaskletContext; import org.apache.ant.tasklet.engine.DefaultTaskletEngine; import org.apache.ant.tasklet.engine.DefaultTaskletInfo; import org.apache.ant.tasklet.engine.DefaultTaskletRegistry; import org.apache.ant.tasklet.engine.TaskletEngine; import org.apache.ant.tasklet.engine.TaskletRegistry; import org.apache.ant.tasklet.engine.TskDeployer; import org.apache.avalon.DefaultComponentManager; import org.apache.avalon.Disposable; import org.apache.avalon.Initializable; import org.apache.avalon.camelot.Deployer; import org.apache.avalon.camelot.DeploymentException; import org.apache.avalon.camelot.RegistryException; import org.apache.log.Logger; public class DefaultProjectEngine implements ProjectEngine, Initializable, Disposable { protected Deployer m_deployer; protected TaskletRegistry m_taskletRegistry; protected ConverterRegistry m_converterRegistry; protected TaskletEngine m_taskletEngine; protected Logger m_logger; public void setLogger( final Logger logger ) { m_logger = logger; } public void init() throws Exception { m_taskletEngine = createTaskletEngine(); m_taskletRegistry = createTaskletRegistry(); m_converterRegistry = createConverterRegistry(); m_deployer = createDeployer(); //final DefaultTaskletContext context = new DefaultTaskletContext(); //m_taskletEngine.contextualize( context ); final DefaultComponentManager componentManager = new DefaultComponentManager(); componentManager.put( "org.apache.ant.tasklet.engine.TaskletRegistry", m_taskletRegistry ); componentManager.put( "org.apache.ant.convert.ConverterRegistry", m_converterRegistry ); componentManager.put( "org.apache.avalon.camelot.Deployer", m_deployer ); m_taskletEngine.compose( componentManager ); if( m_taskletEngine instanceof Initializable ) { ((Initializable)m_taskletEngine).init(); } } public void dispose() throws Exception { if( m_taskletEngine instanceof Disposable ) { ((Disposable)m_taskletEngine).dispose(); } } public Deployer getDeployer() { return m_deployer; } protected TaskletEngine createTaskletEngine() { return new DefaultTaskletEngine(); } protected TaskletRegistry createTaskletRegistry() { return new DefaultTaskletRegistry(); } protected ConverterRegistry createConverterRegistry() { return new DefaultConverterRegistry(); } protected Deployer createDeployer() { final TskDeployer deployer = new TskDeployer( m_taskletRegistry, m_converterRegistry ); deployer.setLogger( m_logger ); return deployer; } public void execute( final Project project, final String target ) throws AntException { m_taskletEngine.contextualize( project.getContext() ); executeTarget( "", project.getImplicitTarget() ); final ArrayList done = new ArrayList(); execute( project, target, done ); } protected void execute( final Project project, final String targetName, final ArrayList done ) throws AntException { final Target target = project.getTarget( targetName ); if( null == target ) { throw new AntException( "Unable to find target " + targetName ); } done.add( targetName ); final Iterator dependencies = target.getDependencies(); while( dependencies.hasNext() ) { final String dependency = (String)dependencies.next(); if( !done.contains( dependency ) ) { execute( project, dependency, done ); } } final TaskletContext context = getContextFor( project, targetName ); m_taskletEngine.contextualize( context ); executeTarget( targetName, target ); } protected TaskletContext getContextFor( final Project project, final String targetName ) { final DefaultTaskletContext context = new DefaultTaskletContext( project.getContext() ); context.setProperty( Project.TARGET, targetName ); context.put( TaskletContext.LOGGER, m_logger ); return context; } protected void executeTarget( final String targetName, final Target target ) throws AntException { m_logger.debug( "Executing target " + targetName ); final Iterator tasks = target.getTasks(); while( tasks.hasNext() ) { final Configuration task = (Configuration)tasks.next(); executeTask( task ); } } protected void executeTask( final Configuration configuration ) throws AntException { final String name = configuration.getName(); m_logger.debug( "Executing task " + name ); m_taskletEngine.execute( configuration ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectListener.java Index: DefaultProjectListener.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import org.apache.log.format.PatternFormatter; import org.apache.log.output.DefaultOutputLogTarget; public class DefaultProjectListener extends DefaultOutputLogTarget implements ProjectListener { protected String m_prefix; /** * Initialize the default pattern. */ protected void initPattern() { final PatternFormatter formatrer = new PatternFormatter(); formatrer.setFormat( "%{message}\\n%{throwable}" ); m_formatter = formatrer; } public void projectStarted( final String projectName ) { output( "Starting project " + projectName + "\n" ); } public void projectFinished() { } public void targetStarted( final String targetName ) { output( targetName + ":\n" ); } public void targetFinished() { } public void taskletStarted( final String taskletName ) { m_prefix = taskletName; } public void taskletFinished() { m_prefix = null; } protected void output( final String data ) { if( null != m_prefix ) super.output( "[" + m_prefix + "] " + data ); else super.output( data ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java Index: DefaultTarget.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.util.ArrayList; import java.util.Iterator; import org.apache.ant.configuration.Configuration; public class DefaultTarget implements Target { protected ArrayList m_dependencies = new ArrayList(); protected ArrayList m_tasks = new ArrayList(); protected String m_condition; protected boolean m_isIfCondition; public Iterator getDependencies() { return m_dependencies.iterator(); } public Iterator getTasks() { return m_tasks.iterator(); } public String getCondition() { return m_condition; } public void setCondition( final String condition ) { m_condition = condition; } public boolean isIfCondition() { return m_isIfCondition; } public void setIfCondition( final boolean isIfCondition ) { m_isIfCondition = isIfCondition; } public void addDependency( final String dependency ) { m_dependencies.add( dependency ); } public void addTask( final Configuration taskConfiguration ) { m_tasks.add( taskConfiguration ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/Project.java Index: Project.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.util.Iterator; import org.apache.ant.AntException; import org.apache.ant.tasklet.TaskletContext; public interface Project { // the name of currently executing project String PROJECT = "ant.project.name"; // the name of currently executing project String PROJECT_FILE = "ant.project.file"; // the name of currently executing target String TARGET = "ant.target.name"; String getDefaultTargetName(); Target getImplicitTarget(); Target getTarget( String name ); Iterator getTargetNames(); TaskletContext getContext(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectBuilder.java Index: ProjectBuilder.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.io.File; import java.io.IOException; import org.apache.ant.AntException; import org.apache.log.Logger; public interface ProjectBuilder { void setLogger( Logger logger ); Project build( File projectFile ) throws IOException, AntException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectEngine.java Index: ProjectEngine.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import org.apache.ant.AntException; import org.apache.avalon.camelot.Deployer; import org.apache.avalon.camelot.Registry; import org.apache.log.Logger; public interface ProjectEngine { Deployer getDeployer(); void setLogger( Logger logger ); void execute( Project project, String target ) throws AntException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/ProjectListener.java Index: ProjectListener.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import org.apache.log.LogTarget; public interface ProjectListener extends LogTarget { void projectStarted( String projectName ); void projectFinished(); void targetStarted( String targetName ); void targetFinished(); void taskletStarted( String taskletName ); void taskletFinished(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/project/Target.java Index: Target.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.project; import java.util.Iterator; public interface Target { Iterator getDependencies(); Iterator getTasks(); String getCondition(); boolean isIfCondition(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java Index: AbstractTasklet.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet; import org.apache.ant.AntException; import org.apache.avalon.Context; import org.apache.avalon.Initializable; import org.apache.log.Logger; /** * This is abstract base class for tasklets. * * @author Peter Donald */ public abstract class AbstractTasklet implements Tasklet, Initializable { protected JavaVersion m_requiredJavaVersion; private TaskletContext m_context; private Logger m_logger; /** * Retrieve context from container. * * @param context the context */ public void contextualize( final Context context ) { m_context = (TaskletContext)context; m_logger = (Logger)m_context.getLogger(); } /** * This will be called before run() method and checks any preconditions. * * Intially preconditions just include JVM version but in future it * will automagically also check if all required parameters are present. * * @exception AntException if an error occurs */ public void init() throws AntException { if( null != m_requiredJavaVersion ) { final JavaVersion suppliedVersion = m_context.getJavaVersion(); if( m_requiredJavaVersion.isLessThan( suppliedVersion ) ) { throw new AntException( "Task requires a JavaVersion of at least " + m_requiredJavaVersion + " but current version is " + suppliedVersion ); } } } /** * Convenience method for sub-class to retrieve context. * * @return the context */ protected TaskletContext getContext() { return m_context; } /** * Convenience method for subclass to get logger. * * @return the Logger */ protected Logger getLogger() { return m_logger; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java Index: DefaultTaskletContext.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet; import java.io.File; import org.apache.ant.AntException; import org.apache.avalon.DefaultContext; import org.apache.avalon.util.PropertyException; import org.apache.avalon.util.PropertyUtil; import org.apache.avalon.util.io.FileUtil; import org.apache.log.Logger; /** * This represents the *Context* in which a task can be executed. * * @author Peter Donald */ public class DefaultTaskletContext extends DefaultContext implements TaskletContext { protected File m_baseDirectory; /** * Constructor for Context with no parent contexts. */ public DefaultTaskletContext() { this( null ); } /** * Constructor. */ public DefaultTaskletContext( final TaskletContext parent ) { super( parent ); if( null != parent ) { m_baseDirectory = (File)parent.get( BASE_DIRECTORY ); } } /** * Retrieve JavaVersion running under. * * @return the version of JVM */ public JavaVersion getJavaVersion() { return (JavaVersion)get( JAVA_VERSION ); } /** * Retrieve Name of tasklet. * * @return the name */ public String getName() { return (String)get( NAME ); } /** * Retrieve Logger associated with task. * * @return the logger */ public Logger getLogger() { return (Logger)get( LOGGER ); } /** * Retrieve base directory. * * @return the base directory */ public File getBaseDirectory() { return m_baseDirectory; } /** * Resolve filename. * This involves resolving it against baseDirectory and * removing ../ and ./ references. It also means formatting * it appropriately for the particular OS (ie different OS have * different volumes, file conventions etc) * * @param filename the filename to resolve * @return the resolved filename */ public String resolveFilename( final String filename ) { final File result = FileUtil.resolveFile( m_baseDirectory, filename ); if( null != result ) return result.toString(); else return null; } /** * Resolve property. * This evaluates all property substitutions based on current context. * * @param property the property to resolve * @return the resolved property */ public Object resolveValue( final String property ) { try { return PropertyUtil.resolveProperty( property, this, false ); } catch( final PropertyException pe ) { throw new AntException( "Error resolving " + property + " due to " +pe.getMessage(), pe ); } } /** * Retrieve property for name. * * @param name the name of property * @return the value of the property */ public Object getProperty( final String name ) { return get( name ); } /** * Set property value in current context. * * @param name the name of property * @param value the value of property */ public void setProperty( final String name, final Object value ) { setProperty( name, value, CURRENT ); } /** * Set property value. * * @param property the property */ public void setProperty( final String name, final Object value, final ScopeEnum scope ) { checkPropertyValid( name, value ); if( CURRENT == scope ) put( name, value ); else if( PARENT == scope ) { if( null == m_parent ) { throw new AntException( "Can't set a property with parent scope when context " + " has no parent" ); } else { ((DefaultTaskletContext)m_parent).put( name, value ); } } else if( TOP_LEVEL == scope ) { DefaultTaskletContext context = this; while( null != context.m_parent ) { context = (DefaultTaskletContext)context.m_parent; } context.put( name, value ); } else { throw new AntException( "Can't set a property with an unknown " + "property context! (" + scope + ")" ); } } public void put( final Object key, final Object value ) { if( key.equals( BASE_DIRECTORY ) ) { try { m_baseDirectory = (File)value; } catch( final ClassCastException cce ) { throw new AntException( "Can not set baseDirectory to a non-file value.", cce ); } } super.put( key, value ); } /** * Make sure property is valid if it is one of the "magic" properties. * * @param name the name of property * @param value the value of proeprty * @exception AntException if an error occurs */ protected void checkPropertyValid( final String name, final Object value ) throws AntException { if( LOGGER.equals( name ) && !( value instanceof Logger ) ) { throw new AntException( "property " + LOGGER + " must have a value of type " + Logger.class.getName() ); } else if( BASE_DIRECTORY.equals( name ) && !( value instanceof File ) ) { throw new AntException( "Property " + BASE_DIRECTORY + " must have a value of type " + File.class.getName() ); } else if( NAME.equals( name ) && !( value instanceof String ) ) { throw new AntException( "Property " + NAME + " must have a value of type " + String.class.getName() ); } else if( JAVA_VERSION.equals( name ) && !( value instanceof JavaVersion ) ) { throw new AntException( "property " + JAVA_VERSION + " must have a value of type " + JavaVersion.class.getName() ); } } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/JavaVersion.java Index: JavaVersion.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet; import org.apache.avalon.util.ValuedEnum; /** * Type safe wrapper class for Java Version enums. */ public final class JavaVersion extends ValuedEnum { //standard enums for version of JVM public final static JavaVersion JAVA1_0 = new JavaVersion( "Java 1.0", 100 ); public final static JavaVersion JAVA1_1 = new JavaVersion( "Java 1.1", 110 ); public final static JavaVersion JAVA1_2 = new JavaVersion( "Java 1.2", 120 ); public final static JavaVersion JAVA1_3 = new JavaVersion( "Java 1.3", 130 ); private JavaVersion( final String name, final int value ) { super( name, value ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java Index: Tasklet.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet; import org.apache.avalon.Component; import org.apache.avalon.Contextualizable; /** * This represents the individual tasks. * * @author Peter Donald */ public interface Tasklet extends Component, Contextualizable, Runnable { } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java Index: TaskletContext.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet; import java.io.File; import org.apache.avalon.Context; import org.apache.avalon.util.Enum; import org.apache.avalon.util.ValuedEnum; import org.apache.log.Logger; /** * This represents the *Context* in which a task can be executed. * * @author Peter Donald */ public interface TaskletContext extends Context { //these values are used when setting properties to indicate the scope at //which properties are set ScopeEnum CURRENT = new ScopeEnum( "Current" ); ScopeEnum PARENT = new ScopeEnum( "Parent" ); ScopeEnum TOP_LEVEL = new ScopeEnum( "TopLevel" ); //these are the names of properties that every TaskContext must contain String JAVA_VERSION = "ant.java.version"; String BASE_DIRECTORY = "ant.base.directory"; String LOGGER = "ant.logger"; String NAME = "ant.task.name"; /** * Retrieve JavaVersion running under. * * @return the version of JVM */ JavaVersion getJavaVersion(); /** * Retrieve Name of tasklet. * * @return the name */ String getName(); /** * Retrieve Logger associated with task. * * @return the logger */ Logger getLogger(); /** * Retrieve base directory. * * @return the base directory */ File getBaseDirectory(); /** * Resolve filename. * This involves resolving it against baseDirectory and * removing ../ and ./ references. It also means formatting * it appropriately for the particular OS (ie different OS have * different volumes, file conventions etc) * * @param filename the filename to resolve * @return the resolved filename */ String resolveFilename( String filename ); /** * Resolve property. * This evaluates all property substitutions based on current context. * * @param property the property to resolve * @return the resolved property */ Object resolveValue( String property ); /** * Retrieve property for name. * * @param name the name of property * @return the value of property */ Object getProperty( String name ); /** * Set property value in current context. * * @param name the name of property * @param value the value of property */ void setProperty( String name, Object value ); /** * Set property value. * * @param name the name of property * @param value the value of property * @param scope the scope at which to set property */ void setProperty( String name, Object value, ScopeEnum scope ); /** * Safe wrapper class for Scope enums. */ final class ScopeEnum extends Enum { ScopeEnum( final String name ) { super( name ); } } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletConfigurer.java Index: DefaultTaskletConfigurer.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import org.apache.ant.configuration.Configurable; import org.apache.ant.configuration.Configuration; import org.apache.ant.convert.Converter; import org.apache.ant.convert.ConverterEntry; import org.apache.ant.convert.ConverterFactory; import org.apache.ant.convert.ConverterInfo; import org.apache.ant.convert.ConverterRegistry; import org.apache.ant.tasklet.Tasklet; import org.apache.avalon.ComponentManager; import org.apache.avalon.ComponentNotAccessibleException; import org.apache.avalon.ComponentNotFoundException; import org.apache.avalon.Composer; import org.apache.avalon.ConfigurationException; import org.apache.avalon.Context; import org.apache.avalon.camelot.FactoryException; import org.apache.avalon.util.PropertyException; import org.apache.avalon.util.PropertyUtil; /** * Class used to configure tasks. * * @author Peter Donald */ public class DefaultTaskletConfigurer implements TaskletConfigurer, Composer { protected final static String RESERVED_ATTRIBUTES[] = { "id" }; protected final static String RESERVED_ELEMENTS[] = { "content" }; protected ConverterRegistry m_converterRegistry; protected ConverterFactory m_converterFactory; public void compose( final ComponentManager componentManager ) throws ComponentNotFoundException, ComponentNotAccessibleException { m_converterRegistry = (ConverterRegistry)componentManager. lookup( "org.apache.ant.convert.ConverterRegistry" ); m_converterFactory = (ConverterFactory)componentManager. lookup( "org.apache.ant.convert.ConverterFactory" ); } public void configure( final Tasklet tasklet, final Configuration configuration, final Context context ) throws ConfigurationException { configure( (Object)tasklet, configuration, context ); } public void configure( final Object object, final Configuration configuration, final Context context ) throws ConfigurationException { if( object instanceof Configurable ) { ((Configurable)object).configure( configuration ); } else { final Iterator attributes = configuration.getAttributeNames(); while( attributes.hasNext() ) { final String name = (String)attributes.next(); final String value = configuration.getAttribute( name ); configureAttribute( object, name, value, context ); } final Iterator elements = configuration.getChildren(); while( elements.hasNext() ) { final Configuration element = (Configuration)elements.next(); configureElement( object, element, context ); } final String content = configuration.getValue( null ); if( null != content ) { if( !content.trim().equals( "" ) ) { configureContent( object, content, context ); } } } } protected void configureContent( final Object object, final String content, final Context context ) throws ConfigurationException { setValue( object, "addContent", content, context ); } protected void configureAttribute( final Object object, final String name, final String value, final Context context ) throws ConfigurationException { for( int i = 0; i < RESERVED_ATTRIBUTES.length; i++ ) { if( RESERVED_ATTRIBUTES[ i ].equals( name ) ) return; } final String methodName = getMethodNameFor( name ); setValue( object, methodName, value, context ); } protected void setValue( final Object object, final String methodName, final String value, final Context context ) throws ConfigurationException { // OMFG the rest of this is soooooooooooooooooooooooooooooooo // slow. Need to cache results per class etc. final Class clazz = object.getClass(); final Method methods[] = getMethodsFor( clazz, methodName ); if( 0 == methods.length ) { throw new ConfigurationException( "Unable to set attribute via " + methodName + " due to not finding any appropriate " + "accessor method" ); } setValue( object, value, context, methods ); } protected void setValue( final Object object, final String value, final Context context, final Method methods[] ) throws ConfigurationException { try { final Object objectValue = PropertyUtil.resolveProperty( value, context, false ); setValue( object, objectValue, methods ); } catch( final PropertyException pe ) { throw new ConfigurationException( "Error resolving property " + value, pe ); } } protected void setValue( final Object object, Object value, final Method methods[] ) throws ConfigurationException { final Class sourceClass = value.getClass(); final String source = sourceClass.getName(); for( int i = 0; i < methods.length; i++ ) { if( setValue( object, value, methods[ i ], sourceClass, source ) ) { return; } } throw new ConfigurationException( "Unable to set attribute via " + methods[ 0 ].getName() + " as could not convert " + source + " to a matching type" ); } protected boolean setValue( final Object object, Object value, final Method method, final Class sourceClass, final String source ) throws ConfigurationException { Class parameterType = method.getParameterTypes()[ 0 ]; if( parameterType.isPrimitive() ) { parameterType = getComplexTypeFor( parameterType ); } if( !parameterType.isAssignableFrom( sourceClass ) ) { final String destination = parameterType.getName(); try { final ConverterInfo info = m_converterRegistry. getConverterInfo( source, destination ); if( null == info ) return false; final ConverterEntry entry = m_converterFactory.create( info ); final Converter converter = entry.getConverter(); value = converter.convert( parameterType, value ); } catch( final FactoryException fe ) { throw new ConfigurationException( "Badly configured ConverterFactory ", fe ); } catch( final Exception e ) { throw new ConfigurationException( "Error converting attribute for " + method.getName(), e ); } } try { method.invoke( object, new Object[] { value } ); } catch( final IllegalAccessException iae ) { //should never happen .... throw new ConfigurationException( "Error retrieving methods with " + "correct access specifiers", iae ); } catch( final InvocationTargetException ite ) { throw new ConfigurationException( "Error calling method attribute " + method.getName(), ite ); } return true; } protected Class getComplexTypeFor( final Class clazz ) { if( String.class == clazz ) return String.class; else if( Integer.TYPE.equals( clazz ) ) return Integer.class; else if( Long.TYPE.equals( clazz ) ) return Long.class; else if( Short.TYPE.equals( clazz ) ) return Short.class; else if( Byte.TYPE.equals( clazz ) ) return Byte.class; else if( Boolean.TYPE.equals( clazz ) ) return Boolean.class; else if( Float.TYPE.equals( clazz ) ) return Float.class; else if( Double.TYPE.equals( clazz ) ) return Double.class; else { throw new IllegalArgumentException( "Can not get complex type for non-primitive " + "type " + clazz.getName() ); } } protected Method[] getMethodsFor( final Class clazz, final String methodName ) { final Method methods[] = clazz.getMethods(); final ArrayList matches = new ArrayList(); for( int i = 0; i < methods.length; i++ ) { final Method method = methods[ i ]; if( methodName.equals( method.getName() ) && Method.PUBLIC == (method.getModifiers() & Method.PUBLIC) ) { if( method.getReturnType().equals( Void.TYPE ) ) { final Class parameters[] = method.getParameterTypes(); if( 1 == parameters.length ) { matches.add( method ); } } } } return (Method[])matches.toArray( new Method[0] ); } protected Method[] getCreateMethodsFor( final Class clazz, final String methodName ) { final Method methods[] = clazz.getMethods(); final ArrayList matches = new ArrayList(); for( int i = 0; i < methods.length; i++ ) { final Method method = methods[ i ]; if( methodName.equals( method.getName() ) && Method.PUBLIC == (method.getModifiers() & Method.PUBLIC) ) { final Class returnType = method.getReturnType(); if( !returnType.equals( Void.TYPE ) && !returnType.isPrimitive() ) { final Class parameters[] = method.getParameterTypes(); if( 0 == parameters.length ) { matches.add( method ); } } } } return (Method[])matches.toArray( new Method[0] ); } protected String getMethodNameFor( final String attribute ) { return "set" + getJavaNameFor( attribute ); } protected String getJavaNameFor( final String name ) { final StringBuffer sb = new StringBuffer(); int index = name.indexOf( '-' ); int last = 0; while( -1 != index ) { final String word = name.substring( last, index ).toLowerCase(); sb.append( Character.toUpperCase( word.charAt( 0 ) ) ); sb.append( word.substring( 1, word.length() ) ); last = index + 1; index = name.indexOf( '-', last ); } index = name.length(); final String word = name.substring( last, index ).toLowerCase(); sb.append( Character.toUpperCase( word.charAt( 0 ) ) ); sb.append( word.substring( 1, word.length() ) ); return sb.toString(); } protected void configureElement( final Object object, final Configuration configuration, final Context context ) throws ConfigurationException { final String name = configuration.getName(); for( int i = 0; i < RESERVED_ELEMENTS.length; i++ ) { if( RESERVED_ATTRIBUTES[ i ].equals( name ) ) return; } final String javaName = getJavaNameFor( name ); // OMFG the rest of this is soooooooooooooooooooooooooooooooo // slow. Need to cache results per class etc. final Class clazz = object.getClass(); Method methods[] = getMethodsFor( clazz, "add" + javaName ); if( 0 != methods.length ) { //guess it is first method ???? addElement( object, methods[ 0 ], configuration, context ); } else { methods = getCreateMethodsFor( clazz, "create" + javaName ); if( 0 == methods.length ) { throw new ConfigurationException( "Unable to set attribute " + javaName + " due to not finding any appropriate " + "accessor method" ); } //guess it is first method ???? createElement( object, methods[ 0 ], configuration, context ); } } protected void createElement( final Object object, final Method method, final Configuration configuration, final Context context ) throws ConfigurationException { try { final Object created = method.invoke( object, new Object[ 0 ] ); configure( created, configuration, context ); } catch( final ConfigurationException ce ) { throw ce; } catch( final Exception e ) { throw new ConfigurationException( "Error creating sub-element", e ); } } protected void addElement( final Object object, final Method method, final Configuration configuration, final Context context ) throws ConfigurationException { try { final Class clazz = method.getParameterTypes()[ 0 ]; final Object created = clazz.newInstance(); configure( created, configuration, context ); method.invoke( object, new Object[] { created } ); } catch( final ConfigurationException ce ) { throw ce; } catch( final Exception e ) { throw new ConfigurationException( "Error creating sub-element", e ); } } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java Index: DefaultTaskletEngine.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.util.HashMap; import org.apache.ant.AntException; import org.apache.ant.configuration.Configurable; import org.apache.ant.configuration.Configuration; import org.apache.ant.convert.ConverterFactory; import org.apache.ant.convert.ConverterRegistry; import org.apache.ant.tasklet.Tasklet; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.ComponentManager; import org.apache.avalon.ComponentNotAccessibleException; import org.apache.avalon.ComponentNotFoundException; import org.apache.avalon.Composer; import org.apache.avalon.Context; import org.apache.avalon.Contextualizable; import org.apache.avalon.DefaultComponentManager; import org.apache.avalon.Disposable; import org.apache.avalon.Initializable; import org.apache.avalon.camelot.FactoryException; import org.apache.avalon.camelot.RegistryException; import org.apache.log.Logger; public class DefaultTaskletEngine implements TaskletEngine, Initializable { protected ComponentManager m_componentManager; protected TaskletContext m_context; protected TaskletFactory m_taskletFactory; protected ConverterFactory m_converterFactory; protected TaskletRegistry m_taskletRegistry; protected ConverterRegistry m_converterRegistry; protected TaskletConfigurer m_configurer; protected Logger m_logger; public void contextualize( final Context context ) { m_context = (TaskletContext)context; m_logger = m_context.getLogger(); } public void compose( final ComponentManager componentManager ) throws ComponentNotFoundException, ComponentNotAccessibleException { m_componentManager = componentManager; m_taskletRegistry = (TaskletRegistry)componentManager. lookup( "org.apache.ant.tasklet.engine.TaskletRegistry" ); m_converterRegistry = (ConverterRegistry)componentManager. lookup( "org.apache.ant.convert.ConverterRegistry" ); } public void init() throws Exception { m_taskletFactory = createTaskletFactory(); m_converterFactory = createConverterFactory(); m_configurer = createTaskletConfigurer(); if( m_configurer instanceof Composer ) { final DefaultComponentManager componentManager = new DefaultComponentManager( m_componentManager ); componentManager.put( "org.apache.ant.convert.ConverterFactory", m_converterFactory ); ((Composer)m_configurer).compose( componentManager ); } if( m_configurer instanceof Initializable ) { ((Initializable)m_configurer).init(); } } protected TaskletConfigurer createTaskletConfigurer() { return new DefaultTaskletConfigurer(); } protected TaskletFactory createTaskletFactory() { return new DefaultTaskletFactory(); } protected ConverterFactory createConverterFactory() { return (ConverterFactory)m_taskletFactory; } public void execute( final Configuration task ) throws AntException { final Tasklet tasklet = createTasklet( task ); final String name = task.getName(); m_logger.debug( "Created task " + name ); doContextualize( tasklet, task ); m_logger.debug( "Contextualized task " + name ); doCompose( tasklet, task ); m_logger.debug( "Composed task " + name ); doConfigure( tasklet, task ); m_logger.debug( "Configured task " + name ); doInitialize( tasklet, task ); m_logger.debug( "Initialize task " + name ); tasklet.run(); m_logger.debug( "Ran task " + name ); doDispose( tasklet, task ); m_logger.debug( "Dispose task " + name ); } protected void doConfigure( final Tasklet tasklet, final Configuration task ) throws AntException { try { m_configurer.configure( tasklet, task, m_context ); } catch( final Throwable throwable ) { throw new AntException( "Error configuring task " + task.getName() + " at " + task.getLocation() + "(Reason: " + throwable.getMessage() + ")", throwable ); } } protected TaskletContext getContextFor( final String name ) { //If we are single threaded we really don't need to have a new object //for context ... if we are not single threaded then we need to create new //context. Alternatively we could remove getName from TaskletContext //final DefaultTaskletContext context = new DefaultTaskletContext( m_context ); m_context.setProperty( TaskletContext.NAME, name ); return m_context; } protected void doCompose( final Tasklet tasklet, final Configuration task ) throws AntException { if( tasklet instanceof Composer ) { try { ((Composer)tasklet).compose( m_componentManager ); } catch( final Throwable throwable ) { throw new AntException( "Error composing task " + task.getName() + " at " + task.getLocation() + "(Reason: " + throwable.getMessage() + ")", throwable ); } } } protected void doContextualize( final Tasklet tasklet, final Configuration task ) throws AntException { final TaskletContext context = getContextFor( task.getName() ); try { tasklet.contextualize( context ); } catch( final Throwable throwable ) { throw new AntException( "Error contextualizing task " + task.getName() + " at " + task.getLocation() + "(Reason: " + throwable.getMessage() + ")", throwable ); } } protected void doDispose( final Tasklet tasklet, final Configuration task ) throws AntException { if( tasklet instanceof Disposable ) { try { ((Disposable)tasklet).dispose(); } catch( final Throwable throwable ) { throw new AntException( "Error disposing task " + task.getName() + " at " + task.getLocation() + "(Reason: " + throwable.getMessage() + ")", throwable ); } } } protected void doInitialize( final Tasklet tasklet, final Configuration task ) throws AntException { if( tasklet instanceof Initializable ) { try { ((Initializable)tasklet).init(); } catch( final Throwable throwable ) { throw new AntException( "Error initializing task " + task.getName() + " at " + task.getLocation() + "(Reason: " + throwable.getMessage() + ")", throwable ); } } } protected Tasklet createTasklet( final Configuration configuration ) throws AntException { final String name = configuration.getName(); TaskletInfo info = null; try { info = (TaskletInfo)m_taskletRegistry.getInfo( name ); } catch( final RegistryException re ) { throw new AntException( "Unable to locate task " + name, re ); } TaskletEntry entry = null; try { entry = m_taskletFactory.create( info ); } catch( final FactoryException fe ) { throw new AntException( "Unable to create task " + name + " (of type " + info.getClassname() + " from " + info.getLocation() + ")", fe ); } return entry.getTasklet(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletFactory.java Index: DefaultTaskletFactory.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import org.apache.ant.tasklet.Tasklet; import org.apache.ant.convert.ConverterLoader; import org.apache.ant.convert.DefaultConverterFactory; import org.apache.avalon.camelot.Entry; import org.apache.avalon.camelot.Factory; import org.apache.avalon.camelot.FactoryException; import org.apache.avalon.camelot.Info; /** * Facility used to load Tasklets. * * @author Peter Donald */ public class DefaultTaskletFactory extends DefaultConverterFactory implements TaskletFactory { public Entry create( final Info info ) throws FactoryException { if( !info.getClass().equals( TaskletInfo.class ) ) { return super.create( info ); } else { return create( (TaskletInfo)info ); } } public TaskletEntry create( final TaskletInfo info ) throws FactoryException { final TaskletLoader loader = (TaskletLoader)getLoader( info.getLocation() ); Object object = null; try { object = loader.load( info.getClassname() ); } catch( final Exception e ) { throw new FactoryException( "Failed loading tasklet from " + info.getLocation() + " due to " + e, e ); } return new TaskletEntry( info, (Tasklet)object ); } protected ConverterLoader createLoader( final URL location ) { if( null != location ) return new DefaultTaskletLoader( location ); else return new DefaultTaskletLoader(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletInfo.java Index: DefaultTaskletInfo.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.net.URL; import org.apache.avalon.camelot.Info; /** * This is default container of information about a task. * A BeanInfo equivelent for a task. Eventually it will auto-magically * generate a schema via reflection for Validator/Editor tools. * * @author Peter Donald */ public class DefaultTaskletInfo implements TaskletInfo { protected final String m_classname; protected final URL m_location; /** * Constructor that takes classname and taskLibraryLocation. */ public DefaultTaskletInfo( final String classname, final URL location ) { m_location = location; m_classname = classname; } /** * Retrieve classname for task. * * @return the taskname */ public String getClassname() { return m_classname; } /** * Retrieve tasklib location from which task is loaded. * * @return the location */ public URL getLocation() { return m_location; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletLoader.java Index: DefaultTaskletLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.net.URL; import org.apache.ant.tasklet.Tasklet; import org.apache.ant.convert.DefaultConverterLoader; /** * Class used to load tasks et al from a source. * * @author Peter Donald */ public class DefaultTaskletLoader extends DefaultConverterLoader implements TaskletLoader { public DefaultTaskletLoader() { } public DefaultTaskletLoader( final URL location ) { super( location ); } public Tasklet loadTasklet( final String tasklet ) throws Exception { return (Tasklet)load( tasklet ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletRegistry.java Index: DefaultTaskletRegistry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.avalon.camelot.AbstractRegistry; public class DefaultTaskletRegistry extends AbstractRegistry implements TaskletRegistry { protected Class getInfoClass() { return TaskletInfo.class; } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletConfigurer.java Index: TaskletConfigurer.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.ant.configuration.Configuration; import org.apache.ant.tasklet.Tasklet; import org.apache.avalon.ConfigurationException; import org.apache.avalon.Context; /** * Class used to configure tasks. * * @author Peter Donald */ public interface TaskletConfigurer { void configure( Tasklet tasklet, Configuration configuration, Context context ) throws ConfigurationException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java Index: TaskletEngine.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.ant.AntException; import org.apache.ant.configuration.Configuration; import org.apache.avalon.Composer; import org.apache.avalon.Contextualizable; public interface TaskletEngine extends Contextualizable, Composer { void execute( final Configuration task ) throws AntException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEntry.java Index: TaskletEntry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.ant.tasklet.Tasklet; import org.apache.avalon.camelot.AbstractEntry; public class TaskletEntry extends AbstractEntry { public TaskletEntry( final TaskletInfo info, final Tasklet tasklet ) { super( info, tasklet ); } /** * Retrieve instance of tasklet. * * @return the component instance */ public Tasklet getTasklet() { return (Tasklet)getInstance(); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletFactory.java Index: TaskletFactory.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.avalon.camelot.Factory; import org.apache.avalon.camelot.FactoryException; /** * Facility used to load Tasklets. * * @author Peter Donald */ public interface TaskletFactory extends Factory { TaskletEntry create( TaskletInfo info ) throws FactoryException; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletInfo.java Index: TaskletInfo.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.net.URL; import org.apache.avalon.camelot.Info; /** * This is information about a task. * A BeanInfo equivelent for a task. Eventually it will auto-magically * generate a schema via reflection for Validator/Editor tools. * * @author Peter Donald */ public interface TaskletInfo extends Info { /** * Retrieve classname for task. * * @return the taskname */ String getClassname(); /** * Retrieve location of task library where task is contained. * * @return the location of task library */ URL getLocation(); } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletLoader.java Index: TaskletLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.ant.tasklet.Tasklet; import org.apache.avalon.camelot.Loader; /** * Class used to load tasks et al from a source. * * @author Peter Donald */ public interface TaskletLoader extends Loader { Tasklet loadTasklet( String tasklet ) throws Exception; } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletRegistry.java Index: TaskletRegistry.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import org.apache.avalon.camelot.Registry; public interface TaskletRegistry extends Registry { } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java Index: TskDeployer.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasklet.engine; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Properties; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.apache.ant.tasklet.engine.DefaultTaskletInfo; import org.apache.ant.convert.ConverterRegistry; import org.apache.ant.convert.DefaultConverterInfo; import org.apache.avalon.Component; import org.apache.avalon.camelot.AbstractDeployer; import org.apache.avalon.camelot.DeploymentException; import org.apache.avalon.camelot.RegistryException; import org.apache.log.Logger; /** * This class deploys a .tsk file into a registry. * * @author Peter Donald */ public class TskDeployer extends AbstractDeployer { protected final static String TASKDEF_FILE = "TASK-LIB/taskdefs.properties"; protected final static String CONVERTER_FILE = "TASK-LIB/converters.properties"; protected TaskletRegistry m_taskletRegistry; protected ConverterRegistry m_converterRegistry; public TskDeployer( final TaskletRegistry taskletRegistry, final ConverterRegistry converterRegistry ) { m_taskletRegistry = taskletRegistry; m_converterRegistry = converterRegistry; m_autoUndeploy = true; m_type = "Tasklet"; } public void setLogger( final Logger logger ) { m_logger = logger; } protected boolean isValidLocation( final String location ) { //TODO: Make sure it is valid JavaIdentifier //that optionally has '-' embedded in it return true; } /** * Deploy Tasklets from a .tsk file. * Eventually this should be cached for performance reasons. * * @param location the location * @param file the file * @exception DeploymentException if an error occurs */ protected void deployFromFile( final String location, final File file ) throws DeploymentException { m_logger.info( "Deploying .tsk file (" + file + ") as " + location ); ZipFile zipFile = null; try { zipFile = new ZipFile( file ); } catch( final IOException ioe ) { throw new DeploymentException( "Error opening " + file + " due to " + ioe.getMessage(), ioe ); } try { final Properties taskdefs = loadProperties( zipFile, TASKDEF_FILE ); final Properties converters = loadProperties( zipFile, CONVERTER_FILE ); try { zipFile.close(); } catch( final IOException ioe ) {} URL url = null; try { url = file.toURL(); } catch( final MalformedURLException mue ) {} handleTaskdefs( taskdefs, url ); handleConverters( converters, url ); } catch( final DeploymentException de ) { try { zipFile.close(); } catch( final IOException ioe ) {} throw de; } } protected void handleConverters( final Properties properties, final URL url ) throws DeploymentException { final Enumeration enum = properties.propertyNames(); while( enum.hasMoreElements() ) { final String key = (String)enum.nextElement(); final String value = (String)properties.get( key ); final int index = value.indexOf( ',' ); if( -1 == index ) { throw new DeploymentException( "Malformed converter definition (" + key + ")" ); } final String source = value.substring( 0, index ).trim(); final String destination = value.substring( index + 1 ).trim(); final DefaultConverterInfo info = new DefaultConverterInfo( source, destination, key, url ); try { m_converterRegistry.register( key, info ); } catch( final RegistryException re ) { throw new DeploymentException( "Error registering converter " + key + " due to " + re, re ); } } } protected void handleTaskdefs( final Properties properties, final URL url ) throws DeploymentException { final Enumeration enum = properties.propertyNames(); while( enum.hasMoreElements() ) { final String key = (String)enum.nextElement(); final String value = (String)properties.get( key ); final DefaultTaskletInfo info = new DefaultTaskletInfo( value, url ); try { m_taskletRegistry.register( key, info ); } catch( final RegistryException re ) { throw new DeploymentException( "Error registering " + key + " due to " + re, re ); } } } protected Properties loadProperties( final ZipFile zipFile, final String filename ) throws DeploymentException { final ZipEntry entry = zipFile.getEntry( filename ); if( null == entry ) { throw new DeploymentException( "Unable to locate " + filename + " in " + zipFile.getName() ); } Properties properties = new Properties(); try { properties.load( zipFile.getInputStream( entry ) ); } catch( final IOException ioe ) { throw new DeploymentException( "Error reading " + filename + " from " + zipFile.getName(), ioe ); } return properties; } protected boolean canUndeploy( final Component component ) throws DeploymentException { return true; } protected void shutdownDeployment( final Component component ) throws DeploymentException { } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/ConfigurationTest.java Index: ConfigurationTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.configuration.Configurable; import org.apache.ant.configuration.Configuration; import org.apache.ant.tasklet.AbstractTasklet; import org.apache.avalon.ConfigurationException; /** * This is abstract base class for tasklets. * * @author Peter Donald */ public class ConfigurationTest extends AbstractTasklet implements Configurable { protected String m_message; public void configure( final Configuration configuration ) throws ConfigurationException { String message = configuration.getAttribute( "message" ); final Object object = getContext().resolveValue( message ); if( object instanceof String ) { m_message = (String)object; } else { m_message = object.toString(); } } public void run() throws AntException { getLogger().info( m_message ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/ContentTest.java Index: ContentTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.tasklet.AbstractTasklet; /** * This is abstract base class for tasklets. * * @author Peter Donald */ public class ContentTest extends AbstractTasklet { public void addContent( final Integer value ) { getLogger().info( "Integer content: " + value ); } /* public void addContent( final String blah ) { System.out.println( "String: " + blah ); } */ public void run() throws AntException { } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Echo.java Index: Echo.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.tasklet.AbstractTasklet; /** * This is abstract base class for tasklets. * * @author Peter Donald */ public class Echo extends AbstractTasklet { protected String m_message; public void setMessage( final String message ) { m_message = message; } public void run() throws AntException { getLogger().info( m_message ); } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/PrimitiveTypesTest.java Index: PrimitiveTypesTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.tasklet.AbstractTasklet; /** * * @author Peter Donald */ public class PrimitiveTypesTest extends AbstractTasklet { public void setInteger( final Integer value ) { getLogger().info( "setInteger( " + value + " );" ); } public void setInteger2( final int value ) { getLogger().info( "setInteger2( " + value + " );" ); } public void setShort( final Short value ) { getLogger().info( "setShort( " + value + " );" ); } public void setShort2( final short value ) { getLogger().info( "setShort2( " + value + " );" ); } public void setByte( final Byte value ) { getLogger().info( "setByte( " + value + " );" ); } public void setByte2( final byte value ) { getLogger().info( "setByte2( " + value + " );" ); } public void setLong( final Long value ) { getLogger().info( "setLong( " + value + " );" ); } public void setLong2( final long value ) { getLogger().info( "setLong2( " + value + " );" ); } public void setFloat( final Float value ) { getLogger().info( "setFloat( " + value + " );" ); } public void setFloat2( final float value ) { getLogger().info( "setFloat2( " + value + " );" ); } public void setDouble( final Double value ) { getLogger().info( "setDouble( " + value + " );" ); } public void setDouble2( final double value ) { getLogger().info( "setDouble2( " + value + " );" ); } public void setString( final String value ) { getLogger().info( "setString( " + value + " );" ); } public void run() throws AntException { } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java Index: Property.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.tasklet.AbstractTasklet; import org.apache.ant.tasklet.TaskletContext; /** * @author Peter Donald */ public class Property extends AbstractTasklet { protected String m_name; protected String m_value; protected boolean m_localScope = true; public void setName( final String name ) { m_name = name; } public void setValue( final String value ) { m_value = value; } public void setLocalScope( final boolean localScope ) { m_localScope = localScope; } public void run() throws AntException { if( null == m_name ) { throw new AntException( "Name must be specified" ); } if( null == m_value ) { throw new AntException( "Value must be specified" ); } final TaskletContext context = getContext(); final Object value = context.resolveValue( m_value ); if( m_localScope ) { context.setProperty( m_name, value ); } else { context.setProperty( m_name, value, TaskletContext.PARENT ); } } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/SubElementTest.java Index: SubElementTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.ant.tasks.core; import org.apache.ant.AntException; import org.apache.ant.tasklet.AbstractTasklet; /** * @author Peter Donald */ public class SubElementTest extends AbstractTasklet { public static final class Beep { public void setMessage( final String string ) { System.out.println( string ); } } public Beep createCreateBeep() { System.out.println( "createCreateBeep()" ); return new Beep(); } public void addAddBeep( final Beep beep ) { System.out.println( "addBeeper(" + beep + ");" ); } public void run() throws AntException { } } 1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/ant/tasks/core/taskdefs.properties Index: taskdefs.properties =================================================================== # TASK-LIB/taskdefs.properties echo=org.apache.ant.tasks.core.Echo prim-test=org.apache.ant.tasks.core.PrimitiveTypesTest sub-elements-test=org.apache.ant.tasks.core.SubElementTest conf-test=org.apache.ant.tasks.core.ConfigurationTest content-test=org.apache.ant.tasks.core.ContentTest property=org.apache.ant.tasks.core.Property 1.1 jakarta-ant/proposal/myrmidon/src/make/sample.xmk Index: sample.xmk =================================================================== 123 1.1 jakarta-ant/proposal/myrmidon/src/script/ant Index: ant =================================================================== #!/bin/sh if [ -f $HOME/.antrc ] ; then . $HOME/.antrc fi # Cygwin support. if [ "$OSTYPE" == "cygwin32" ] || [ "$OSTYPE" = "cygwin" ]; then if [ ! "$JAVA_HOME" = "" ]; then JAVA_HOME=`cygpath --path --unix $JAVA_HOME` fi fi ## resolve links - $0 may be a link to ant's home PRG=$0 progname=`basename $0` while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '.*/.*' > /dev/null; then PRG="$link" else PRG="`dirname $PRG`/$link" fi done ANT_HOME=`dirname "$PRG"`/.. # Allow .antrc to specifiy flags to java cmd if [ "$JAVACMD" = "" ] ; then JAVACMD=java fi LOCALCLASSPATH=`echo $ANT_HOME/lib/*.jar | tr ' ' ':'` if [ "$CLASSPATH" != "" ] ; then LOCALCLASSPATH=$CLASSPATH:$LOCALCLASSPATH fi if [ "$JAVA_HOME" != "" ] ; then if test -f $JAVA_HOME/lib/tools.jar ; then LOCALCLASSPATH=$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar fi else echo "Warning: JAVA_HOME environment variable is not set." echo " If build fails because sun.* classes could not be found" echo " you will need to set the JAVA_HOME environment variable" echo " to the installation directory of java." fi # More Cygwin support if [ "$OSTYPE" == "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then LOCALCLASSPATH=`cygpath --path --windows "$LOCALCLASSPATH"` fi $JAVACMD -classpath $LOCALCLASSPATH $ANT_OPTS org.apache.ant.Main --ant-home=${ANT_HOME} $@ 1.1 jakarta-ant/proposal/myrmidon/src/script/ant.bat Index: ant.bat =================================================================== @echo off :checkJava if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java if not "%JAVA_HOME%" == "" goto setupClasspath echo. echo Warning: JAVA_HOME environment variable is not set. echo If build fails because sun.* classes could not be found echo you will need to set the JAVA_HOME environment variable echo to the installation directory of java. echo. goto end :setupClasspath set LOCALCLASSPATH=lib\xerces.jar;lib\ant.jar;lib\avalonapi.jar;%JAVA_HOME%\lib\tools.jar set THIS_FILE=%0 set ANT_CMD_LINE_ARGS= rem Slurp all args... :setupArgs if "%0" == "" goto doneArgs set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1 shift goto setupArgs :doneArgs rem Mmmmmm tasty - finished slurping args %JAVACMD% -classpath "%LOCALCLASSPATH%" %ANT_OPTS% org.apache.ant.Main "--bin-dir=%THIS_FILE%" %ANT_CMD_LINE_ARGS% :end set LOCALCLASSPATH= 1.1 jakarta-ant/proposal/myrmidon/src/script/antRun Index: antRun =================================================================== #! /bin/sh # Args: DIR command cd "$1" CMD="$2" shift shift exec $CMD "$@" 1.1 jakarta-ant/proposal/myrmidon/src/script/antRun.bat Index: antRun.bat =================================================================== @echo off cd %1 set ANT_RUN_CMD=%2 shift shift set PARAMS= :loop if "%1" == "" goto runCommand set PARAMS=%PARAMS% %1 shift goto loop :runCommand echo %ANT_RUN_CMD% %PARAMS% %ANT_RUN_CMD% %PARAMS%