git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269079 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,120 @@ | |||||
| /* | |||||
| * 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.ComponentException; | |||||
| import org.apache.avalon.framework.component.ComponentSelector; | |||||
| /** | |||||
| * The interface that is used to manage types. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public class DefaultTypeManager | |||||
| implements TypeManager | |||||
| { | |||||
| ///Parent type manager to inherit values from. | |||||
| private final TypeManager m_parent; | |||||
| ///Maps role to TypedComponentSelector. | |||||
| private final HashMap m_roleMap = new HashMap(); | |||||
| public DefaultTypeManager( final TypeManager parent ) | |||||
| { | |||||
| m_parent = parent; | |||||
| } | |||||
| public Component lookup( final String role ) | |||||
| throws ComponentException | |||||
| { | |||||
| final ComponentSelector selector = (ComponentSelector)m_roleMap.get( role ); | |||||
| if( null != selector ) | |||||
| { | |||||
| return selector; | |||||
| } | |||||
| else | |||||
| { | |||||
| throw new ComponentException( "Unable to provide implementation for '" + | |||||
| role + "'" ); | |||||
| } | |||||
| } | |||||
| public void release( final Component component ) | |||||
| { | |||||
| } | |||||
| public void registerType( final String role, | |||||
| final String shorthandName, | |||||
| final ComponentFactory factory ) | |||||
| throws Exception | |||||
| { | |||||
| final TypedComponentSelector selector = createSelector( role ); | |||||
| selector.register( shorthandName, factory ); | |||||
| } | |||||
| /** | |||||
| * Get a selector of appropriate role. | |||||
| * Create a Selector 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 | |||||
| */ | |||||
| private TypedComponentSelector createSelector( final String role ) | |||||
| throws ComponentException | |||||
| { | |||||
| TypedComponentSelector selector = (TypedComponentSelector)m_roleMap.get( role ); | |||||
| if( null != selector ) return selector; | |||||
| if( null != m_parent ) | |||||
| { | |||||
| final TypedComponentSelector parentSelector = getTypedSelector( m_parent, role ); | |||||
| if( null != parentSelector ) | |||||
| { | |||||
| selector = new TypedComponentSelector( parentSelector ); | |||||
| } | |||||
| } | |||||
| ///If we haven't goa selector try to create a new one | |||||
| if( null == selector ) | |||||
| { | |||||
| try | |||||
| { | |||||
| //TODO: Should we use ContextClassLoader here ??? Or perhaps try that on failure?? | |||||
| final Class clazz = Class.forName( role ); | |||||
| selector = new TypedComponentSelector( clazz ); | |||||
| } | |||||
| catch( final Exception e ) | |||||
| { | |||||
| throw new ComponentException( "Role '" + role + "' does not specify " + | |||||
| "accessible work interface" ); | |||||
| } | |||||
| } | |||||
| m_roleMap.put( role, selector ); | |||||
| return selector; | |||||
| } | |||||
| private TypedComponentSelector getTypedSelector( final TypeManager typeManager, | |||||
| final String role ) | |||||
| { | |||||
| try | |||||
| { | |||||
| return (TypedComponentSelector)typeManager.lookup( role ); | |||||
| } | |||||
| catch( final ComponentException ce ) {} | |||||
| catch( final ClassCastException cce ) {} | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| /* | |||||
| * 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 org.apache.avalon.framework.component.ComponentManager; | |||||
| /** | |||||
| * The interface that is used to manage types. | |||||
| * | |||||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||||
| */ | |||||
| public interface TypeManager | |||||
| extends ComponentManager | |||||
| { | |||||
| String ROLE = "org.apache.myrmidon.components.type.TypeManager"; | |||||
| void registerType( String role, String shorthandName, ComponentFactory factory ) | |||||
| throws Exception; | |||||
| } | |||||
| @@ -21,13 +21,25 @@ import org.apache.avalon.framework.component.ComponentException; | |||||
| public class TypedComponentSelector | public class TypedComponentSelector | ||||
| implements ComponentSelector | implements ComponentSelector | ||||
| { | { | ||||
| private final HashMap m_factorys = new HashMap(); | |||||
| ///Parent Selector | |||||
| private final TypedComponentSelector m_parent; | |||||
| private final Class m_type; | |||||
| ///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 ) | public TypedComponentSelector( final Class type ) | ||||
| { | { | ||||
| m_type = type; | m_type = type; | ||||
| m_parent = null; | |||||
| } | |||||
| public TypedComponentSelector( final TypedComponentSelector parent ) | |||||
| { | |||||
| m_type = parent.getType(); | |||||
| m_parent = parent; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -46,14 +58,15 @@ public class TypedComponentSelector | |||||
| throw new ComponentException( "Invalid hint, expected a string not a " + | throw new ComponentException( "Invalid hint, expected a string not a " + | ||||
| hint.getClass().getName() ); | hint.getClass().getName() ); | ||||
| } | } | ||||
| final Component component = createComponent( (String)hint ); | |||||
| final String name = (String)hint; | |||||
| final Component component = createComponent( name ); | |||||
| if( null != component ) | if( null != component ) | ||||
| { | { | ||||
| if( m_type.isInstance( component ) ) | if( m_type.isInstance( component ) ) | ||||
| { | { | ||||
| throw new ComponentException( "Implementation of " + hint + " is not of " + | |||||
| throw new ComponentException( "Implementation of " + name + " is not of " + | |||||
| "correct type (" + m_type.getClass().getName() + ")" ); | "correct type (" + m_type.getClass().getName() + ")" ); | ||||
| } | } | ||||
| @@ -61,7 +74,7 @@ public class TypedComponentSelector | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| throw new ComponentException( "Unable to provide implementation for " + hint ); | |||||
| throw new ComponentException( "Unable to provide implementation for " + name ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -77,11 +90,22 @@ public class TypedComponentSelector | |||||
| /** | /** | ||||
| * Populate the ComponentSelector. | * Populate the ComponentSelector. | ||||
| */ | */ | ||||
| public void put( final String name, final ComponentFactory factory ) | |||||
| public void register( final String name, final ComponentFactory factory ) | |||||
| { | { | ||||
| m_factorys.put( name, 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. | * Helper method for subclasses to retrieve component map. | ||||
| * | * | ||||