Browse Source

Allow typelibs to define custom roles:

* Add TypeDeployer interface, which allows control over the deployment of
  types from a typelib.

* Add RoleManager.addNameRoleMapping().

* TypeManager methods now take a role Class object, rather than role name.

* Replace implicit role and type deployment in DefaultRoleManager.initialize()
  and DefaultDeployer.initialize() with explicit createDeployer( ClassLoader )
  method.

* DefaultDeployer now keeps track of the ClassLoader created for each typelib.

* Moved all ClassLoader creation to DefaultDeployer, for the time being.

* ConverterDef and AbstractTypeDef now use Deployer, rather than
  deploying manually.

* Fixed DefaultMasterConverter for the case where destination is an interface,
  and there is no appropriate converter registered.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271030 13f79535-47bb-0310-9956-ffa450edef68
master
adammurdoch 23 years ago
parent
commit
bc34bb06ca
26 changed files with 648 additions and 527 deletions
  1. +1
    -1
      proposal/myrmidon/src/java/org/apache/antlib/core/Property.java
  2. +6
    -14
      proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java
  3. +1
    -1
      proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java
  4. +3
    -1
      proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java
  5. +1
    -1
      proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java
  6. +7
    -5
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
  7. +2
    -1
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
  8. +4
    -7
      proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java
  9. +93
    -245
      proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java
  10. +332
    -40
      proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java
  11. +16
    -22
      proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties
  12. +16
    -2
      proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
  13. +1
    -3
      proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java
  14. +3
    -59
      proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java
  15. +7
    -17
      proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java
  16. +28
    -16
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
  17. +3
    -3
      proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java
  18. +11
    -38
      proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java
  19. +1
    -1
      proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java
  20. +21
    -8
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java
  21. +54
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/TypeDeployer.java
  22. +9
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java
  23. +1
    -36
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java
  24. +23
    -2
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java
  25. +2
    -2
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
  26. +2
    -2
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java

+ 1
- 1
proposal/myrmidon/src/java/org/apache/antlib/core/Property.java View File

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


+ 6
- 14
proposal/myrmidon/src/java/org/apache/antlib/runtime/ConverterDef.java View File

@@ -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 )
{


+ 1
- 1
proposal/myrmidon/src/java/org/apache/antlib/runtime/Facility.java View File

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


+ 3
- 1
proposal/myrmidon/src/java/org/apache/antlib/runtime/Import.java View File

@@ -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 )
{


+ 1
- 1
proposal/myrmidon/src/java/org/apache/antlib/runtime/TypeDef.java View File

@@ -24,7 +24,7 @@ public class TypeDef
m_type = type;
}

protected String getTypeName()
protected String getRoleShorthand()
{
return m_type;
}


+ 7
- 5
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java View File

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


+ 2
- 1
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties View File

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

+ 4
- 7
proposal/myrmidon/src/java/org/apache/myrmidon/components/converter/DefaultMasterConverter.java View File

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


+ 93
- 245
proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java View File

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

+ 332
- 40
proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Deployment.java View File

@@ -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 <a href="mailto:peter@apache.org">Peter Donald</a>
*/
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;
}

}

+ 16
- 22
proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/Resources.properties View File

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

+ 16
- 2
proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java View File

@@ -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 )
{


+ 1
- 3
proposal/myrmidon/src/java/org/apache/myrmidon/components/executor/DefaultExecutor.java View File

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


+ 3
- 59
proposal/myrmidon/src/java/org/apache/myrmidon/components/role/DefaultRoleManager.java View File

@@ -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 <code>RoleManager</code> 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 );


+ 7
- 17
proposal/myrmidon/src/java/org/apache/myrmidon/components/type/DefaultTypeManager.java View File

@@ -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 )
{


+ 28
- 16
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java View File

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


+ 3
- 3
proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractContainerTask.java View File

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


+ 11
- 38
proposal/myrmidon/src/java/org/apache/myrmidon/framework/AbstractTypeDef.java View File

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

+ 1
- 1
proposal/myrmidon/src/java/org/apache/myrmidon/framework/TypeInstanceTask.java View File

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


+ 21
- 8
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/Deployer.java View File

@@ -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 <a href="mailto:peter@apache.org">Peter Donald</a>
*/
@@ -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;
}

+ 54
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/deployer/TypeDeployer.java View File

@@ -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 <em>shorthand</em> 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;
}

+ 9
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/role/RoleManager.java View File

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

+ 1
- 36
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/DefaultTypeFactory.java View File

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

+ 23
- 2
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/type/TypeManager.java View File

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

+ 2
- 2
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

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



+ 2
- 2
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

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



Loading…
Cancel
Save