Settings are now passed to aspect as appropriate. Empty ones passed to aspects that do no have any defined on task. Attributes/elements that have namespace marked but have no equivelent aspect cause a TaskException git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269114 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -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; | |||
| @@ -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 ) | |||
| @@ -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 <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class NoopAspectHandler | |||
| extends AbstractAspectHandler | |||
| { | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| 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 ) | |||
| @@ -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; | |||
| } | |||
| @@ -64,8 +64,7 @@ public class TaskAdapter | |||
| getProject().contextualize( getContext() ); | |||
| getProject().init(); | |||
| //getTask().setProject( getProject() ); | |||
| getTask().setProject( getProject() ); | |||
| getTask().init(); | |||
| getTask().execute(); | |||
| } | |||
| @@ -103,7 +103,12 @@ Legal: | |||
| <echo message="${blah}"/> | |||
| <echo message="Whoa - it no fail. Did you use ant-call to call me and set param blah?"/> | |||
| <echo ant:fail-on-error="true" message="This should fail ...."/> | |||
| <echo ant:fail-on-error="true" message="Some random message"> | |||
| <doc:description> | |||
| Test case for aspects | |||
| </doc:description> | |||
| <ant:some-element some-attribute="blah"/> | |||
| </echo> | |||
| </target> | |||
| </project> | |||