diff --git a/proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java b/proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java index 49328d513..5b361675d 100644 --- a/proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java +++ b/proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java @@ -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() ); } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java b/proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java index 0ccbbeb47..af286807e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java @@ -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 Peter Donald */ public interface DataType - extends Component { String ROLE = "org.apache.myrmidon.api.DataType"; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java b/proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java index e81ac3376..ccc6615c7 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java @@ -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 Peter Donald */ public interface Task - extends Component { String ROLE = "org.apache.myrmidon.api.Task"; diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java index 3081f1c9a..c45796879 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java @@ -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 ); } } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java index 17eda1b26..78238e8ef 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java @@ -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 ); } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java index 34b21c188..fd178fd7c 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java @@ -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; } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/MultiSourceTypeFactory.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/MultiSourceTypeFactory.java new file mode 100644 index 000000000..329d20e2a --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/MultiSourceTypeFactory.java @@ -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 Peter Donald + */ +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 ); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java index 1cddc0387..7b88ab18c 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java @@ -8,7 +8,7 @@ package org.apache.myrmidon.components.type; /** - * Create a component based on role and hint. + * Create an instance on name. * * @author Peter Donald * @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; diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java index 7811993fa..eac2afc3e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java @@ -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 Peter Donald */ 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; } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java deleted file mode 100644 index e1e60167c..000000000 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java +++ /dev/null @@ -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 Peter Donald - */ -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 ); - } - } - } -} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java b/proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java index 21463f56f..fab5fd2f6 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java @@ -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 Peter Donald */ public interface Converter - extends Component { String ROLE = "org.apache.myrmidon.converter.Converter";