diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AbstractAspectHandler.java b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AbstractAspectHandler.java index 71493dd8c..74a34a799 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AbstractAspectHandler.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AbstractAspectHandler.java @@ -35,7 +35,7 @@ public abstract class AbstractAspectHandler return taskModel; } - public void aspect( final Parameters parameters, final Configuration[] elements ) + public void aspectSettings( final Parameters parameters, final Configuration[] elements ) throws TaskException { m_aspectParameters = parameters; diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AspectHandler.java b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AspectHandler.java index aa3d38f10..ff5222dc4 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AspectHandler.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/AspectHandler.java @@ -24,7 +24,7 @@ public interface AspectHandler Configuration preCreate( Configuration taskModel ) throws TaskException; - void aspect( Parameters parameters, Configuration[] children ) + void aspectSettings( Parameters parameters, Configuration[] children ) throws TaskException; void postCreate( Task task ) diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/NoopAspectHandler.java b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/NoopAspectHandler.java new file mode 100644 index 000000000..2ca3525d8 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/aspects/NoopAspectHandler.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE file. + */ +package org.apache.myrmidon.aspects; + +/** + * A Noop aspect handler that does nothing. + * + * @author Peter Donald + */ +public class NoopAspectHandler + extends AbstractAspectHandler +{ +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/AspectManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/AspectManager.java index a1775fbd6..2706ffd26 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/AspectManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/AspectManager.java @@ -7,8 +7,11 @@ */ package org.apache.myrmidon.components.aspect; -import org.apache.myrmidon.aspects.AspectHandler; import org.apache.avalon.framework.component.Component; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.aspects.AspectHandler; /** * Manage and propogate Aspects. @@ -20,6 +23,14 @@ public interface AspectManager { String ROLE = "org.apache.myrmidon.components.aspect.AspectManager"; - void addAspectHandler( AspectHandler handler ); - void removeAspectHandler( AspectHandler handler ); + String[] getNames(); + + void dispatchAspectSettings( String name, Parameters parameters, Configuration[] elements ) + throws TaskException; + + void addAspectHandler( String name, AspectHandler handler ) + throws TaskException; + + void removeAspectHandler( String name, AspectHandler handler ) + throws TaskException; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/DefaultAspectManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/DefaultAspectManager.java index 76ec89687..de94dc570 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/DefaultAspectManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/aspect/DefaultAspectManager.java @@ -7,13 +7,15 @@ */ package org.apache.myrmidon.components.aspect; -import java.util.ArrayList; +import java.util.HashMap; +import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.parameters.Parameters; import org.apache.log.Logger; import org.apache.myrmidon.api.Task; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.aspects.AspectHandler; +import org.apache.myrmidon.aspects.NoopAspectHandler; /** * Manage and propogate Aspects. @@ -21,21 +23,62 @@ import org.apache.myrmidon.aspects.AspectHandler; * @author Peter Donald */ public class DefaultAspectManager - implements AspectManager + implements AspectManager, Initializable { - private ArrayList m_aspectCopy = new ArrayList(); - private AspectHandler[] m_aspects = new AspectHandler[ 0 ]; + private HashMap m_aspectMap = new HashMap(); + private AspectHandler[] m_aspects = new AspectHandler[ 0 ]; + private String[] m_names = new String[ 0 ]; - public synchronized void addAspectHandler( final AspectHandler handler ) + public void initialize() + throws Exception { - m_aspectCopy.add( handler ); - m_aspects = (AspectHandler[])m_aspectCopy.toArray( m_aspects ); + ///UGLY HACK!!!! + addAspectHandler( "ant", new NoopAspectHandler() ); + addAspectHandler( "doc", new NoopAspectHandler() ); } - public synchronized void removeAspectHandler( final AspectHandler handler ) + public synchronized void addAspectHandler( final String name, final AspectHandler handler ) + throws TaskException + { + m_aspectMap.put( name, handler ); + rebuildArrays(); + } + + public synchronized void removeAspectHandler( final String name, final AspectHandler handler ) + throws TaskException + { + final AspectHandler entry = (AspectHandler)m_aspectMap.remove( name ); + if( null == entry ) + { + throw new TaskException( "No such aspect with name '" + name + "'" ); + } + + rebuildArrays(); + } + + private void rebuildArrays() { - m_aspectCopy.remove( handler ); - m_aspects = (AspectHandler[])m_aspectCopy.toArray( m_aspects ); + m_aspects = (AspectHandler[])m_aspectMap.values().toArray( m_aspects ); + m_names = (String[])m_aspectMap.keySet().toArray( m_names ); + } + + public String[] getNames() + { + return m_names; + } + + public void dispatchAspectSettings( final String name, + final Parameters parameters, + final Configuration[] elements ) + throws TaskException + { + final AspectHandler handler = (AspectHandler)m_aspectMap.get( name ); + if( null == handler ) + { + throw new TaskException( "No such aspect with name '" + name + "'" ); + } + + handler.aspectSettings( parameters, elements ); } public Configuration preCreate( final Configuration configuration ) @@ -52,10 +95,10 @@ public class DefaultAspectManager return model; } - public void aspect( final Parameters parameters, final Configuration[] elements ) + public void aspectSettings( final Parameters parameters, final Configuration[] elements ) throws TaskException { - throw new UnsupportedOperationException( "Can not provide parameters to AspectManager" ); + throw new UnsupportedOperationException( "Can not provide Settings to AspectManager" ); } public void postCreate( final Task task ) 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 381b1d4b1..b6908c7b0 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 @@ -34,10 +34,6 @@ public class AspectAwareExecutor private AspectManager m_aspectManager; - public AspectAwareExecutor() - { - } - /** * Retrieve relevent services. * @@ -61,7 +57,7 @@ public class AspectAwareExecutor } catch( final TaskException te ) { - if( false == getAspectHandler().error( te ) ) + if( false == getAspectManager().error( te ) ) { throw te; } @@ -73,14 +69,14 @@ public class AspectAwareExecutor { getLogger().debug( "Creating" ); - taskModel = getAspectHandler().preCreate( taskModel ); + taskModel = getAspectManager().preCreate( taskModel ); taskModel = prepareAspects( taskModel ); final Task task = createTask( taskModel.getName() ); - getAspectHandler().postCreate( task ); + getAspectManager().postCreate( task ); - getAspectHandler().preLoggable( getLogger() ); + getAspectManager().preLoggable( getLogger() ); setupLogger( task ); getLogger().debug( "Contextualizing" ); @@ -90,25 +86,25 @@ public class AspectAwareExecutor doCompose( task, taskModel ); getLogger().debug( "Configuring" ); - getAspectHandler().preConfigure( taskModel ); + getAspectManager().preConfigure( taskModel ); doConfigure( task, taskModel, context ); getLogger().debug( "Initializing" ); doInitialize( task, taskModel ); getLogger().debug( "Executing" ); - getAspectHandler().preExecute(); + getAspectManager().preExecute(); task.execute(); getLogger().debug( "Disposing" ); - getAspectHandler().preDestroy(); + getAspectManager().preDestroy(); doDispose( task, taskModel ); } //TODO: Extract and clean taskModel here. //Get all parameters from model and provide to appropriate aspect. //aspect( final Parameters parameters, final Configuration[] elements ) - private Configuration prepareAspects( final Configuration taskModel ) + private final Configuration prepareAspects( final Configuration taskModel ) throws TaskException { final DefaultConfiguration newTaskModel = @@ -119,9 +115,105 @@ public class AspectAwareExecutor processAttributes( taskModel, newTaskModel, parameterMap ); processElements( taskModel, newTaskModel, elementMap ); + dispatchAspectsSettings( parameterMap, elementMap ); + checkForUnusedSettings( parameterMap, elementMap ); + return newTaskModel; } + private final void dispatchAspectsSettings( final HashMap parameterMap, + final HashMap elementMap ) + throws TaskException + { + final String[] names = getAspectManager().getNames(); + + for( int i = 0; i < names.length; i++ ) + { + final ArrayList elementList = (ArrayList)elementMap.remove( names[ i ] ); + + Parameters parameters = (Parameters)parameterMap.remove( names[ i ] ); + if( null == parameters ) parameters = EMPTY_PARAMETERS; + + Configuration[] elements = null; + if( null == elementList ) elements = EMPTY_ELEMENTS; + else + { + elements = (Configuration[])elementList.toArray( EMPTY_ELEMENTS ); + } + + dispatch( names[ i ], parameters, elements ); + } + } + + private final void checkForUnusedSettings( final HashMap parameterMap, + final HashMap elementMap ) + throws TaskException + { + if( 0 != parameterMap.size() ) + { + final String[] namespaces = + (String[])parameterMap.keySet().toArray( new String[ 0 ] ); + + for( int i = 0; i < namespaces.length; i++ ) + { + final String namespace = namespaces[ i ]; + final Parameters parameters = (Parameters)parameterMap.get( namespace ); + final ArrayList elementList = (ArrayList)elementMap.remove( namespace ); + + Configuration[] elements = null; + + if( null == elementList ) elements = EMPTY_ELEMENTS; + else + { + elements = (Configuration[])elementList.toArray( EMPTY_ELEMENTS ); + } + + unusedSetting( namespace, parameters, elements ); + } + } + + if( 0 != elementMap.size() ) + { + final String[] namespaces = + (String[])elementMap.keySet().toArray( new String[ 0 ] ); + + for( int i = 0; i < namespaces.length; i++ ) + { + final String namespace = namespaces[ i ]; + final ArrayList elementList = (ArrayList)elementMap.remove( namespace ); + final Configuration[] elements = + (Configuration[])elementList.toArray( EMPTY_ELEMENTS ); + + unusedSetting( namespace, EMPTY_PARAMETERS, elements ); + } + } + } + + private void unusedSetting( final String namespace, + final Parameters parameters, + final Configuration[] elements ) + throws TaskException + { + throw new TaskException( "Unused aspect settings for namespace " + namespace + + " (parameterCount=" + parameters.getNames().length + + " elementCount=" + elements.length + ")" ); + } + + private void dispatch( final String namespace, + final Parameters parameters, + final Configuration[] elements ) + throws TaskException + { + getAspectManager().dispatchAspectSettings( namespace, parameters, elements ); + + if( getLogger().isDebugEnabled() ) + { + getLogger().debug( "Dispatching Aspect Settings to: " + namespace + + " parameterCount=" + parameters.getNames().length + + " elementCount=" + elements.length ); + } + } + private final void processElements( final Configuration taskModel, final DefaultConfiguration newTaskModel, final HashMap map ) @@ -198,7 +290,7 @@ public class AspectAwareExecutor return parameters; } - protected final AspectHandler getAspectHandler() + protected final AspectManager getAspectManager() { return m_aspectManager; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/ant1/TaskAdapter.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/ant1/TaskAdapter.java index 3a11cdfce..c2a4fdbf5 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/ant1/TaskAdapter.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/ant1/TaskAdapter.java @@ -64,8 +64,7 @@ public class TaskAdapter getProject().contextualize( getContext() ); getProject().init(); - //getTask().setProject( getProject() ); - + getTask().setProject( getProject() ); getTask().init(); getTask().execute(); } diff --git a/proposal/myrmidon/src/make/sample.ant b/proposal/myrmidon/src/make/sample.ant index 538c25ec4..bc9bfe60f 100644 --- a/proposal/myrmidon/src/make/sample.ant +++ b/proposal/myrmidon/src/make/sample.ant @@ -103,7 +103,12 @@ Legal: - + + + Test case for aspects + + + \ No newline at end of file diff --git a/proposal/myrmidon/tools/lib/ant.jar b/proposal/myrmidon/tools/lib/ant.jar index 91947a529..434771752 100644 Binary files a/proposal/myrmidon/tools/lib/ant.jar and b/proposal/myrmidon/tools/lib/ant.jar differ