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; | return taskModel; | ||||
} | } | ||||
public void aspect( final Parameters parameters, final Configuration[] elements ) | |||||
public void aspectSettings( final Parameters parameters, final Configuration[] elements ) | |||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
m_aspectParameters = parameters; | m_aspectParameters = parameters; | ||||
@@ -24,7 +24,7 @@ public interface AspectHandler | |||||
Configuration preCreate( Configuration taskModel ) | Configuration preCreate( Configuration taskModel ) | ||||
throws TaskException; | throws TaskException; | ||||
void aspect( Parameters parameters, Configuration[] children ) | |||||
void aspectSettings( Parameters parameters, Configuration[] children ) | |||||
throws TaskException; | throws TaskException; | ||||
void postCreate( Task task ) | 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; | package org.apache.myrmidon.components.aspect; | ||||
import org.apache.myrmidon.aspects.AspectHandler; | |||||
import org.apache.avalon.framework.component.Component; | 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. | * Manage and propogate Aspects. | ||||
@@ -20,6 +23,14 @@ public interface AspectManager | |||||
{ | { | ||||
String ROLE = "org.apache.myrmidon.components.aspect.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; | 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.configuration.Configuration; | ||||
import org.apache.avalon.framework.parameters.Parameters; | import org.apache.avalon.framework.parameters.Parameters; | ||||
import org.apache.log.Logger; | import org.apache.log.Logger; | ||||
import org.apache.myrmidon.api.Task; | import org.apache.myrmidon.api.Task; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.myrmidon.aspects.AspectHandler; | import org.apache.myrmidon.aspects.AspectHandler; | ||||
import org.apache.myrmidon.aspects.NoopAspectHandler; | |||||
/** | /** | ||||
* Manage and propogate Aspects. | * Manage and propogate Aspects. | ||||
@@ -21,21 +23,62 @@ import org.apache.myrmidon.aspects.AspectHandler; | |||||
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public class DefaultAspectManager | 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 ) | public Configuration preCreate( final Configuration configuration ) | ||||
@@ -52,10 +95,10 @@ public class DefaultAspectManager | |||||
return model; | return model; | ||||
} | } | ||||
public void aspect( final Parameters parameters, final Configuration[] elements ) | |||||
public void aspectSettings( final Parameters parameters, final Configuration[] elements ) | |||||
throws TaskException | 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 ) | public void postCreate( final Task task ) | ||||
@@ -34,10 +34,6 @@ public class AspectAwareExecutor | |||||
private AspectManager m_aspectManager; | private AspectManager m_aspectManager; | ||||
public AspectAwareExecutor() | |||||
{ | |||||
} | |||||
/** | /** | ||||
* Retrieve relevent services. | * Retrieve relevent services. | ||||
* | * | ||||
@@ -61,7 +57,7 @@ public class AspectAwareExecutor | |||||
} | } | ||||
catch( final TaskException te ) | catch( final TaskException te ) | ||||
{ | { | ||||
if( false == getAspectHandler().error( te ) ) | |||||
if( false == getAspectManager().error( te ) ) | |||||
{ | { | ||||
throw te; | throw te; | ||||
} | } | ||||
@@ -73,14 +69,14 @@ public class AspectAwareExecutor | |||||
{ | { | ||||
getLogger().debug( "Creating" ); | getLogger().debug( "Creating" ); | ||||
taskModel = getAspectHandler().preCreate( taskModel ); | |||||
taskModel = getAspectManager().preCreate( taskModel ); | |||||
taskModel = prepareAspects( taskModel ); | taskModel = prepareAspects( taskModel ); | ||||
final Task task = createTask( taskModel.getName() ); | final Task task = createTask( taskModel.getName() ); | ||||
getAspectHandler().postCreate( task ); | |||||
getAspectManager().postCreate( task ); | |||||
getAspectHandler().preLoggable( getLogger() ); | |||||
getAspectManager().preLoggable( getLogger() ); | |||||
setupLogger( task ); | setupLogger( task ); | ||||
getLogger().debug( "Contextualizing" ); | getLogger().debug( "Contextualizing" ); | ||||
@@ -90,25 +86,25 @@ public class AspectAwareExecutor | |||||
doCompose( task, taskModel ); | doCompose( task, taskModel ); | ||||
getLogger().debug( "Configuring" ); | getLogger().debug( "Configuring" ); | ||||
getAspectHandler().preConfigure( taskModel ); | |||||
getAspectManager().preConfigure( taskModel ); | |||||
doConfigure( task, taskModel, context ); | doConfigure( task, taskModel, context ); | ||||
getLogger().debug( "Initializing" ); | getLogger().debug( "Initializing" ); | ||||
doInitialize( task, taskModel ); | doInitialize( task, taskModel ); | ||||
getLogger().debug( "Executing" ); | getLogger().debug( "Executing" ); | ||||
getAspectHandler().preExecute(); | |||||
getAspectManager().preExecute(); | |||||
task.execute(); | task.execute(); | ||||
getLogger().debug( "Disposing" ); | getLogger().debug( "Disposing" ); | ||||
getAspectHandler().preDestroy(); | |||||
getAspectManager().preDestroy(); | |||||
doDispose( task, taskModel ); | doDispose( task, taskModel ); | ||||
} | } | ||||
//TODO: Extract and clean taskModel here. | //TODO: Extract and clean taskModel here. | ||||
//Get all parameters from model and provide to appropriate aspect. | //Get all parameters from model and provide to appropriate aspect. | ||||
//aspect( final Parameters parameters, final Configuration[] elements ) | //aspect( final Parameters parameters, final Configuration[] elements ) | ||||
private Configuration prepareAspects( final Configuration taskModel ) | |||||
private final Configuration prepareAspects( final Configuration taskModel ) | |||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
final DefaultConfiguration newTaskModel = | final DefaultConfiguration newTaskModel = | ||||
@@ -119,9 +115,105 @@ public class AspectAwareExecutor | |||||
processAttributes( taskModel, newTaskModel, parameterMap ); | processAttributes( taskModel, newTaskModel, parameterMap ); | ||||
processElements( taskModel, newTaskModel, elementMap ); | processElements( taskModel, newTaskModel, elementMap ); | ||||
dispatchAspectsSettings( parameterMap, elementMap ); | |||||
checkForUnusedSettings( parameterMap, elementMap ); | |||||
return newTaskModel; | 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, | private final void processElements( final Configuration taskModel, | ||||
final DefaultConfiguration newTaskModel, | final DefaultConfiguration newTaskModel, | ||||
final HashMap map ) | final HashMap map ) | ||||
@@ -198,7 +290,7 @@ public class AspectAwareExecutor | |||||
return parameters; | return parameters; | ||||
} | } | ||||
protected final AspectHandler getAspectHandler() | |||||
protected final AspectManager getAspectManager() | |||||
{ | { | ||||
return m_aspectManager; | return m_aspectManager; | ||||
} | } | ||||
@@ -64,8 +64,7 @@ public class TaskAdapter | |||||
getProject().contextualize( getContext() ); | getProject().contextualize( getContext() ); | ||||
getProject().init(); | getProject().init(); | ||||
//getTask().setProject( getProject() ); | |||||
getTask().setProject( getProject() ); | |||||
getTask().init(); | getTask().init(); | ||||
getTask().execute(); | getTask().execute(); | ||||
} | } | ||||
@@ -103,7 +103,12 @@ Legal: | |||||
<echo message="${blah}"/> | <echo message="${blah}"/> | ||||
<echo message="Whoa - it no fail. Did you use ant-call to call me and set param 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> | </target> | ||||
</project> | </project> |