Renamed TskDeployer->Deployer, and refactored some code into Deployment class to make it easier to understand. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269092 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -13,13 +13,10 @@ import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.configuration.Configurable; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.framework.context.Resolvable; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.framework.AbstractContainerTask; | |||
| import org.apache.myrmidon.api.DataType; | |||
| import org.apache.myrmidon.api.TaskContext; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.components.configurer.Configurer; | |||
| import org.apache.myrmidon.components.converter.MasterConverter; | |||
| import org.apache.myrmidon.api.TaskContext; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.components.type.TypeException; | |||
| import org.apache.myrmidon.components.type.TypeFactory; | |||
| @@ -30,29 +27,25 @@ import org.apache.myrmidon.components.type.TypeFactory; | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class Property | |||
| extends AbstractTask | |||
| implements Configurable, Composable | |||
| extends AbstractContainerTask | |||
| implements Configurable | |||
| { | |||
| private String m_name; | |||
| private Object m_value; | |||
| private boolean m_localScope = true; | |||
| private TypeFactory m_factory; | |||
| private MasterConverter m_converter; | |||
| private Configurer m_configurer; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_configurer = (Configurer)componentManager.lookup( Configurer.ROLE ); | |||
| super.compose( componentManager ); | |||
| final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| try { m_factory = typeManager.getFactory( DataType.ROLE ); } | |||
| catch( final TypeException te ) | |||
| { | |||
| throw new ComponentException( "Unable to retrieve factory from TypeManager", te ); | |||
| } | |||
| m_converter = (MasterConverter)componentManager.lookup( MasterConverter.ROLE ); | |||
| } | |||
| public void configure( final Configuration configuration ) | |||
| @@ -65,32 +58,12 @@ public class Property | |||
| final String name = attributes[ i ]; | |||
| final String value = configuration.getAttribute( name ); | |||
| Object object = null; | |||
| try { object = getContext().resolveValue( value ); } | |||
| catch( final TaskException te ) | |||
| { | |||
| throw new ConfigurationException( "Error resolving value: " + value, te ); | |||
| } | |||
| if( null == object ) | |||
| { | |||
| throw new ConfigurationException( "Value for attribute " + name + "resolved to null" ); | |||
| } | |||
| final Object object = resolve( value ); | |||
| if( name.equals( "name" ) ) | |||
| { | |||
| try | |||
| { | |||
| final String convertedValue = | |||
| (String)m_converter.convert( String.class, object, getContext() ); | |||
| setName( convertedValue ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Error converting value", e ); | |||
| } | |||
| final String convertedValue = (String)convert( String.class, object ); | |||
| setName( convertedValue ); | |||
| } | |||
| else if( name.equals( "value" ) ) | |||
| { | |||
| @@ -102,16 +75,8 @@ public class Property | |||
| } | |||
| else if( name.equals( "local-scope" ) ) | |||
| { | |||
| try | |||
| { | |||
| final Boolean localScope = | |||
| (Boolean)m_converter.convert( Boolean.class, object, getContext() ); | |||
| setLocalScope( Boolean.TRUE == localScope ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new ConfigurationException( "Error converting value", e ); | |||
| } | |||
| final Boolean localScope = (Boolean)convert( Boolean.class, object ); | |||
| setLocalScope( Boolean.TRUE == localScope ); | |||
| } | |||
| else | |||
| { | |||
| @@ -128,8 +93,8 @@ public class Property | |||
| try | |||
| { | |||
| final DataType value = (DataType)m_factory.create( child.getName() ); | |||
| configure( value, child ); | |||
| setValue( value ); | |||
| m_configurer.configure( value, child, getContext() ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| @@ -172,27 +137,13 @@ public class Property | |||
| throw new TaskException( "Value must be specified" ); | |||
| } | |||
| final TaskContext context = getContext(); | |||
| Object value = m_value; | |||
| if( value instanceof String ) | |||
| { | |||
| value = context.resolveValue( (String)value ); | |||
| } | |||
| while( null != value && value instanceof Resolvable ) | |||
| { | |||
| value = ((Resolvable)value).resolve( context ); | |||
| } | |||
| if( m_localScope ) | |||
| { | |||
| context.setProperty( m_name, value ); | |||
| getContext().setProperty( m_name, m_value ); | |||
| } | |||
| else | |||
| { | |||
| context.setProperty( m_name, value, TaskContext.PARENT ); | |||
| getContext().setProperty( m_name, m_value, TaskContext.PARENT ); | |||
| } | |||
| } | |||
| } | |||
| @@ -13,7 +13,7 @@ import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.components.deployer.TskDeployer; | |||
| import org.apache.myrmidon.components.deployer.Deployer; | |||
| import org.apache.myrmidon.components.executor.Executor; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| @@ -29,14 +29,14 @@ public abstract class AbstractTypeDefinition | |||
| private String m_lib; | |||
| private String m_name; | |||
| private String m_classname; | |||
| private TskDeployer m_tskDeployer; | |||
| private Deployer m_deployer; | |||
| private TypeManager m_typeManager; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_tskDeployer = (TskDeployer)componentManager.lookup( TskDeployer.ROLE ); | |||
| m_deployer = (Deployer)componentManager.lookup( Deployer.ROLE ); | |||
| } | |||
| public void setLib( final String lib ) | |||
| @@ -72,9 +72,9 @@ public abstract class AbstractTypeDefinition | |||
| registerResource( m_name, m_classname, file ); | |||
| } | |||
| protected final TskDeployer getDeployer() | |||
| protected final Deployer getDeployer() | |||
| { | |||
| return m_tskDeployer; | |||
| return m_deployer; | |||
| } | |||
| protected final TypeManager getTypeManager() | |||
| @@ -17,7 +17,7 @@ import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.components.converter.ConverterRegistry; | |||
| import org.apache.myrmidon.components.deployer.DeploymentException; | |||
| import org.apache.myrmidon.components.deployer.TskDeployer; | |||
| import org.apache.myrmidon.components.deployer.Deployer; | |||
| import org.apache.myrmidon.components.type.DefaultTypeFactory; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.converter.Converter; | |||
| @@ -35,14 +35,14 @@ public class RegisterConverter | |||
| private String m_destinationType; | |||
| private String m_lib; | |||
| private String m_classname; | |||
| private TskDeployer m_tskDeployer; | |||
| private Deployer m_deployer; | |||
| private ConverterRegistry m_converterRegistry; | |||
| private TypeManager m_typeManager; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_tskDeployer = (TskDeployer)componentManager.lookup( TskDeployer.ROLE ); | |||
| m_deployer = (Deployer)componentManager.lookup( Deployer.ROLE ); | |||
| m_converterRegistry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE ); | |||
| m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| @@ -99,7 +99,7 @@ public class RegisterConverter | |||
| { | |||
| try | |||
| { | |||
| m_tskDeployer.deployConverter( m_classname, file ); | |||
| m_deployer.deployConverter( m_classname, file ); | |||
| } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| @@ -29,7 +29,7 @@ public class RegisterDataType | |||
| { | |||
| if( null == className ) | |||
| { | |||
| try { getDeployer().deployDataType( name, file ); } | |||
| try { getDeployer().deployType( DataType.ROLE, name, file ); } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| throw new TaskException( "Failed deploying " + name + " from " + file, de ); | |||
| @@ -29,7 +29,7 @@ public class RegisterTasklet | |||
| { | |||
| if( null == className ) | |||
| { | |||
| try { getDeployer().deployTask( name, file ); } | |||
| try { getDeployer().deployType( Task.ROLE, name, file ); } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| throw new TaskException( "Failed deploying " + name + " from " + file, de ); | |||
| @@ -16,7 +16,7 @@ import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.components.deployer.DeploymentException; | |||
| import org.apache.myrmidon.components.deployer.TskDeployer; | |||
| import org.apache.myrmidon.components.deployer.Deployer; | |||
| /** | |||
| * Method to register a tasklib. | |||
| @@ -28,12 +28,12 @@ public class RegisterTasklib | |||
| implements Composable | |||
| { | |||
| protected String m_lib; | |||
| protected TskDeployer m_tskDeployer; | |||
| protected Deployer m_deployer; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_tskDeployer = (TskDeployer)componentManager.lookup( TskDeployer.ROLE ); | |||
| m_deployer = (Deployer)componentManager.lookup( Deployer.ROLE ); | |||
| } | |||
| public void setLib( final String lib ) | |||
| @@ -55,7 +55,7 @@ public class RegisterTasklib | |||
| try | |||
| { | |||
| m_tskDeployer.deploy( file ); | |||
| m_deployer.deploy( file ); | |||
| } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| @@ -121,7 +121,7 @@ public class DefaultTaskContext | |||
| catch( final PropertyException pe ) | |||
| { | |||
| throw new TaskException( "Error resolving " + property + " due to " + pe.getMessage(), | |||
| pe ); | |||
| pe ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,226 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.components.deployer; | |||
| import java.io.File; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.framework.logger.AbstractLoggable; | |||
| import org.apache.myrmidon.components.converter.ConverterRegistry; | |||
| import org.apache.myrmidon.components.executor.Executor; | |||
| import org.apache.myrmidon.components.type.DefaultTypeFactory; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.converter.Converter; | |||
| import org.apache.myrmidon.api.DataType; | |||
| import org.apache.myrmidon.api.Task; | |||
| /** | |||
| * This class deploys a .tsk file into a registry. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class DefaultDeployer | |||
| extends AbstractLoggable | |||
| implements Composable, Deployer | |||
| { | |||
| private ConverterRegistry m_converterRegistry; | |||
| private TypeManager m_typeManager; | |||
| private RoleManager m_roleManager; | |||
| /** | |||
| * Retrieve relevent services needed to deploy. | |||
| * | |||
| * @param componentManager the ComponentManager | |||
| * @exception ComponentException if an error occurs | |||
| */ | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_converterRegistry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE ); | |||
| m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_roleManager = (RoleManager)componentManager.lookup( RoleManager.ROLE ); | |||
| } | |||
| public void deploy( final File file ) | |||
| throws DeploymentException | |||
| { | |||
| getLogger().info( "Deploying AntLib file (" + file + ")" ); | |||
| try | |||
| { | |||
| checkFile( file ); | |||
| final Deployment deployment = new Deployment( file ); | |||
| final Configuration descriptor = deployment.getDescriptor(); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( deployment.getURL() ); | |||
| final Configuration[] children = descriptor.getChildren(); | |||
| for( int i = 0; i < children.length; i++ ) | |||
| { | |||
| final String name = children[ i ].getName(); | |||
| if( name.equals( "converter" ) ) | |||
| { | |||
| handleConverter( children[ i ], factory ); | |||
| } | |||
| else | |||
| { | |||
| final String role = getRoleForName( name ); | |||
| handleType( role, children[ i ], factory ); | |||
| } | |||
| } | |||
| } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| throw de; | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Error deploying library", e ); | |||
| } | |||
| } | |||
| public void deployConverter( final String name, final File file ) | |||
| throws DeploymentException | |||
| { | |||
| checkFile( file ); | |||
| final Deployment deployment = new Deployment( file ); | |||
| final Configuration descriptor = deployment.getDescriptor(); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( deployment.getURL() ); | |||
| try | |||
| { | |||
| final Configuration[] converters = descriptor.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 ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Failed to deploy " + name, e ); | |||
| } | |||
| } | |||
| public void deployType( final String role, final String name, final File file ) | |||
| throws DeploymentException | |||
| { | |||
| checkFile( file ); | |||
| 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.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 ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Failed to deploy " + name, e ); | |||
| } | |||
| } | |||
| private String getNameForRole( final String role ) | |||
| throws DeploymentException | |||
| { | |||
| final String name = m_roleManager.getNameForRole( role ); | |||
| if( null == name ) | |||
| { | |||
| throw new DeploymentException( "RoleManager does not know name for role " + role ); | |||
| } | |||
| return name; | |||
| } | |||
| private String getRoleForName( final String name ) | |||
| throws DeploymentException | |||
| { | |||
| final String role = m_roleManager.getRoleForName( name ); | |||
| if( null == role ) | |||
| { | |||
| throw new DeploymentException( "RoleManager does not know role for name " + name ); | |||
| } | |||
| return role; | |||
| } | |||
| private void checkFile( final File file ) | |||
| throws DeploymentException | |||
| { | |||
| if( !file.exists() ) | |||
| { | |||
| throw new DeploymentException( "Could not find application archive at " + | |||
| file ); | |||
| } | |||
| if( file.isDirectory() ) | |||
| { | |||
| throw new DeploymentException( "Could not find application archive at " + | |||
| file + " as it is a directory." ); | |||
| } | |||
| } | |||
| 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 ); | |||
| getLogger().debug( "Registered converter " + name + " that converts from " + | |||
| source + " to " + destination ); | |||
| } | |||
| 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 ); | |||
| getLogger().debug( "Registered " + role + "/" + name + " as " + className ); | |||
| } | |||
| } | |||
| @@ -8,6 +8,9 @@ | |||
| package org.apache.myrmidon.components.deployer; | |||
| import java.util.HashMap; | |||
| import org.apache.myrmidon.api.DataType; | |||
| import org.apache.myrmidon.api.Task; | |||
| import org.apache.avalon.framework.activity.Initializable; | |||
| /** | |||
| * Interface to manage roles and mapping to shorthand names. | |||
| @@ -19,7 +22,7 @@ import java.util.HashMap; | |||
| * @version CVS $Revision$ $Date$ | |||
| */ | |||
| public class DefaultRoleManager | |||
| implements RoleManager | |||
| implements RoleManager, Initializable | |||
| { | |||
| /** Parent <code>RoleManager</code> for nested resolution */ | |||
| private final RoleManager m_parent; | |||
| @@ -49,6 +52,16 @@ public class DefaultRoleManager | |||
| m_parent = parent; | |||
| } | |||
| public void initialize() | |||
| throws Exception | |||
| { | |||
| ///UGLY HACK!!!!!!!!!!!!!!!!!!!!!!! | |||
| addNameRoleMapping( "task", Task.ROLE ); | |||
| addNameRoleMapping( "data-type", DataType.ROLE ); | |||
| //getClass().getClassLoader().getResources( "META-INF/ant-types.xml" ); | |||
| } | |||
| /** | |||
| * Find Role name based on shorthand name. | |||
| * | |||
| @@ -1,390 +0,0 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.components.deployer; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.net.MalformedURLException; | |||
| import java.net.URL; | |||
| import java.util.Iterator; | |||
| import java.util.zip.ZipEntry; | |||
| import java.util.zip.ZipException; | |||
| import java.util.zip.ZipFile; | |||
| import org.apache.avalon.framework.component.Component; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; | |||
| import org.apache.avalon.framework.logger.AbstractLoggable; | |||
| import org.apache.myrmidon.api.Task; | |||
| import org.apache.myrmidon.api.DataType; | |||
| import org.apache.myrmidon.components.converter.ConverterRegistry; | |||
| import org.apache.myrmidon.components.executor.Executor; | |||
| import org.apache.myrmidon.components.type.DefaultTypeFactory; | |||
| import org.apache.myrmidon.components.type.TypeManager; | |||
| import org.apache.myrmidon.converter.Converter; | |||
| import org.xml.sax.SAXException; | |||
| /** | |||
| * This class deploys a .tsk file into a registry. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class DefaultTskDeployer | |||
| extends AbstractLoggable | |||
| implements Composable, TskDeployer | |||
| { | |||
| private final static String TSKDEF_FILE = "TASK-LIB/taskdefs.xml"; | |||
| private DefaultConfigurationBuilder m_configurationBuilder = new DefaultConfigurationBuilder(); | |||
| private ConverterRegistry m_converterRegistry; | |||
| private TypeManager m_typeManager; | |||
| private RoleManager m_roleManager; | |||
| /** | |||
| * Retrieve relevent services needed to deploy. | |||
| * | |||
| * @param componentManager the ComponentManager | |||
| * @exception ComponentException if an error occurs | |||
| */ | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_converterRegistry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE ); | |||
| m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
| m_roleManager = (RoleManager)componentManager.lookup( RoleManager.ROLE ); | |||
| } | |||
| public void deploy( final File file ) | |||
| throws DeploymentException | |||
| { | |||
| getLogger().info( "Deploying AntLib file (" + file + ")" ); | |||
| final URL url = getURL( file ); | |||
| final ZipFile zipFile = getZipFileFor( file ); | |||
| try | |||
| { | |||
| loadResources( zipFile, url ); | |||
| } | |||
| catch( final DeploymentException de ) | |||
| { | |||
| throw de; | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Error deploying library", e ); | |||
| } | |||
| finally | |||
| { | |||
| try { zipFile.close(); } | |||
| catch( final IOException ioe ) {} | |||
| } | |||
| } | |||
| private void loadResources( final ZipFile zipFile, final URL url ) | |||
| throws Exception | |||
| { | |||
| final Configuration taskdefs = getDescriptor( zipFile ); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( new URL[] { url } ); | |||
| try | |||
| { | |||
| final Configuration[] tasks = taskdefs.getChildren( "task" ); | |||
| for( int i = 0; i < tasks.length; i++ ) | |||
| { | |||
| handleTask( tasks[ i ], url, factory ); | |||
| } | |||
| final Configuration[] converters = taskdefs.getChildren( "converter" ); | |||
| for( int i = 0; i < converters.length; i++ ) | |||
| { | |||
| handleConverter( converters[ i ], url, factory ); | |||
| } | |||
| final Configuration[] datatypes = taskdefs.getChildren( "datatype" ); | |||
| for( int i = 0; i < datatypes.length; i++ ) | |||
| { | |||
| handleDataType( datatypes[ i ], url, factory ); | |||
| } | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| } | |||
| public void deployConverter( final String name, final File file ) | |||
| throws DeploymentException | |||
| { | |||
| final ZipFile zipFile = getZipFileFor( file ); | |||
| final Configuration taskdefs = getDescriptor( zipFile ); | |||
| try | |||
| { | |||
| final Configuration[] converters = taskdefs.getChildren( "converter" ); | |||
| for( int i = 0; i < converters.length; i++ ) | |||
| { | |||
| if( converters[ i ].getAttribute( "classname" ).equals( name ) ) | |||
| { | |||
| final URL url = getURL( file ); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( new URL[] { url } ); | |||
| handleConverter( converters[ i ], url, factory ); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Failed to deploy " + name, e ); | |||
| } | |||
| } | |||
| public void deployDataType( final String name, final File file ) | |||
| throws DeploymentException | |||
| { | |||
| final ZipFile zipFile = getZipFileFor( file ); | |||
| final Configuration datatypedefs = getDescriptor( zipFile ); | |||
| try | |||
| { | |||
| final Configuration[] datatypes = datatypedefs.getChildren( "datatype" ); | |||
| for( int i = 0; i < datatypes.length; i++ ) | |||
| { | |||
| if( datatypes[ i ].getAttribute( "name" ).equals( name ) ) | |||
| { | |||
| final URL url = getURL( file ); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( new URL[] { url } ); | |||
| handleDataType( datatypes[ i ], url, factory ); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Failed to deploy " + name, e ); | |||
| } | |||
| } | |||
| public void deployTask( final String name, final File file ) | |||
| throws DeploymentException | |||
| { | |||
| final ZipFile zipFile = getZipFileFor( file ); | |||
| final Configuration taskdefs = getDescriptor( zipFile ); | |||
| try | |||
| { | |||
| final Configuration[] tasks = taskdefs.getChildren( "task" ); | |||
| for( int i = 0; i < tasks.length; i++ ) | |||
| { | |||
| if( tasks[ i ].getAttribute( "name" ).equals( name ) ) | |||
| { | |||
| final URL url = getURL( file ); | |||
| final DefaultTypeFactory factory = new DefaultTypeFactory( new URL[] { url } ); | |||
| handleTask( tasks[ i ], url, factory ); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Malformed taskdefs.xml", ce ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new DeploymentException( "Failed to deploy " + name, e ); | |||
| } | |||
| } | |||
| /** | |||
| * Retrieve zip file for file. | |||
| * | |||
| * @param file the file | |||
| * @return the zipFile | |||
| * @exception DeploymentException if an error occurs | |||
| */ | |||
| private ZipFile getZipFileFor( final File file ) | |||
| throws DeploymentException | |||
| { | |||
| try { return new ZipFile( file ); } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new DeploymentException( "Error opening " + file + | |||
| " due to " + ioe.getMessage(), | |||
| ioe ); | |||
| } | |||
| } | |||
| /** | |||
| * Utility method to load configuration from zip. | |||
| * | |||
| * @param zipFile the zip file | |||
| * @param filename the property filename | |||
| * @return the Configuration | |||
| * @exception DeploymentException if an error occurs | |||
| */ | |||
| private Configuration getDescriptor( final ZipFile zipFile ) | |||
| throws DeploymentException | |||
| { | |||
| return buildConfiguration( loadResourceStream( zipFile, TSKDEF_FILE ) ); | |||
| } | |||
| /** | |||
| * Build a configuration tree based on input stream. | |||
| * | |||
| * @param input the InputStream | |||
| * @return the Configuration tree | |||
| * @exception DeploymentException if an error occurs | |||
| */ | |||
| private Configuration buildConfiguration( final InputStream input ) | |||
| throws DeploymentException | |||
| { | |||
| try { return m_configurationBuilder.build( input ); } | |||
| catch( final SAXException se ) | |||
| { | |||
| throw new DeploymentException( "Malformed configuration data", se ); | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Error building configuration", ce ); | |||
| } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new DeploymentException( "Error reading configuration", ioe ); | |||
| } | |||
| } | |||
| private File getFileFor( final URL url ) | |||
| throws DeploymentException | |||
| { | |||
| File file = null; | |||
| if( url.getProtocol().equals( "file" ) ) | |||
| { | |||
| file = new File( url.getFile() ); | |||
| } | |||
| else | |||
| { | |||
| throw new DeploymentException( "Currently unable to deploy non-local " + | |||
| "archives (" + url + ")" ); | |||
| } | |||
| file = file.getAbsoluteFile(); | |||
| if( !file.exists() ) | |||
| { | |||
| throw new DeploymentException( "Could not find application archive at " + | |||
| file ); | |||
| } | |||
| if( file.isDirectory() ) | |||
| { | |||
| throw new DeploymentException( "Could not find application archive at " + | |||
| file + " as it is a directory." ); | |||
| } | |||
| return file; | |||
| } | |||
| private void handleConverter( final Configuration converter, | |||
| final URL url, | |||
| 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 ); | |||
| getLogger().debug( "Registered converter " + name + " that converts from " + | |||
| source + " to " + destination ); | |||
| } | |||
| private void handleTask( final Configuration task, | |||
| final URL url, | |||
| final DefaultTypeFactory factory ) | |||
| throws Exception | |||
| { | |||
| final String name = task.getAttribute( "name" ); | |||
| final String className = task.getAttribute( "classname" ); | |||
| factory.addNameClassMapping( name, className ); | |||
| m_typeManager.registerType( Task.ROLE, name, factory ); | |||
| getLogger().debug( "Registered task " + name + " as " + className ); | |||
| } | |||
| private void handleDataType( final Configuration datatype, | |||
| final URL url, | |||
| final DefaultTypeFactory factory ) | |||
| throws Exception | |||
| { | |||
| final String name = datatype.getAttribute( "name" ); | |||
| final String className = datatype.getAttribute( "classname" ); | |||
| factory.addNameClassMapping( name, className ); | |||
| m_typeManager.registerType( DataType.ROLE, name, factory ); | |||
| getLogger().debug( "Registered datatype " + name + " as " + className ); | |||
| } | |||
| /** | |||
| * Load a resource from a zip file. | |||
| * | |||
| * @param zipFile the ZipFile | |||
| * @param filename the filename | |||
| * @return the InputStream | |||
| * @exception DeploymentException if an error occurs | |||
| */ | |||
| private InputStream loadResourceStream( final ZipFile zipFile, final String filename ) | |||
| throws DeploymentException | |||
| { | |||
| final ZipEntry entry = zipFile.getEntry( filename ); | |||
| if( null == entry ) | |||
| { | |||
| throw new DeploymentException( "Unable to locate " + filename + | |||
| " in " + zipFile.getName() ); | |||
| } | |||
| try { return zipFile.getInputStream( entry ); } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new DeploymentException( "Error reading " + filename + | |||
| " from " + zipFile.getName(), | |||
| ioe ); | |||
| } | |||
| } | |||
| private URL getURL( final File file ) | |||
| throws DeploymentException | |||
| { | |||
| try { return file.toURL(); } | |||
| catch( final MalformedURLException mue ) | |||
| { | |||
| throw new DeploymentException( "Unable to form url", mue ); | |||
| } | |||
| } | |||
| } | |||
| @@ -15,10 +15,10 @@ import org.apache.avalon.framework.component.Component; | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public interface TskDeployer | |||
| public interface Deployer | |||
| extends Component | |||
| { | |||
| String ROLE = "org.apache.myrmidon.components.deployer.TskDeployer"; | |||
| String ROLE = "org.apache.myrmidon.components.deployer.Deployer"; | |||
| /** | |||
| * Deploy a library. | |||
| @@ -32,10 +32,7 @@ public interface TskDeployer | |||
| void deployConverter( String name, File file ) | |||
| throws DeploymentException; | |||
| void deployDataType( String name, File file ) | |||
| throws DeploymentException; | |||
| void deployTask( String name, File file ) | |||
| void deployType( String role, String name, File file ) | |||
| throws DeploymentException; | |||
| } | |||
| @@ -0,0 +1,84 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.components.deployer; | |||
| import java.io.File; | |||
| import java.net.URL; | |||
| import java.net.MalformedURLException; | |||
| import java.io.IOException; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; | |||
| import org.xml.sax.SAXException; | |||
| import org.xml.sax.InputSource; | |||
| /** | |||
| * This class deploys a .tsk file into a registry. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class Deployment | |||
| { | |||
| private final static String TSKDEF_FILE = "TASK-LIB/taskdefs.xml"; | |||
| private File m_file; | |||
| private Configuration m_descriptor; | |||
| public Deployment( final File file ) | |||
| { | |||
| m_file = file; | |||
| } | |||
| public Configuration getDescriptor() | |||
| throws DeploymentException | |||
| { | |||
| if( null == m_descriptor ) | |||
| { | |||
| m_descriptor = buildDescriptor(); | |||
| } | |||
| return m_descriptor; | |||
| } | |||
| public URL getURL() | |||
| throws DeploymentException | |||
| { | |||
| try { return m_file.toURL(); } | |||
| catch( final MalformedURLException mue ) | |||
| { | |||
| throw new DeploymentException( "Unable to form url", mue ); | |||
| } | |||
| } | |||
| private Configuration buildDescriptor() | |||
| throws DeploymentException | |||
| { | |||
| final String systemID = "jar:" + getURL() + "!/" + TSKDEF_FILE; | |||
| final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); | |||
| try | |||
| { | |||
| return builder.build( new InputSource( systemID ) ); | |||
| } | |||
| catch( final SAXException se ) | |||
| { | |||
| throw new DeploymentException( "Malformed configuration data", se ); | |||
| } | |||
| catch( final ConfigurationException ce ) | |||
| { | |||
| throw new DeploymentException( "Error building configuration", ce ); | |||
| } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new DeploymentException( "Error reading configuration", ioe ); | |||
| } | |||
| } | |||
| } | |||
| @@ -29,7 +29,7 @@ public interface RoleManager | |||
| * @param shorthandName the shorthand name | |||
| * @return the role | |||
| */ | |||
| String getRoleForName( String shorthandName ); | |||
| String getRoleForName( String name ); | |||
| /** | |||
| * Find name based on role. | |||
| @@ -23,7 +23,7 @@ import org.apache.avalon.framework.parameters.Parameters; | |||
| import org.apache.myrmidon.api.JavaVersion; | |||
| import org.apache.myrmidon.components.builder.ProjectBuilder; | |||
| import org.apache.myrmidon.components.configurer.Configurer; | |||
| import org.apache.myrmidon.components.deployer.TskDeployer; | |||
| import org.apache.myrmidon.components.deployer.Deployer; | |||
| import org.apache.myrmidon.components.deployer.RoleManager; | |||
| import org.apache.myrmidon.components.deployer.DeploymentException; | |||
| import org.apache.myrmidon.components.executor.Executor; | |||
| @@ -42,7 +42,7 @@ public class MyrmidonEmbeddor | |||
| { | |||
| private ProjectManager m_projectManager; | |||
| private ProjectBuilder m_builder; | |||
| private TskDeployer m_deployer; | |||
| private Deployer m_deployer; | |||
| private RoleManager m_roleManager; | |||
| private TypeManager m_typeManager; | |||
| @@ -182,8 +182,8 @@ public class MyrmidonEmbeddor | |||
| "org.apache.myrmidon.components.manager.DefaultProjectManager" ); | |||
| defaults.setParameter( ProjectBuilder.ROLE, | |||
| "org.apache.myrmidon.components.builder.DefaultProjectBuilder" ); | |||
| defaults.setParameter( TskDeployer.ROLE, | |||
| "org.apache.myrmidon.components.deployer.DefaultTskDeployer" ); | |||
| defaults.setParameter( Deployer.ROLE, | |||
| "org.apache.myrmidon.components.deployer.DefaultDeployer" ); | |||
| defaults.setParameter( Configurer.ROLE, | |||
| "org.apache.myrmidon.components.configurer.DefaultConfigurer" ); | |||
| @@ -207,7 +207,7 @@ public class MyrmidonEmbeddor | |||
| //Following components required when Myrmidon allows user deployment of tasks etal. | |||
| componentManager.put( RoleManager.ROLE, m_roleManager ); | |||
| componentManager.put( TskDeployer.ROLE, m_deployer ); | |||
| componentManager.put( Deployer.ROLE, m_deployer ); | |||
| //Following components used when want to types (ie tasks/mappers etc) | |||
| componentManager.put( TypeManager.ROLE, m_typeManager ); | |||
| @@ -245,8 +245,8 @@ public class MyrmidonEmbeddor | |||
| component = getParameter( RoleManager.ROLE ); | |||
| m_roleManager = (RoleManager)createComponent( component, RoleManager.class ); | |||
| component = getParameter( TskDeployer.ROLE ); | |||
| m_deployer = (TskDeployer)createComponent( component, TskDeployer.class ); | |||
| component = getParameter( Deployer.ROLE ); | |||
| m_deployer = (Deployer)createComponent( component, Deployer.class ); | |||
| component = getParameter( Executor.ROLE ); | |||
| m_executor = (Executor)createComponent( component, Executor.class ); | |||
| @@ -433,7 +433,7 @@ public class MyrmidonEmbeddor | |||
| } | |||
| private void deployFromDirectory( final TskDeployer deployer, | |||
| private void deployFromDirectory( final Deployer deployer, | |||
| final File directory, | |||
| final FilenameFilter filter ) | |||
| throws DeploymentException | |||
| @@ -446,7 +446,7 @@ public class MyrmidonEmbeddor | |||
| } | |||
| } | |||
| private void deployFiles( final TskDeployer deployer, final File[] files ) | |||
| private void deployFiles( final Deployer deployer, final File[] files ) | |||
| throws DeploymentException | |||
| { | |||
| for( int i = 0; i < files.length; i++ ) | |||
| @@ -32,6 +32,11 @@ public class DefaultTypeFactory | |||
| ///The parent classLoader (if any) | |||
| private ClassLoader m_classLoader; | |||
| public DefaultTypeFactory( final URL url ) | |||
| { | |||
| this( new URL[] { url } ); | |||
| } | |||
| public DefaultTypeFactory( final URL[] urls ) | |||
| { | |||
| this( urls, Thread.currentThread().getContextClassLoader() ); | |||
| @@ -0,0 +1,138 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.framework; | |||
| import org.apache.avalon.framework.component.ComponentException; | |||
| import org.apache.avalon.framework.component.ComponentManager; | |||
| import org.apache.avalon.framework.component.Composable; | |||
| import org.apache.avalon.framework.configuration.Configuration; | |||
| import org.apache.avalon.framework.configuration.ConfigurationException; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.converter.Converter; | |||
| import org.apache.myrmidon.converter.ConverterException; | |||
| import org.apache.myrmidon.components.configurer.Configurer; | |||
| import org.apache.myrmidon.components.converter.MasterConverter; | |||
| import org.apache.myrmidon.components.executor.Executor; | |||
| /** | |||
| * This is the class that Task writers should extend to provide custom tasks. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public abstract class AbstractContainerTask | |||
| extends AbstractTask | |||
| { | |||
| ///For converting own attributes | |||
| private MasterConverter m_converter; | |||
| ///For configuring own sub-elements | |||
| private Configurer m_configurer; | |||
| ///For executing sub-elements as tasks | |||
| private Executor m_executor; | |||
| public void compose( final ComponentManager componentManager ) | |||
| throws ComponentException | |||
| { | |||
| m_configurer = (Configurer)componentManager.lookup( Configurer.ROLE ); | |||
| m_converter = (MasterConverter)componentManager.lookup( MasterConverter.ROLE ); | |||
| m_executor = (Executor)componentManager.lookup( Executor.ROLE ); | |||
| } | |||
| /** | |||
| * Helper method to resolve a string. | |||
| * | |||
| * @param value the value to resolve | |||
| * @return the resolved value | |||
| * @exception ConfigurationException if an error occurs | |||
| */ | |||
| protected final Object resolve( final String value ) | |||
| throws ConfigurationException | |||
| { | |||
| try | |||
| { | |||
| final Object object = getContext().resolveValue( value ); | |||
| if( null == object ) | |||
| { | |||
| throw new ConfigurationException( "Value (" + value + | |||
| ") resolved to null" ); | |||
| } | |||
| return object; | |||
| } | |||
| catch( final TaskException te ) | |||
| { | |||
| throw new ConfigurationException( "Error resolving value: " + value, te ); | |||
| } | |||
| } | |||
| /** | |||
| * Helper method to convert an object to a specific type. | |||
| * | |||
| * @param to type to convert object to | |||
| * @param object the object to convert | |||
| * @return the converted object | |||
| * @exception ConfigurationException if an error occurs | |||
| */ | |||
| protected final Object convert( final Class to, final Object object ) | |||
| throws ConfigurationException | |||
| { | |||
| try | |||
| { | |||
| return getConverter().convert( to, object, getContext() ); | |||
| } | |||
| catch( final ConverterException ce ) | |||
| { | |||
| throw new ConfigurationException( "Error converting value", ce ); | |||
| } | |||
| } | |||
| /** | |||
| * Configure a value using specific configuration element. | |||
| * | |||
| * @param child the child | |||
| * @param element the configuration element | |||
| */ | |||
| protected final void configure( final Object value, final Configuration element ) | |||
| throws ConfigurationException | |||
| { | |||
| getConfigurer().configure( value, element, getContext() ); | |||
| } | |||
| /** | |||
| * Convenience method for sub-class to retrieve Configurer. | |||
| * | |||
| * @return the configurer | |||
| */ | |||
| protected final Configurer getConfigurer() | |||
| { | |||
| return m_configurer; | |||
| } | |||
| /** | |||
| * Convenience method for sub-class to retrieve Converter. | |||
| * | |||
| * @return the converter | |||
| */ | |||
| protected final Converter getConverter() | |||
| { | |||
| return m_converter; | |||
| } | |||
| /** | |||
| * Convenience method for sub-class to retrieve Executor. | |||
| * | |||
| * @return the executor | |||
| */ | |||
| protected final Executor getExecutor() | |||
| { | |||
| return m_executor; | |||
| } | |||
| } | |||