* 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-ffa450edef68master
@@ -54,7 +54,7 @@ public class Property | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
final TypeFactory typeFactory = getTypeFactory( DataType.ROLE ); | |||||
final TypeFactory typeFactory = getTypeFactory( DataType.class ); | |||||
final DataType value = (DataType)typeFactory.create( children[ i ].getName() ); | final DataType value = (DataType)typeFactory.create( children[ i ].getName() ); | ||||
configure( value, children[ i ] ); | configure( value, children[ i ] ); | ||||
setValue( value ); | setValue( value ); | ||||
@@ -8,15 +8,12 @@ | |||||
package org.apache.antlib.runtime; | package org.apache.antlib.runtime; | ||||
import java.io.File; | import java.io.File; | ||||
import java.net.URL; | |||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
import org.apache.myrmidon.api.TaskException; | 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. | * Task to define a converter. | ||||
@@ -80,15 +77,10 @@ public class ConverterDef | |||||
try | 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 ) | catch( final Exception e ) | ||||
{ | { | ||||
@@ -50,7 +50,7 @@ public class Facility | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
final TypeFactory typeFactory = getTypeFactory( AspectHandler.ROLE ); | |||||
final TypeFactory typeFactory = getTypeFactory( AspectHandler.class ); | |||||
m_aspectHandler = (AspectHandler)typeFactory.create( children[ 0 ].getName() ); | m_aspectHandler = (AspectHandler)typeFactory.create( children[ 0 ].getName() ); | ||||
} | } | ||||
catch( final Exception e ) | catch( final Exception e ) | ||||
@@ -14,6 +14,7 @@ import org.apache.myrmidon.api.AbstractTask; | |||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.myrmidon.interfaces.deployer.Deployer; | import org.apache.myrmidon.interfaces.deployer.Deployer; | ||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | import org.apache.myrmidon.interfaces.deployer.DeploymentException; | ||||
import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | |||||
/** | /** | ||||
* Task to import a tasklib. | * Task to import a tasklib. | ||||
@@ -45,7 +46,8 @@ public class Import | |||||
try | try | ||||
{ | { | ||||
final Deployer deployer = (Deployer)getService( Deployer.class ); | final Deployer deployer = (Deployer)getService( Deployer.class ); | ||||
deployer.deploy( m_lib ); | |||||
TypeDeployer typeDeployer = deployer.createDeployer( m_lib ); | |||||
typeDeployer.deployAll(); | |||||
} | } | ||||
catch( final DeploymentException de ) | catch( final DeploymentException de ) | ||||
{ | { | ||||
@@ -24,7 +24,7 @@ public class TypeDef | |||||
m_type = type; | m_type = type; | ||||
} | } | ||||
protected String getTypeName() | |||||
protected String getRoleShorthand() | |||||
{ | { | ||||
return m_type; | return m_type; | ||||
} | } | ||||
@@ -403,6 +403,9 @@ public class DefaultConfigurer | |||||
return configurer; | return configurer; | ||||
} | } | ||||
/** | |||||
* Creates and configures an inline object. | |||||
*/ | |||||
private Object setupChild( final ConfigurationState state, | private Object setupChild( final ConfigurationState state, | ||||
final Configuration element, | final Configuration element, | ||||
final Context context, | final Context context, | ||||
@@ -424,14 +427,13 @@ public class DefaultConfigurer | |||||
if( type.isInterface() ) | if( type.isInterface() ) | ||||
{ | { | ||||
child = createdTypedObject( name, type ); | child = createdTypedObject( name, type ); | ||||
configureObject( child, element, context ); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
child = createObject( type ); | child = createObject( type ); | ||||
configureObject( child, element, context ); | |||||
} | } | ||||
} | } | ||||
configureObject( child, element, context ); | configureObject( child, element, context ); | ||||
return child; | return child; | ||||
} | } | ||||
@@ -444,7 +446,7 @@ public class DefaultConfigurer | |||||
final Class type ) | final Class type ) | ||||
throws ConfigurationException | throws ConfigurationException | ||||
{ | { | ||||
final TypeFactory factory = getTypeFactory( type.getName() ); | |||||
final TypeFactory factory = getTypeFactory( type ); | |||||
try | try | ||||
{ | { | ||||
return factory.create( name ); | return factory.create( name ); | ||||
@@ -481,7 +483,7 @@ public class DefaultConfigurer | |||||
/** | /** | ||||
* Locates a type factory. | * Locates a type factory. | ||||
*/ | */ | ||||
protected final TypeFactory getTypeFactory( final String role ) | |||||
protected final TypeFactory getTypeFactory( final Class role ) | |||||
throws ConfigurationException | throws ConfigurationException | ||||
{ | { | ||||
try | try | ||||
@@ -490,7 +492,7 @@ public class DefaultConfigurer | |||||
} | } | ||||
catch( final TypeException te ) | 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 ); | throw new ConfigurationException( message, te ); | ||||
} | } | ||||
} | } | ||||
@@ -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}>. | no-content.error=Text content is not allowed for element <{0}>. | ||||
bad-set-content.error=Could not set text content 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. | 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}. |
@@ -53,7 +53,7 @@ public class DefaultMasterConverter | |||||
final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | ||||
try | try | ||||
{ | { | ||||
m_factory = typeManager.getFactory( Converter.ROLE ); | |||||
m_factory = typeManager.getFactory( Converter.class ); | |||||
} | } | ||||
catch( final TypeException te ) | catch( final TypeException te ) | ||||
{ | { | ||||
@@ -132,11 +132,10 @@ public class DefaultMasterConverter | |||||
final Class destination ) | final Class destination ) | ||||
throws ConverterException | throws ConverterException | ||||
{ | { | ||||
Class clazz = destination; | |||||
//TODO: Maybe we should search the source classes hierarchy aswell | //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 = | final String name = | ||||
m_registry.getConverterName( originalClass.getName(), | m_registry.getConverterName( originalClass.getName(), | ||||
@@ -145,8 +144,6 @@ public class DefaultMasterConverter | |||||
{ | { | ||||
return name; | return name; | ||||
} | } | ||||
clazz = clazz.getSuperclass(); | |||||
} | } | ||||
final String message = | final String message = | ||||
@@ -14,33 +14,22 @@ import java.net.URL; | |||||
import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Enumeration; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | |||||
import java.util.jar.Manifest; | 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.Extension; | ||||
import org.apache.avalon.excalibur.extension.OptionalPackage; | import org.apache.avalon.excalibur.extension.OptionalPackage; | ||||
import org.apache.avalon.excalibur.extension.PackageManager; | import org.apache.avalon.excalibur.extension.PackageManager; | ||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | 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.ComponentException; | ||||
import org.apache.avalon.framework.component.ComponentManager; | import org.apache.avalon.framework.component.ComponentManager; | ||||
import org.apache.avalon.framework.component.Composable; | 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.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.Deployer; | ||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | 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.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. | * This class deploys a .tsk file into a registry. | ||||
@@ -49,16 +38,38 @@ import org.xml.sax.XMLReader; | |||||
*/ | */ | ||||
public class DefaultDeployer | public class DefaultDeployer | ||||
extends AbstractLogEnabled | extends AbstractLogEnabled | ||||
implements Deployer, Initializable, Composable | |||||
implements Deployer, Composable | |||||
{ | { | ||||
private final static Resources REZ = | private final static Resources REZ = | ||||
ResourceManager.getPackageResources( DefaultDeployer.class ); | 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; | 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. | * Retrieve relevent services needed to deploy. | ||||
* | * | ||||
@@ -68,145 +79,99 @@ public class DefaultDeployer | |||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentException | 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 = | final ExtensionManager extensionManager = | ||||
(ExtensionManager)componentManager.lookup( ExtensionManager.ROLE ); | (ExtensionManager)componentManager.lookup( ExtensionManager.ROLE ); | ||||
m_packageManager = new PackageManager( extensionManager ); | 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 | throws DeploymentException | ||||
{ | { | ||||
if( getLogger().isInfoEnabled() ) | |||||
{ | |||||
final String message = REZ.getString( "file-deploy.notice", file ); | |||||
getLogger().info( message ); | |||||
} | |||||
checkFile( file ); | |||||
try | 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 ); | 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 | throws DeploymentException | ||||
{ | { | ||||
checkFile( file ); | |||||
final Deployment deployment = new Deployment( file ); | |||||
final Configuration descriptor = deployment.getDescriptor(); | |||||
final DefaultTypeFactory factory = new DefaultTypeFactory( deployment.getURL() ); | |||||
try | 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 ); | 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 ) | private URL[] buildClasspath( final File file, final File[] dependencies ) | ||||
@@ -243,10 +208,10 @@ public class DefaultDeployer | |||||
if( getLogger().isDebugEnabled() ) | if( getLogger().isDebugEnabled() ) | ||||
{ | { | ||||
final String message1 = | final String message1 = | ||||
REZ.getString( "available-extensions", Arrays.asList( available ) ); | |||||
REZ.getString( "available-extensions.notice", Arrays.asList( available ) ); | |||||
getLogger().debug( message1 ); | getLogger().debug( message1 ); | ||||
final String message2 = | final String message2 = | ||||
REZ.getString( "required-extensions", Arrays.asList( required ) ); | |||||
REZ.getString( "required-extensions.notice", Arrays.asList( required ) ); | |||||
getLogger().debug( message2 ); | getLogger().debug( message2 ); | ||||
} | } | ||||
@@ -279,7 +244,7 @@ public class DefaultDeployer | |||||
} | } | ||||
final String message = | final String message = | ||||
REZ.getString( "unsatisfied.extensions", new Integer( size ) ); | |||||
REZ.getString( "unsatisfied.extensions.error", new Integer( size ) ); | |||||
throw new Exception( message ); | throw new Exception( message ); | ||||
} | } | ||||
@@ -288,87 +253,9 @@ public class DefaultDeployer | |||||
return OptionalPackage.toFiles( packages ); | 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 ) | private void checkFile( final File file ) | ||||
throws DeploymentException | 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 ); | |||||
} | |||||
} | |||||
} | } |
@@ -7,99 +7,391 @@ | |||||
*/ | */ | ||||
package org.apache.myrmidon.components.deployer; | package org.apache.myrmidon.components.deployer; | ||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.FileNotFoundException; | |||||
import java.net.URL; | 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.SAXParser; | ||||
import javax.xml.parsers.SAXParserFactory; | import javax.xml.parsers.SAXParserFactory; | ||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | 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.Configuration; | ||||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||||
import org.apache.avalon.framework.configuration.SAXConfigurationHandler; | 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.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; | 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> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
*/ | */ | ||||
public class Deployment | |||||
class Deployment | |||||
extends AbstractLogEnabled | |||||
implements TypeDeployer | |||||
{ | { | ||||
private final static Resources REZ = | private final static Resources REZ = | ||||
ResourceManager.getPackageResources( Deployment.class ); | 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 | 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 | throws DeploymentException | ||||
{ | { | ||||
try | 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 | 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 | 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; | |||||
} | |||||
} | } |
@@ -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. |
@@ -27,6 +27,7 @@ import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | |||||
import org.apache.myrmidon.interfaces.converter.MasterConverter; | import org.apache.myrmidon.interfaces.converter.MasterConverter; | ||||
import org.apache.myrmidon.interfaces.deployer.Deployer; | import org.apache.myrmidon.interfaces.deployer.Deployer; | ||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | 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.embeddor.Embeddor; | ||||
import org.apache.myrmidon.interfaces.executor.Executor; | import org.apache.myrmidon.interfaces.executor.Executor; | ||||
import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | ||||
@@ -106,7 +107,7 @@ public class DefaultEmbeddor | |||||
throws Exception | 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 ); | final ProjectBuilder builder = (ProjectBuilder)factory.create( type ); | ||||
setupLogger( builder ); | setupLogger( builder ); | ||||
@@ -181,6 +182,12 @@ public class DefaultEmbeddor | |||||
public void start() | public void start() | ||||
throws Exception | 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" ); | final ExtensionFileFilter filter = new ExtensionFileFilter( ".atl" ); | ||||
deployFromDirectory( m_deployer, m_taskLibDir, filter ); | 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, | private void deployFromDirectory( final Deployer deployer, | ||||
final File directory, | final File directory, | ||||
final FilenameFilter filter ) | 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 ) | private void deployFiles( final Deployer deployer, final File[] files ) | ||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
@@ -508,7 +521,8 @@ public class DefaultEmbeddor | |||||
try | try | ||||
{ | { | ||||
final File file = files[ i ].getCanonicalFile(); | final File file = files[ i ].getCanonicalFile(); | ||||
deployer.deploy( file ); | |||||
final TypeDeployer typeDeployer = deployer.createDeployer( file ); | |||||
typeDeployer.deployAll(); | |||||
} | } | ||||
catch( final DeploymentException de ) | catch( final DeploymentException de ) | ||||
{ | { | ||||
@@ -32,8 +32,6 @@ public class DefaultExecutor | |||||
private final static Resources REZ = | private final static Resources REZ = | ||||
ResourceManager.getPackageResources( DefaultExecutor.class ); | ResourceManager.getPackageResources( DefaultExecutor.class ); | ||||
private final static String TASK_ROLE = Task.class.getName(); | |||||
private Configurer m_configurer; | private Configurer m_configurer; | ||||
/** | /** | ||||
@@ -81,7 +79,7 @@ public class DefaultExecutor | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
final TypeFactory factory = frame.getTypeManager().getFactory( TASK_ROLE ); | |||||
final TypeFactory factory = frame.getTypeManager().getFactory( Task.class ); | |||||
return (Task)factory.create( name ); | return (Task)factory.create( name ); | ||||
} | } | ||||
catch( final TypeException te ) | catch( final TypeException te ) | ||||
@@ -7,19 +7,10 @@ | |||||
*/ | */ | ||||
package org.apache.myrmidon.components.role; | package org.apache.myrmidon.components.role; | ||||
import java.net.URL; | |||||
import java.util.Enumeration; | |||||
import java.util.HashMap; | 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.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | 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.apache.myrmidon.interfaces.role.RoleManager; | ||||
import org.xml.sax.XMLReader; | |||||
/** | /** | ||||
* Interface to manage roles and mapping to names. | * Interface to manage roles and mapping to names. | ||||
@@ -28,13 +19,11 @@ import org.xml.sax.XMLReader; | |||||
* @version CVS $Revision$ $Date$ | * @version CVS $Revision$ $Date$ | ||||
*/ | */ | ||||
public class DefaultRoleManager | public class DefaultRoleManager | ||||
implements RoleManager, Initializable | |||||
implements RoleManager | |||||
{ | { | ||||
private final static Resources REZ = | private final static Resources REZ = | ||||
ResourceManager.getPackageResources( DefaultRoleManager.class ); | ResourceManager.getPackageResources( DefaultRoleManager.class ); | ||||
private final static String ROLE_DESCRIPTOR = "META-INF/ant-roles.xml"; | |||||
/** Parent <code>RoleManager</code> for nested resolution */ | /** Parent <code>RoleManager</code> for nested resolution */ | ||||
private final RoleManager m_parent; | private final RoleManager m_parent; | ||||
@@ -63,51 +52,6 @@ public class DefaultRoleManager | |||||
m_parent = parent; | 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. | * Find Role name based on shorthand name. | ||||
* | * | ||||
@@ -155,14 +99,14 @@ public class DefaultRoleManager | |||||
throws IllegalArgumentException | throws IllegalArgumentException | ||||
{ | { | ||||
final String oldRole = (String)m_names.get( name ); | 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 ); | final String message = REZ.getString( "duplicate-name.error", oldRole ); | ||||
throw new IllegalArgumentException( message ); | throw new IllegalArgumentException( message ); | ||||
} | } | ||||
final String oldName = (String)m_roles.get( role ); | 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 ); | final String message = REZ.getString( "duplicate-role.error", oldName ); | ||||
throw new IllegalArgumentException( message ); | throw new IllegalArgumentException( message ); | ||||
@@ -28,7 +28,7 @@ public class DefaultTypeManager | |||||
///Parent type manager to inherit values from. | ///Parent type manager to inherit values from. | ||||
private final DefaultTypeManager m_parent; | private final DefaultTypeManager m_parent; | ||||
///Maps role to MultiSourceTypeFactory. | |||||
///Maps role Class to MultiSourceTypeFactory. | |||||
private final HashMap m_roleMap = new HashMap(); | private final HashMap m_roleMap = new HashMap(); | ||||
public DefaultTypeManager() | public DefaultTypeManager() | ||||
@@ -41,7 +41,7 @@ public class DefaultTypeManager | |||||
m_parent = parent; | m_parent = parent; | ||||
} | } | ||||
public void registerType( final String role, | |||||
public void registerType( final Class role, | |||||
final String shorthandName, | final String shorthandName, | ||||
final TypeFactory factory ) | final TypeFactory factory ) | ||||
throws TypeException | throws TypeException | ||||
@@ -50,7 +50,7 @@ public class DefaultTypeManager | |||||
msFactory.register( shorthandName, factory ); | msFactory.register( shorthandName, factory ); | ||||
} | } | ||||
public TypeFactory getFactory( final String role ) | |||||
public TypeFactory getFactory( final Class role ) | |||||
throws TypeException | throws TypeException | ||||
{ | { | ||||
return createFactory( role ); | return createFactory( role ); | ||||
@@ -61,7 +61,7 @@ public class DefaultTypeManager | |||||
return new DefaultTypeManager( this ); | return new DefaultTypeManager( this ); | ||||
} | } | ||||
protected final MultiSourceTypeFactory lookupFactory( final String role ) | |||||
protected final MultiSourceTypeFactory lookupFactory( final Class role ) | |||||
{ | { | ||||
return (MultiSourceTypeFactory)m_roleMap.get( role ); | return (MultiSourceTypeFactory)m_roleMap.get( role ); | ||||
} | } | ||||
@@ -74,7 +74,7 @@ public class DefaultTypeManager | |||||
* @return the Factory for interface | * @return the Factory for interface | ||||
* @exception TypeException role does not specify accessible work interface | * @exception TypeException role does not specify accessible work interface | ||||
*/ | */ | ||||
private MultiSourceTypeFactory createFactory( final String role ) | |||||
private MultiSourceTypeFactory createFactory( final Class role ) | |||||
throws TypeException | throws TypeException | ||||
{ | { | ||||
MultiSourceTypeFactory factory = (MultiSourceTypeFactory)m_roleMap.get( role ); | 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 we haven't got factory try to create a new one | ||||
if( null == factory ) | 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 ); | m_roleMap.put( role, factory ); | ||||
@@ -110,7 +100,7 @@ public class DefaultTypeManager | |||||
return factory; | return factory; | ||||
} | } | ||||
private MultiSourceTypeFactory getParentTypedFactory( final String role ) | |||||
private MultiSourceTypeFactory getParentTypedFactory( final Class role ) | |||||
{ | { | ||||
if( null != m_parent ) | if( null != m_parent ) | ||||
{ | { | ||||
@@ -28,11 +28,11 @@ import org.apache.avalon.framework.parameters.Parameters; | |||||
import org.apache.log.Hierarchy; | import org.apache.log.Hierarchy; | ||||
import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.myrmidon.components.deployer.DefaultDeployer; | |||||
import org.apache.myrmidon.components.executor.DefaultExecutionFrame; | import org.apache.myrmidon.components.executor.DefaultExecutionFrame; | ||||
import org.apache.myrmidon.framework.Condition; | import org.apache.myrmidon.framework.Condition; | ||||
import org.apache.myrmidon.interfaces.deployer.Deployer; | import org.apache.myrmidon.interfaces.deployer.Deployer; | ||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | 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.ExecutionFrame; | ||||
import org.apache.myrmidon.interfaces.executor.Executor; | import org.apache.myrmidon.interfaces.executor.Executor; | ||||
import org.apache.myrmidon.interfaces.model.Project; | import org.apache.myrmidon.interfaces.model.Project; | ||||
@@ -61,6 +61,7 @@ public class DefaultWorkspace | |||||
private TaskContext m_baseContext; | private TaskContext m_baseContext; | ||||
private HashMap m_entrys = new HashMap(); | private HashMap m_entrys = new HashMap(); | ||||
private TypeManager m_typeManager; | private TypeManager m_typeManager; | ||||
private Deployer m_deployer; | |||||
private Hierarchy m_hierarchy; | private Hierarchy m_hierarchy; | ||||
private int m_projectID; | private int m_projectID; | ||||
@@ -96,6 +97,7 @@ public class DefaultWorkspace | |||||
m_componentManager = componentManager; | m_componentManager = componentManager; | ||||
m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | ||||
m_executor = (Executor)componentManager.lookup( Executor.ROLE ); | m_executor = (Executor)componentManager.lookup( Executor.ROLE ); | ||||
m_deployer = (Deployer)componentManager.lookup( Deployer.ROLE ); | |||||
} | } | ||||
public void parameterize( final Parameters parameters ) | public void parameterize( final Parameters parameters ) | ||||
@@ -198,13 +200,16 @@ public class DefaultWorkspace | |||||
try | try | ||||
{ | { | ||||
final TypeDeployer typeDeployer = deployer.createDeployer( file ); | |||||
if( null == typeLib.getRole() ) | if( null == typeLib.getRole() ) | ||||
{ | { | ||||
deployer.deploy( file ); | |||||
// Deploy everything in the typelib | |||||
typeDeployer.deployAll(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
deployer.deployType( typeLib.getRole(), typeLib.getName(), file ); | |||||
// Deploy the specified type | |||||
typeDeployer.deployType( typeLib.getRole(), typeLib.getName() ); | |||||
} | } | ||||
} | } | ||||
catch( final DeploymentException de ) | catch( final DeploymentException de ) | ||||
@@ -227,27 +232,34 @@ public class DefaultWorkspace | |||||
final TypeManager typeManager = m_typeManager.createChildTypeManager(); | final TypeManager typeManager = m_typeManager.createChildTypeManager(); | ||||
componentManager.put( TypeManager.ROLE, typeManager ); | 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 | //We need to create a new deployer so that it deploys | ||||
//to project specific TypeManager | //to project specific TypeManager | ||||
final DefaultDeployer deployer = new DefaultDeployer(); | |||||
deployer.enableLogging( getLogger() ); | |||||
final Deployer deployer; | |||||
try | 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 ); | deployTypeLib( deployer, project ); | ||||
//We need to place projects and ProjectManager | //We need to place projects and ProjectManager | ||||
@@ -109,17 +109,17 @@ public abstract class AbstractContainerTask | |||||
/** | /** | ||||
* Locates a type factory. | * Locates a type factory. | ||||
*/ | */ | ||||
protected final TypeFactory getTypeFactory( final String role ) | |||||
protected final TypeFactory getTypeFactory( final Class roleType ) | |||||
throws TaskException | throws TaskException | ||||
{ | { | ||||
final TypeManager typeManager = (TypeManager)getService( TypeManager.class ); | final TypeManager typeManager = (TypeManager)getService( TypeManager.class ); | ||||
try | try | ||||
{ | { | ||||
return typeManager.getFactory( role ); | |||||
return typeManager.getFactory( roleType ); | |||||
} | } | ||||
catch( final TypeException te ) | 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 ); | throw new TaskException( message, te ); | ||||
} | } | ||||
} | } | ||||
@@ -8,16 +8,13 @@ | |||||
package org.apache.myrmidon.framework; | package org.apache.myrmidon.framework; | ||||
import java.io.File; | 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.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
import org.apache.myrmidon.api.TaskException; | 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. | * Abstract task to extend to define a type. | ||||
@@ -66,44 +63,20 @@ public abstract class AbstractTypeDef | |||||
throw new TaskException( message ); | 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 | 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(); | |||||
} | } |
@@ -63,7 +63,7 @@ public class TypeInstanceTask | |||||
try | try | ||||
{ | { | ||||
final TypeFactory typeFactory = getTypeFactory( DataType.ROLE ); | |||||
final TypeFactory typeFactory = getTypeFactory( DataType.class ); | |||||
m_value = typeFactory.create( configuration.getName() ); | m_value = typeFactory.create( configuration.getName() ); | ||||
} | } | ||||
catch( final Exception e ) | catch( final Exception e ) | ||||
@@ -9,9 +9,11 @@ package org.apache.myrmidon.interfaces.deployer; | |||||
import java.io.File; | import java.io.File; | ||||
import org.apache.avalon.framework.component.Component; | 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> | * @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"; | 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; | 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; | throws DeploymentException; | ||||
void deployType( String role, String name, File file ) | |||||
throws DeploymentException; | |||||
/** | |||||
* Creates a child deployer. | |||||
*/ | |||||
Deployer createChildDeployer( ComponentManager componentManager ) | |||||
throws ComponentException; | |||||
} | } |
@@ -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; | |||||
} |
@@ -38,4 +38,13 @@ public interface RoleManager | |||||
* @return the name | * @return the name | ||||
*/ | */ | ||||
String getNameForRole( String role ); | 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; | |||||
} | } |
@@ -7,8 +7,6 @@ | |||||
*/ | */ | ||||
package org.apache.myrmidon.interfaces.type; | package org.apache.myrmidon.interfaces.type; | ||||
import java.net.URL; | |||||
import java.net.URLClassLoader; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
@@ -28,34 +26,11 @@ public class DefaultTypeFactory | |||||
///A Map of shortnames to classnames | ///A Map of shortnames to classnames | ||||
private final HashMap m_classNames = new HashMap(); | 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) | ///The parent classLoader (if any) | ||||
private ClassLoader m_classLoader; | 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 ) | public DefaultTypeFactory( final ClassLoader classLoader ) | ||||
{ | { | ||||
this( null, null ); | |||||
m_classLoader = classLoader; | m_classLoader = classLoader; | ||||
} | } | ||||
@@ -78,7 +53,7 @@ public class DefaultTypeFactory | |||||
try | try | ||||
{ | { | ||||
return getClassLoader().loadClass( className ).newInstance(); | |||||
return m_classLoader.loadClass( className ).newInstance(); | |||||
} | } | ||||
catch( final Exception e ) | catch( final Exception e ) | ||||
{ | { | ||||
@@ -100,14 +75,4 @@ public class DefaultTypeFactory | |||||
return className; | return className; | ||||
} | } | ||||
private ClassLoader getClassLoader() | |||||
{ | |||||
if( null == m_classLoader ) | |||||
{ | |||||
m_classLoader = new URLClassLoader( m_urls, m_parent ); | |||||
} | |||||
return m_classLoader; | |||||
} | |||||
} | } |
@@ -19,11 +19,32 @@ public interface TypeManager | |||||
{ | { | ||||
String ROLE = "org.apache.myrmidon.interfaces.type.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; | throws TypeException; | ||||
TypeFactory getFactory( String role ) | |||||
/** | |||||
* Returns the factory for a role. | |||||
*/ | |||||
TypeFactory getFactory( Class roleType ) | |||||
throws TypeException; | 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(); | TypeManager createChildTypeManager(); | ||||
} | } |
@@ -433,8 +433,8 @@ public class DefaultConfigurerTest | |||||
final DefaultTypeFactory factory = new DefaultTypeFactory( loader ); | final DefaultTypeFactory factory = new DefaultTypeFactory( loader ); | ||||
factory.addNameClassMapping( "my-type1", MyType1.class.getName() ); | factory.addNameClassMapping( "my-type1", MyType1.class.getName() ); | ||||
factory.addNameClassMapping( "my-type2", MyType2.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(); | final ConfigTest6 test = new ConfigTest6(); | ||||
@@ -433,8 +433,8 @@ public class DefaultConfigurerTest | |||||
final DefaultTypeFactory factory = new DefaultTypeFactory( loader ); | final DefaultTypeFactory factory = new DefaultTypeFactory( loader ); | ||||
factory.addNameClassMapping( "my-type1", MyType1.class.getName() ); | factory.addNameClassMapping( "my-type1", MyType1.class.getName() ); | ||||
factory.addNameClassMapping( "my-type2", MyType2.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(); | final ConfigTest6 test = new ConfigTest6(); | ||||