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> |