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