diff --git a/proposal/myrmidon/src/java/org/apache/antlib/core/Property.java b/proposal/myrmidon/src/java/org/apache/antlib/core/Property.java
index dc058890b..4e16e689c 100644
--- a/proposal/myrmidon/src/java/org/apache/antlib/core/Property.java
+++ b/proposal/myrmidon/src/java/org/apache/antlib/core/Property.java
@@ -54,7 +54,7 @@ public class Property
{
try
{
- final TypeFactory typeFactory = getTypeFactory( DataType.ROLE );
+ final TypeFactory typeFactory = getTypeFactory( DataType.class );
final DataType value = (DataType)typeFactory.create( children[ i ].getName() );
configure( value, children[ i ] );
setValue( value );
diff --git a/proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java b/proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java
index 69cadb2cd..4df17b7bc 100644
--- a/proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java
+++ b/proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java
@@ -8,15 +8,12 @@
package org.apache.antlib.runtime;
import java.io.File;
-import java.net.URL;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
-import org.apache.myrmidon.converter.Converter;
-import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
-import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
-import org.apache.myrmidon.interfaces.type.TypeManager;
+import org.apache.myrmidon.interfaces.deployer.Deployer;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
/**
* Task to define a converter.
@@ -80,15 +77,10 @@ public class ConverterDef
try
{
- final ConverterRegistry converterRegistry = (ConverterRegistry)getService( ConverterRegistry.class );
- converterRegistry.registerConverter( m_classname, m_sourceType, m_destinationType );
-
- final URL url = m_lib.toURL();
- final DefaultTypeFactory factory = new DefaultTypeFactory( new URL[]{url} );
- factory.addNameClassMapping( m_classname, m_classname );
-
- final TypeManager typeManager = (TypeManager)getService( TypeManager.class );
- typeManager.registerType( Converter.ROLE, m_classname, factory );
+ // Locate the deployer, then deploy the converter
+ final Deployer deployer = (Deployer)getService( Deployer.class );
+ final TypeDeployer typeDeployer = deployer.createDeployer( m_lib );
+ typeDeployer.deployConverter( m_classname, m_sourceType, m_destinationType );
}
catch( final Exception e )
{
diff --git a/proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java b/proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java
index 1c0033520..70cfd0301 100644
--- a/proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java
+++ b/proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java
@@ -50,7 +50,7 @@ public class Facility
{
try
{
- final TypeFactory typeFactory = getTypeFactory( AspectHandler.ROLE );
+ final TypeFactory typeFactory = getTypeFactory( AspectHandler.class );
m_aspectHandler = (AspectHandler)typeFactory.create( children[ 0 ].getName() );
}
catch( final Exception e )
diff --git a/proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java b/proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java
index ba9cfba03..0ace7064e 100644
--- a/proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java
+++ b/proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java
@@ -14,6 +14,7 @@ import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
/**
* Task to import a tasklib.
@@ -45,7 +46,8 @@ public class Import
try
{
final Deployer deployer = (Deployer)getService( Deployer.class );
- deployer.deploy( m_lib );
+ TypeDeployer typeDeployer = deployer.createDeployer( m_lib );
+ typeDeployer.deployAll();
}
catch( final DeploymentException de )
{
diff --git a/proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java b/proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java
index 147d4ebc2..843030d3e 100644
--- a/proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java
+++ b/proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java
@@ -24,7 +24,7 @@ public class TypeDef
m_type = type;
}
- protected String getTypeName()
+ protected String getRoleShorthand()
{
return m_type;
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
index f69e1a377..dd7caa22c 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
@@ -403,6 +403,9 @@ public class DefaultConfigurer
return configurer;
}
+ /**
+ * Creates and configures an inline object.
+ */
private Object setupChild( final ConfigurationState state,
final Configuration element,
final Context context,
@@ -424,14 +427,13 @@ public class DefaultConfigurer
if( type.isInterface() )
{
child = createdTypedObject( name, type );
- configureObject( child, element, context );
}
else
{
child = createObject( type );
- configureObject( child, element, context );
}
}
+
configureObject( child, element, context );
return child;
}
@@ -444,7 +446,7 @@ public class DefaultConfigurer
final Class type )
throws ConfigurationException
{
- final TypeFactory factory = getTypeFactory( type.getName() );
+ final TypeFactory factory = getTypeFactory( type );
try
{
return factory.create( name );
@@ -481,7 +483,7 @@ public class DefaultConfigurer
/**
* Locates a type factory.
*/
- protected final TypeFactory getTypeFactory( final String role )
+ protected final TypeFactory getTypeFactory( final Class role )
throws ConfigurationException
{
try
@@ -490,7 +492,7 @@ public class DefaultConfigurer
}
catch( final TypeException te )
{
- final String message = REZ.getString( "no-factory-for-role.error", role );
+ final String message = REZ.getString( "no-factory-for-role.error", role.getName() );
throw new ConfigurationException( message, te );
}
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
index 28f739b8f..746848141 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
@@ -21,4 +21,5 @@ bad-set-element.error=Could not handle element <{1}>, nested in element <{0}>.
no-content.error=Text content is not allowed for element <{0}>.
bad-set-content.error=Could not set text content for element <{0}>.
typed-adder-non-interface.error=The typed adder for class "{0}" must have a single parameter that is an interface rather than {1} which defines a class.
-no-factory-for-role.error=Unable to locate type factory for role "{0}"
\ No newline at end of file
+no-factory-for-role.error=Unable to locate type factory for role "{0}"
+create-typed-object.error=Could not create an object of type "{0}" of class {1}.
\ No newline at end of file
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 6c1ef5b51..be6d5876f 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
@@ -53,7 +53,7 @@ public class DefaultMasterConverter
final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
try
{
- m_factory = typeManager.getFactory( Converter.ROLE );
+ m_factory = typeManager.getFactory( Converter.class );
}
catch( final TypeException te )
{
@@ -132,11 +132,10 @@ public class DefaultMasterConverter
final Class destination )
throws ConverterException
{
- Class clazz = destination;
-
//TODO: Maybe we should search the source classes hierarchy aswell
- final Class terminator = Object.class;
- while( terminator != clazz )
+ for( Class clazz = destination;
+ clazz != null;
+ clazz = clazz.getSuperclass() )
{
final String name =
m_registry.getConverterName( originalClass.getName(),
@@ -145,8 +144,6 @@ public class DefaultMasterConverter
{
return name;
}
-
- clazz = clazz.getSuperclass();
}
final String message =
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java
index 938a2918d..f04216905 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java
@@ -14,33 +14,22 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Enumeration;
import java.util.HashMap;
+import java.util.Map;
import java.util.jar.Manifest;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.PackageManager;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
-import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.myrmidon.converter.Converter;
-import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
-import org.apache.myrmidon.interfaces.role.RoleManager;
-import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
-import org.apache.myrmidon.interfaces.type.TypeManager;
-import org.xml.sax.XMLReader;
/**
* This class deploys a .tsk file into a registry.
@@ -49,16 +38,38 @@ import org.xml.sax.XMLReader;
*/
public class DefaultDeployer
extends AbstractLogEnabled
- implements Deployer, Initializable, Composable
+ implements Deployer, Composable
{
private final static Resources REZ =
ResourceManager.getPackageResources( DefaultDeployer.class );
- private ConverterRegistry m_converterRegistry;
- private TypeManager m_typeManager;
- private RoleManager m_roleManager;
+ private Deployer m_parent;
+ private ComponentManager m_componentManager;
private PackageManager m_packageManager;
+ /** Map from ClassLoader to the deployer for that class loader. */
+ private Map m_classLoaderDeployers = new HashMap();
+
+ /**
+ * Map from File to the ClassLoader for that library. This map is shared
+ * by all descendents of the root deployer.
+ */
+ private Map m_fileDeployers;
+
+ /**
+ * Creates a root deployer.
+ */
+ public DefaultDeployer()
+ {
+ m_fileDeployers = new HashMap();
+ }
+
+ private DefaultDeployer( final DefaultDeployer parent )
+ {
+ m_parent = parent;
+ m_fileDeployers = parent.m_fileDeployers;
+ }
+
/**
* Retrieve relevent services needed to deploy.
*
@@ -68,145 +79,99 @@ public class DefaultDeployer
public void compose( final ComponentManager componentManager )
throws ComponentException
{
- m_converterRegistry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE );
- m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
- m_roleManager = (RoleManager)componentManager.lookup( RoleManager.ROLE );
-
+ m_componentManager = componentManager;
final ExtensionManager extensionManager =
(ExtensionManager)componentManager.lookup( ExtensionManager.ROLE );
m_packageManager = new PackageManager( extensionManager );
}
- public void initialize()
- throws Exception
+ /**
+ * Creates a child deployer.
+ */
+ public Deployer createChildDeployer( ComponentManager componentManager )
+ throws ComponentException
{
- final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
- final SAXParser saxParser = saxParserFactory.newSAXParser();
- final XMLReader parser = saxParser.getXMLReader();
- //parser.setFeature( "http://xml.org/sax/features/namespace-prefixes", false );
-
- final SAXConfigurationHandler handler = new SAXConfigurationHandler();
- parser.setContentHandler( handler );
- parser.setErrorHandler( handler );
-
- final ClassLoader classLoader = getClass().getClassLoader();
-
- final Enumeration enum = classLoader.getResources( Deployment.DESCRIPTOR_NAME );
- while( enum.hasMoreElements() )
- {
- final URL url = (URL)enum.nextElement();
- parser.parse( url.toString() );
-
- final String message = REZ.getString( "url-deploy.notice", url );
- getLogger().debug( message );
-
- deployFromDescriptor( handler.getConfiguration(), classLoader, url );
- }
+ final DefaultDeployer child = new DefaultDeployer( this );
+ setupLogger( child );
+ child.compose( componentManager );
+ return child;
}
- public void deploy( final File file )
+ /**
+ * Returns the deployer for a ClassLoader, creating the deployer if
+ * necessary.
+ */
+ public TypeDeployer createDeployer( final ClassLoader loader )
throws DeploymentException
{
- if( getLogger().isInfoEnabled() )
- {
- final String message = REZ.getString( "file-deploy.notice", file );
- getLogger().info( message );
- }
-
- checkFile( file );
-
try
{
- final File[] extensions = getOptionalPackagesFor( file );
- final URL[] urls = buildClasspath( file, extensions );
- final Deployment deployment = new Deployment( file );
- final Configuration descriptor = deployment.getDescriptor();
-
- final URLClassLoader classLoader =
- new URLClassLoader( urls, Thread.currentThread().getContextClassLoader() );
-
- deployFromDescriptor( descriptor, classLoader, deployment.getURL() );
- }
- catch( final DeploymentException de )
- {
- throw de;
+ return createDeployment( loader, null );
}
- catch( final Exception e )
+ catch( Exception e )
{
- final String message = REZ.getString( "deploy-lib.error" );
+ final String message = REZ.getString( "deploy-from-classloader.error" );
throw new DeploymentException( message, e );
}
}
- public void deployConverter( final String name, final File file )
+ /**
+ * Returns the deployer for a type library, creating the deployer if
+ * necessary.
+ */
+ public TypeDeployer createDeployer( final File file )
throws DeploymentException
{
- checkFile( file );
-
- final Deployment deployment = new Deployment( file );
- final Configuration descriptor = deployment.getDescriptor();
- final DefaultTypeFactory factory = new DefaultTypeFactory( deployment.getURL() );
-
try
{
- final Configuration[] converters =
- descriptor.getChild( "converters" ).getChildren( "converter" );
-
- for( int i = 0; i < converters.length; i++ )
- {
- if( converters[ i ].getAttribute( "classname" ).equals( name ) )
- {
- handleConverter( converters[ i ], factory );
- break;
- }
- }
- }
- catch( final ConfigurationException ce )
- {
- final String message = REZ.getString( "bad-descriptor.error" );
- throw new DeploymentException( message, ce );
+ URLClassLoader classLoader = getClassLoaderForFile( file );
+ return createDeployment( classLoader, file.toURL() );
}
- catch( final Exception e )
+ catch( Exception e )
{
- final String message = REZ.getString( "deploy-converter.error", name );
+ final String message = REZ.getString( "deploy-from-file.error", file );
throw new DeploymentException( message, e );
}
}
- public void deployType( final String role, final String name, final File file )
- throws DeploymentException
+ /**
+ * Locates the classloader for a typelib file.
+ */
+ private URLClassLoader getClassLoaderForFile( final File file )
+ throws Exception
{
- checkFile( file );
+ File canonFile = file.getCanonicalFile();
- final String shorthand = getNameForRole( role );
- final Deployment deployment = new Deployment( file );
- final Configuration descriptor = deployment.getDescriptor();
- final DefaultTypeFactory factory = new DefaultTypeFactory( deployment.getURL() );
-
- try
- {
- final Configuration[] datatypes =
- descriptor.getChild( "types" ).getChildren( shorthand );
-
- for( int i = 0; i < datatypes.length; i++ )
- {
- if( datatypes[ i ].getAttribute( "name" ).equals( name ) )
- {
- handleType( role, datatypes[ i ], factory );
- break;
- }
- }
- }
- catch( final ConfigurationException ce )
+ // Locate cached classloader, creating it if necessary
+ URLClassLoader classLoader = (URLClassLoader)m_fileDeployers.get( canonFile );
+ if( classLoader == null )
{
- final String message = REZ.getString( "bad-descriptor.error" );
- throw new DeploymentException( message, ce );
+ checkFile( canonFile );
+ final File[] extensions = getOptionalPackagesFor( canonFile );
+ final URL[] urls = buildClasspath( canonFile, extensions );
+ classLoader = new URLClassLoader( urls, Thread.currentThread().getContextClassLoader() );
+ m_fileDeployers.put( canonFile, classLoader );
}
- catch( final Exception e )
+ return classLoader;
+ }
+
+ /**
+ * Creates a deployer for a ClassLoader.
+ */
+ private Deployment createDeployment( final ClassLoader loader,
+ final URL jarUrl ) throws Exception
+ {
+ // Locate cached deployer, creating it if necessary
+ Deployment deployment = (Deployment)m_classLoaderDeployers.get( loader );
+ if( deployment == null )
{
- final String message = REZ.getString( "deploy-type.error", name );
- throw new DeploymentException( message, e );
+ deployment = new Deployment( loader, m_componentManager );
+ setupLogger( deployment );
+ deployment.loadDescriptors( jarUrl );
+ m_classLoaderDeployers.put( loader, deployment );
}
+
+ return deployment;
}
private URL[] buildClasspath( final File file, final File[] dependencies )
@@ -243,10 +208,10 @@ public class DefaultDeployer
if( getLogger().isDebugEnabled() )
{
final String message1 =
- REZ.getString( "available-extensions", Arrays.asList( available ) );
+ REZ.getString( "available-extensions.notice", Arrays.asList( available ) );
getLogger().debug( message1 );
final String message2 =
- REZ.getString( "required-extensions", Arrays.asList( required ) );
+ REZ.getString( "required-extensions.notice", Arrays.asList( required ) );
getLogger().debug( message2 );
}
@@ -279,7 +244,7 @@ public class DefaultDeployer
}
final String message =
- REZ.getString( "unsatisfied.extensions", new Integer( size ) );
+ REZ.getString( "unsatisfied.extensions.error", new Integer( size ) );
throw new Exception( message );
}
@@ -288,87 +253,9 @@ public class DefaultDeployer
return OptionalPackage.toFiles( packages );
}
- private void deployFromDescriptor( final Configuration descriptor,
- final ClassLoader classLoader,
- final URL url )
- throws DeploymentException, Exception
- {
- try
- {
- //Have to keep a new factory per role
- //To avoid name clashes (ie a datatype and task with same name)
- final HashMap factorys = new HashMap();
-
- final Configuration[] types = descriptor.getChild( "types" ).getChildren();
- for( int i = 0; i < types.length; i++ )
- {
- final String name = types[ i ].getName();
- final String role = getRoleForName( name );
- final DefaultTypeFactory factory = getFactory( role, classLoader, factorys );
- handleType( role, types[ i ], factory );
- }
-
- final DefaultTypeFactory factory = new DefaultTypeFactory( classLoader );
- final Configuration[] converters = descriptor.getChild( "converters" ).getChildren();
- for( int i = 0; i < converters.length; i++ )
- {
- handleConverter( converters[ i ], factory );
- }
- }
- catch( final DeploymentException de )
- {
- throw de;
- }
- catch( final Exception e )
- {
- final String message = REZ.getString( "deploy-lib.error", url );
- throw new DeploymentException( message, e );
- }
- }
-
- private DefaultTypeFactory getFactory( final String role,
- final ClassLoader classLoader,
- final HashMap factorys )
- {
- DefaultTypeFactory factory = (DefaultTypeFactory)factorys.get( role );
-
- if( null == factory )
- {
- factory = new DefaultTypeFactory( classLoader );
- factorys.put( role, factory );
- }
-
- return factory;
- }
-
- private String getNameForRole( final String role )
- throws DeploymentException
- {
- final String name = m_roleManager.getNameForRole( role );
-
- if( null == name )
- {
- final String message = REZ.getString( "unknown-name4role.error", role );
- throw new DeploymentException( message );
- }
-
- return name;
- }
-
- private String getRoleForName( final String name )
- throws DeploymentException
- {
- final String role = m_roleManager.getRoleForName( name );
-
- if( null == role )
- {
- final String message = REZ.getString( "unknown-role4name.error", name );
- throw new DeploymentException( message );
- }
-
- return role;
- }
-
+ /**
+ * Ensures a file exists and is not a directory.
+ */
private void checkFile( final File file )
throws DeploymentException
{
@@ -385,43 +272,4 @@ public class DefaultDeployer
}
}
- private void handleConverter( final Configuration converter,
- final DefaultTypeFactory factory )
- throws Exception
- {
- final String name = converter.getAttribute( "classname" );
- final String source = converter.getAttribute( "source" );
- final String destination = converter.getAttribute( "destination" );
-
- m_converterRegistry.registerConverter( name, source, destination );
-
- factory.addNameClassMapping( name, name );
- m_typeManager.registerType( Converter.ROLE, name, factory );
-
- if( getLogger().isDebugEnabled() )
- {
- final String message =
- REZ.getString( "register-converter.notice", name, source, destination );
- getLogger().debug( message );
- }
- }
-
- private void handleType( final String role,
- final Configuration type,
- final DefaultTypeFactory factory )
- throws Exception
- {
- final String name = type.getAttribute( "name" );
- final String className = type.getAttribute( "classname" );
-
- factory.addNameClassMapping( name, className );
- m_typeManager.registerType( role, name, factory );
-
- if( getLogger().isDebugEnabled() )
- {
- final String message =
- REZ.getString( "register-role.notice", role, name, className );
- getLogger().debug( message );
- }
- }
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java
index 70c6f0d5c..a4c0029b8 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java
@@ -7,99 +7,391 @@
*/
package org.apache.myrmidon.components.deployer;
-import java.io.File;
-import java.io.IOException;
+import java.io.FileNotFoundException;
import java.net.URL;
-import javax.xml.parsers.ParserConfigurationException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
+import org.apache.avalon.framework.component.ComponentException;
+import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.myrmidon.converter.Converter;
+import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
-import org.xml.sax.SAXException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
+import org.apache.myrmidon.interfaces.role.RoleManager;
+import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
+import org.apache.myrmidon.interfaces.type.TypeManager;
import org.xml.sax.XMLReader;
/**
- * This class deploys a .tsk file into a registry.
+ * This class deploys type libraries from a ClassLoader into a registry.
*
* @author Peter Donald
*/
-public class Deployment
+class Deployment
+ extends AbstractLogEnabled
+ implements TypeDeployer
{
private final static Resources REZ =
ResourceManager.getPackageResources( Deployment.class );
- public final static String DESCRIPTOR_NAME = "META-INF/ant-descriptor.xml";
+ private final static String DESCRIPTOR_NAME = "META-INF/ant-descriptor.xml";
+ private final static String ROLE_DESCRIPTOR = "META-INF/ant-roles.xml";
- private File m_file;
+ private ClassLoader m_classLoader;
+ private ConverterRegistry m_converterRegistry;
+ private TypeManager m_typeManager;
+ private RoleManager m_roleManager;
+ private String[] m_descriptorUrls;
+ private Configuration[] m_descriptors;
+ private DefaultTypeFactory m_converterFactory;
- private Configuration m_descriptor;
+ /** Map from role name -> DefaultTypeFactory for that role. */
+ private Map m_factories = new HashMap();
- public Deployment( final File file )
+ public Deployment( final ClassLoader classLoader, ComponentManager manager )
+ throws ComponentException
{
- m_file = file;
+ // Locate the various components needed
+ m_classLoader = classLoader;
+ m_converterRegistry = (ConverterRegistry)manager.lookup( ConverterRegistry.ROLE );
+ m_typeManager = (TypeManager)manager.lookup( TypeManager.ROLE );
+ m_roleManager = (RoleManager)manager.lookup( RoleManager.ROLE );
}
- public Configuration getDescriptor()
+ /**
+ * Load the descriptors. Deploys all roles, then loads the descriptors
+ * for, but does not deploy, all the types.
+ */
+ public void loadDescriptors( URL jarUrl )
+ throws Exception
+ {
+ final ArrayList descriptors = new ArrayList();
+
+ // Create a SAX parser to assemble the descriptors into Configuration
+ // objects
+ final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ final SAXParser saxParser = saxParserFactory.newSAXParser();
+ final XMLReader parser = saxParser.getXMLReader();
+ //parser.setFeature( "http://xml.org/sax/features/namespace-prefixes", false );
+
+ final SAXConfigurationHandler handler = new SAXConfigurationHandler();
+ parser.setContentHandler( handler );
+ parser.setErrorHandler( handler );
+
+ // Load the role descriptors, and deploy all roles
+ final List roleUrls = locateResources( ROLE_DESCRIPTOR, jarUrl );
+ for( Iterator iterator = roleUrls.iterator(); iterator.hasNext(); )
+ {
+ String url = (String)iterator.next();
+ try
+ {
+ parser.parse( url );
+ }
+ catch( FileNotFoundException e )
+ {
+ // Ignore - this happens when jarUrl != null and the Jar does
+ // not contain a role descriptor.
+ continue;
+ }
+
+ handleRoleDescriptor( handler.getConfiguration(), url );
+ }
+
+ // Load type descriptors
+ final List typeUrls = locateResources( DESCRIPTOR_NAME, jarUrl );
+ for( Iterator iterator = typeUrls.iterator(); iterator.hasNext(); )
+ {
+ String url = (String)iterator.next();
+ try
+ {
+ parser.parse( url.toString() );
+ }
+ catch( FileNotFoundException e )
+ {
+ // Ignore - this happens when jarUrl != null and the Jar does
+ // not contain a type descriptor
+ }
+
+ descriptors.add( handler.getConfiguration() );
+ }
+ m_descriptorUrls = (String[])typeUrls.toArray( new String[ typeUrls.size() ] );
+ m_descriptors = (Configuration[])descriptors.toArray( new Configuration[ descriptors.size() ] );
+ }
+
+ /**
+ * Deploys everything in the type library.
+ */
+ public void deployAll()
throws DeploymentException
{
- if( null == m_descriptor )
+ for( int i = 0; i < m_descriptors.length; i++ )
{
- m_descriptor = buildDescriptor();
+ Configuration descriptor = m_descriptors[ i ];
+ deployFromDescriptor( descriptor, m_classLoader, m_descriptorUrls[i] );
}
+ }
- return m_descriptor;
+ /**
+ * Deploys a single type in the type library.
+ */
+ public void deployType( final String roleShorthand, final String typeName )
+ throws DeploymentException
+ {
+ try
+ {
+ // Locate the entry for the type
+ for( int i = 0; i < m_descriptors.length; i++ )
+ {
+ Configuration descriptor = m_descriptors[ i ];
+ final Configuration[] datatypes =
+ descriptor.getChild( "types" ).getChildren( roleShorthand );
+ for( int j = 0; j < datatypes.length; j++ )
+ {
+ Configuration datatype = datatypes[ j ];
+ if( datatype.getAttribute( "name" ).equals( typeName ) )
+ {
+ final String className = datatype.getAttribute( "classname" );
+ handleType( roleShorthand, typeName, className );
+ }
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ final String message = REZ.getString( "deploy-type.error", roleShorthand, typeName );
+ throw new DeploymentException( message, e );
+ }
}
- public URL getURL()
+ /**
+ * Deploys a single type from the type library.
+ */
+ public void deployType( String roleShorthand, String typeName, String className )
throws DeploymentException
{
try
{
- return m_file.getCanonicalFile().toURL();
+ handleType( roleShorthand, typeName, className );
}
- catch( final IOException ioe )
+ catch( Exception e )
{
- final String message = REZ.getString( "bad-url.error", m_file );
- throw new DeploymentException( message, ioe );
+ final String message = REZ.getString( "deploy-type.error", roleShorthand, typeName );
+ throw new DeploymentException( message, e );
}
}
- private Configuration buildDescriptor()
+ /**
+ * Deploys a converter from the type library. The converter definition
+ * is read from the type library descriptor.
+ */
+ public void deployConverter( String className )
throws DeploymentException
{
- final String systemID = "jar:" + getURL() + "!/" + DESCRIPTOR_NAME;
+ // TODO - implement this
+ throw new DeploymentException( "Not implemented." );
+ }
+ /**
+ * Deploys a converter from the type library.
+ */
+ public void deployConverter( String className, String srcClass, String destClass )
+ throws DeploymentException
+ {
try
{
- final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
- final SAXParser saxParser = saxParserFactory.newSAXParser();
- final XMLReader parser = saxParser.getXMLReader();
- //parser.setFeature( "http://xml.org/sax/features/namespace-prefixes", false );
+ handleConverter( className, srcClass, destClass );
+ }
+ catch( Exception e )
+ {
+ final String message = REZ.getString( "deploy-converter.error", srcClass, destClass );
+ throw new DeploymentException( message, e );
+ }
+ }
- final SAXConfigurationHandler handler = new SAXConfigurationHandler();
- parser.setContentHandler( handler );
- parser.setErrorHandler( handler );
+ /**
+ * Locates all resources of a particular name.
+ */
+ private List locateResources( final String resource, final URL jarUrl )
+ throws Exception
+ {
+ ArrayList urls = new ArrayList();
+ if( jarUrl != null )
+ {
+ final String systemID = "jar:" + jarUrl + "!/" + resource;
+ urls.add( systemID );
+ }
+ else
+ {
+ Enumeration enum = m_classLoader.getResources( resource );
+ while( enum.hasMoreElements() )
+ {
+ urls.add( enum.nextElement().toString() );
+ }
+ }
- parser.parse( systemID );
- return handler.getConfiguration();
+ return urls;
+ }
+
+ /**
+ * Configure RoleManager based on contents of single descriptor.
+ *
+ * @param descriptor the descriptor
+ * @exception ConfigurationException if an error occurs
+ */
+ private void handleRoleDescriptor( final Configuration descriptor,
+ final String url )
+ throws ConfigurationException
+ {
+ final String message = REZ.getString( "url-deploy-roles.notice", url );
+ getLogger().info( message );
+
+ final Configuration[] types = descriptor.getChildren( "role" );
+ for( int i = 0; i < types.length; i++ )
+ {
+ final String name = types[ i ].getAttribute( "shorthand" );
+ final String role = types[ i ].getAttribute( "name" );
+ m_roleManager.addNameRoleMapping( name, role );
+
+ if( getLogger().isDebugEnabled() )
+ {
+ final String debugMessage = REZ.getString( "register-role.notice", role, name );
+ getLogger().debug( debugMessage );
+ }
}
- catch( final SAXException se )
+ }
+
+ /**
+ * Deploys all types from a typelib descriptor.
+ */
+ private void deployFromDescriptor( final Configuration descriptor,
+ final ClassLoader classLoader,
+ final String url )
+ throws DeploymentException
+ {
+ try
{
- final String message = REZ.getString( "bad-descriptor.error" );
- throw new DeploymentException( message, se );
+ final String message = REZ.getString( "url-deploy-types.notice", url );
+ getLogger().info( message );
+
+ // Deploy all the types
+ final Configuration[] typeEntries = descriptor.getChild( "types" ).getChildren();
+ for( int i = 0; i < typeEntries.length; i++ )
+ {
+ final Configuration typeEntry = typeEntries[ i ];
+ final String roleShorthand = typeEntry.getName();
+ final String typeName = typeEntry.getAttribute( "name" );
+ final String className = typeEntry.getAttribute( "classname" );
+ handleType( roleShorthand, typeName, className );
+ }
+
+ // Deploy all the converters
+ final Configuration[] converterEntries = descriptor.getChild( "converters" ).getChildren();
+ for( int i = 0; i < converterEntries.length; i++ )
+ {
+ final Configuration converter = converterEntries[ i ];
+ final String className = converter.getAttribute( "classname" );
+ final String source = converter.getAttribute( "source" );
+ final String destination = converter.getAttribute( "destination" );
+ handleConverter( className, source, destination );
+ }
}
- catch( final ParserConfigurationException pce )
+ catch( final Exception e )
{
- final String message = REZ.getString( "bad-parser.error" );
- throw new DeploymentException( message, pce );
+ final String message = REZ.getString( "deploy-lib.error", url );
+ throw new DeploymentException( message, e );
}
- catch( final IOException ioe )
+ }
+
+ /**
+ * Returns the type factory for a role.
+ */
+ private DefaultTypeFactory getFactory( final Class roleType)
+ {
+ DefaultTypeFactory factory = (DefaultTypeFactory)m_factories.get( roleType );
+
+ if( null == factory )
{
- final String message = REZ.getString( "bad-read.error" );
- throw new DeploymentException( message, ioe );
+ factory = new DefaultTypeFactory( m_classLoader );
+ m_factories.put( roleType, factory );
}
+
+ return factory;
}
+
+ /**
+ * Handles a converter definition.
+ */
+ private void handleConverter( final String className,
+ final String source,
+ final String destination ) throws Exception
+ {
+ m_converterRegistry.registerConverter( className, source, destination );
+
+ if( m_converterFactory == null )
+ {
+ m_converterFactory = new DefaultTypeFactory( m_classLoader );
+ }
+ m_converterFactory.addNameClassMapping( className, className );
+ m_typeManager.registerType( Converter.class, className, m_converterFactory );
+
+ if( getLogger().isDebugEnabled() )
+ {
+ final String message =
+ REZ.getString( "register-converter.notice", source, destination );
+ getLogger().debug( message );
+ }
+ }
+
+ /**
+ * Handles a type definition.
+ */
+ private void handleType( final String roleShorthand,
+ final String typeName,
+ final String className )
+ throws Exception
+ {
+ // TODO - detect duplicates
+ final String role = getRoleForName( roleShorthand );
+ final Class roleType = m_classLoader.loadClass( role );
+ final DefaultTypeFactory factory = getFactory( roleType );
+ factory.addNameClassMapping( typeName, className );
+ m_typeManager.registerType( roleType, typeName, factory );
+
+ if( getLogger().isDebugEnabled() )
+ {
+ final String message =
+ REZ.getString( "register-type.notice", roleShorthand, typeName );
+ getLogger().debug( message );
+ }
+ }
+
+ /**
+ * Determines the role name from shorthand name.
+ */
+ private String getRoleForName( final String name )
+ throws DeploymentException
+ {
+ final String role = m_roleManager.getRoleForName( name );
+
+ if( null == role )
+ {
+ final String message = REZ.getString( "unknown-role4name.error", name );
+ throw new DeploymentException( message );
+ }
+
+ return role;
+ }
+
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties
index 3138fa3bc..a6908d198 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties
@@ -1,24 +1,18 @@
-register-converter.notice=Registered converter {0} that converts from {1} to {2}.
-register-role.notice=Registered {0}/{1} as {2}.
-url-deploy.notice=Deploying {0}.
-file-deploy.notice=Deploying AntLib file ({0}).
+register-converter.notice=Registered converter that converts from {1} to {2}.
+register-type.notice=Registered type {0}/{1}.
+register-role.notice=Registered role {0} with shorthand name {1}.
+url-deploy-types.notice=Registering types from "{0}".
+url-deploy-roles.notice=Registering roles from "{0}".
-deploy-lib.error=Error deploying library from {0}.
-deploy-converter.error=Failed to deploy {0} converter.
-bad-descriptor.error=Malformed descriptor.
-deploy-type.error=Failed to deploy {0} type.
-unknown-name4role.error=RoleManager does not know name for role {0}.
-unknown-role4name.error=RoleManager does not know role for name {0}.
-no-file.error=Could not find application archive at {0}.
-file-is-dir.error=Could not find application archive at {0} as it is a directory.
+deploy-from-classloader.error=Could not register types from ClassLoader {0}.
+deploy-from-file.error=Could not register types from type library "{0}".
+deploy-lib.error=Could not register types from "{0}".
+deploy-converter.error=Could not register converter that converts from {0} to {1}.
+deploy-type.error=Could not register type {0}/{1}.
+unknown-role4name.error=Unknown role "{0}".
+no-file.error=Could not find type library "{0}".
+file-is-dir.error=Type library "{0}" is a directory.
-bad-url.error=Unable to form url from file {0}.
-bad-parser.error=Error configuring parser.
-bad-read.error=Error reading configuration.
-
-available-extensions=The list of available extensions for Type Library includes; {0}
-required-extensions=The list of required extensions for Type Library includes; {0}
-optional-packages-added=The list of "Optional Packages" added to the Type Library includes; {0}
-classpath-entries=The list of classpath entrys for the Type Library includes; {0}
-missing.extension=Unable to locate an extension that is required by Type Library.\nExtension Name: {0}\nSpecification Vendor: {1}\nSpecification Version: {2}\nImplementation Vendor: {3}\nImplementation Vendor-Id: {4}\nImplementation Version: {5}\nImplementation URL: {6}
-unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader for Type Library.
\ No newline at end of file
+available-extensions.notice=The list of available extensions for type library includes; {0}
+required-extensions.notice=The list of required extensions for type library includes; {0}
+unsatisfied.extensions.error=Missing {0} extensions for type library.
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
index 2e9fcdfa0..a71d7afc3 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
@@ -27,6 +27,7 @@ import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.converter.MasterConverter;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
import org.apache.myrmidon.interfaces.embeddor.Embeddor;
import org.apache.myrmidon.interfaces.executor.Executor;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
@@ -106,7 +107,7 @@ public class DefaultEmbeddor
throws Exception
{
- final TypeFactory factory = m_typeManager.getFactory( ProjectBuilder.ROLE );
+ final TypeFactory factory = m_typeManager.getFactory( ProjectBuilder.class );
final ProjectBuilder builder = (ProjectBuilder)factory.create( type );
setupLogger( builder );
@@ -181,6 +182,12 @@ public class DefaultEmbeddor
public void start()
throws Exception
{
+ // Deploy all type libraries found in the classpath
+ final ClassLoader libClassloader = Thread.currentThread().getContextClassLoader();
+ final TypeDeployer typeDeployer = m_deployer.createDeployer( libClassloader );
+ typeDeployer.deployAll();
+
+ // Deploy all type libraries in the lib directory
final ExtensionFileFilter filter = new ExtensionFileFilter( ".atl" );
deployFromDirectory( m_deployer, m_taskLibDir, filter );
}
@@ -479,6 +486,9 @@ public class DefaultEmbeddor
}
}
+ /**
+ * Deploys all type libraries in a directory.
+ */
private void deployFromDirectory( final Deployer deployer,
final File directory,
final FilenameFilter filter )
@@ -492,6 +502,9 @@ public class DefaultEmbeddor
}
}
+ /**
+ * Deploys a set of type libraries.
+ */
private void deployFiles( final Deployer deployer, final File[] files )
throws DeploymentException
{
@@ -508,7 +521,8 @@ public class DefaultEmbeddor
try
{
final File file = files[ i ].getCanonicalFile();
- deployer.deploy( file );
+ final TypeDeployer typeDeployer = deployer.createDeployer( file );
+ typeDeployer.deployAll();
}
catch( final DeploymentException de )
{
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 0d0e2a6a6..ad31d2568 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
@@ -32,8 +32,6 @@ public class DefaultExecutor
private final static Resources REZ =
ResourceManager.getPackageResources( DefaultExecutor.class );
- private final static String TASK_ROLE = Task.class.getName();
-
private Configurer m_configurer;
/**
@@ -81,7 +79,7 @@ public class DefaultExecutor
{
try
{
- final TypeFactory factory = frame.getTypeManager().getFactory( TASK_ROLE );
+ final TypeFactory factory = frame.getTypeManager().getFactory( Task.class );
return (Task)factory.create( name );
}
catch( final TypeException te )
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java
index f6b46326f..f78ad8221 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java
@@ -7,19 +7,10 @@
*/
package org.apache.myrmidon.components.role;
-import java.net.URL;
-import java.util.Enumeration;
import java.util.HashMap;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.myrmidon.interfaces.role.RoleManager;
-import org.xml.sax.XMLReader;
/**
* Interface to manage roles and mapping to names.
@@ -28,13 +19,11 @@ import org.xml.sax.XMLReader;
* @version CVS $Revision$ $Date$
*/
public class DefaultRoleManager
- implements RoleManager, Initializable
+ implements RoleManager
{
private final static Resources REZ =
ResourceManager.getPackageResources( DefaultRoleManager.class );
- private final static String ROLE_DESCRIPTOR = "META-INF/ant-roles.xml";
-
/** Parent RoleManager
for nested resolution */
private final RoleManager m_parent;
@@ -63,51 +52,6 @@ public class DefaultRoleManager
m_parent = parent;
}
- /**
- * initialize the RoleManager.
- * This involves reading all Role descriptors in common classloader.
- *
- * @exception Exception if an error occurs
- */
- public void initialize()
- throws Exception
- {
- final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
- final SAXParser saxParser = saxParserFactory.newSAXParser();
- final XMLReader parser = saxParser.getXMLReader();
- //parser.setFeature( "http://xml.org/sax/features/namespace-prefixes", false );
-
- final SAXConfigurationHandler handler = new SAXConfigurationHandler();
- parser.setContentHandler( handler );
- parser.setErrorHandler( handler );
-
- final Enumeration enum = getClass().getClassLoader().getResources( ROLE_DESCRIPTOR );
- while( enum.hasMoreElements() )
- {
- final URL url = (URL)enum.nextElement();
- parser.parse( url.toString() );
- handleDescriptor( handler.getConfiguration() );
- }
- }
-
- /**
- * Configure RoleManager based on contents of single descriptor.
- *
- * @param descriptor the descriptor
- * @exception ConfigurationException if an error occurs
- */
- private void handleDescriptor( final Configuration descriptor )
- throws ConfigurationException
- {
- final Configuration[] types = descriptor.getChildren( "role" );
- for( int i = 0; i < types.length; i++ )
- {
- final String name = types[ i ].getAttribute( "shorthand" );
- final String role = types[ i ].getAttribute( "name" );
- addNameRoleMapping( name, role );
- }
- }
-
/**
* Find Role name based on shorthand name.
*
@@ -155,14 +99,14 @@ public class DefaultRoleManager
throws IllegalArgumentException
{
final String oldRole = (String)m_names.get( name );
- if( null != oldRole && oldRole.equals( role ) )
+ if( null != oldRole && ! oldRole.equals( role ) )
{
final String message = REZ.getString( "duplicate-name.error", oldRole );
throw new IllegalArgumentException( message );
}
final String oldName = (String)m_roles.get( role );
- if( null != oldName && oldName.equals( name ) )
+ if( null != oldName && ! oldName.equals( name ) )
{
final String message = REZ.getString( "duplicate-role.error", oldName );
throw new IllegalArgumentException( message );
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 94021dc74..2a674f48f 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
@@ -28,7 +28,7 @@ public class DefaultTypeManager
///Parent type manager to inherit values from.
private final DefaultTypeManager m_parent;
- ///Maps role to MultiSourceTypeFactory.
+ ///Maps role Class to MultiSourceTypeFactory.
private final HashMap m_roleMap = new HashMap();
public DefaultTypeManager()
@@ -41,7 +41,7 @@ public class DefaultTypeManager
m_parent = parent;
}
- public void registerType( final String role,
+ public void registerType( final Class role,
final String shorthandName,
final TypeFactory factory )
throws TypeException
@@ -50,7 +50,7 @@ public class DefaultTypeManager
msFactory.register( shorthandName, factory );
}
- public TypeFactory getFactory( final String role )
+ public TypeFactory getFactory( final Class role )
throws TypeException
{
return createFactory( role );
@@ -61,7 +61,7 @@ public class DefaultTypeManager
return new DefaultTypeManager( this );
}
- protected final MultiSourceTypeFactory lookupFactory( final String role )
+ protected final MultiSourceTypeFactory lookupFactory( final Class role )
{
return (MultiSourceTypeFactory)m_roleMap.get( role );
}
@@ -74,7 +74,7 @@ public class DefaultTypeManager
* @return the Factory for interface
* @exception TypeException role does not specify accessible work interface
*/
- private MultiSourceTypeFactory createFactory( final String role )
+ private MultiSourceTypeFactory createFactory( final Class role )
throws TypeException
{
MultiSourceTypeFactory factory = (MultiSourceTypeFactory)m_roleMap.get( role );
@@ -92,17 +92,7 @@ public class DefaultTypeManager
///If we haven't got factory try to create a new one
if( null == factory )
{
- try
- {
- //TODO: Should we use ContextClassLoader here ??? Or perhaps try that on failure??
- final Class clazz = Class.forName( role );
- factory = new MultiSourceTypeFactory( clazz );
- }
- catch( final Exception e )
- {
- final String message = REZ.getString( "no-work-interface.error", role );
- throw new TypeException( message );
- }
+ factory = new MultiSourceTypeFactory( role );
}
m_roleMap.put( role, factory );
@@ -110,7 +100,7 @@ public class DefaultTypeManager
return factory;
}
- private MultiSourceTypeFactory getParentTypedFactory( final String role )
+ private MultiSourceTypeFactory getParentTypedFactory( final Class role )
{
if( null != m_parent )
{
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
index 36e9b5a54..a6e2f8d6a 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
@@ -28,11 +28,11 @@ import org.apache.avalon.framework.parameters.Parameters;
import org.apache.log.Hierarchy;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
-import org.apache.myrmidon.components.deployer.DefaultDeployer;
import org.apache.myrmidon.components.executor.DefaultExecutionFrame;
import org.apache.myrmidon.framework.Condition;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
import org.apache.myrmidon.interfaces.executor.ExecutionFrame;
import org.apache.myrmidon.interfaces.executor.Executor;
import org.apache.myrmidon.interfaces.model.Project;
@@ -61,6 +61,7 @@ public class DefaultWorkspace
private TaskContext m_baseContext;
private HashMap m_entrys = new HashMap();
private TypeManager m_typeManager;
+ private Deployer m_deployer;
private Hierarchy m_hierarchy;
private int m_projectID;
@@ -96,6 +97,7 @@ public class DefaultWorkspace
m_componentManager = componentManager;
m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
m_executor = (Executor)componentManager.lookup( Executor.ROLE );
+ m_deployer = (Deployer)componentManager.lookup( Deployer.ROLE );
}
public void parameterize( final Parameters parameters )
@@ -198,13 +200,16 @@ public class DefaultWorkspace
try
{
+ final TypeDeployer typeDeployer = deployer.createDeployer( file );
if( null == typeLib.getRole() )
{
- deployer.deploy( file );
+ // Deploy everything in the typelib
+ typeDeployer.deployAll();
}
else
{
- deployer.deployType( typeLib.getRole(), typeLib.getName(), file );
+ // Deploy the specified type
+ typeDeployer.deployType( typeLib.getRole(), typeLib.getName() );
}
}
catch( final DeploymentException de )
@@ -227,27 +232,34 @@ public class DefaultWorkspace
final TypeManager typeManager = m_typeManager.createChildTypeManager();
componentManager.put( TypeManager.ROLE, typeManager );
+ //try
+ //{
+ // //Add VFS manager
+ // // TODO - need to drive this from a typelib descriptor, plus
+ // // should be adding services to the root frame, rather than here
+ // final DefaultFileSystemManager vfsManager = new DefaultFileSystemManager();
+ // vfsManager.setBaseFile( project.getBaseDirectory() );
+ // componentManager.put( FileSystemManager.ROLE, vfsManager );
+ //}
+ //catch( Exception e )
+ //{
+ // throw new TaskException( e.getMessage(), e );
+ //}
+
//We need to create a new deployer so that it deploys
//to project specific TypeManager
- final DefaultDeployer deployer = new DefaultDeployer();
- deployer.enableLogging( getLogger() );
-
+ final Deployer deployer;
try
{
- deployer.compose( componentManager );
+ deployer = m_deployer.createChildDeployer( componentManager );
+ componentManager.put( Deployer.ROLE, deployer );
}
- catch( final ComponentException ce )
+ catch( ComponentException e )
{
- final String message = REZ.getString( "bad-deployer-config.error" );
- throw new TaskException( message, ce );
+ throw new TaskException( e.getMessage(), e );
}
- //HACK: Didn't call initialize because Deployer contained in Embeddor
- // Already initialized and this would be reduendent
- //deployer.initialize();
-
- componentManager.put( Deployer.ROLE, deployer );
-
+ // Deploy the imported typelibs
deployTypeLib( deployer, project );
//We need to place projects and ProjectManager
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java
index 3932af4c2..02528c18c 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java
@@ -109,17 +109,17 @@ public abstract class AbstractContainerTask
/**
* Locates a type factory.
*/
- protected final TypeFactory getTypeFactory( final String role )
+ protected final TypeFactory getTypeFactory( final Class roleType )
throws TaskException
{
final TypeManager typeManager = (TypeManager)getService( TypeManager.class );
try
{
- return typeManager.getFactory( role );
+ return typeManager.getFactory( roleType );
}
catch( final TypeException te )
{
- final String message = REZ.getString( "container.no-factory.error", role );
+ final String message = REZ.getString( "container.no-factory.error", roleType.getName() );
throw new TaskException( message, te );
}
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java
index 01132fcc2..13409beea 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java
@@ -8,16 +8,13 @@
package org.apache.myrmidon.framework;
import java.io.File;
-import java.net.URL;
-import java.net.URLClassLoader;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
-import org.apache.myrmidon.interfaces.role.RoleManager;
-import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
-import org.apache.myrmidon.interfaces.type.TypeException;
-import org.apache.myrmidon.interfaces.type.TypeManager;
+import org.apache.myrmidon.interfaces.deployer.Deployer;
+import org.apache.myrmidon.interfaces.deployer.DeploymentException;
+import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
/**
* Abstract task to extend to define a type.
@@ -66,44 +63,20 @@ public abstract class AbstractTypeDef
throw new TaskException( message );
}
- final String typeName = getTypeName();
- final RoleManager roleManager = (RoleManager)getService( RoleManager.class );
- final String role = roleManager.getRoleForName( typeName );
+ final String shorthand = getRoleShorthand();
- final ClassLoader classLoader = createClassLoader();
- final DefaultTypeFactory factory = new DefaultTypeFactory( classLoader );
- factory.addNameClassMapping( m_name, m_className );
-
- final TypeManager typeManager = (TypeManager)getService( TypeManager.class );
try
{
- typeManager.registerType( role, m_name, factory );
- }
- catch( final TypeException te )
- {
- final String message = REZ.getString( "typedef.no-register.error" );
- throw new TaskException( message, te );
- }
- }
-
- protected ClassLoader createClassLoader()
- throws TaskException
- {
- //TODO: Make this support classpath sub-element in future
- try
- {
- final URL url = m_lib.toURL();
- final ClassLoader classLoader =
- Thread.currentThread().getContextClassLoader();
-
- return new URLClassLoader( new URL[]{url}, classLoader );
+ // Locate the deployer, and use it to deploy the type
+ final Deployer deployer = (Deployer)getService( Deployer.class );
+ final TypeDeployer typeDeployer = deployer.createDeployer( m_lib );
+ typeDeployer.deployType( shorthand, m_name, m_className );
}
- catch( final Exception e )
+ catch( DeploymentException e )
{
- final String message = REZ.getString( "typedef.bad-classloader.error", e );
- throw new TaskException( message, e );
+ throw new TaskException( e.getMessage(), e );
}
}
- protected abstract String getTypeName();
+ protected abstract String getRoleShorthand();
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java
index 8853b565d..d55a30a39 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java
@@ -63,7 +63,7 @@ public class TypeInstanceTask
try
{
- final TypeFactory typeFactory = getTypeFactory( DataType.ROLE );
+ final TypeFactory typeFactory = getTypeFactory( DataType.class );
m_value = typeFactory.create( configuration.getName() );
}
catch( final Exception e )
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java
index cddb07df7..be276bf4f 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java
@@ -9,9 +9,11 @@ package org.apache.myrmidon.interfaces.deployer;
import java.io.File;
import org.apache.avalon.framework.component.Component;
+import org.apache.avalon.framework.component.ComponentException;
+import org.apache.avalon.framework.component.ComponentManager;
/**
- * This class deploys a .tsk file into a registry.
+ * This class deploys type libraries into a registry.
*
* @author Peter Donald
*/
@@ -21,17 +23,28 @@ public interface Deployer
String ROLE = "org.apache.myrmidon.interfaces.deployer.Deployer";
/**
- * Deploy a library.
+ * Returns the deployer for the type libraries contained in a ClassLoader,
+ * creating the deployer if necessary.
*
- * @param file the file deployment
- * @exception DeploymentException if an error occurs
+ * @param loader The ClassLoader to get the deployer for.
+ * @exception DeploymentException if an error occurs.
*/
- void deploy( File file )
+ TypeDeployer createDeployer( ClassLoader loader )
throws DeploymentException;
- void deployConverter( String name, File file )
+ /**
+ * Returns the deployer for a type library, creating the deployer if
+ * necessary.
+ *
+ * @param file the file containing the type library.
+ * @exception DeploymentException if an error occurs.
+ */
+ TypeDeployer createDeployer( File file )
throws DeploymentException;
- void deployType( String role, String name, File file )
- throws DeploymentException;
+ /**
+ * Creates a child deployer.
+ */
+ Deployer createChildDeployer( ComponentManager componentManager )
+ throws ComponentException;
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/TypeDeployer.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/TypeDeployer.java
new file mode 100644
index 000000000..f453987d9
--- /dev/null
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/TypeDeployer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.txt file.
+ */
+package org.apache.myrmidon.interfaces.deployer;
+
+/**
+ * A deployer for a type library. Allows individual elements from a type
+ * library to be deployed.
+ *
+ * @author Adam Murdoch
+ */
+public interface TypeDeployer
+{
+ /**
+ * Deploys everything in the type library.
+ */
+ void deployAll()
+ throws DeploymentException;
+
+ /**
+ * Deploys a single type from the type library. The type definition is
+ * read from the type library descriptor.
+ *
+ * @param roleShorthand
+ * The shorthand for the role.
+ * @param typeName
+ * The type name.
+ */
+ void deployType( String roleShorthand, String typeName )
+ throws DeploymentException;
+
+ /**
+ * Deploys a single type from the type library.
+ */
+ void deployType( String roleShorthand, String typeName, String className )
+ throws DeploymentException;
+
+ /**
+ * Deploys a converter from the type library. The converter definition
+ * is read from the type library descriptor.
+ */
+ void deployConverter( String className )
+ throws DeploymentException;
+
+ /**
+ * Deploys a converter from the type library.
+ */
+ void deployConverter( String className, String srcClass, String destClass )
+ throws DeploymentException;
+}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java
index aa90c17ad..8dce64ecd 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java
@@ -38,4 +38,13 @@ public interface RoleManager
* @return the name
*/
String getNameForRole( String role );
+
+ /**
+ * Adds a role mapping.
+ *
+ * @param name the shorthand name.
+ * @param role the role name.
+ */
+ void addNameRoleMapping( String name, String role )
+ throws IllegalArgumentException;
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java
index 7fcd52490..1b2c0a102 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java
@@ -7,8 +7,6 @@
*/
package org.apache.myrmidon.interfaces.type;
-import java.net.URL;
-import java.net.URLClassLoader;
import java.util.HashMap;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
@@ -28,34 +26,11 @@ public class DefaultTypeFactory
///A Map of shortnames to classnames
private final HashMap m_classNames = new HashMap();
- ///A list of URLs from which classLoader is constructed
- private final URL[] m_urls;
-
- ///The parent classLoader (if any)
- private final ClassLoader m_parent;
-
///The parent classLoader (if any)
private ClassLoader m_classLoader;
- public DefaultTypeFactory( final URL url )
- {
- this( new URL[]{url} );
- }
-
- public DefaultTypeFactory( final URL[] urls )
- {
- this( urls, Thread.currentThread().getContextClassLoader() );
- }
-
- public DefaultTypeFactory( final URL[] urls, final ClassLoader parent )
- {
- m_urls = urls;
- m_parent = parent;
- }
-
public DefaultTypeFactory( final ClassLoader classLoader )
{
- this( null, null );
m_classLoader = classLoader;
}
@@ -78,7 +53,7 @@ public class DefaultTypeFactory
try
{
- return getClassLoader().loadClass( className ).newInstance();
+ return m_classLoader.loadClass( className ).newInstance();
}
catch( final Exception e )
{
@@ -100,14 +75,4 @@ public class DefaultTypeFactory
return className;
}
-
- private ClassLoader getClassLoader()
- {
- if( null == m_classLoader )
- {
- m_classLoader = new URLClassLoader( m_urls, m_parent );
- }
-
- return m_classLoader;
- }
}
diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java
index ccd427f19..3e0643bb0 100644
--- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java
@@ -19,11 +19,32 @@ public interface TypeManager
{
String ROLE = "org.apache.myrmidon.interfaces.type.TypeManager";
- void registerType( String role, String shorthandName, TypeFactory factory )
+ /**
+ * Registers a new type.
+ *
+ * @param roleType
+ * The role interface for the type. Objects created by the factory
+ * must implement this interface.
+ *
+ * @param shorthandName
+ * The shorthand name for the type.
+ *
+ * @param factory
+ * The type factory.
+ */
+ void registerType( Class roleType, String shorthandName, TypeFactory factory )
throws TypeException;
- TypeFactory getFactory( String role )
+ /**
+ * Returns the factory for a role.
+ */
+ TypeFactory getFactory( Class roleType )
throws TypeException;
+ /**
+ * Creates a child type manager. The child inherits the type factories
+ * from this type manager. Additional type factories may be added to the
+ * child, without affecting this type manager.
+ */
TypeManager createChildTypeManager();
}
diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
index 98122db39..5006b45d0 100644
--- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
+++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
@@ -433,8 +433,8 @@ public class DefaultConfigurerTest
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
- m_typeManager.registerType( MyRole1.class.getName(), "my-type1", factory );
- m_typeManager.registerType( MyRole1.class.getName(), "my-type2", factory );
+ m_typeManager.registerType( MyRole1.class, "my-type1", factory );
+ m_typeManager.registerType( MyRole1.class, "my-type2", factory );
final ConfigTest6 test = new ConfigTest6();
diff --git a/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java b/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
index 98122db39..5006b45d0 100644
--- a/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
+++ b/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
@@ -433,8 +433,8 @@ public class DefaultConfigurerTest
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
- m_typeManager.registerType( MyRole1.class.getName(), "my-type1", factory );
- m_typeManager.registerType( MyRole1.class.getName(), "my-type2", factory );
+ m_typeManager.registerType( MyRole1.class, "my-type1", factory );
+ m_typeManager.registerType( MyRole1.class, "my-type2", factory );
final ConfigTest6 test = new ConfigTest6();