git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269090 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -9,7 +9,6 @@ package org.apache.ant.modules.basic; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.ComponentSelector; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.configuration.Configurable; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| @@ -22,6 +21,8 @@ import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.components.configurer.Configurer; | |||
| import org.apache.myrmidon.components.converter.MasterConverter; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.components.type.TypeException; | |||
| import org.apache.myrmidon.components.type.TypeFactory; | |||
| /** | |||
| * This is the property "task" to declare a binding of a datatype to a name. | |||
| @@ -35,7 +36,7 @@ public class Property | |||
| private String m_name; | |||
| private Object m_value; | |||
| private boolean m_localScope = true; | |||
| private ComponentSelector m_selector; | |||
| private TypeFactory m_factory; | |||
| private MasterConverter m_converter; | |||
| private Configurer m_configurer; | |||
| @@ -44,7 +45,12 @@ public class Property | |||
| { | |||
| m_configurer = (Configurer)componentManager.lookup( Configurer.ROLE ); | |||
| final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_selector = (ComponentSelector)typeManager.lookup( DataType.ROLE + "Selector" ); | |||
| try { m_factory = typeManager.getFactory( DataType.ROLE ); } | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ComponentException( "Unable to retrieve factory from TypeManager", te ); | |||
| } | |||
| m_converter = (MasterConverter)componentManager.lookup( MasterConverter.ROLE ); | |||
| } | |||
| @@ -121,7 +127,7 @@ public class Property | |||
| try | |||
| { | |||
| final DataType value = (DataType)m_selector.select( child.getName() ); | |||
| final DataType value = (DataType)m_factory.create( child.getName() ); | |||
| setValue( value ); | |||
| m_configurer.configure( value, child, getContext() ); | |||
| } | |||
| @@ -7,8 +7,6 @@ | |||
| */ | |||
| package org.apache.myrmidon.api; | |||
| import org.apache.avalon.framework.component.Component; | |||
| /** | |||
| * Base class for those classes that can appear inside the build file | |||
| * as stand alone data types. | |||
| @@ -16,7 +14,6 @@ import org.apache.avalon.framework.component.Component; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface DataType | |||
| extends Component | |||
| { | |||
| String ROLE = "org.apache.myrmidon.api.DataType"; | |||
| } | |||
| @@ -7,8 +7,6 @@ | |||
| */ | |||
| package org.apache.myrmidon.api; | |||
| import org.apache.avalon.framework.component.Component; | |||
| /** | |||
| * This is the interface that tasks implement to be executed in Myrmidon runtime. | |||
| * | |||
| @@ -26,7 +24,6 @@ import org.apache.avalon.framework.component.Component; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface Task | |||
| extends Component | |||
| { | |||
| String ROLE = "org.apache.myrmidon.api.Task"; | |||
| @@ -9,11 +9,12 @@ package org.apache.myrmidon.components.converter; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.ComponentSelector; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.context.Context; | |||
| import org.apache.avalon.framework.logger.AbstractLoggable; | |||
| import org.apache.myrmidon.components.converter.MasterConverter; | |||
| import org.apache.myrmidon.components.type.TypeException; | |||
| import org.apache.myrmidon.components.type.TypeFactory; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.converter.Converter; | |||
| import org.apache.myrmidon.converter.ConverterException; | |||
| @@ -30,7 +31,7 @@ public class DefaultMasterConverter | |||
| private final static boolean DEBUG = false; | |||
| private ConverterRegistry m_registry; | |||
| private ComponentSelector m_selector; | |||
| private TypeFactory m_factory; | |||
| /** | |||
| * Retrieve relevent services needed to deploy. | |||
| @@ -44,7 +45,11 @@ public class DefaultMasterConverter | |||
| m_registry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE ); | |||
| final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_selector = (ComponentSelector)typeManager.lookup( Converter.ROLE + "Selector" ); | |||
| try { m_factory = typeManager.getFactory( Converter.ROLE ); } | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ComponentException( "Unable to retrieve factory from TypeManager", te ); | |||
| } | |||
| } | |||
| /** | |||
| @@ -86,7 +91,7 @@ public class DefaultMasterConverter | |||
| try | |||
| { | |||
| //TODO: Start caching converters instead of repeatedly instantiating em. | |||
| final Converter converter = (Converter)m_selector.select( name ); | |||
| final Converter converter = (Converter)m_factory.create( name ); | |||
| if( DEBUG ) | |||
| @@ -96,10 +101,10 @@ public class DefaultMasterConverter | |||
| return converter.convert( destination, original, context ); | |||
| } | |||
| catch( final ComponentException ce ) | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ConverterException( "Badly configured TypeManager missing " + | |||
| "converter definition" ); | |||
| "converter definition", te ); | |||
| } | |||
| } | |||
| } | |||
| @@ -12,7 +12,6 @@ import org.apache.avalon.framework.activity.Initializable; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.ComponentSelector; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.component.DefaultComponentManager; | |||
| import org.apache.avalon.framework.configuration.Configurable; | |||
| @@ -27,6 +26,8 @@ import org.apache.myrmidon.api.TaskContext; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.components.configurer.Configurer; | |||
| import org.apache.myrmidon.components.type.TypeException; | |||
| import org.apache.myrmidon.components.type.TypeFactory; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| public class DefaultExecutor | |||
| @@ -34,7 +35,7 @@ public class DefaultExecutor | |||
| implements Executor, Composable | |||
| { | |||
| private Configurer m_configurer; | |||
| private ComponentSelector m_selector; | |||
| private TypeFactory m_factory; | |||
| private ComponentManager m_componentManager; | |||
| @@ -53,7 +54,11 @@ public class DefaultExecutor | |||
| m_configurer = (Configurer)componentManager.lookup( Configurer.ROLE ); | |||
| final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_selector = (ComponentSelector)typeManager.lookup( Task.ROLE + "Selector" ); | |||
| try { m_factory = typeManager.getFactory( Task.ROLE ); } | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ComponentException( "Unable to retrieve factory from TypeManager", te ); | |||
| } | |||
| } | |||
| public void execute( final Configuration taskData, final TaskContext context ) | |||
| @@ -88,11 +93,11 @@ public class DefaultExecutor | |||
| { | |||
| try | |||
| { | |||
| return (Task)m_selector.select( name ); | |||
| return (Task)m_factory.create( name ); | |||
| } | |||
| catch( final ComponentException ce ) | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new TaskException( "Unable to create task " + name, ce ); | |||
| throw new TaskException( "Unable to create task " + name, te ); | |||
| } | |||
| } | |||
| @@ -8,9 +8,6 @@ | |||
| package org.apache.myrmidon.components.type; | |||
| import java.util.HashMap; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentSelector; | |||
| /** | |||
| * The interface that is used to manage types. | |||
| @@ -21,80 +18,68 @@ public class DefaultTypeManager | |||
| implements TypeManager | |||
| { | |||
| ///Parent type manager to inherit values from. | |||
| private final TypeManager m_parent; | |||
| private final DefaultTypeManager m_parent; | |||
| ///Maps role to TypedComponentSelector. | |||
| private final HashMap m_roleMap = new HashMap(); | |||
| ///Maps role to MultiSourceTypeFactory. | |||
| private final HashMap m_roleMap = new HashMap(); | |||
| public DefaultTypeManager() | |||
| { | |||
| this( null ); | |||
| } | |||
| public DefaultTypeManager( final TypeManager parent ) | |||
| public DefaultTypeManager( final DefaultTypeManager parent ) | |||
| { | |||
| m_parent = parent; | |||
| } | |||
| public Component lookup( final String role ) | |||
| throws ComponentException | |||
| public void registerType( final String role, | |||
| final String shorthandName, | |||
| final TypeFactory factory ) | |||
| throws TypeException | |||
| { | |||
| if( role.endsWith( "Selector" ) ) | |||
| { | |||
| return createSelector( role ); | |||
| } | |||
| else | |||
| { | |||
| throw new ComponentException( "Unable to provide implementation for '" + | |||
| role + "'" ); | |||
| } | |||
| final MultiSourceTypeFactory msFactory = createFactory( role + "Selector" ); | |||
| msFactory.register( shorthandName, factory ); | |||
| } | |||
| public void release( final Component component ) | |||
| public TypeFactory getFactory( final String role ) | |||
| throws TypeException | |||
| { | |||
| return createFactory( role + "Selector" ); | |||
| } | |||
| public void registerType( final String role, | |||
| final String shorthandName, | |||
| final TypeFactory factory ) | |||
| throws Exception | |||
| protected final MultiSourceTypeFactory lookupFactory( final String role ) | |||
| { | |||
| final TypedComponentSelector selector = createSelector( role + "Selector" ); | |||
| selector.register( shorthandName, factory ); | |||
| return (MultiSourceTypeFactory)m_roleMap.get( role ); | |||
| } | |||
| /** | |||
| * Get a selector of appropriate role. | |||
| * Create a Selector if none exists with same name. | |||
| * Get a factory of appropriate role. | |||
| * Create a Factory if none exists with same name. | |||
| * | |||
| * @param role the role name(must be name of work interface) | |||
| * @return the Selector for interface | |||
| * @exception ComponentException if role exists and not a selector, role does not | |||
| * specify accessible work interface, or | |||
| * @return the Factory for interface | |||
| * @exception TypeException role does not specify accessible work interface | |||
| */ | |||
| private TypedComponentSelector createSelector( final String role ) | |||
| throws ComponentException | |||
| private MultiSourceTypeFactory createFactory( final String role ) | |||
| throws TypeException | |||
| { | |||
| TypedComponentSelector selector = (TypedComponentSelector)m_roleMap.get( role ); | |||
| if( null != selector ) | |||
| MultiSourceTypeFactory factory = (MultiSourceTypeFactory)m_roleMap.get( role ); | |||
| if( null != factory ) | |||
| { | |||
| return selector; | |||
| return factory; | |||
| } | |||
| if( null != m_parent ) | |||
| final MultiSourceTypeFactory parentFactory = getParentTypedFactory( role ); | |||
| if( null != parentFactory ) | |||
| { | |||
| final TypedComponentSelector parentSelector = getTypedSelector( m_parent, role ); | |||
| if( null != parentSelector ) | |||
| { | |||
| selector = new TypedComponentSelector( parentSelector ); | |||
| } | |||
| factory = new MultiSourceTypeFactory( parentFactory ); | |||
| } | |||
| ///If we haven't goa selector try to create a new one | |||
| if( null == selector ) | |||
| ///If we haven't goa factory try to create a new one | |||
| if( null == factory ) | |||
| { | |||
| //Precondition that role.endsWith( "Selector" ) | |||
| //Precondition that role.endsWith( "Factory" ) | |||
| final int length = role.length() - 8; | |||
| final String workInterface = role.substring( 0, length ); | |||
| @@ -102,30 +87,29 @@ public class DefaultTypeManager | |||
| { | |||
| //TODO: Should we use ContextClassLoader here ??? Or perhaps try that on failure?? | |||
| final Class clazz = Class.forName( workInterface ); | |||
| selector = new TypedComponentSelector( clazz ); | |||
| factory = new MultiSourceTypeFactory( clazz ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ComponentException( "Role '" + role + "' does not specify " + | |||
| "accessible work interface" ); | |||
| throw new TypeException( "Role '" + role + "' does not specify " + | |||
| "accessible work interface" ); | |||
| } | |||
| } | |||
| m_roleMap.put( role, selector ); | |||
| m_roleMap.put( role, factory ); | |||
| return selector; | |||
| return factory; | |||
| } | |||
| private TypedComponentSelector getTypedSelector( final TypeManager typeManager, | |||
| final String role ) | |||
| private MultiSourceTypeFactory getParentTypedFactory( final String role ) | |||
| { | |||
| try | |||
| if( null != m_parent ) | |||
| { | |||
| return (TypedComponentSelector)typeManager.lookup( role ); | |||
| return m_parent.lookupFactory( role ); | |||
| } | |||
| else | |||
| { | |||
| return null; | |||
| } | |||
| catch( final ComponentException ce ) {} | |||
| catch( final ClassCastException cce ) {} | |||
| return null; | |||
| } | |||
| } | |||
| @@ -0,0 +1,96 @@ | |||
| /* | |||
| * 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.components.type; | |||
| import java.util.HashMap; | |||
| /** | |||
| * This factory acts as a proxy to set of object factorys. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class MultiSourceTypeFactory | |||
| implements TypeFactory | |||
| { | |||
| ///Parent Selector | |||
| private final MultiSourceTypeFactory m_parent; | |||
| ///Map of name->factory list | |||
| private final HashMap m_factorys = new HashMap(); | |||
| ///Type expected to be created from factorys | |||
| private final Class m_type; | |||
| public MultiSourceTypeFactory( final Class type ) | |||
| { | |||
| m_type = type; | |||
| m_parent = null; | |||
| } | |||
| public MultiSourceTypeFactory( final MultiSourceTypeFactory parent ) | |||
| { | |||
| m_type = parent.getType(); | |||
| m_parent = parent; | |||
| } | |||
| /** | |||
| * Populate the ComponentSelector. | |||
| */ | |||
| public void register( final String name, final TypeFactory factory ) | |||
| { | |||
| m_factorys.put( name, factory ); | |||
| } | |||
| /** | |||
| * Create a type instance based on name. | |||
| * | |||
| * @param name the name | |||
| * @return the type instance | |||
| * @exception TypeException if an error occurs | |||
| */ | |||
| public Object create( final String name ) | |||
| throws TypeException | |||
| { | |||
| TypeFactory factory = getTypeFactory( name ); | |||
| if( null == factory && null != m_parent ) | |||
| { | |||
| m_parent.getTypeFactory( name ); | |||
| } | |||
| if( null == factory ) return null; | |||
| else | |||
| { | |||
| final Object object = factory.create( name ); | |||
| if( !m_type.isInstance( object ) ) | |||
| { | |||
| throw new TypeException( "Object '" + name + "' is not of " + | |||
| "correct Type (" + m_type.getName() + ")" ); | |||
| } | |||
| return object; | |||
| } | |||
| } | |||
| /** | |||
| * Retrieve type managed by selector. | |||
| * Used by other instances of TypedComponentSelector. | |||
| * | |||
| * @return the type class | |||
| */ | |||
| protected final Class getType() | |||
| { | |||
| return m_type; | |||
| } | |||
| protected final TypeFactory getTypeFactory( final String name ) | |||
| { | |||
| return (TypeFactory)m_factorys.get( name ); | |||
| } | |||
| } | |||
| @@ -8,7 +8,7 @@ | |||
| package org.apache.myrmidon.components.type; | |||
| /** | |||
| * Create a component based on role and hint. | |||
| * Create an instance on name. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| * @version CVS $Revision$ $Date$ | |||
| @@ -16,11 +16,11 @@ package org.apache.myrmidon.components.type; | |||
| public interface TypeFactory | |||
| { | |||
| /** | |||
| * Create a Component with appropriate name. | |||
| * Create a type instance based on name. | |||
| * | |||
| * @param name the name | |||
| * @return the created component | |||
| * @exception ComponentException if an error occurs | |||
| * @return the type instance | |||
| * @exception TypeException if an error occurs | |||
| */ | |||
| Object create( String name ) | |||
| throws TypeException; | |||
| @@ -8,7 +8,6 @@ | |||
| package org.apache.myrmidon.components.type; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| /** | |||
| * The interface that is used to manage types. | |||
| @@ -16,10 +15,13 @@ import org.apache.avalon.framework.component.ComponentManager; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface TypeManager | |||
| extends Component, ComponentManager | |||
| extends Component | |||
| { | |||
| String ROLE = "org.apache.myrmidon.components.type.TypeManager"; | |||
| void registerType( String role, String shorthandName, TypeFactory factory ) | |||
| throws Exception; | |||
| throws TypeException; | |||
| TypeFactory getFactory( String role ) | |||
| throws TypeException; | |||
| } | |||
| @@ -1,129 +0,0 @@ | |||
| /* | |||
| * 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.components.type; | |||
| import java.util.HashMap; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.component.ComponentSelector; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| /** | |||
| * This is a ComponentSelector implementation that acts as factory | |||
| * for objects and checks type on creation. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class TypedComponentSelector | |||
| implements ComponentSelector | |||
| { | |||
| ///Parent Selector | |||
| private final TypedComponentSelector m_parent; | |||
| ///Map of name->factory list | |||
| private final HashMap m_factorys = new HashMap(); | |||
| ///Type expected to be created from factorys | |||
| private final Class m_type; | |||
| public TypedComponentSelector( final Class type ) | |||
| { | |||
| m_type = type; | |||
| m_parent = null; | |||
| } | |||
| public TypedComponentSelector( final TypedComponentSelector parent ) | |||
| { | |||
| m_type = parent.getType(); | |||
| m_parent = parent; | |||
| } | |||
| /** | |||
| * Select the desired component. | |||
| * This creates component and checks if type appropriate. | |||
| * | |||
| * @param hint the hint to retrieve Component | |||
| * @return the Component | |||
| * @exception ComponentException if an error occurs | |||
| */ | |||
| public Component select( Object hint ) | |||
| throws ComponentException | |||
| { | |||
| if( !(hint instanceof String) ) | |||
| { | |||
| throw new ComponentException( "Invalid hint, expected a string not a " + | |||
| hint.getClass().getName() ); | |||
| } | |||
| final String name = (String)hint; | |||
| final Component component = createComponent( name ); | |||
| if( null != component ) | |||
| { | |||
| if( !m_type.isInstance( component ) ) | |||
| { | |||
| throw new ComponentException( "Implementation of " + name + " is not of " + | |||
| "correct type (" + m_type.getClass().getName() + ")" ); | |||
| } | |||
| return component; | |||
| } | |||
| else | |||
| { | |||
| throw new ComponentException( "Unable to provide implementation for " + name ); | |||
| } | |||
| } | |||
| /** | |||
| * Release component. | |||
| * | |||
| * @param component the component | |||
| */ | |||
| public void release( final Component component ) | |||
| { | |||
| } | |||
| /** | |||
| * Populate the ComponentSelector. | |||
| */ | |||
| public void register( final String name, final TypeFactory factory ) | |||
| { | |||
| m_factorys.put( name, factory ); | |||
| } | |||
| /** | |||
| * Retrieve type managed by selector. | |||
| * Used by other instances of TypedComponentSelector. | |||
| * | |||
| * @return the type class | |||
| */ | |||
| protected final Class getType() | |||
| { | |||
| return m_type; | |||
| } | |||
| /** | |||
| * Helper method for subclasses to retrieve component map. | |||
| * | |||
| * @return the component map | |||
| */ | |||
| private Component createComponent( final String name ) | |||
| throws ComponentException | |||
| { | |||
| final TypeFactory factory = (TypeFactory)m_factorys.get( name ); | |||
| if( null == factory ) return null; | |||
| else | |||
| { | |||
| try { return (Component)factory.create( name ); } | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ComponentException( "Failed to create type " + name, te ); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -7,7 +7,6 @@ | |||
| */ | |||
| package org.apache.myrmidon.converter; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.context.Context; | |||
| /** | |||
| @@ -16,7 +15,6 @@ import org.apache.avalon.framework.context.Context; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface Converter | |||
| extends Component | |||
| { | |||
| String ROLE = "org.apache.myrmidon.converter.Converter"; | |||