diff --git a/proposal/myrmidon/lib/avalonapi.jar b/proposal/myrmidon/lib/avalonapi.jar index f68bdb822..8a8f6ad5c 100644 Binary files a/proposal/myrmidon/lib/avalonapi.jar and b/proposal/myrmidon/lib/avalonapi.jar differ diff --git a/proposal/myrmidon/src/java/org/apache/ant/Main.java b/proposal/myrmidon/src/java/org/apache/ant/Main.java index 8446af2e7..a5424a039 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/Main.java +++ b/proposal/myrmidon/src/java/org/apache/ant/Main.java @@ -27,7 +27,7 @@ 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.project.ProjectToListenerAdapter; +import org.apache.ant.project.LogTargetToListenerAdapter; import org.apache.ant.tasklet.JavaVersion; import org.apache.ant.tasklet.TaskletContext; import org.apache.ant.tasklet.engine.TaskletEngine; @@ -232,7 +232,8 @@ public class Main new CLOptionDescriptor( "define", CLOptionDescriptor.ARGUMENTS_REQUIRED_2, DEFINE_OPT, - "Define a variable (ie -Dfoo=var)" ); + "Define a variable (ie -Dfoo=var)", + new int[ 0 ] ); return options; } @@ -481,7 +482,7 @@ public class Main protected void setupListener( final String listenerName ) { m_listener = createListener( listenerName ); - m_logger.addLogTarget( new ProjectToListenerAdapter( m_listener ) ); + m_logger.addLogTarget( new LogTargetToListenerAdapter( m_listener ) ); } /** @@ -566,7 +567,6 @@ public class Main defines.put( AntContextResources.LIB_DIR, m_libDir ); defines.put( AntContextResources.TASKLIB_DIR, m_taskLibDir ); //defines.put( AntContextResources.USER_DIR, m_userDir ); - defines.put( TaskletContext.LOGGER, m_logger ); defines.put( TaskletContext.JAVA_VERSION, getJavaVersion() ); final TaskletContext context = project.getContext(); diff --git a/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfigurer.java b/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfigurer.java index f10195ca9..1dbbfc644 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfigurer.java +++ b/proposal/myrmidon/src/java/org/apache/ant/configuration/DefaultConfigurer.java @@ -19,8 +19,10 @@ import org.apache.avalon.ComponentNotFoundException; import org.apache.avalon.Composer; import org.apache.avalon.ConfigurationException; import org.apache.avalon.Context; +import org.apache.avalon.Loggable; import org.apache.avalon.util.PropertyException; import org.apache.avalon.util.PropertyUtil; +import org.apache.log.Logger; /** * Class used to configure tasks. @@ -28,7 +30,7 @@ import org.apache.avalon.util.PropertyUtil; * @author Peter Donald */ public class DefaultConfigurer - implements Configurer, Composer + implements Configurer, Composer, Loggable { protected final static String RESERVED_ATTRIBUTES[] = { @@ -40,7 +42,14 @@ public class DefaultConfigurer "content" }; + protected final static boolean DEBUG = false; protected Converter m_converter; + protected Logger m_logger; + + public void setLogger( final Logger logger ) + { + m_logger = logger; + } public void compose( final ComponentManager componentManager ) throws ComponentNotFoundException, ComponentNotAccessibleException @@ -66,18 +75,39 @@ public class DefaultConfigurer final Context context ) throws ConfigurationException { + if( DEBUG ) + { + m_logger.debug( "Configuring " + object ); + } + if( object instanceof Configurable ) { + if( DEBUG ) + { + m_logger.debug( "Configuring object via Configurable interface" ); + } + ((Configurable)object).configure( configuration ); } else { - final Iterator attributes = configuration.getAttributeNames(); + if( DEBUG ) + { + m_logger.debug( "Configuring object via Configurable reflection" ); + } + final Iterator attributes = configuration.getAttributeNames(); while( attributes.hasNext() ) { final String name = (String)attributes.next(); final String value = configuration.getAttribute( name ); + + if( DEBUG ) + { + m_logger.debug( "Configuring attribute name=" + name + + " value=" + value ); + } + configureAttribute( object, name, value, context ); } @@ -86,6 +116,12 @@ public class DefaultConfigurer while( elements.hasNext() ) { final Configuration element = (Configuration)elements.next(); + + if( DEBUG ) + { + m_logger.debug( "Configuring subelement name=" + element.getName() ); + } + configureElement( object, element, context ); } @@ -95,6 +131,11 @@ public class DefaultConfigurer { if( !content.trim().equals( "" ) ) { + if( DEBUG ) + { + m_logger.debug( "Configuring content " + content ); + } + configureContent( object, content, context ); } } @@ -206,22 +247,24 @@ public class DefaultConfigurer parameterType = getComplexTypeFor( parameterType ); } - if( !parameterType.isAssignableFrom( sourceClass ) ) + try { - try - { - value = m_converter.convert( parameterType, object ); - } - catch( final ConverterException ce ) - { - return false; - } - catch( final Exception e ) + value = m_converter.convert( parameterType, value ); + } + catch( final ConverterException ce ) + { + if( DEBUG ) { - throw new ConfigurationException( "Error converting attribute for " + - method.getName(), - e ); + m_logger.debug( "Failed to find converter ", ce ); } + + return false; + } + catch( final Exception e ) + { + throw new ConfigurationException( "Error converting attribute for " + + method.getName(), + e ); } try diff --git a/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEngine.java b/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEngine.java index 8dff694f4..08b2b7485 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEngine.java +++ b/proposal/myrmidon/src/java/org/apache/ant/convert/ConverterEngine.java @@ -15,6 +15,6 @@ import org.apache.log.Logger; public interface ConverterEngine extends Component, Converter, Loggable { - LocatorRegistry getLocatorRegistry(); - ConverterRegistry getConverterRegistry(); + LocatorRegistry getRegistry(); + ConverterRegistry getInfoRegistry(); } diff --git a/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterEngine.java b/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterEngine.java index 4a16b3c55..daabefe2c 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterEngine.java +++ b/proposal/myrmidon/src/java/org/apache/ant/convert/DefaultConverterEngine.java @@ -19,9 +19,10 @@ import org.apache.log.Logger; public class DefaultConverterEngine implements ConverterEngine, Initializable { + protected final static boolean DEBUG = false; protected DefaultFactory m_factory; - protected LocatorRegistry m_locatorRegistry; - protected ConverterRegistry m_converterRegistry; + protected LocatorRegistry m_registry; + protected ConverterRegistry m_infoRegistry; protected Logger m_logger; public void setLogger( final Logger logger ) @@ -29,30 +30,30 @@ public class DefaultConverterEngine m_logger = logger; } - public LocatorRegistry getLocatorRegistry() + public LocatorRegistry getRegistry() { - return m_locatorRegistry; + return m_registry; } - public ConverterRegistry getConverterRegistry() + public ConverterRegistry getInfoRegistry() { - return m_converterRegistry; + return m_infoRegistry; } public void init() throws Exception { - m_converterRegistry = createConverterRegistry(); - m_locatorRegistry = createLocatorRegistry(); + m_infoRegistry = createInfoRegistry(); + m_registry = createRegistry(); m_factory = createFactory(); } - protected ConverterRegistry createConverterRegistry() + protected ConverterRegistry createInfoRegistry() { return new DefaultConverterRegistry(); } - protected LocatorRegistry createLocatorRegistry() + protected LocatorRegistry createRegistry() { return new DefaultLocatorRegistry(); } @@ -65,18 +66,31 @@ public class DefaultConverterEngine public Object convert( Class destination, final Object original ) throws Exception { + final Class originalClass = original.getClass(); + + if( destination.isAssignableFrom( originalClass ) ) + { + return original; + } + + if( DEBUG ) + { + m_logger.debug( "Looking for converter from " + originalClass.getName() + + " to " + destination.getName() ); + } + final String name = - m_converterRegistry.getConverterInfoName( original.getClass().getName(), - destination.getName() ); + m_infoRegistry.getConverterInfoName( originalClass.getName(), + destination.getName() ); if( null == name ) { throw new ConverterException( "Unable to find converter for " + - original.getClass() + " to " + destination + - " conversion" ); + originalClass.getName() + " to " + + destination.getName() + " conversion" ); } - final Locator locator = m_locatorRegistry.getLocator( name ); + final Locator locator = m_registry.getLocator( name ); final Converter converter = (Converter)m_factory.create( locator, Converter.class ); return converter.convert( destination, original ); } diff --git a/proposal/myrmidon/src/java/org/apache/ant/datatypes/Condition.java b/proposal/myrmidon/src/java/org/apache/ant/datatypes/Condition.java new file mode 100644 index 000000000..c22f73eca --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/datatypes/Condition.java @@ -0,0 +1,71 @@ +/* + * 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.datatypes; + +import org.apache.ant.AntException; +import org.apache.avalon.Component; +import org.apache.avalon.Context; +import org.apache.avalon.util.PropertyException; +import org.apache.avalon.util.PropertyUtil; + +/** + * Class representing a condition. + * + * @author Peter Donald + */ +public class Condition + implements Component +{ + protected String m_condition; + protected boolean m_isIfCondition; + + public Condition( final boolean isIfCondition, final String condition ) + { + m_isIfCondition = isIfCondition; + m_condition = condition; + } + + public String getCondition() + { + return m_condition; + } + + public boolean isIfCondition() + { + return m_isIfCondition; + } + + public boolean evaluate( final Context context ) + { + try + { + final Object resolved = + PropertyUtil.resolveProperty( m_condition, context, false ); + + boolean result = false; + + if( null != resolved ) + { + result = ( null != context.get( resolved ) ); + } + + if( !m_isIfCondition ) + { + result = !result; + } + + return result; + } + catch( final PropertyException pe ) + { + throw new AntException( "Error resolving " + m_condition, pe ); + } + } +} + + diff --git a/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataType.java b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataType.java new file mode 100644 index 000000000..48a9e311f --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataType.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE file. + */ +package org.apache.ant.datatypes; + +import org.apache.avalon.Component; + +/** + * Base class for those classes that can appear inside the build file + * as stand alone data types. + * + * @author Stefan Bodewig + * @author Peter Donald + */ +public interface DataType + extends Component +{ +} diff --git a/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataTypeEngine.java b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataTypeEngine.java new file mode 100644 index 000000000..db51c1458 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DataTypeEngine.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE file. + */ +package org.apache.ant.datatypes; + +import org.apache.avalon.Component; +import org.apache.avalon.Loggable; +import org.apache.avalon.camelot.FactoryException; +import org.apache.avalon.camelot.LocatorRegistry; +import org.apache.avalon.camelot.RegistryException; + +public interface DataTypeEngine + extends Component, Loggable +{ + LocatorRegistry getRegistry(); + + DataType createDataType( String name ) + throws RegistryException, FactoryException; +} diff --git a/proposal/myrmidon/src/java/org/apache/ant/datatypes/DefaultDataTypeEngine.java b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DefaultDataTypeEngine.java new file mode 100644 index 000000000..3dc2f1cc4 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/datatypes/DefaultDataTypeEngine.java @@ -0,0 +1,73 @@ +/* + * 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.datatypes; + +import org.apache.ant.AntException; +import org.apache.avalon.Initializable; +import org.apache.avalon.Loggable; +import org.apache.avalon.camelot.DefaultFactory; +import org.apache.avalon.camelot.DefaultLocatorRegistry; +import org.apache.avalon.camelot.Locator; +import org.apache.avalon.camelot.LocatorRegistry; +import org.apache.avalon.camelot.RegistryException; +import org.apache.avalon.camelot.FactoryException; +import org.apache.log.Logger; + +public class DefaultDataTypeEngine + implements DataTypeEngine, Initializable +{ + protected DefaultFactory m_factory; + protected LocatorRegistry m_registry; + protected Logger m_logger; + + public void setLogger( final Logger logger ) + { + m_logger = logger; + } + + public LocatorRegistry getRegistry() + { + return m_registry; + } + + public void init() + throws Exception + { + m_registry = createRegistry(); + setupComponent( m_registry ); + + m_factory = createFactory(); + setupComponent( m_factory ); + } + + protected void setupComponent( final Object object ) + throws Exception + { + if( object instanceof Loggable ) + { + ((Loggable)object).setLogger( m_logger ); + } + } + + protected LocatorRegistry createRegistry() + { + return new DefaultLocatorRegistry(); + } + + protected DefaultFactory createFactory() + { + return new DefaultFactory(); + } + + public DataType createDataType( final String name ) + throws RegistryException, FactoryException + { + final Locator locator = m_registry.getLocator( name ); + return (DataType)m_factory.create( locator, DataType.class ); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/ant/datatypes/Pattern.java b/proposal/myrmidon/src/java/org/apache/ant/datatypes/Pattern.java new file mode 100644 index 000000000..ca64161ee --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/datatypes/Pattern.java @@ -0,0 +1,60 @@ +/* + * 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.datatypes; + +import org.apache.ant.AntException; + +/** + * Basic data type for holding patterns. + * + * @author Peter Donald + */ +public class Pattern + implements DataType +{ + protected String m_name; + protected Condition m_condition; + + public String getName() + { + return m_name; + } + + public Condition getCondition() + { + return m_condition; + } + + public void setName( final String name ) + { + m_name = name; + } + + public void setIf( final String condition ) + throws AntException + { + verifyConditionNull(); + m_condition = new Condition( true, condition ); + } + + public void setUnless( final String condition ) + throws AntException + { + verifyConditionNull(); + m_condition = new Condition( false, condition ); + } + + protected void verifyConditionNull() + throws AntException + { + if( null != m_condition ) + { + throw new AntException( "Can only set one of if/else for pattern data type" ); + } + } +} diff --git a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java index ab760516a..2978cbb05 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java +++ b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectBuilder.java @@ -13,6 +13,7 @@ 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.datatypes.Condition; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.ConfigurationException; import org.apache.log.Logger; @@ -133,21 +134,21 @@ public class DefaultProjectBuilder "unless condition at " + configuration.getLocation() ); } - final DefaultTarget target = new DefaultTarget(); - + Condition condition = null; + if( null != ifCondition ) { m_logger.debug( "Target if condition: " + ifCondition ); - target.setIfCondition( true ); - target.setCondition( ifCondition ); + condition = new Condition( true, ifCondition ); } else if( null != unlessCondition ) { m_logger.debug( "Target unless condition: " + unlessCondition ); - target.setIfCondition( false ); - target.setCondition( unlessCondition ); + condition = new Condition( false, unlessCondition ); } + final DefaultTarget target = new DefaultTarget( condition ); + if( null != depends ) { int start = 0; diff --git a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java index e6374c897..836a52817 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java +++ b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultProjectEngine.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Iterator; import org.apache.ant.AntException; import org.apache.ant.configuration.Configuration; +import org.apache.ant.datatypes.Condition; import org.apache.ant.tasklet.DefaultTaskletContext; import org.apache.ant.tasklet.TaskletContext; import org.apache.ant.tasklet.engine.DefaultTaskletEngine; @@ -100,13 +101,9 @@ public class DefaultProjectEngine m_listenerSupport.projectStarted( projectName ); - executeTargetWork( "", project.getImplicitTarget(), context ); - //context = new DefaultTaskletContext( context ); - - //placing logger lower (at targetlevel or at task level) - //is possible if you want more fine grained control - context.setProperty( TaskletContext.LOGGER, m_logger ); + + executeTargetWork( "", project.getImplicitTarget(), context ); execute( project, target, context ); @@ -168,6 +165,18 @@ public class DefaultProjectEngine final Target target, final TaskletContext context ) { + final Condition condition = target.getCondition(); + + if( null != condition ) + { + if( false == condition.evaluate( context ) ) + { + m_logger.debug( "Skipping target " + name + + " as it does not satisfy condition" ); + return; + } + } + m_logger.debug( "Executing target " + name ); final Iterator tasks = target.getTasks(); diff --git a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java index 242062aa5..952fc3c7f 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java +++ b/proposal/myrmidon/src/java/org/apache/ant/project/DefaultTarget.java @@ -10,43 +10,38 @@ package org.apache.ant.project; import java.util.ArrayList; import java.util.Iterator; import org.apache.ant.configuration.Configuration; +import org.apache.ant.datatypes.Condition; 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; + protected final ArrayList m_dependencies = new ArrayList(); + protected final ArrayList m_tasks = new ArrayList(); + protected final Condition m_condition; - public Iterator getDependencies() + public DefaultTarget( final Condition condition ) { - return m_dependencies.iterator(); + m_condition = condition; } - public Iterator getTasks() + public DefaultTarget() { - return m_tasks.iterator(); + this( null ); } - public String getCondition() + public Condition getCondition() { return m_condition; } - - public void setCondition( final String condition ) - { - m_condition = condition; - } - - public boolean isIfCondition() + + public Iterator getDependencies() { - return m_isIfCondition; + return m_dependencies.iterator(); } - public void setIfCondition( final boolean isIfCondition ) + public Iterator getTasks() { - m_isIfCondition = isIfCondition; + return m_tasks.iterator(); } public void addDependency( final String dependency ) diff --git a/proposal/myrmidon/src/java/org/apache/ant/project/ProjectToListenerAdapter.java b/proposal/myrmidon/src/java/org/apache/ant/project/LogTargetToListenerAdapter.java similarity index 88% rename from proposal/myrmidon/src/java/org/apache/ant/project/ProjectToListenerAdapter.java rename to proposal/myrmidon/src/java/org/apache/ant/project/LogTargetToListenerAdapter.java index d9d1a8206..0b32ee08a 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/project/ProjectToListenerAdapter.java +++ b/proposal/myrmidon/src/java/org/apache/ant/project/LogTargetToListenerAdapter.java @@ -10,13 +10,13 @@ package org.apache.ant.project; import org.apache.log.LogEntry; import org.apache.log.LogTarget; -public class ProjectToListenerAdapter +public class LogTargetToListenerAdapter implements LogTarget { protected final ProjectListener m_listener; - public ProjectToListenerAdapter( final ProjectListener listener ) + public LogTargetToListenerAdapter( final ProjectListener listener ) { m_listener = listener; } diff --git a/proposal/myrmidon/src/java/org/apache/ant/project/Target.java b/proposal/myrmidon/src/java/org/apache/ant/project/Target.java index 1697f98c9..419e8c91c 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/project/Target.java +++ b/proposal/myrmidon/src/java/org/apache/ant/project/Target.java @@ -9,14 +9,14 @@ package org.apache.ant.project; import java.util.Iterator; import org.apache.avalon.Component; +import org.apache.ant.datatypes.Condition; public interface Target extends Component { Iterator getDependencies(); Iterator getTasks(); - String getCondition(); - boolean isIfCondition(); + Condition getCondition(); } diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java index d381f811b..32288933b 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/AbstractTasklet.java @@ -26,6 +26,16 @@ public abstract class AbstractTasklet private TaskletContext m_context; private Logger m_logger; + /** + * Receive logger from container. + * + * @param logger the logger + */ + public void setLogger( final Logger logger ) + { + m_logger = logger; + } + /** * Retrieve context from container. * @@ -34,7 +44,6 @@ public abstract class AbstractTasklet public void contextualize( final Context context ) { m_context = (TaskletContext)context; - m_logger = (Logger)m_context.getLogger(); } /** diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java index 3f7e53675..f5cb60b0a 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/DefaultTaskletContext.java @@ -13,7 +13,6 @@ 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; /** * Default implementation of TaskletContext. @@ -68,16 +67,6 @@ public class DefaultTaskletContext return (String)get( NAME ); } - /** - * Retrieve Logger associated with task. - * - * @return the logger - */ - public Logger getLogger() - { - return (Logger)get( LOGGER ); - } - /** * Retrieve base directory. * @@ -209,13 +198,7 @@ public class DefaultTaskletContext 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 ) ) + if( BASE_DIRECTORY.equals( name ) && !( value instanceof File ) ) { throw new AntException( "Property " + BASE_DIRECTORY + " must have a value of type " + diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java index cb31a5df4..1a643c1f2 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/Tasklet.java @@ -9,6 +9,7 @@ package org.apache.ant.tasklet; import org.apache.avalon.Component; import org.apache.avalon.Contextualizable; +import org.apache.avalon.Loggable; /** * This represents the individual tasks. @@ -23,6 +24,6 @@ import org.apache.avalon.Contextualizable; * @author Peter Donald */ public interface Tasklet - extends Component, Contextualizable, Runnable + extends Component, Contextualizable, Runnable, Loggable { } diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java index 3c089d7d0..7f641de9f 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/TaskletContext.java @@ -11,7 +11,6 @@ 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. @@ -30,7 +29,6 @@ public interface TaskletContext //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"; /** @@ -46,13 +44,6 @@ public interface TaskletContext * @return the name */ String getName(); - - /** - * Retrieve Logger associated with task. - * - * @return the logger - */ - Logger getLogger(); /** * Retrieve base directory. diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java index 133f4ef65..fd2f16a6f 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTaskletEngine.java @@ -14,6 +14,7 @@ import org.apache.ant.configuration.Configuration; import org.apache.ant.configuration.Configurer; import org.apache.ant.configuration.DefaultConfigurer; import org.apache.ant.convert.ConverterEngine; +import org.apache.ant.datatypes.DataTypeEngine; import org.apache.ant.tasklet.Tasklet; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.Component; @@ -23,13 +24,13 @@ import org.apache.avalon.Context; import org.apache.avalon.Contextualizable; import org.apache.avalon.DefaultComponentManager; import org.apache.avalon.Disposable; -import org.apache.avalon.Loggable; import org.apache.avalon.Initializable; +import org.apache.avalon.Loggable; import org.apache.avalon.camelot.DefaultFactory; +import org.apache.avalon.camelot.DefaultLocatorRegistry; import org.apache.avalon.camelot.FactoryException; -import org.apache.avalon.camelot.LocatorRegistry; import org.apache.avalon.camelot.Locator; -import org.apache.avalon.camelot.DefaultLocatorRegistry; +import org.apache.avalon.camelot.LocatorRegistry; import org.apache.avalon.camelot.RegistryException; import org.apache.log.Logger; @@ -41,6 +42,7 @@ public class DefaultTaskletEngine protected LocatorRegistry m_locatorRegistry; protected Configurer m_configurer; protected Logger m_logger; + protected DataTypeEngine m_dataTypeEngine; protected ConverterEngine m_converterEngine; public void setLogger( final Logger logger ) @@ -58,27 +60,41 @@ public class DefaultTaskletEngine return m_converterEngine; } - public LocatorRegistry getLocatorRegistry() + public LocatorRegistry getRegistry() { return m_locatorRegistry; } + /** + * Retrieve datatype engine. + * + * @return the DataTypeEngine + */ + public DataTypeEngine getDataTypeEngine() + { + return m_dataTypeEngine; + } + public void init() throws Exception { - m_locatorRegistry = createLocatorRegistry(); - m_factory = createFactory(); - setupSubComponent( m_factory ); - + //converter must be created before configurerer + //so that it gets placed in configurers componentManager m_converterEngine = createConverterEngine(); - m_converterEngine.setLogger( m_logger ); setupSubComponent( m_converterEngine ); m_configurer = createConfigurer(); setupSubComponent( m_configurer ); + m_locatorRegistry = createLocatorRegistry(); + m_factory = createFactory(); + setupSubComponent( m_factory ); + + m_dataTypeEngine = createDataTypeEngine(); + setupSubComponent( m_dataTypeEngine ); + + m_tskDeployer = createTskDeployer(); - m_tskDeployer.setLogger( m_logger ); setupSubComponent( m_tskDeployer ); } @@ -93,10 +109,10 @@ public class DefaultTaskletEngine if( component instanceof Composer ) { final DefaultComponentManager componentManager = new DefaultComponentManager(); - componentManager.put( "org.apache.ant.convert.Converter", - getConverterEngine() ); - componentManager.put( "org.apache.ant.convert.ConverterEngine", + componentManager.put( "org.apache.ant.convert.Converter", getConverterEngine() ); + componentManager.put( "org.apache.ant.configuration.Configurer", + m_configurer ); componentManager.put( "org.apache.ant.tasklet.engine.TaskletEngine", this ); @@ -108,6 +124,13 @@ public class DefaultTaskletEngine ((Initializable)component).init(); } } + + protected DataTypeEngine createDataTypeEngine() + { + final TaskletDataTypeEngine engine = new TaskletDataTypeEngine(); + engine.setFactory( m_factory ); + return engine; + } protected TskDeployer createTskDeployer() { @@ -143,9 +166,9 @@ public class DefaultTaskletEngine final ComponentManager componentManager ) throws AntException { - m_logger.debug( "Creating" ); - final Tasklet tasklet = createTasklet( task ); + final Tasklet tasklet = createTasklet( task.getName() ); + tasklet.setLogger( m_logger ); m_logger.debug( "Contextualizing" ); doContextualize( tasklet, task, context ); @@ -185,9 +208,15 @@ public class DefaultTaskletEngine final ComponentManager componentManager ) throws AntException { + + final DefaultComponentManager subComponentManager = + new DefaultComponentManager( componentManager ); + + subComponentManager.put( "org.apache.ant.configuration.Configurer", m_configurer ); + if( tasklet instanceof Composer ) { - try { ((Composer)tasklet).compose( componentManager ); } + try { ((Composer)tasklet).compose( subComponentManager ); } catch( final Throwable throwable ) { throw new AntException( "Error composing task " + task.getName() + " at " + @@ -244,10 +273,9 @@ public class DefaultTaskletEngine } } - protected Tasklet createTasklet( final Configuration configuration ) + protected Tasklet createTasklet( final String name ) throws AntException { - final String name = configuration.getName(); try { final Locator locator = m_locatorRegistry.getLocator( name ); diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTskDeployer.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTskDeployer.java index 7db41ded3..c83494c5f 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTskDeployer.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/DefaultTskDeployer.java @@ -45,6 +45,7 @@ public class DefaultTskDeployer { protected final static String TSKDEF_FILE = "TASK-LIB/taskdefs.xml"; + protected LocatorRegistry m_dataTypeRegistry; protected LocatorRegistry m_taskletRegistry; protected LocatorRegistry m_converterRegistry; protected ConverterRegistry m_converterInfoRegistry; @@ -69,16 +70,17 @@ public class DefaultTskDeployer public void compose( final ComponentManager componentManager ) throws ComponentNotFoundException, ComponentNotAccessibleException { - final ConverterEngine converterEngine = (ConverterEngine)componentManager. - lookup( "org.apache.ant.convert.ConverterEngine" ); - - m_converterInfoRegistry = converterEngine.getConverterRegistry(); - m_converterRegistry = converterEngine.getLocatorRegistry(); - final TaskletEngine taskletEngine = (TaskletEngine)componentManager. lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); - m_taskletRegistry = taskletEngine.getLocatorRegistry(); + final ConverterEngine converterEngine = taskletEngine.getConverterEngine(); + + m_converterInfoRegistry = converterEngine.getInfoRegistry(); + m_converterRegistry = converterEngine.getRegistry(); + + m_taskletRegistry = taskletEngine.getRegistry(); + + m_dataTypeRegistry = taskletEngine.getDataTypeEngine().getRegistry(); } public void setLogger( final Logger logger ) @@ -106,6 +108,13 @@ public class DefaultTskDeployer final Configuration converter = (Configuration)converters.next(); handleConverter( converter, url ); } + + final Iterator datatypes = taskdefs.getChildren( "datatype" ); + while( datatypes.hasNext() ) + { + final Configuration datatype = (Configuration)datatypes.next(); + handleDataType( datatype, url ); + } } catch( final ConfigurationException ce ) { @@ -138,6 +147,11 @@ public class DefaultTskDeployer throw new DeploymentException( "Malformed taskdefs.xml", ce ); } } + + public void deployDataType( final String name, final String location, final URL url ) + throws DeploymentException + { + } public void deployTasklet( final String name, final String location, final URL url ) throws DeploymentException @@ -213,4 +227,22 @@ public class DefaultTskDeployer m_logger.debug( "Registered tasklet " + name + " as " + classname ); } + + protected void handleDataType( final Configuration datatype, final URL url ) + throws DeploymentException, ConfigurationException + { + final String name = datatype.getAttribute( "name" ); + final String classname = datatype.getAttribute( "classname" ); + + final DefaultLocator info = new DefaultLocator( classname, url ); + + try { m_dataTypeRegistry.register( name, info ); } + catch( final RegistryException re ) + { + throw new DeploymentException( "Error registering " + name + " due to " + re, + re ); + } + + m_logger.debug( "Registered datatype " + name + " as " + classname ); + } } diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletDataTypeEngine.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletDataTypeEngine.java new file mode 100644 index 000000000..11d53bb06 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletDataTypeEngine.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE file. + */ +package org.apache.ant.tasklet.engine; + +import org.apache.ant.datatypes.DefaultDataTypeEngine; +import org.apache.avalon.camelot.DefaultFactory; + +public class TaskletDataTypeEngine + extends DefaultDataTypeEngine +{ + /** + * Set the DataTypeFactory. + * Package access intended. + */ + void setFactory( final DefaultFactory factory ) + { + m_factory = factory; + } + + protected DefaultFactory createFactory() + { + return m_factory; + } +} diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java index d1026ee46..8419c1c60 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TaskletEngine.java @@ -10,10 +10,11 @@ package org.apache.ant.tasklet.engine; import org.apache.ant.AntException; import org.apache.ant.configuration.Configuration; import org.apache.ant.convert.ConverterEngine; +import org.apache.ant.datatypes.DataTypeEngine; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.Component; -import org.apache.avalon.Loggable; import org.apache.avalon.ComponentManager; +import org.apache.avalon.Loggable; import org.apache.avalon.camelot.LocatorRegistry; import org.apache.log.Logger; @@ -37,7 +38,7 @@ public interface TaskletEngine * * @return the LocatorRegistry */ - LocatorRegistry getLocatorRegistry(); + LocatorRegistry getRegistry(); /** * Retrieve converter engine. @@ -46,6 +47,13 @@ public interface TaskletEngine */ ConverterEngine getConverterEngine(); + /** + * Retrieve datatype engine. + * + * @return the DataTypeEngine + */ + DataTypeEngine getDataTypeEngine(); + /** * execute a task. * diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java index dad49a5da..89d706acb 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasklet/engine/TskDeployer.java @@ -23,7 +23,10 @@ public interface TskDeployer { void deployConverter( String name, String location, URL url ) throws DeploymentException; - + + void deployDataType( String name, String location, URL url ) + throws DeploymentException; + void deployTasklet( String name, String location, URL url ) throws DeploymentException; } diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/AntCall.java b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/AntCall.java index b0c019bac..291372294 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/AntCall.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/AntCall.java @@ -15,6 +15,7 @@ import org.apache.ant.tasklet.AbstractTasklet; import org.apache.ant.tasklet.DefaultTaskletContext; import org.apache.ant.tasklet.TaskletContext; import org.apache.avalon.ComponentManager; +import org.apache.avalon.Context; import org.apache.avalon.ComponentNotAccessibleException; import org.apache.avalon.ComponentNotFoundException; import org.apache.avalon.Composer; @@ -32,10 +33,19 @@ public class AntCall protected Project m_project; protected String m_target; protected ArrayList m_properties = new ArrayList(); + protected TaskletContext m_childContext; + protected ComponentManager m_componentManager; + + public void contextualize( final Context context ) + { + super.contextualize( context ); + m_childContext = new DefaultTaskletContext( getContext() ); + } public void compose( final ComponentManager componentManager ) throws ComponentNotFoundException, ComponentNotAccessibleException { + m_componentManager = componentManager; m_projectEngine = (ProjectEngine)componentManager. lookup( "org.apache.ant.project.ProjectEngine" ); m_project = (Project)componentManager.lookup( "org.apache.ant.project.Project" ); @@ -47,8 +57,12 @@ public class AntCall } public Property createParam() + throws Exception { final Property property = new Property(); + property.setLogger( getLogger() ); + property.contextualize( m_childContext ); + property.compose( m_componentManager ); m_properties.add( property ); return property; } @@ -61,17 +75,14 @@ public class AntCall throw new AntException( "Target attribute must be specified" ); } - final TaskletContext context = new DefaultTaskletContext( getContext() ); - final int size = m_properties.size(); for( int i = 0; i < size; i++ ) { final Property property = (Property)m_properties.get( i ); - property.contextualize( context ); property.run(); } getLogger().info( "Calling target " + m_target ); - m_projectEngine.execute( m_project, m_target, context ); + m_projectEngine.execute( m_project, m_target, m_childContext ); } } diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java index dcf2a892d..8c819c32d 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/Property.java @@ -7,27 +7,130 @@ */ package org.apache.ant.tasks.core; +import java.util.Iterator; import org.apache.ant.AntException; +import org.apache.ant.configuration.Configurable; +import org.apache.ant.configuration.Configuration; +import org.apache.ant.configuration.Configurer; +import org.apache.ant.convert.Converter; +import org.apache.ant.datatypes.DataType; +import org.apache.ant.datatypes.DataTypeEngine; import org.apache.ant.tasklet.AbstractTasklet; import org.apache.ant.tasklet.TaskletContext; +import org.apache.ant.tasklet.engine.TaskletEngine; +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.Resolvable; /** * @author Peter Donald */ public class Property extends AbstractTasklet + implements Configurable, Composer { protected String m_name; - protected String m_value; + protected Object m_value; protected boolean m_localScope = true; + protected DataTypeEngine m_engine; + protected Converter m_converter; + protected Configurer m_configurer; + + public void compose( final ComponentManager componentManager ) + throws ComponentNotFoundException, ComponentNotAccessibleException + { + m_configurer = (Configurer)componentManager. + lookup( "org.apache.ant.configuration.Configurer" ); + + final TaskletEngine taskletEngine = (TaskletEngine)componentManager. + lookup( "org.apache.ant.tasklet.engine.TaskletEngine" ); + + m_engine = taskletEngine.getDataTypeEngine(); + m_converter = taskletEngine.getConverterEngine(); + } + + public void configure( final Configuration configuration ) + throws ConfigurationException + { + final Iterator attributes = configuration.getAttributeNames(); + + while( attributes.hasNext() ) + { + final String name = (String)attributes.next(); + final String value = configuration.getAttribute( name ); + + final Object object = getContext().resolveValue( value ); + + if( null == object ) + { + throw new AntException( "Value for attribute " + name + "resolved to null" ); + } + + if( name.equals( "name" ) ) + { + try { setName( (String)m_converter.convert( String.class, object ) ); } + catch( final Exception e ) + { + throw new ConfigurationException( "Error converting value", e ); + } + } + else if( name.equals( "value" ) ) + { + setValue( object ); + } + else if( name.equals( "local-scope" ) ) + { + try + { + final Boolean localScope = + (Boolean)m_converter.convert( Boolean.class, object ); + setLocalScope( Boolean.TRUE == localScope ); + } + catch( final Exception e ) + { + throw new ConfigurationException( "Error converting value", e ); + } + } + else + { + throw new ConfigurationException( "Unknown attribute " + name ); + } + } + + final Iterator children = configuration.getChildren(); + while( children.hasNext() ) + { + final Configuration child = (Configuration)children.next(); + + try + { + final DataType value = m_engine.createDataType( child.getName() ); + setValue( value ); + m_configurer.configure( value, child, getContext() ); + } + catch( final Exception e ) + { + throw new ConfigurationException( "Unable to set datatype", e ); + } + } + } public void setName( final String name ) { m_name = name; } - public void setValue( final String value ) + public void setValue( final Object value ) + throws AntException { + if( null != m_value ) + { + throw new AntException( "Value can not be set multiple times" ); + } + m_value = value; } @@ -50,7 +153,18 @@ public class Property } final TaskletContext context = getContext(); - final Object value = context.resolveValue( m_value ); + + Object value = m_value; + + if( value instanceof String ) + { + value = context.resolveValue( (String)value ); + } + + while( null != value && value instanceof Resolvable ) + { + value = ((Resolvable)value).resolve( context ); + } if( m_localScope ) { diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterConverter.java b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterConverter.java index f2aeda607..ee5874cf4 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterConverter.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterConverter.java @@ -112,10 +112,8 @@ public class RegisterConverter try { - m_engine.getConverterEngine(). - getConverterRegistry().register( m_classname, info ); - m_engine.getConverterEngine(). - getLocatorRegistry().register( m_classname, locator ); + m_engine.getConverterEngine().getInfoRegistry().register( m_classname, info ); + m_engine.getConverterEngine().getRegistry().register( m_classname, locator ); } catch( final RegistryException re ) { diff --git a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterTasklet.java b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterTasklet.java index 5b9c12236..ddecb0168 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterTasklet.java +++ b/proposal/myrmidon/src/java/org/apache/ant/tasks/core/RegisterTasklet.java @@ -37,7 +37,7 @@ public class RegisterTasklet else { final DefaultLocator locator = new DefaultLocator( classname, url ); - m_engine.getLocatorRegistry().register( name, locator ); + m_engine.getRegistry().register( name, locator ); } } } diff --git a/proposal/myrmidon/src/make/sample.xmk b/proposal/myrmidon/src/make/sample.xmk index 67fb3d9e2..00e7316a2 100644 --- a/proposal/myrmidon/src/make/sample.xmk +++ b/proposal/myrmidon/src/make/sample.xmk @@ -20,12 +20,13 @@ Legal: - - + + + + + + + - + @@ -77,6 +78,12 @@ Legal: + + + + + + diff --git a/proposal/myrmidon/src/manifest/taskdefs.xml b/proposal/myrmidon/src/manifest/taskdefs.xml index f3a10589d..eb5d6f226 100644 --- a/proposal/myrmidon/src/manifest/taskdefs.xml +++ b/proposal/myrmidon/src/manifest/taskdefs.xml @@ -9,6 +9,8 @@ + +