diff --git a/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAntTask.java b/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAntTask.java index 1a7c1d820..f97c15cdb 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAntTask.java +++ b/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAntTask.java @@ -7,15 +7,14 @@ */ package org.apache.antlib.core; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import org.apache.myrmidon.api.AbstractTask; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.interfaces.embeddor.Embeddor; import org.apache.myrmidon.interfaces.model.Project; import org.apache.myrmidon.interfaces.workspace.Workspace; -import org.apache.myrmidon.interfaces.embeddor.Embeddor; -import org.apache.avalon.framework.parameters.Parameters; -import java.util.Map; -import java.util.Iterator; -import java.util.ArrayList; /** * Abstract base class for Tasks which execute targets. @@ -24,7 +23,8 @@ import java.util.ArrayList; * @author Darrell DeBoer * @version $Revision$ $Date$ */ -public abstract class AbstractAntTask extends AbstractTask +public abstract class AbstractAntTask + extends AbstractTask { /** * If true, inherit all properties from parent Project @@ -32,6 +32,7 @@ public abstract class AbstractAntTask extends AbstractTask * inside the ant call itself */ private boolean m_inheritAll; + /** * The target to process in build file. If not specified * will use default in specified build file. @@ -90,6 +91,7 @@ public abstract class AbstractAntTask extends AbstractTask final Workspace workspace = embeddor.createWorkspace( buildParameters() ); + // TODO - inherit listeners, and services (TypeManager specifically) workspace.addProjectListener( embeddor.createListener("default")); if( null == m_target ) @@ -134,21 +136,14 @@ public abstract class AbstractAntTask extends AbstractTask * * @return the created parameters */ - private Parameters buildParameters() + private Map buildParameters() throws TaskException { - final Parameters parameters = new Parameters(); + final Map parameters = new HashMap(); if( m_inheritAll ) { - final Map properties = getContext().getProperties(); - final Iterator keys = properties.keySet().iterator(); - while( keys.hasNext() ) - { - final String key = (String)keys.next(); - final Object value = properties.get( key ); - setProperty( parameters, key, value ); - } + parameters.putAll( getContext().getProperties() ); } final int size = m_parameters.size(); @@ -157,28 +152,10 @@ public abstract class AbstractAntTask extends AbstractTask final AntParam param = (AntParam)m_parameters.get( i ); param.validate(); final String name = param.getName(); - final String value = param.getValue().toString(); - setProperty( parameters, name, value ); + final Object value = param.getValue(); + parameters.put( name, value ); } return parameters; } - - /** - * Utility method to add the property into parameters object. - * - * @param parameters where to put property - * @param name the property - * @param value the value of property - * @todo allow non-string params to be passed down - */ - private void setProperty( final Parameters parameters, - final String name, - final Object value ) - { - if( !name.startsWith( "myrmidon." ) ) - { - parameters.setParameter( name, value.toString() ); - } - } } diff --git a/proposal/myrmidon/src/java/org/apache/antlib/core/AntCallTask.java b/proposal/myrmidon/src/java/org/apache/antlib/core/AntCallTask.java index 26da9011b..1bbe78ef4 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/core/AntCallTask.java +++ b/proposal/myrmidon/src/java/org/apache/antlib/core/AntCallTask.java @@ -20,7 +20,8 @@ import org.apache.myrmidon.interfaces.model.Project; * @version $Revision$ $Date$ * @ant.task name="ant-call" */ -public class AntCallTask extends AbstractAntTask +public class AntCallTask + extends AbstractAntTask { private static final Resources REZ = ResourceManager.getPackageResources( AntCallTask.class ); diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java index ca14b760e..400e6e7f7 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java @@ -12,6 +12,7 @@ import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.aut.converter.Converter; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; @@ -37,15 +38,20 @@ import org.apache.myrmidon.interfaces.deployer.DeploymentException; import org.apache.myrmidon.interfaces.deployer.TypeDeployer; import org.apache.myrmidon.interfaces.embeddor.Embeddor; import org.apache.myrmidon.interfaces.executor.Executor; +import org.apache.myrmidon.interfaces.executor.ExecutionFrame; +import org.apache.myrmidon.interfaces.executor.ExecutionContainer; import org.apache.myrmidon.interfaces.extensions.ExtensionManager; import org.apache.myrmidon.interfaces.model.Project; import org.apache.myrmidon.interfaces.property.PropertyResolver; +import org.apache.myrmidon.interfaces.property.PropertyStore; import org.apache.myrmidon.interfaces.role.RoleManager; import org.apache.myrmidon.interfaces.service.MultiSourceServiceManager; import org.apache.myrmidon.interfaces.type.TypeFactory; import org.apache.myrmidon.interfaces.type.TypeManager; import org.apache.myrmidon.interfaces.workspace.Workspace; import org.apache.myrmidon.listeners.ProjectListener; +import org.apache.myrmidon.components.workspace.DefaultExecutionFrame; +import org.apache.myrmidon.components.store.DefaultPropertyStore; /** * Default implementation of Embeddor. @@ -72,8 +78,6 @@ public class DefaultEmbeddor private DefaultServiceManager m_serviceManager = new DefaultServiceManager(); private Parameters m_parameters; - private static final String MYRMIDON_HOME = "myrmidon.home"; - /** * Setup basic properties of engine. * Called before init() and can be used to specify alternate components in system. @@ -121,22 +125,29 @@ public class DefaultEmbeddor { final TypeFactory factory = m_typeManager.getFactory( ProjectBuilder.ROLE ); final ProjectBuilder builder = (ProjectBuilder)factory.create( type ); - setupObject( builder, m_workspaceServiceManager, parameters ); + setupObject( builder, m_serviceManager, parameters ); return builder; } /** * Creates a workspace. */ - public Workspace createWorkspace( final Parameters parameters ) + public Workspace createWorkspace( final Map properties ) throws Exception { final Workspace workspace = (Workspace)createService( Workspace.class, PREFIX + "workspace.DefaultWorkspace" ); - // TODO - don't do this; need some way to pass separate sets of defines and config - // to the workspace - parameters.setParameter( MYRMIDON_HOME, m_parameters.getParameter( MYRMIDON_HOME ) ); - setupObject( workspace, m_workspaceServiceManager, parameters ); + setupObject( workspace, m_workspaceServiceManager, m_parameters ); + + // Create the property store + final PropertyStore propStore = createBaseStore( properties ); + + // Create an execution frame, and attach it to the workspace + final ExecutionFrame frame = + new DefaultExecutionFrame( getLogger(), + propStore, + m_workspaceServiceManager); + ( (ExecutionContainer)workspace ).setRootExecutionFrame( frame ); // TODO - should keep track of workspaces, to dispose them later return workspace; @@ -395,4 +406,39 @@ public class DefaultEmbeddor } } } + + /** + * Creates the root property store for a workspace + */ + private PropertyStore createBaseStore( final Map properties ) + throws Exception + { + final DefaultPropertyStore store = new DefaultPropertyStore(); + + addToStore( store, properties ); + + //Add system properties so that they overide user-defined properties + addToStore( store, System.getProperties() ); + + return store; + } + + /** + * Helper method to add values to a store. + * + * @param store the store + * @param map the map of names->values + */ + private void addToStore( final PropertyStore store, final Map map ) + throws Exception + { + final Iterator keys = map.keySet().iterator(); + + while( keys.hasNext() ) + { + final String key = (String)keys.next(); + final Object value = map.get( key ); + store.setProperty( key, value ); + } + } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/AspectAwareExecutor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/AspectAwareExecutor.java index 9eb093e41..233c2d8ba 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/AspectAwareExecutor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/AspectAwareExecutor.java @@ -18,8 +18,10 @@ import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; import org.apache.myrmidon.api.Task; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.interfaces.aspect.AspectManager; import org.apache.myrmidon.interfaces.executor.ExecutionFrame; @@ -32,6 +34,7 @@ import org.apache.myrmidon.interfaces.executor.ExecutionFrame; */ public class AspectAwareExecutor extends DefaultExecutor + implements Serviceable { private static final Resources REZ = ResourceManager.getPackageResources( AspectAwareExecutor.class ); @@ -49,8 +52,6 @@ public class AspectAwareExecutor public void service( final ServiceManager serviceManager ) throws ServiceException { - super.service( serviceManager ); - m_aspectManager = (AspectManager)serviceManager.lookup( AspectManager.ROLE ); } @@ -90,11 +91,12 @@ public class AspectAwareExecutor getAspectManager().preLogEnabled( logger ); debug( "contextualizing.notice", taskName ); - doContextualize( task, taskModel, frame.getContext() ); + final TaskContext context = doCreateContext( frame ); + doContextualize( task, taskModel, context, frame ); debug( "configuring.notice", taskName ); getAspectManager().preConfigure( taskModel ); - doConfigure( task, taskModel, frame.getContext() ); + doConfigure( task, taskModel, context, frame ); debug( "executing.notice", taskName ); getAspectManager().preExecute(); diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java index 36fe51750..47c7bc46c 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java @@ -10,19 +10,16 @@ package org.apache.myrmidon.components.executor; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.logger.AbstractLogEnabled; -import org.apache.avalon.framework.service.ServiceException; -import org.apache.avalon.framework.service.ServiceManager; -import org.apache.avalon.framework.service.Serviceable; import org.apache.myrmidon.api.Task; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.components.workspace.DefaultTaskContext; import org.apache.myrmidon.interfaces.configurer.Configurer; import org.apache.myrmidon.interfaces.executor.ExecutionFrame; import org.apache.myrmidon.interfaces.executor.Executor; -import org.apache.myrmidon.interfaces.type.TypeException; import org.apache.myrmidon.interfaces.type.TypeFactory; +import org.apache.myrmidon.interfaces.type.TypeManager; /** * The basic executor that just executes the tasks. @@ -32,25 +29,11 @@ import org.apache.myrmidon.interfaces.type.TypeFactory; */ public class DefaultExecutor extends AbstractLogEnabled - implements Executor, Serviceable + implements Executor { private static final Resources REZ = ResourceManager.getPackageResources( DefaultExecutor.class ); - private Configurer m_configurer; - - /** - * Retrieve relevent services needed to deploy. - * - * @param serviceManager the ServiceManager - * @exception ServiceException if an error occurs - */ - public void service( final ServiceManager serviceManager ) - throws ServiceException - { - m_configurer = (Configurer)serviceManager.lookup( Configurer.ROLE ); - } - /** * Executes a task. */ @@ -64,10 +47,11 @@ public class DefaultExecutor final Task task = doCreateTask( taskName, frame ); debug( "contextualizing.notice", taskName ); - doContextualize( task, taskModel, frame.getContext() ); + final TaskContext context = doCreateContext( frame ); + doContextualize( task, taskModel, context, frame ); debug( "configuring.notice", taskName ); - doConfigure( task, taskModel, frame.getContext() ); + doConfigure( task, taskModel, context, frame ); debug( "executing.notice", taskName ); task.execute(); @@ -90,6 +74,18 @@ public class DefaultExecutor } } + /** + * Creates a context for the task. + */ + protected TaskContext doCreateContext( final ExecutionFrame frame ) + { + // TODO - need to deactivate the context once the task has finished + // executing + return new DefaultTaskContext( frame.getServiceManager(), + frame.getLogger(), + frame.getProperties() ); + } + /** * Creates a task instance. */ @@ -98,10 +94,11 @@ public class DefaultExecutor { try { - final TypeFactory factory = frame.getTypeManager().getFactory( Task.ROLE ); + final TypeManager typeManager = (TypeManager)frame.getServiceManager().lookup( TypeManager.ROLE ); + final TypeFactory factory = typeManager.getFactory( Task.ROLE ); return (Task)factory.create( name ); } - catch( final TypeException te ) + catch( final Exception te ) { final String message = REZ.getString( "create.error", name ); throw new TaskException( message, te ); @@ -113,10 +110,12 @@ public class DefaultExecutor */ protected final void doConfigure( final Task task, final Configuration taskModel, - final TaskContext taskContext ) - throws ConfigurationException + final TaskContext taskContext, + final ExecutionFrame frame ) + throws Exception { - m_configurer.configureElement( task, taskModel, taskContext ); + final Configurer configurer = (Configurer)frame.getServiceManager().lookup( Configurer.ROLE ); + configurer.configureElement( task, taskModel, taskContext ); } /** @@ -124,12 +123,13 @@ public class DefaultExecutor */ protected final void doContextualize( final Task task, final Configuration taskModel, - final TaskContext context ) + final TaskContext taskContext, + final ExecutionFrame frame ) throws TaskException { try { - task.contextualize( context ); + task.contextualize( taskContext ); } catch( final Throwable throwable ) { diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/ClassicPropertyResolver.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/ClassicPropertyResolver.java index 0bf4592f6..79ef47471 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/ClassicPropertyResolver.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/ClassicPropertyResolver.java @@ -10,6 +10,7 @@ package org.apache.myrmidon.components.property; import org.apache.myrmidon.interfaces.property.PropertyResolver; import org.apache.myrmidon.interfaces.property.PropertyStore; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.api.TaskContext; /** * A {@link PropertyResolver} implementation which resolves properties @@ -29,16 +30,20 @@ public class ClassicPropertyResolver * If there is no such value, returns the original property reference. * * @param propertyName the name of the property to retrieve - * @param properties the set of known properties + * @param context the set of known properties */ protected Object getPropertyValue( final String propertyName, - final PropertyStore properties ) + final TaskContext context ) throws TaskException { - if( ! properties.isPropertySet( propertyName ) ) + final Object value = context.getProperty( propertyName ); + if( value != null ) + { + return value; + } + else { return "${" + propertyName + "}"; } - return properties.getProperty( propertyName ); } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/DefaultPropertyResolver.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/DefaultPropertyResolver.java index 74a7a6ad9..035d6c1e9 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/DefaultPropertyResolver.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/DefaultPropertyResolver.java @@ -15,6 +15,7 @@ import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.Serviceable; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.interfaces.property.PropertyResolver; import org.apache.myrmidon.interfaces.property.PropertyStore; @@ -51,12 +52,12 @@ public class DefaultPropertyResolver * toString() called on the property value. * * @param content the property to resolve - * @param properties the context in which to resolve property + * @param context the context in which to resolve property * @return the reolved property * @exception TaskException if an error occurs */ public Object resolveProperties( final String content, - final PropertyStore properties ) + final TaskContext context ) throws TaskException { int start = findNextProperty( content, 0 ); @@ -72,7 +73,7 @@ public class DefaultPropertyResolver if( 0 == start && end == ( length - 1 ) ) { return getPropertyValue( content.substring( start + 2, end ), - properties ); + context ); } final StringBuffer sb = new StringBuffer( length * 2 ); @@ -82,7 +83,7 @@ public class DefaultPropertyResolver { final String propertyValue = getPropertyStringValue( content.substring( start + 2, end ), - properties ); + context ); sb.append( content.substring( lastPlace, start ) ); sb.append( propertyValue ); @@ -108,12 +109,12 @@ public class DefaultPropertyResolver * substitutions based on specified context. * * @param content the property to resolve - * @param properties the context in which to resolve property + * @param context the context in which to resolve property * @return the reolved property * @exception TaskException if an error occurs */ private Object recursiveResolveProperty( final String content, - final PropertyStore properties ) + final TaskContext context ) throws TaskException { int start = findNextProperty( content, 0 ); @@ -129,8 +130,8 @@ public class DefaultPropertyResolver if( 0 == start && end == ( length - 1 ) ) { final String propertyName = content.substring( start + 2, end ); - final Object key = recursiveResolveProperty( propertyName, properties ); - return getPropertyValue( key.toString(), properties ); + final Object key = recursiveResolveProperty( propertyName, context ); + return getPropertyValue( key.toString(), context ); } final StringBuffer sb = new StringBuffer( length * 2 ); @@ -140,8 +141,8 @@ public class DefaultPropertyResolver while( true ) { final String propertyName = content.substring( start + 2, end ); - final Object key = recursiveResolveProperty( propertyName, properties ); - final String value = getPropertyStringValue( key.toString(), properties ); + final Object key = recursiveResolveProperty( propertyName, context ); + final String value = getPropertyStringValue( key.toString(), context ); sb.append( content.substring( lastPlace, start ) ); sb.append( value ); @@ -246,17 +247,17 @@ public class DefaultPropertyResolver * Returns a property's value, converted to a String. */ private String getPropertyStringValue( final String propertyName, - final PropertyStore properties ) + final TaskContext context ) throws TaskException { - final Object value = getPropertyValue( propertyName, properties ); + final Object value = getPropertyValue( propertyName, context ); if( value instanceof String ) { return (String)value; } try { - return (String)m_converter.convert( String.class, value, properties ); + return (String)m_converter.convert( String.class, value, context ); } catch( final ConverterException e ) { @@ -268,15 +269,22 @@ public class DefaultPropertyResolver * Retrieve a value from the specified context using the specified key. * * @param propertyName the key of value in context - * @param properties the set of known properties + * @param context the set of known properties * @return the object retrieved from context * @exception TaskException if the property is undefined */ protected Object getPropertyValue( final String propertyName, - final PropertyStore properties ) + final TaskContext context ) throws TaskException { - return properties.getProperty( propertyName ); + final Object value = context.getProperty( propertyName ); + if( value != null ) + { + return value; + } + + final String message = REZ.getString( "prop.missing-value.error", propertyName ); + throw new TaskException( message ); } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties index cabd0d25b..ed5ea183e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties @@ -1,3 +1,3 @@ #AbstractPropertyResolver prop.mismatched-braces.error=Malformed property with mismatched }'s. -prop.missing-value.error=Unable to find "{0}" to expand during property resolution. +prop.missing-value.error=Unknown property "{0}". diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultExecutionFrame.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultExecutionFrame.java index 500f4c96a..39f03e39c 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultExecutionFrame.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultExecutionFrame.java @@ -8,9 +8,9 @@ package org.apache.myrmidon.components.workspace; import org.apache.avalon.framework.logger.Logger; -import org.apache.myrmidon.api.TaskContext; +import org.apache.avalon.framework.service.ServiceManager; import org.apache.myrmidon.interfaces.executor.ExecutionFrame; -import org.apache.myrmidon.interfaces.type.TypeManager; +import org.apache.myrmidon.interfaces.property.PropertyStore; /** * Frames in which tasks are executed. @@ -18,34 +18,44 @@ import org.apache.myrmidon.interfaces.type.TypeManager; * @author Peter Donald * @version $Revision$ $Date$ */ -class DefaultExecutionFrame +public class DefaultExecutionFrame implements ExecutionFrame { private final Logger m_logger; - private final TaskContext m_context; - private final TypeManager m_typeManager; + private final PropertyStore m_propertyStore; + private final ServiceManager m_serviceManager; public DefaultExecutionFrame( final Logger logger, - final TaskContext context, - final TypeManager typeManager ) + final PropertyStore propertyStore, + final ServiceManager serviceManager ) { m_logger = logger; - m_context = context; - m_typeManager = typeManager; + m_propertyStore = propertyStore; + m_serviceManager = serviceManager; } - public TypeManager getTypeManager() + /** + * Returns the logger which is to be supplied to tasks. + */ + public Logger getLogger() { - return m_typeManager; + return m_logger; } - public Logger getLogger() + /** + * Returns the set of services to use to create, configure, and execute + * tasks. + */ + public ServiceManager getServiceManager() { - return m_logger; + return m_serviceManager; } - public TaskContext getContext() + /** + * Returns the set of properties to be supplied to tasks. + */ + public PropertyStore getProperties() { - return m_context; + return m_propertyStore; } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java index 3858e8f0a..9da9039cb 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java @@ -149,7 +149,7 @@ public class DefaultTaskContext m_propertyResolver = (PropertyResolver)getService( PropertyResolver.class ); } final Object object = - m_propertyResolver.resolveProperties( value, m_store ); + m_propertyResolver.resolveProperties( value, this ); if( null == object ) { final String message = REZ.getString( "null-resolved-value.error", value ); diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java index 0b95c4696..9c252f551 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java @@ -9,11 +9,8 @@ package org.apache.myrmidon.components.workspace; import java.io.File; import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; -import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.logger.Logger; @@ -21,25 +18,23 @@ import org.apache.avalon.framework.parameters.ParameterException; import org.apache.avalon.framework.parameters.Parameterizable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.service.DefaultServiceManager; -import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; -import org.apache.avalon.framework.service.Serviceable; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.interfaces.deployer.Deployer; import org.apache.myrmidon.interfaces.deployer.DeploymentException; import org.apache.myrmidon.interfaces.deployer.TypeDeployer; +import org.apache.myrmidon.interfaces.executor.ExecutionContainer; import org.apache.myrmidon.interfaces.executor.ExecutionFrame; import org.apache.myrmidon.interfaces.executor.Executor; import org.apache.myrmidon.interfaces.model.Dependency; import org.apache.myrmidon.interfaces.model.Project; import org.apache.myrmidon.interfaces.model.Target; import org.apache.myrmidon.interfaces.model.TypeLib; +import org.apache.myrmidon.interfaces.property.PropertyStore; import org.apache.myrmidon.interfaces.type.TypeManager; import org.apache.myrmidon.interfaces.workspace.Workspace; -import org.apache.myrmidon.interfaces.property.PropertyStore; import org.apache.myrmidon.listeners.ProjectListener; -import org.apache.myrmidon.components.store.DefaultPropertyStore; /** * This is the default implementation of Workspace. @@ -49,7 +44,7 @@ import org.apache.myrmidon.components.store.DefaultPropertyStore; */ public class DefaultWorkspace extends AbstractLogEnabled - implements Workspace, Serviceable, Parameterizable, Initializable + implements Workspace, ExecutionContainer, Parameterizable { private static final Resources REZ = ResourceManager.getPackageResources( DefaultWorkspace.class ); @@ -59,10 +54,12 @@ public class DefaultWorkspace private ServiceManager m_serviceManager; private Parameters m_parameters; private PropertyStore m_baseStore; - private HashMap m_entries = new HashMap(); private TypeManager m_typeManager; private Deployer m_deployer; + /** A map from Project object -> ProjectEntry for that project. */ + private HashMap m_entries = new HashMap(); + /** * Add a listener to project events. * @@ -84,18 +81,15 @@ public class DefaultWorkspace } /** - * Retrieve relevent services needed for engine. - * - * @param serviceManager the ServiceManager - * @exception ServiceException if an error occurs + * Sets the root execution frame. */ - public void service( final ServiceManager serviceManager ) - throws ServiceException + public void setRootExecutionFrame( final ExecutionFrame frame ) throws Exception { - m_serviceManager = serviceManager; - m_typeManager = (TypeManager)serviceManager.lookup( TypeManager.ROLE ); - m_executor = (Executor)serviceManager.lookup( Executor.ROLE ); - m_deployer = (Deployer)serviceManager.lookup( Deployer.ROLE ); + m_baseStore = frame.getProperties(); + m_serviceManager = frame.getServiceManager(); + m_typeManager = (TypeManager)m_serviceManager.lookup( TypeManager.ROLE ); + m_executor = (Executor)m_serviceManager.lookup( Executor.ROLE ); + m_deployer = (Deployer)m_serviceManager.lookup( Deployer.ROLE ); } public void parameterize( final Parameters parameters ) @@ -104,12 +98,6 @@ public class DefaultWorkspace m_parameters = parameters; } - public void initialize() - throws Exception - { - m_baseStore = createBaseStore(); - } - /** * Execute a target in a particular project. * Execute in the project context. @@ -130,24 +118,6 @@ public class DefaultWorkspace m_listenerSupport.projectFinished( project.getProjectName() ); } - private PropertyStore createBaseStore() - throws Exception - { - final DefaultPropertyStore store = new DefaultPropertyStore(); - - final String[] names = m_parameters.getNames(); - for( int i = 0; i < names.length; i++ ) - { - final String value = m_parameters.getParameter( names[ i ], null ); - store.setProperty( names[ i ], value ); - } - - //Add system properties so that they overide user-defined properties - addToStore( store, System.getProperties() ); - - return store; - } - private File findTypeLib( final String libraryName ) throws Exception { @@ -227,7 +197,7 @@ public class DefaultWorkspace final TypeManager typeManager = m_typeManager.createChildTypeManager(); serviceManager.put( TypeManager.ROLE, typeManager ); - // TODO - Add child role manager + // TODO - Add child role manager and configurer //We need to create a new deployer so that it deploys //to project specific TypeManager @@ -239,31 +209,20 @@ public class DefaultWorkspace //We need to place projects and ProjectManager //in ComponentManager so as to support project-local call() + // TODO - add project to properties, not services serviceManager.put( Workspace.ROLE, this ); serviceManager.put( Project.ROLE, project ); - final String[] names = project.getProjectNames(); - for( int i = 0; i < names.length; i++ ) - { - final String name = names[ i ]; - final Project other = project.getProject( name ); - serviceManager.put( Project.ROLE + "/" + name, other ); - } - // Create a logger final Logger logger = new RoutingLogger( getLogger(), m_listenerSupport ); - //TODO: Put this in Execution Frame + // Properties final PropertyStore store = m_baseStore.createChildStore(""); - - // Create and configure the context - final DefaultTaskContext context = - new DefaultTaskContext( serviceManager, logger, store ); - context.setProperty( TaskContext.BASE_DIRECTORY, project.getBaseDirectory() ); + store.setProperty( TaskContext.BASE_DIRECTORY, project.getBaseDirectory() ); final DefaultExecutionFrame frame = - new DefaultExecutionFrame( logger, context, typeManager ); + new DefaultExecutionFrame( logger, store, serviceManager ); /** * @todo Should no occur but done for the time being to simplify evolution. @@ -462,7 +421,7 @@ public class DefaultWorkspace } //is setting name even necessary ??? - frame.getContext().setProperty( TaskContext.NAME, name ); + frame.getProperties().setProperty( TaskContext.NAME, name ); //notify listeners m_listenerSupport.taskStarted( name ); @@ -474,22 +433,4 @@ public class DefaultWorkspace m_listenerSupport.taskFinished(); } - /** - * Helper method to add values to a store. - * - * @param store the store - * @param map the map of names->values - */ - private void addToStore( final PropertyStore store, final Map map ) - throws Exception - { - final Iterator keys = map.keySet().iterator(); - - while( keys.hasNext() ) - { - final String key = (String)keys.next(); - final Object value = map.get( key ); - store.setProperty( key, value ); - } - } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java index 1be3e5316..ab4036e91 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java @@ -9,6 +9,8 @@ package org.apache.myrmidon.frontends; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.avalon.excalibur.io.FileUtil; @@ -50,9 +52,9 @@ public class EmbeddedAnt private Project m_project; private String m_listenerName = "default"; private ArrayList m_listeners = new ArrayList(); - private Parameters m_workspaceProps = new Parameters(); private Parameters m_builderProps = new Parameters(); private Parameters m_embeddorParameters = new Parameters(); + private Map m_workspaceProperties = new HashMap(); private ClassLoader m_sharedClassLoader; private Embeddor m_embeddor; private File m_homeDir; @@ -122,8 +124,7 @@ public class EmbeddedAnt */ public void setWorkspaceProperty( final String name, final Object value ) { - // TODO - Make properties Objects, not Strings - m_workspaceProps.setParameter( name, value.toString() ); + m_workspaceProperties.put( name, value ); } /** @@ -174,7 +175,7 @@ public class EmbeddedAnt final Project project = prepareProjectModel( embeddor ); // Create a new workspace - final Workspace workspace = embeddor.createWorkspace( m_workspaceProps ); + final Workspace workspace = embeddor.createWorkspace( m_workspaceProperties ); prepareListeners( embeddor, workspace ); //execute the project diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/embeddor/Embeddor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/embeddor/Embeddor.java index eb53831b4..2c3da907c 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/embeddor/Embeddor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/embeddor/Embeddor.java @@ -11,6 +11,7 @@ import org.apache.avalon.framework.parameters.Parameters; import org.apache.myrmidon.interfaces.model.Project; import org.apache.myrmidon.interfaces.workspace.Workspace; import org.apache.myrmidon.listeners.ProjectListener; +import java.util.Map; /** * Interface through which you embed Myrmidon into applications. @@ -53,10 +54,12 @@ public interface Embeddor /** * Creates a {@link Workspace} that can be used to execute projects. * - * @param parameters The properties to define in the workspace + * @param properties The properties to define in the workspace. These + * are added to the properties in the embeddor's + * root execution frame. * @return the Workspace * @throws Exception If the workspace could not be created. */ - Workspace createWorkspace( Parameters parameters ) + Workspace createWorkspace( Map properties ) throws Exception; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionContainer.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionContainer.java new file mode 100644 index 000000000..a3c6b2569 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionContainer.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.txt file. + */ +package org.apache.myrmidon.interfaces.executor; + +/** + * This interface is used to supply a root execution frame to a container + * that executes tasks. + * + * @author Adam Murdoch + * @version $Revision$ $Date$ + */ +public interface ExecutionContainer +{ + /** + * Sets the root execution frame for the container. + */ + void setRootExecutionFrame( ExecutionFrame frame ) throws Exception; +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionFrame.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionFrame.java index 156e39dbe..f737ef2c1 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionFrame.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/executor/ExecutionFrame.java @@ -8,11 +8,17 @@ package org.apache.myrmidon.interfaces.executor; import org.apache.avalon.framework.logger.Logger; -import org.apache.myrmidon.api.TaskContext; -import org.apache.myrmidon.interfaces.type.TypeManager; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.myrmidon.interfaces.property.PropertyStore; /** - * Frames in which tasks are executed. + * An Execution Frame represents the scope in which tasks are executed. + * The scope may include an entire workspace, a project, target, or + * individual task. + * + *

An Execution Frame bundles together all of the context required to + * execute tasks - that is, a set of properties, a set of services, and + * a logger. * * @author Peter Donald * @version $Revision$ $Date$ @@ -23,17 +29,18 @@ public interface ExecutionFrame String ROLE = ExecutionFrame.class.getName(); /** - * @return The TypeManager to use for creating Tasks. + * Returns the set of services to use to create, configure, and execute + * tasks. */ - TypeManager getTypeManager(); + ServiceManager getServiceManager(); /** - * @return The logger which is used for execution messages. + * Returns the logger which is to be supplied to tasks. */ Logger getLogger(); /** - * @return The TaskContext in which the task is executed. + * Returns the set of properties to be supplied to tasks. */ - TaskContext getContext(); + PropertyStore getProperties(); } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/MapPropertyStore.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/MapPropertyStore.java new file mode 100644 index 000000000..4d0f2712d --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/MapPropertyStore.java @@ -0,0 +1,119 @@ +/* + * 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.txt file. + */ +package org.apache.myrmidon.interfaces.property; + +import java.util.Map; +import java.util.HashMap; +import org.apache.myrmidon.api.TaskException; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; + +/** + * A simple unscoped, unsynchronized property store which is backed by a Map. + * + * @author Adam Murdoch + * @version $Revision$ $Date$ + */ +public class MapPropertyStore + implements PropertyStore +{ + private static final Resources REZ = + ResourceManager.getPackageResources( MapPropertyStore.class ); + + private final Map m_properties = new HashMap(); + + /** + * Creates an empty store. + */ + public MapPropertyStore() + { + } + + /** + * Creates a store containing the given properties. + */ + public MapPropertyStore( final Map properties ) + { + m_properties.putAll( properties ); + } + + /** + * Return true if the specified property is set. + * + * @param name the name of property + */ + public boolean isPropertySet( final String name ) + { + return m_properties.containsKey( name ); + } + + /** + * Retrieve the value of specified property. + * + * @param name the name of the property + * @return the value of the property. Never returns null. + * @throws TaskException if there is no such property, or on error + * retrieving property, such as an invalid property name. + */ + public Object getProperty( final String name ) + throws TaskException + { + final Object value = m_properties.get( name ); + if( value == null ) + { + final String message = REZ.getString( "unknown-property.error", name ); + throw new TaskException( message ); + } + return value; + } + + /** + * Retrieve a copy of all the properties that are "in-scope" + * for store. + * + * @return a copy of all the properties that are "in-scope" + * for store. + * @throws TaskException if theres an error retrieving propertys + */ + public Map getProperties() + throws TaskException + { + return new HashMap( m_properties ); + } + + /** + * Set the property with specified name to specified value. + * The specific implementation will apply various rules + * before setting the property. + * + * @param name the name of property + * @param value the value of property + * @throws TaskException if property can not be set + */ + public void setProperty( String name, Object value ) + throws TaskException + { + m_properties.put( name, value ); + } + + /** + * Return a child PropertyStore with specified name. + * This is to allow support for scoped stores. However a + * store may choose to be unscoped and just return a + * reference to itself. + * + * @param name the name of child store + * @return the child store + * @throws TaskException if theres an error creating child store + */ + public PropertyStore createChildStore( String name ) + throws TaskException + { + return this; + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/PropertyResolver.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/PropertyResolver.java index a97fbe754..66d09dd22 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/PropertyResolver.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/PropertyResolver.java @@ -8,6 +8,7 @@ package org.apache.myrmidon.interfaces.property; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.api.TaskContext; /** * @@ -30,11 +31,11 @@ public interface PropertyResolver * Rules used for property resolution are implementation dependent. * * @param value the value to resolve, which may contain property identifiers - * @param properties the set of properties to resolve against. + * @param context the set of properties to resolve against. * @return the resolved content * @exception TaskException if an error occurs */ Object resolveProperties( final String value, - final PropertyStore properties ) + final TaskContext context ) throws TaskException; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/Resources.properties new file mode 100644 index 000000000..368a4fd47 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/property/Resources.properties @@ -0,0 +1 @@ +unknown-property.error=Unknown property "{0}". \ No newline at end of file diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java index d96fad6d0..480429154 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java @@ -8,6 +8,7 @@ package org.apache.myrmidon.components.embeddor.test; import java.io.File; +import java.util.HashMap; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.logger.Logger; import org.apache.myrmidon.AbstractProjectTest; @@ -118,7 +119,7 @@ public class DefaultEmbeddorTest final Project project = embeddor.createProject( projectFile.getAbsolutePath(), null, null ); // Build the workspace - final Workspace workspace = embeddor.createWorkspace( new Parameters() ); + final Workspace workspace = embeddor.createWorkspace( new HashMap() ); // Install a listener final LogMessageTracker listener = new LogMessageTracker(); diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/AbstractPropertyResolverTestCase.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/AbstractPropertyResolverTestCase.java index b2925afa8..da422a1b7 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/AbstractPropertyResolverTestCase.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/AbstractPropertyResolverTestCase.java @@ -11,8 +11,11 @@ import java.io.File; import java.util.Date; import org.apache.aut.converter.lib.ObjectToStringConverter; import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.avalon.framework.service.DefaultServiceManager; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.components.AbstractComponentTest; +import org.apache.myrmidon.components.workspace.DefaultTaskContext; import org.apache.myrmidon.components.property.DefaultPropertyResolver; import org.apache.myrmidon.components.store.DefaultPropertyStore; import org.apache.myrmidon.interfaces.property.PropertyResolver; @@ -28,7 +31,7 @@ public abstract class AbstractPropertyResolverTestCase extends AbstractComponentTest { protected PropertyResolver m_resolver; - protected PropertyStore m_store; + protected TaskContext m_context; public AbstractPropertyResolverTestCase( final String name ) { @@ -39,9 +42,12 @@ public abstract class AbstractPropertyResolverTestCase { m_resolver = (PropertyResolver)getServiceManager().lookup( PropertyResolver.ROLE ); - m_store = new DefaultPropertyStore(); - m_store.setProperty( "intProp", new Integer( 333 ) ); - m_store.setProperty( "stringProp", "String property" ); + final PropertyStore store = new DefaultPropertyStore(); + m_context = + new DefaultTaskContext( new DefaultServiceManager(), getLogger(), store ); + + m_context.setProperty( "intProp", new Integer( 333 ) ); + m_context.setProperty( "stringProp", "String property" ); registerConverter( ObjectToStringConverter.class, Object.class, String.class ); } @@ -87,14 +93,14 @@ public abstract class AbstractPropertyResolverTestCase private void testPropertyValue( final Object propObject ) throws Exception { - m_store.setProperty( "typedProp", propObject ); + m_context.setProperty( "typedProp", propObject ); final String propString = propObject.toString(); - doTestResolution( "${typedProp}", propObject, m_store ); + doTestResolution( "${typedProp}", propObject, m_context ); doTestResolution( "${typedProp} with following text", - propString + " with following text", m_store ); + propString + " with following text", m_context ); doTestResolution( "Preceding text with ${typedProp}", - "Preceding text with " + propString, m_store ); + "Preceding text with " + propString, m_context ); } /** @@ -102,15 +108,15 @@ public abstract class AbstractPropertyResolverTestCase */ public void testMultipleProperties() throws Exception { - m_store.setProperty( "prop1", "value1" ); - m_store.setProperty( "prop2", "value2" ); - m_store.setProperty( "int1", new Integer( 123 ) ); + m_context.setProperty( "prop1", "value1" ); + m_context.setProperty( "prop2", "value2" ); + m_context.setProperty( "int1", new Integer( 123 ) ); - doTestResolution( "${prop1}${prop2}", "value1value2", m_store ); - doTestResolution( "${prop1}${prop1}${prop1}", "value1value1value1", m_store ); + doTestResolution( "${prop1}${prop2}", "value1value2", m_context ); + doTestResolution( "${prop1}${prop1}${prop1}", "value1value1value1", m_context ); doTestResolution( "before ${prop2} between ${prop1} after", - "before value2 between value1 after", m_store ); - doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", m_store ); + "before value2 between value1 after", m_context ); + doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", m_context ); } /** @@ -121,10 +127,10 @@ public abstract class AbstractPropertyResolverTestCase final Resources rez = getResourcesForTested( DefaultPropertyResolver.class ); doTestFailure( "${unclosed", rez.getString( "prop.mismatched-braces.error" ), - m_store ); + m_context ); doTestFailure( "${", rez.getString( "prop.mismatched-braces.error" ), - m_store ); + m_context ); /* TODO - need to handle these cases. */ // testFailure( "${bad${}", "", m_context ); @@ -136,10 +142,10 @@ public abstract class AbstractPropertyResolverTestCase */ protected void doTestResolution( final String value, final Object expected, - final PropertyStore properties ) + final TaskContext context ) throws Exception { - final Object resolved = m_resolver.resolveProperties( value, properties ); + final Object resolved = m_resolver.resolveProperties( value, context ); assertEquals( expected, resolved ); } @@ -150,11 +156,11 @@ public abstract class AbstractPropertyResolverTestCase */ protected void doTestFailure( final String value, final String expectedErrorMessage, - final PropertyStore properties ) + final TaskContext context ) { try { - m_resolver.resolveProperties( value, properties ); + m_resolver.resolveProperties( value, context ); fail( "Unexpected sucess - test should have failed." ); } catch( TaskException e ) diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/ClassicPropertyResolverTestCase.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/ClassicPropertyResolverTestCase.java index 742e2478d..12eef075a 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/ClassicPropertyResolverTestCase.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/ClassicPropertyResolverTestCase.java @@ -37,6 +37,6 @@ public class ClassicPropertyResolverTestCase { final String undefinedProp = "undefinedProperty"; final String propRef = "${" + undefinedProp + "}"; - doTestResolution( propRef, propRef, m_store ); + doTestResolution( propRef, propRef, m_context ); } } diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/DefaultPropertyResolverTestCase.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/DefaultPropertyResolverTestCase.java index cc358f07f..985a5a493 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/DefaultPropertyResolverTestCase.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/property/test/DefaultPropertyResolverTestCase.java @@ -41,11 +41,11 @@ public class DefaultPropertyResolverTestCase final String undefinedProp = "undefinedProperty"; doTestFailure( "${" + undefinedProp + "}", rez.getString( "unknown-prop.error", undefinedProp ), - m_store ); + m_context ); //TODO - "" should be disallowed as a property name doTestFailure( "${}", rez.getString( "unknown-prop.error", "" ), - m_store ); + m_context ); } } diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/PathTestCase.java b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/PathTestCase.java index 36b391051..e23055298 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/PathTestCase.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/PathTestCase.java @@ -8,6 +8,7 @@ package org.apache.myrmidon.framework.file.test; import java.io.File; +import org.apache.aut.nativelib.PathUtil; import org.apache.avalon.excalibur.io.FileUtil; import org.apache.myrmidon.AbstractProjectTest; import org.apache.myrmidon.LogMessageTracker; @@ -31,7 +32,7 @@ public class PathTestCase */ public void testLocationAttribute() throws Exception { - testPathContent( "set-location", new String[] { "location" } ); + testPathContent( "set-location", new String[]{"location"} ); } /** @@ -40,13 +41,13 @@ public class PathTestCase public void testPathAttribute() throws Exception { // Test a path with a single file - testPathContent( "set-path", new String[] { "single-file" } ); + testPathContent( "set-path", new String[]{"single-file"} ); // Test a path with several files, using ; separator - testPathContent( "set-multi-path", new String[] { "file1", "file2", ".." } ); + testPathContent( "set-multi-path", new String[]{"file1", "file2", ".."} ); // Test a path with several files, using : separator - testPathContent( "set-multi-path2", new String[] { "file1", "file2", ".." } ); + testPathContent( "set-multi-path2", new String[]{"file1", "file2", ".."} ); } /** @@ -54,8 +55,8 @@ public class PathTestCase */ public void testPathElement() throws Exception { - testPathContent( "nested-path", new String[] { "some-file" } ); - testPathContent( "mixed-path", new String[] { "file1", "file2", "file3", "file4", "file5" } ); + testPathContent( "nested-path", new String[]{"some-file"} ); + testPathContent( "mixed-path", new String[]{"file1", "file2", "file3", "file4", "file5"} ); } /** @@ -63,7 +64,7 @@ public class PathTestCase */ public void testFilesetElement() throws Exception { - testPathContent( "set-fileset", new String[] { "path.ant" } ); + testPathContent( "set-fileset", new String[]{"path.ant"} ); } /** @@ -71,7 +72,27 @@ public class PathTestCase */ public void testCustomFileList() throws Exception { - testPathContent( "test-custom-file-list", new String[] { "file1" } ); + testPathContent( "test-custom-file-list", new String[]{"file1"} ); + } + + /** + * Test converting between string and path. + */ + public void testConvert() throws Exception + { + testPathContent( "convert-string-to-path", new String[]{"file1", "file2"} ); + + // Test conversion from path -> string + final File[] files = { + getTestResource( "file1", false ), + getTestResource( "file2", false ) + }; + final String path = PathUtil.formatPath( files ); + final LogMessageTracker listener = new LogMessageTracker(); + listener.addExpectedMessage( "convert-path-to-string", "test-path = " + path ); + + final File projectFile = getTestResource( "path.ant" ); + executeTarget( projectFile, "convert-path-to-string", listener ); } /** diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/TestFileList.java b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/TestFileList.java index d134a0c48..8ca76f0e7 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/TestFileList.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/TestFileList.java @@ -7,10 +7,12 @@ */ package org.apache.myrmidon.framework.file.test; -import org.apache.myrmidon.framework.file.FileList; +import java.io.File; +import java.util.ArrayList; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; -import java.io.File; +import org.apache.myrmidon.framework.file.FileList; +import org.apache.myrmidon.framework.file.Path; /** * A test FileList implementation. @@ -24,19 +26,38 @@ public class TestFileList implements FileList { private String m_name; + private Path m_path; public void setName( final String name ) { m_name = name; } + public void setPath( final Path path ) + { + m_path = path; + } + /** * Returns the files in this list. */ public String[] listFiles( final TaskContext context ) throws TaskException { - final File file = context.resolveFile( m_name ); - return new String[] { file.getAbsolutePath() }; + final ArrayList files = new ArrayList(); + if( m_name != null ) + { + final File file = context.resolveFile( m_name ); + files.add( file.getAbsolutePath() ); + } + if( m_path != null ) + { + final String[] fileNames = m_path.listFiles( context ); + for( int i = 0; i < fileNames.length; i++ ) + { + files.add( fileNames[ i ] ); + } + } + return (String[])files.toArray( new String[ files.size() ] ); } } diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/path.ant b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/path.ant index 319f92336..006c3f441 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/path.ant +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/framework/file/test/path.ant @@ -13,14 +13,14 @@ - + - + @@ -64,4 +64,17 @@ + + + + + + + + + + + test-path = ${test-path} + + \ No newline at end of file