From 758feca17109ce14f03d7cb5f2f0ac590726e35c Mon Sep 17 00:00:00 2001 From: Peter Donald Date: Sat, 2 Jun 2001 05:47:28 +0000 Subject: [PATCH] Continued work on registry (which I am now terming TypeManager). git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269079 13f79535-47bb-0310-9956-ffa450edef68 --- .../components/type/DefaultTypeManager.java | 120 ++++++++++++++++++ .../myrmidon/components/type/TypeManager.java | 24 ++++ .../type/TypedComponentSelector.java | 38 +++++- 3 files changed, 175 insertions(+), 7 deletions(-) create mode 100644 proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java create mode 100644 proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java 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 new file mode 100644 index 000000000..e87e334b3 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java @@ -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 Peter Donald + */ +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; + } +} 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 new file mode 100644 index 000000000..5cc645cca --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java @@ -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 Peter Donald + */ +public interface TypeManager + extends ComponentManager +{ + String ROLE = "org.apache.myrmidon.components.type.TypeManager"; + + void registerType( String role, String shorthandName, ComponentFactory factory ) + throws Exception; +} 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 index b682b7852..4746273ea 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java @@ -21,13 +21,25 @@ import org.apache.avalon.framework.component.ComponentException; public class TypedComponentSelector 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 ) { 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 " + hint.getClass().getName() ); } - - final Component component = createComponent( (String)hint ); + + final String name = (String)hint; + final Component component = createComponent( name ); if( null != 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() + ")" ); } @@ -61,7 +74,7 @@ public class TypedComponentSelector } 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. */ - public void put( final String name, final ComponentFactory factory ) + public void register( final String name, final ComponentFactory 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. *