Browse Source

Converted TypeManager so that types no longer have to implement Avalons 'Component' interface.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269090 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 24 years ago
parent
commit
d23b08a302
11 changed files with 179 additions and 218 deletions
  1. +10
    -4
      proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java
  2. +0
    -3
      proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java
  3. +0
    -3
      proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java
  4. +11
    -6
      proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java
  5. +11
    -6
      proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java
  6. +42
    -58
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java
  7. +96
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/MultiSourceTypeFactory.java
  8. +4
    -4
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java
  9. +5
    -3
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java
  10. +0
    -129
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java
  11. +0
    -2
      proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java

+ 10
- 4
proposal/myrmidon/src/java/org/apache/ant/modules/basic/Property.java View File

@@ -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() );
}


+ 0
- 3
proposal/myrmidon/src/java/org/apache/myrmidon/api/DataType.java View File

@@ -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";
}

+ 0
- 3
proposal/myrmidon/src/java/org/apache/myrmidon/api/Task.java View File

@@ -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";



+ 11
- 6
proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java View File

@@ -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 );
}
}
}

+ 11
- 6
proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java View File

@@ -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 );
}
}



+ 42
- 58
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java View File

@@ -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;
}
}

+ 96
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/MultiSourceTypeFactory.java View File

@@ -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 );
}
}

+ 4
- 4
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeFactory.java View File

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


+ 5
- 3
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypeManager.java View File

@@ -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;
}

+ 0
- 129
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/TypedComponentSelector.java View File

@@ -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 );
}
}
}
}

+ 0
- 2
proposal/myrmidon/src/java/org/apache/myrmidon/converter/Converter.java View File

@@ -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";



Loading…
Cancel
Save