* Got rid of <converters> element from antlib descriptor. Converters are now defined in the <types> element. * Moved (most of) the role-specific knowledge from Deployment back to DefaultDeployer. * Split out ClassLoader management into DefaultClassLoaderManager. This is living in the deployer package for now. * Tidied-up the component set-up and clean-up in DefaultEmbeddor. Added the ClassLoaderManager component. * Added test for TypeDeployer.deployAll(). Changes to unit tests: * Added AbstractMyrmidonTest, which takes care of locating test resources. * Changed the VFS, type factory, and deployer tests to use AbstractMyrmidonTest. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271271 13f79535-47bb-0310-9956-ffa450edef68master
@@ -416,20 +416,35 @@ Legal: | |||||
<classpath refid="project.class.path"/> | <classpath refid="project.class.path"/> | ||||
</javac> | </javac> | ||||
<property name="test.local.dir" location="${test.working.dir}/localfs"/> | |||||
<property name="test.zip.file" location="${test.working.dir}/zipfs/test.zip"/> | |||||
<!-- Prepare test files --> | <!-- Prepare test files --> | ||||
<delete dir="${test.working.dir}"/> | <delete dir="${test.working.dir}"/> | ||||
<copy todir="${test.local.dir}/read-tests"> | |||||
<fileset dir="etc/testcases/org/apache/aut/vfs/basedir"/> | |||||
<copy todir="${test.working.dir}"> | |||||
<fileset dir="etc/testcases"/> | |||||
</copy> | </copy> | ||||
<mkdir dir="${test.local.dir}/read-tests/emptydir"/> | |||||
<mkdir dir="${test.working.dir}/zipfs"/> | |||||
<zip zipfile="${test.zip.file}"> | |||||
<zipfileset dir="${test.local.dir}/read-tests" prefix="/basedir"/> | |||||
<!-- Prepare the VFS tests --> | |||||
<property name="test.vfs.dir" location="${test.working.dir}/org/apache/aut/vfs"/> | |||||
<mkdir dir="${test.vfs.dir}/basedir/emptydir"/> | |||||
<zip zipfile="${test.vfs.dir}/test.zip"> | |||||
<fileset dir="${test.vfs.dir}" includes="basedir/**"/> | |||||
</zip> | </zip> | ||||
<!-- Prepare deployer tests --> | |||||
<property name="test.deployer.dir" | |||||
value="${test.working.dir}/org/apache/myrmidon/components/deployer"/> | |||||
<mkdir dir="${test.deployer.dir}"/> | |||||
<jar jarfile="${test.deployer.dir}/test.atl"> | |||||
<zipfileset dir="etc/testcases/org/apache/myrmidon/components/deployer" | |||||
prefix="META-INF" | |||||
includes="*.xml"/> | |||||
</jar> | |||||
<!-- Prepare type factory tests --> | |||||
<mkdir dir="${test.working.dir}/org/apache/myrmidon/interfaces/type"/> | |||||
<jar jarfile="${test.working.dir}/org/apache/myrmidon/interfaces/type/types.jar"> | |||||
<fileset dir="${test.classes}" includes="org/apache/myrmidon/interfaces/type/MyType1.class"/> | |||||
</jar> | |||||
<junit printsummary="on" | <junit printsummary="on" | ||||
fork="true"> | fork="true"> | ||||
<formatter type="brief" usefile="false"/> | <formatter type="brief" usefile="false"/> | ||||
@@ -437,8 +452,7 @@ Legal: | |||||
<classpath location="${test.classes}"/> | <classpath location="${test.classes}"/> | ||||
<!-- Pass config to the tests --> | <!-- Pass config to the tests --> | ||||
<sysproperty key="test.local.dir" value="${test.local.dir}"/> | |||||
<sysproperty key="test.zip.file" value="${test.zip.file}"/> | |||||
<sysproperty key="test.basedir" value="${test.working.dir}"/> | |||||
<sysproperty key="test.smb.uri" value="smb://${vfs.user}:${vfs.password}@${vfs.host}/${vfs.user}/vfs"/> | <sysproperty key="test.smb.uri" value="smb://${vfs.user}:${vfs.password}@${vfs.host}/${vfs.user}/vfs"/> | ||||
<sysproperty key="test.ftp.uri" value="ftp://${vfs.user}:${vfs.password}@${vfs.host}/home/${vfs.user}/vfs"/> | <sysproperty key="test.ftp.uri" value="ftp://${vfs.user}:${vfs.password}@${vfs.host}/home/${vfs.user}/vfs"/> | ||||
@@ -0,0 +1,18 @@ | |||||
<antlib> | |||||
<types> | |||||
<!-- Register a data-type --> | |||||
<data-type name="test-type1" | |||||
classname="org.apache.myrmidon.components.deployer.TestType1"/> | |||||
<!-- Register a custom role implementation --> | |||||
<test-role1 name="test-type1" | |||||
classname="org.apache.myrmidon.components.deployer.TestType1"/> | |||||
<!-- Register a converter --> | |||||
<converter classname="org.apache.myrmidon.components.deployer.TestConverter1" | |||||
source="java.lang.String" | |||||
destination="org.apache.myrmidon.components.deployer.TestType1"/> | |||||
</types> | |||||
</antlib> |
@@ -0,0 +1,4 @@ | |||||
<roles> | |||||
<!-- A custom role --> | |||||
<role shorthand="test-role1" name="org.apache.myrmidon.components.deployer.TestRole1"/> | |||||
</roles> |
@@ -0,0 +1,28 @@ | |||||
/* | |||||
* 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.components.deployer; | |||||
import java.io.File; | |||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | |||||
import org.apache.avalon.framework.component.Component; | |||||
/** | |||||
* Manages a classloader hierarchy. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public interface ClassLoaderManager | |||||
extends Component | |||||
{ | |||||
String ROLE = ClassLoaderManager.class.getName(); | |||||
/** | |||||
* Builds the ClassLoader for a Jar file. | |||||
*/ | |||||
ClassLoader createClassLoader( File jar ) throws DeploymentException; | |||||
} |
@@ -0,0 +1,209 @@ | |||||
/* | |||||
* 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.components.deployer; | |||||
import java.io.File; | |||||
import java.net.JarURLConnection; | |||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | |||||
import java.net.URLClassLoader; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.jar.Manifest; | |||||
import org.apache.avalon.excalibur.extension.Extension; | |||||
import org.apache.avalon.excalibur.extension.OptionalPackage; | |||||
import org.apache.avalon.excalibur.extension.PackageManager; | |||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||||
import org.apache.avalon.excalibur.i18n.Resources; | |||||
import org.apache.avalon.framework.activity.Initializable; | |||||
import org.apache.avalon.framework.component.ComponentException; | |||||
import org.apache.avalon.framework.component.ComponentManager; | |||||
import org.apache.avalon.framework.component.Composable; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | |||||
import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | |||||
/** | |||||
* A default implementation of a classloader manager. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public class DefaultClassLoaderManager | |||||
extends AbstractLogEnabled | |||||
implements ClassLoaderManager, Composable, Initializable | |||||
{ | |||||
private final static Resources REZ = | |||||
ResourceManager.getPackageResources( DefaultClassLoaderManager.class ); | |||||
/** | |||||
* Map from File to the ClassLoader for that file. | |||||
*/ | |||||
private final Map m_fileDeployers = new HashMap(); | |||||
private PackageManager m_packageManager; | |||||
private ClassLoader m_baseClassLoader; | |||||
public void initialize() throws Exception | |||||
{ | |||||
if( m_baseClassLoader == null ) | |||||
{ | |||||
m_baseClassLoader = Thread.currentThread().getContextClassLoader(); | |||||
} | |||||
} | |||||
/** | |||||
* Sets the ClassLoader to use as the parent for all classloaders | |||||
* created by this ClassLoader manager. | |||||
*/ | |||||
public void setBaseClassLoader( final ClassLoader classLoader ) | |||||
{ | |||||
m_baseClassLoader = classLoader; | |||||
} | |||||
/** | |||||
* Retrieve relevent services needed to deploy. | |||||
*/ | |||||
public void compose( final ComponentManager componentManager ) | |||||
throws ComponentException | |||||
{ | |||||
final ExtensionManager extensionManager = | |||||
(ExtensionManager)componentManager.lookup( ExtensionManager.ROLE ); | |||||
m_packageManager = new PackageManager( extensionManager ); | |||||
} | |||||
/** | |||||
* Creates a class loader for a Jar file. | |||||
*/ | |||||
public ClassLoader createClassLoader( File file ) throws DeploymentException | |||||
{ | |||||
try | |||||
{ | |||||
final File canonFile = file.getCanonicalFile(); | |||||
// Locate cached classloader, creating it if necessary | |||||
URLClassLoader classLoader = (URLClassLoader)m_fileDeployers.get( canonFile ); | |||||
if( classLoader == null ) | |||||
{ | |||||
checkFile( canonFile ); | |||||
final File[] extensions = getOptionalPackagesFor( canonFile ); | |||||
final URL[] urls = buildClasspath( canonFile, extensions ); | |||||
classLoader = new URLClassLoader( urls, m_baseClassLoader ); | |||||
m_fileDeployers.put( canonFile, classLoader ); | |||||
} | |||||
return classLoader; | |||||
} | |||||
catch( Exception e ) | |||||
{ | |||||
final String message = REZ.getString( "create-classloader-for-file.error", file ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
} | |||||
/** | |||||
* Assembles a set of files into a URL classpath. | |||||
*/ | |||||
private URL[] buildClasspath( final File file, final File[] dependencies ) | |||||
throws MalformedURLException | |||||
{ | |||||
final URL[] urls = new URL[ dependencies.length + 1 ]; | |||||
for( int i = 0; i < dependencies.length; i++ ) | |||||
{ | |||||
urls[ i ] = dependencies[ i ].toURL(); | |||||
} | |||||
urls[ dependencies.length ] = file.toURL(); | |||||
return urls; | |||||
} | |||||
/** | |||||
* Retrieve the files for the optional packages required by | |||||
* the specified typeLibrary jar. | |||||
* | |||||
* @param typeLibrary the typeLibrary | |||||
* @return the files that need to be added to ClassLoader | |||||
*/ | |||||
private File[] getOptionalPackagesFor( final File typeLibrary ) | |||||
throws Exception | |||||
{ | |||||
final URL url = new URL( "jar:" + typeLibrary.getCanonicalFile().toURL() + "!/" ); | |||||
final JarURLConnection connection = (JarURLConnection)url.openConnection(); | |||||
final Manifest manifest = connection.getManifest(); | |||||
final Extension[] available = Extension.getAvailable( manifest ); | |||||
final Extension[] required = Extension.getRequired( manifest ); | |||||
if( getLogger().isDebugEnabled() ) | |||||
{ | |||||
final String message1 = | |||||
REZ.getString( "available-extensions.notice", Arrays.asList( available ) ); | |||||
getLogger().debug( message1 ); | |||||
final String message2 = | |||||
REZ.getString( "required-extensions.notice", Arrays.asList( required ) ); | |||||
getLogger().debug( message2 ); | |||||
} | |||||
final ArrayList dependencies = new ArrayList(); | |||||
final ArrayList unsatisfied = new ArrayList(); | |||||
m_packageManager.scanDependencies( required, | |||||
available, | |||||
dependencies, | |||||
unsatisfied ); | |||||
if( 0 != unsatisfied.size() ) | |||||
{ | |||||
final int size = unsatisfied.size(); | |||||
for( int i = 0; i < size; i++ ) | |||||
{ | |||||
final Extension extension = (Extension)unsatisfied.get( i ); | |||||
final Object[] params = new Object[] | |||||
{ | |||||
extension.getExtensionName(), | |||||
extension.getSpecificationVendor(), | |||||
extension.getSpecificationVersion(), | |||||
extension.getImplementationVendor(), | |||||
extension.getImplementationVendorId(), | |||||
extension.getImplementationVersion(), | |||||
extension.getImplementationURL() | |||||
}; | |||||
final String message = REZ.format( "missing.extension", params ); | |||||
getLogger().warn( message ); | |||||
} | |||||
final String message = | |||||
REZ.getString( "unsatisfied.extensions.error", new Integer( size ) ); | |||||
throw new Exception( message ); | |||||
} | |||||
final OptionalPackage[] packages = | |||||
(OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] ); | |||||
return OptionalPackage.toFiles( packages ); | |||||
} | |||||
/** | |||||
* Ensures a file exists and is not a directory. | |||||
*/ | |||||
private void checkFile( final File file ) | |||||
throws DeploymentException | |||||
{ | |||||
if( !file.exists() ) | |||||
{ | |||||
final String message = REZ.getString( "no-file.error", file ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
if( file.isDirectory() ) | |||||
{ | |||||
final String message = REZ.getString( "file-is-dir.error", file ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
} | |||||
} |
@@ -8,31 +8,30 @@ | |||||
package org.apache.myrmidon.components.deployer; | package org.apache.myrmidon.components.deployer; | ||||
import java.io.File; | import java.io.File; | ||||
import java.net.JarURLConnection; | |||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | import java.net.URL; | ||||
import java.net.URLClassLoader; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.jar.Manifest; | |||||
import org.apache.avalon.excalibur.extension.Extension; | |||||
import org.apache.avalon.excalibur.extension.OptionalPackage; | |||||
import org.apache.avalon.excalibur.extension.PackageManager; | |||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.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.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.logger.AbstractLogEnabled; | import org.apache.avalon.framework.logger.AbstractLogEnabled; | ||||
import org.apache.avalon.framework.configuration.Configuration; | |||||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||||
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.deployer.TypeDeployer; | ||||
import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | |||||
import org.apache.myrmidon.interfaces.deployer.TypeDefinition; | |||||
import org.apache.myrmidon.interfaces.deployer.ConverterDefinition; | |||||
import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | |||||
import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | |||||
import org.apache.myrmidon.interfaces.role.RoleManager; | |||||
import org.apache.myrmidon.converter.Converter; | |||||
/** | /** | ||||
* This class deploys a .tsk file into a registry. | |||||
* This class deploys roles, types and services from a typelib. | |||||
* | * | ||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
@@ -44,34 +43,15 @@ public class DefaultDeployer | |||||
private final static Resources REZ = | private final static Resources REZ = | ||||
ResourceManager.getPackageResources( DefaultDeployer.class ); | ResourceManager.getPackageResources( DefaultDeployer.class ); | ||||
private Deployer m_parent; | |||||
private ComponentManager m_componentManager; | |||||
private PackageManager m_packageManager; | |||||
// The components used to deploy | |||||
private ConverterRegistry m_converterRegistry; | |||||
private TypeManager m_typeManager; | |||||
private RoleManager m_roleManager; | |||||
private ClassLoaderManager m_classLoaderManager; | |||||
/** Map from ClassLoader to the deployer for that class loader. */ | /** Map from ClassLoader to the deployer for that class loader. */ | ||||
private final Map m_classLoaderDeployers = new HashMap(); | private final 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 final Map m_fileDeployers; | |||||
/** | |||||
* Creates a root deployer. | |||||
*/ | |||||
public DefaultDeployer() | |||||
{ | |||||
m_fileDeployers = new HashMap(); | |||||
} | |||||
private DefaultDeployer( final DefaultDeployer parent ) | |||||
{ | |||||
m_parent = parent; | |||||
m_fileDeployers = new HashMap(); | |||||
m_fileDeployers.putAll( parent.m_fileDeployers ); | |||||
} | |||||
/** | /** | ||||
* Retrieve relevent services needed to deploy. | * Retrieve relevent services needed to deploy. | ||||
* | * | ||||
@@ -81,10 +61,10 @@ public class DefaultDeployer | |||||
public void compose( final ComponentManager componentManager ) | public void compose( final ComponentManager componentManager ) | ||||
throws ComponentException | throws ComponentException | ||||
{ | { | ||||
m_componentManager = componentManager; | |||||
final ExtensionManager extensionManager = | |||||
(ExtensionManager)componentManager.lookup( ExtensionManager.ROLE ); | |||||
m_packageManager = new PackageManager( extensionManager ); | |||||
m_converterRegistry = (ConverterRegistry)componentManager.lookup( ConverterRegistry.ROLE ); | |||||
m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||||
m_roleManager = (RoleManager)componentManager.lookup( RoleManager.ROLE ); | |||||
m_classLoaderManager = (ClassLoaderManager)componentManager.lookup( ClassLoaderManager.ROLE ); | |||||
} | } | ||||
/** | /** | ||||
@@ -93,7 +73,7 @@ public class DefaultDeployer | |||||
public Deployer createChildDeployer( ComponentManager componentManager ) | public Deployer createChildDeployer( ComponentManager componentManager ) | ||||
throws ComponentException | throws ComponentException | ||||
{ | { | ||||
final DefaultDeployer child = new DefaultDeployer( this ); | |||||
final DefaultDeployer child = new DefaultDeployer( ); | |||||
setupLogger( child ); | setupLogger( child ); | ||||
child.compose( componentManager ); | child.compose( componentManager ); | ||||
return child; | return child; | ||||
@@ -126,7 +106,7 @@ public class DefaultDeployer | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
final URLClassLoader classLoader = getClassLoaderForFile( file ); | |||||
final ClassLoader classLoader = m_classLoaderManager.createClassLoader( file ); | |||||
return createDeployment( classLoader, file.toURL() ); | return createDeployment( classLoader, file.toURL() ); | ||||
} | } | ||||
catch( Exception e ) | catch( Exception e ) | ||||
@@ -136,27 +116,6 @@ public class DefaultDeployer | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Locates the classloader for a typelib file. | |||||
*/ | |||||
private URLClassLoader getClassLoaderForFile( final File file ) | |||||
throws Exception | |||||
{ | |||||
final File canonFile = file.getCanonicalFile(); | |||||
// Locate cached classloader, creating it if necessary | |||||
URLClassLoader classLoader = (URLClassLoader)m_fileDeployers.get( canonFile ); | |||||
if( classLoader == null ) | |||||
{ | |||||
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 ); | |||||
} | |||||
return classLoader; | |||||
} | |||||
/** | /** | ||||
* Creates a deployer for a ClassLoader. | * Creates a deployer for a ClassLoader. | ||||
*/ | */ | ||||
@@ -168,7 +127,7 @@ public class DefaultDeployer | |||||
Deployment deployment = (Deployment)m_classLoaderDeployers.get( loader ); | Deployment deployment = (Deployment)m_classLoaderDeployers.get( loader ); | ||||
if( deployment == null ) | if( deployment == null ) | ||||
{ | { | ||||
deployment = new Deployment( loader, m_componentManager ); | |||||
deployment = new Deployment( this, loader ); | |||||
setupLogger( deployment ); | setupLogger( deployment ); | ||||
deployment.loadDescriptors( jarUrl ); | deployment.loadDescriptors( jarUrl ); | ||||
m_classLoaderDeployers.put( loader, deployment ); | m_classLoaderDeployers.put( loader, deployment ); | ||||
@@ -177,102 +136,165 @@ public class DefaultDeployer | |||||
return deployment; | return deployment; | ||||
} | } | ||||
private URL[] buildClasspath( final File file, final File[] dependencies ) | |||||
throws MalformedURLException | |||||
/** | |||||
* Creates a type definition. | |||||
*/ | |||||
public TypeDefinition createTypeDefinition( final Configuration configuration ) | |||||
throws ConfigurationException | |||||
{ | { | ||||
final URL[] urls = new URL[ dependencies.length + 1 ]; | |||||
for( int i = 0; i < dependencies.length; i++ ) | |||||
final String converterShorthand = m_roleManager.getNameForRole( Converter.ROLE ); | |||||
final String roleShorthand = configuration.getName(); | |||||
if( roleShorthand.equals( converterShorthand ) ) | |||||
{ | { | ||||
urls[ i ] = dependencies[ i ].toURL(); | |||||
// A converter definition | |||||
final String className = configuration.getAttribute( "classname" ); | |||||
final String source = configuration.getAttribute( "source" ); | |||||
final String destination = configuration.getAttribute( "destination" ); | |||||
return new ConverterDefinition( className, source, destination ); | |||||
} | |||||
else | |||||
{ | |||||
// A type definition | |||||
final String typeName = configuration.getAttribute( "name" ); | |||||
final String className = configuration.getAttribute( "classname" ); | |||||
return new TypeDefinition( typeName, roleShorthand, className ); | |||||
} | } | ||||
urls[ dependencies.length ] = file.toURL(); | |||||
return urls; | |||||
} | } | ||||
/** | /** | ||||
* Retrieve the files for the optional packages required by | |||||
* the specified typeLibrary jar. | |||||
* | |||||
* @param typeLibrary the typeLibrary | |||||
* @return the files that need to be added to ClassLoader | |||||
* Handles a converter definition. | |||||
*/ | */ | ||||
private File[] getOptionalPackagesFor( final File typeLibrary ) | |||||
private void handleConverter( final Deployment deployment, | |||||
final String className, | |||||
final String source, | |||||
final String destination ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
final URL url = new URL( "jar:" + typeLibrary.getCanonicalFile().toURL() + "!/" ); | |||||
final JarURLConnection connection = (JarURLConnection)url.openConnection(); | |||||
final Manifest manifest = connection.getManifest(); | |||||
final Extension[] available = Extension.getAvailable( manifest ); | |||||
final Extension[] required = Extension.getRequired( manifest ); | |||||
m_converterRegistry.registerConverter( className, source, destination ); | |||||
final DefaultTypeFactory factory = deployment.getFactory( Converter.class ); | |||||
factory.addNameClassMapping( className, className ); | |||||
m_typeManager.registerType( Converter.class, className, factory ); | |||||
if( getLogger().isDebugEnabled() ) | if( getLogger().isDebugEnabled() ) | ||||
{ | { | ||||
final String message1 = | |||||
REZ.getString( "available-extensions.notice", Arrays.asList( available ) ); | |||||
getLogger().debug( message1 ); | |||||
final String message2 = | |||||
REZ.getString( "required-extensions.notice", Arrays.asList( required ) ); | |||||
getLogger().debug( message2 ); | |||||
final String message = | |||||
REZ.getString( "register-converter.notice", source, destination ); | |||||
getLogger().debug( message ); | |||||
} | } | ||||
} | |||||
/** | |||||
* Handles a type definition. | |||||
*/ | |||||
public void handleType( final Deployment deployment, | |||||
final TypeDefinition typeDef ) | |||||
throws Exception | |||||
{ | |||||
final String typeName = typeDef.getName(); | |||||
final String roleShorthand = typeDef.getRole(); | |||||
final ArrayList dependencies = new ArrayList(); | |||||
final ArrayList unsatisfied = new ArrayList(); | |||||
final String className = typeDef.getClassname(); | |||||
if( null == className ) | |||||
{ | |||||
final String message = REZ.getString( "typedef.no-classname.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
m_packageManager.scanDependencies( required, | |||||
available, | |||||
dependencies, | |||||
unsatisfied ); | |||||
if( typeDef instanceof ConverterDefinition ) | |||||
{ | |||||
// Validate the definition | |||||
final ConverterDefinition converterDef = (ConverterDefinition)typeDef; | |||||
final String srcClass = converterDef.getSourceType(); | |||||
final String destClass = converterDef.getDestinationType(); | |||||
if( null == srcClass ) | |||||
{ | |||||
final String message = REZ.getString( "converterdef.no-source.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
if( null == destClass ) | |||||
{ | |||||
final String message = REZ.getString( "converterdef.no-destination.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
if( 0 != unsatisfied.size() ) | |||||
// Deploy the converter | |||||
handleConverter( deployment, className, srcClass, destClass ); | |||||
} | |||||
else | |||||
{ | { | ||||
final int size = unsatisfied.size(); | |||||
for( int i = 0; i < size; i++ ) | |||||
// Validate the definition | |||||
if( null == roleShorthand ) | |||||
{ | |||||
final String message = REZ.getString( "typedef.no-role.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
else if( null == typeName ) | |||||
{ | { | ||||
final Extension extension = (Extension)unsatisfied.get( i ); | |||||
final Object[] params = new Object[] | |||||
{ | |||||
extension.getExtensionName(), | |||||
extension.getSpecificationVendor(), | |||||
extension.getSpecificationVersion(), | |||||
extension.getImplementationVendor(), | |||||
extension.getImplementationVendorId(), | |||||
extension.getImplementationVersion(), | |||||
extension.getImplementationURL() | |||||
}; | |||||
final String message = REZ.format( "missing.extension", params ); | |||||
getLogger().warn( message ); | |||||
final String message = REZ.getString( "typedef.no-name.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | } | ||||
final String message = | |||||
REZ.getString( "unsatisfied.extensions.error", new Integer( size ) ); | |||||
throw new Exception( message ); | |||||
// Deploy general-purpose type | |||||
handleType( deployment, roleShorthand, typeName, className ); | |||||
} | } | ||||
} | |||||
/** | |||||
* Handles a type definition. | |||||
*/ | |||||
private void handleType( final Deployment deployment, | |||||
final String roleShorthand, | |||||
final String typeName, | |||||
final String className ) | |||||
throws Exception | |||||
{ | |||||
// TODO - detect duplicates | |||||
final String role = getRoleForName( roleShorthand ); | |||||
final Class roleType = deployment.getClassLoader().loadClass( role ); | |||||
final DefaultTypeFactory factory = deployment.getFactory( roleType ); | |||||
factory.addNameClassMapping( typeName, className ); | |||||
m_typeManager.registerType( roleType, typeName, factory ); | |||||
final OptionalPackage[] packages = | |||||
(OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] ); | |||||
return OptionalPackage.toFiles( packages ); | |||||
if( getLogger().isDebugEnabled() ) | |||||
{ | |||||
final String message = | |||||
REZ.getString( "register-type.notice", roleShorthand, typeName ); | |||||
getLogger().debug( message ); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Ensures a file exists and is not a directory. | |||||
* Handles a role definition. | |||||
*/ | */ | ||||
private void checkFile( final File file ) | |||||
throws DeploymentException | |||||
public void handleRole( final Deployment deployment, | |||||
final RoleDefinition roleDef ) | |||||
{ | { | ||||
if( !file.exists() ) | |||||
final String name = roleDef.getShortHand(); | |||||
final String role = roleDef.getRoleName(); | |||||
m_roleManager.addNameRoleMapping( name, role ); | |||||
if( getLogger().isDebugEnabled() ) | |||||
{ | { | ||||
final String message = REZ.getString( "no-file.error", file ); | |||||
throw new DeploymentException( message ); | |||||
final String debugMessage = REZ.getString( "register-role.notice", role, name ); | |||||
getLogger().debug( debugMessage ); | |||||
} | } | ||||
} | |||||
/** | |||||
* Determines the role name from shorthand name. | |||||
*/ | |||||
private String getRoleForName( final String name ) | |||||
throws DeploymentException | |||||
{ | |||||
final String role = m_roleManager.getRoleForName( name ); | |||||
if( file.isDirectory() ) | |||||
if( null == role ) | |||||
{ | { | ||||
final String message = REZ.getString( "file-is-dir.error", file ); | |||||
final String message = REZ.getString( "unknown-role4name.error", name ); | |||||
throw new DeploymentException( message ); | throw new DeploymentException( message ); | ||||
} | } | ||||
return role; | |||||
} | } | ||||
} | } |
@@ -50,27 +50,20 @@ class Deployment | |||||
ResourceManager.getPackageResources( Deployment.class ); | ResourceManager.getPackageResources( Deployment.class ); | ||||
private 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 final static String ROLE_DESCRIPTOR_NAME = "META-INF/ant-roles.xml"; | |||||
private ClassLoader m_classLoader; | private ClassLoader m_classLoader; | ||||
private ConverterRegistry m_converterRegistry; | |||||
private TypeManager m_typeManager; | |||||
private RoleManager m_roleManager; | |||||
private DefaultDeployer m_deployer; | |||||
private String[] m_descriptorUrls; | private String[] m_descriptorUrls; | ||||
private Configuration[] m_descriptors; | private Configuration[] m_descriptors; | ||||
private DefaultTypeFactory m_converterFactory; | |||||
/** Map from role name -> DefaultTypeFactory for that role. */ | |||||
/** Map from role Class -> DefaultTypeFactory for that role. */ | |||||
private Map m_factories = new HashMap(); | private Map m_factories = new HashMap(); | ||||
public Deployment( final ClassLoader classLoader, ComponentManager manager ) | |||||
throws ComponentException | |||||
public Deployment( final DefaultDeployer deployer, final ClassLoader classLoader ) | |||||
{ | { | ||||
// Locate the various components needed | |||||
m_deployer = deployer; | |||||
m_classLoader = classLoader; | m_classLoader = classLoader; | ||||
m_converterRegistry = (ConverterRegistry)manager.lookup( ConverterRegistry.ROLE ); | |||||
m_typeManager = (TypeManager)manager.lookup( TypeManager.ROLE ); | |||||
m_roleManager = (RoleManager)manager.lookup( RoleManager.ROLE ); | |||||
} | } | ||||
/** | /** | ||||
@@ -94,7 +87,7 @@ class Deployment | |||||
parser.setErrorHandler( handler ); | parser.setErrorHandler( handler ); | ||||
// Load the role descriptors, and deploy all roles | // Load the role descriptors, and deploy all roles | ||||
final List roleUrls = locateResources( ROLE_DESCRIPTOR, jarUrl ); | |||||
final List roleUrls = locateResources( ROLE_DESCRIPTOR_NAME, jarUrl ); | |||||
for( Iterator iterator = roleUrls.iterator(); iterator.hasNext(); ) | for( Iterator iterator = roleUrls.iterator(); iterator.hasNext(); ) | ||||
{ | { | ||||
String url = (String)iterator.next(); | String url = (String)iterator.next(); | ||||
@@ -143,7 +136,7 @@ class Deployment | |||||
for( int i = 0; i < m_descriptors.length; i++ ) | for( int i = 0; i < m_descriptors.length; i++ ) | ||||
{ | { | ||||
Configuration descriptor = m_descriptors[ i ]; | Configuration descriptor = m_descriptors[ i ]; | ||||
deployFromDescriptor( descriptor, m_classLoader, m_descriptorUrls[ i ] ); | |||||
deployFromDescriptor( descriptor, m_descriptorUrls[ i ] ); | |||||
} | } | ||||
} | } | ||||
@@ -166,8 +159,8 @@ class Deployment | |||||
Configuration datatype = datatypes[ j ]; | Configuration datatype = datatypes[ j ]; | ||||
if( datatype.getAttribute( "name" ).equals( typeName ) ) | if( datatype.getAttribute( "name" ).equals( typeName ) ) | ||||
{ | { | ||||
final String className = datatype.getAttribute( "classname" ); | |||||
handleType( roleShorthand, typeName, className ); | |||||
final TypeDefinition typeDef = m_deployer.createTypeDefinition( datatype ); | |||||
m_deployer.handleType( this, typeDef ); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -187,53 +180,9 @@ class Deployment | |||||
{ | { | ||||
final String typeName = typeDef.getName(); | final String typeName = typeDef.getName(); | ||||
final String roleShorthand = typeDef.getRole(); | final String roleShorthand = typeDef.getRole(); | ||||
final String className = typeDef.getClassname(); | |||||
if( null == className ) | |||||
{ | |||||
final String message = REZ.getString( "typedef.no-classname.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
try | try | ||||
{ | { | ||||
if( typeDef instanceof ConverterDefinition ) | |||||
{ | |||||
// Validate the definition | |||||
final ConverterDefinition converterDef = (ConverterDefinition)typeDef; | |||||
final String srcClass = converterDef.getSourceType(); | |||||
final String destClass = converterDef.getDestinationType(); | |||||
if( null == srcClass ) | |||||
{ | |||||
final String message = REZ.getString( "converterdef.no-source.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
if( null == destClass ) | |||||
{ | |||||
final String message = REZ.getString( "converterdef.no-destination.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
// Deploy the converter | |||||
handleConverter( className, srcClass, destClass ); | |||||
} | |||||
else | |||||
{ | |||||
// Validate the definition | |||||
if( null == roleShorthand ) | |||||
{ | |||||
final String message = REZ.getString( "typedef.no-role.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
else if( null == typeName ) | |||||
{ | |||||
final String message = REZ.getString( "typedef.no-name.error" ); | |||||
throw new DeploymentException( message ); | |||||
} | |||||
// Deploy general-purpose type | |||||
handleType( roleShorthand, typeName, className ); | |||||
} | |||||
m_deployer.handleType( this, typeDef ); | |||||
} | } | ||||
catch( Exception e ) | catch( Exception e ) | ||||
{ | { | ||||
@@ -284,13 +233,8 @@ class Deployment | |||||
{ | { | ||||
final String name = types[ i ].getAttribute( "shorthand" ); | final String name = types[ i ].getAttribute( "shorthand" ); | ||||
final String role = types[ i ].getAttribute( "name" ); | 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 ); | |||||
} | |||||
final RoleDefinition roleDef = new RoleDefinition( role, name ); | |||||
m_deployer.handleRole( this, roleDef ); | |||||
} | } | ||||
} | } | ||||
@@ -298,7 +242,6 @@ class Deployment | |||||
* Deploys all types from a typelib descriptor. | * Deploys all types from a typelib descriptor. | ||||
*/ | */ | ||||
private void deployFromDescriptor( final Configuration descriptor, | private void deployFromDescriptor( final Configuration descriptor, | ||||
final ClassLoader classLoader, | |||||
final String url ) | final String url ) | ||||
throws DeploymentException | throws DeploymentException | ||||
{ | { | ||||
@@ -312,21 +255,8 @@ class Deployment | |||||
for( int i = 0; i < typeEntries.length; i++ ) | for( int i = 0; i < typeEntries.length; i++ ) | ||||
{ | { | ||||
final Configuration typeEntry = typeEntries[ 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 ); | |||||
final TypeDefinition typeDef = m_deployer.createTypeDefinition( typeEntry ); | |||||
m_deployer.handleType( this, typeDef ); | |||||
} | } | ||||
} | } | ||||
catch( final Exception e ) | catch( final Exception e ) | ||||
@@ -339,7 +269,7 @@ class Deployment | |||||
/** | /** | ||||
* Returns the type factory for a role. | * Returns the type factory for a role. | ||||
*/ | */ | ||||
private DefaultTypeFactory getFactory( final Class roleType ) | |||||
public DefaultTypeFactory getFactory( final Class roleType ) | |||||
{ | { | ||||
DefaultTypeFactory factory = (DefaultTypeFactory)m_factories.get( roleType ); | DefaultTypeFactory factory = (DefaultTypeFactory)m_factories.get( roleType ); | ||||
@@ -353,67 +283,10 @@ class Deployment | |||||
} | } | ||||
/** | /** | ||||
* 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. | |||||
* Returns the classloader for this deployment. | |||||
*/ | */ | ||||
private void handleType( final String roleShorthand, | |||||
final String typeName, | |||||
final String className ) | |||||
throws Exception | |||||
public ClassLoader getClassLoader() | |||||
{ | { | ||||
// 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; | |||||
return m_classLoader; | |||||
} | } | ||||
} | } |
@@ -21,3 +21,4 @@ converterdef.no-destination.error=Must specify the destination-type parameter. | |||||
available-extensions.notice=The list of available extensions for type library includes; {0} | 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} | required-extensions.notice=The list of required extensions for type library includes; {0} | ||||
unsatisfied.extensions.error=Missing {0} extensions for type library. | unsatisfied.extensions.error=Missing {0} extensions for type library. | ||||
create-classloader-for-file.error=Could not create ClassLoader for file {0}. |
@@ -0,0 +1,36 @@ | |||||
/* | |||||
* 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.components.deployer; | |||||
/** | |||||
* A role definition. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
class RoleDefinition | |||||
{ | |||||
private final String m_roleName; | |||||
private final String m_shortHand; | |||||
public RoleDefinition( final String roleName, | |||||
final String shortHand ) | |||||
{ | |||||
m_roleName = roleName; | |||||
m_shortHand = shortHand; | |||||
} | |||||
public String getRoleName() | |||||
{ | |||||
return m_roleName; | |||||
} | |||||
public String getShortHand() | |||||
{ | |||||
return m_shortHand; | |||||
} | |||||
} |
@@ -9,10 +9,14 @@ package org.apache.myrmidon.components.embeddor; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FilenameFilter; | import java.io.FilenameFilter; | ||||
import java.util.ArrayList; | |||||
import java.util.Iterator; | |||||
import java.util.List; | |||||
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.excalibur.io.ExtensionFileFilter; | import org.apache.avalon.excalibur.io.ExtensionFileFilter; | ||||
import org.apache.avalon.excalibur.io.FileUtil; | import org.apache.avalon.excalibur.io.FileUtil; | ||||
import org.apache.avalon.framework.activity.Disposable; | |||||
import org.apache.avalon.framework.activity.Initializable; | import org.apache.avalon.framework.activity.Initializable; | ||||
import org.apache.avalon.framework.component.Component; | import org.apache.avalon.framework.component.Component; | ||||
import org.apache.avalon.framework.component.Composable; | import org.apache.avalon.framework.component.Composable; | ||||
@@ -20,6 +24,7 @@ import org.apache.avalon.framework.component.DefaultComponentManager; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | import org.apache.avalon.framework.logger.AbstractLogEnabled; | ||||
import org.apache.avalon.framework.parameters.Parameterizable; | import org.apache.avalon.framework.parameters.Parameterizable; | ||||
import org.apache.avalon.framework.parameters.Parameters; | import org.apache.avalon.framework.parameters.Parameters; | ||||
import org.apache.myrmidon.components.deployer.ClassLoaderManager; | |||||
import org.apache.myrmidon.interfaces.aspect.AspectManager; | import org.apache.myrmidon.interfaces.aspect.AspectManager; | ||||
import org.apache.myrmidon.interfaces.builder.ProjectBuilder; | import org.apache.myrmidon.interfaces.builder.ProjectBuilder; | ||||
import org.apache.myrmidon.interfaces.configurer.Configurer; | import org.apache.myrmidon.interfaces.configurer.Configurer; | ||||
@@ -52,37 +57,33 @@ public class DefaultEmbeddor | |||||
ResourceManager.getPackageResources( DefaultEmbeddor.class ); | ResourceManager.getPackageResources( DefaultEmbeddor.class ); | ||||
private Deployer m_deployer; | private Deployer m_deployer; | ||||
private RoleManager m_roleManager; | |||||
private AspectManager m_aspectManager; | |||||
private TypeManager m_typeManager; | private TypeManager m_typeManager; | ||||
private MasterConverter m_converter; | |||||
private ConverterRegistry m_converterRegistry; | |||||
private ExtensionManager m_extensionManager; | |||||
private Executor m_executor; | |||||
private Configurer m_configurer; | |||||
private DefaultComponentManager m_componentManager; | |||||
private List m_components = new ArrayList(); | |||||
private DefaultComponentManager m_componentManager = new DefaultComponentManager(); | |||||
private Parameters m_parameters; | private Parameters m_parameters; | ||||
private Parameters m_defaults; | private Parameters m_defaults; | ||||
private File m_homeDir; | private File m_homeDir; | ||||
private File m_binDir; | |||||
private File m_libDir; | |||||
private File m_taskLibDir; | private File m_taskLibDir; | ||||
/** Package containing the default component implementations. */ | |||||
private static final String PREFIX = "org.apache.myrmidon.components."; | |||||
/** | /** | ||||
* Setup basic properties of engine. | * Setup basic properties of engine. | ||||
* Called before init() and can be used to specify alternate components in system. | * Called before init() and can be used to specify alternate components in system. | ||||
* | * | ||||
* @param properties the properties | |||||
* @param parameters the parameters. | |||||
*/ | */ | ||||
public void parameterize( final Parameters parameters ) | public void parameterize( final Parameters parameters ) | ||||
{ | { | ||||
m_parameters = parameters; | m_parameters = parameters; | ||||
} | } | ||||
/** | |||||
* Builds a project. | |||||
*/ | |||||
public Project createProject( final String location, | public Project createProject( final String location, | ||||
final String type, | final String type, | ||||
final Parameters parameters ) | final Parameters parameters ) | ||||
@@ -91,18 +92,16 @@ public class DefaultEmbeddor | |||||
String projectType = type; | String projectType = type; | ||||
if( null == projectType ) | if( null == projectType ) | ||||
{ | { | ||||
projectType = guessTypeFor( location ); | |||||
projectType = FileUtil.getExtension( location ); | |||||
} | } | ||||
final ProjectBuilder builder = getProjectBuilder( projectType, parameters ); | final ProjectBuilder builder = getProjectBuilder( projectType, parameters ); | ||||
return builder.build( location ); | return builder.build( location ); | ||||
} | } | ||||
private String guessTypeFor( final String location ) | |||||
{ | |||||
return FileUtil.getExtension( location ); | |||||
} | |||||
/** | |||||
* Creates a project builder for a project type. | |||||
*/ | |||||
private ProjectBuilder getProjectBuilder( final String type, | private ProjectBuilder getProjectBuilder( final String type, | ||||
final Parameters parameters ) | final Parameters parameters ) | ||||
throws Exception | throws Exception | ||||
@@ -110,51 +109,20 @@ public class DefaultEmbeddor | |||||
final TypeFactory factory = m_typeManager.getFactory( ProjectBuilder.class ); | final TypeFactory factory = m_typeManager.getFactory( ProjectBuilder.class ); | ||||
final ProjectBuilder builder = (ProjectBuilder)factory.create( type ); | final ProjectBuilder builder = (ProjectBuilder)factory.create( type ); | ||||
setupLogger( builder ); | |||||
if( builder instanceof Composable ) | |||||
{ | |||||
( (Composable)builder ).compose( m_componentManager ); | |||||
} | |||||
if( builder instanceof Parameterizable ) | |||||
{ | |||||
( (Parameterizable)builder ).parameterize( parameters ); | |||||
} | |||||
if( builder instanceof Initializable ) | |||||
{ | |||||
( (Initializable)builder ).initialize(); | |||||
} | |||||
setupObject( builder, parameters ); | |||||
return builder; | return builder; | ||||
} | } | ||||
/** | |||||
* Creates a workspace. | |||||
*/ | |||||
public Workspace createWorkspace( final Parameters parameters ) | public Workspace createWorkspace( final Parameters parameters ) | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
final String component = getParameter( Workspace.ROLE ); | final String component = getParameter( Workspace.ROLE ); | ||||
final Workspace workspace = | final Workspace workspace = | ||||
(Workspace)createComponent( component, Workspace.class ); | (Workspace)createComponent( component, Workspace.class ); | ||||
setupLogger( workspace ); | |||||
if( workspace instanceof Composable ) | |||||
{ | |||||
( (Composable)workspace ).compose( m_componentManager ); | |||||
} | |||||
if( workspace instanceof Parameterizable ) | |||||
{ | |||||
( (Parameterizable)workspace ).parameterize( parameters ); | |||||
} | |||||
if( workspace instanceof Initializable ) | |||||
{ | |||||
( (Initializable)workspace ).initialize(); | |||||
} | |||||
setupObject( workspace, parameters ); | |||||
return workspace; | return workspace; | ||||
} | } | ||||
@@ -172,11 +140,12 @@ public class DefaultEmbeddor | |||||
//create all the components | //create all the components | ||||
createComponents(); | createComponents(); | ||||
//setup the component manager | |||||
m_componentManager = createComponentManager(); | |||||
//setup the components | |||||
setupComponents(); | setupComponents(); | ||||
m_deployer = (Deployer)m_componentManager.lookup( Deployer.ROLE ); | |||||
m_typeManager = (TypeManager)m_componentManager.lookup( TypeManager.ROLE ); | |||||
setupFiles(); | setupFiles(); | ||||
} | } | ||||
@@ -193,32 +162,36 @@ public class DefaultEmbeddor | |||||
deployFromDirectory( m_deployer, m_taskLibDir, filter ); | deployFromDirectory( m_deployer, m_taskLibDir, filter ); | ||||
} | } | ||||
/** | |||||
* Stops the engine. | |||||
*/ | |||||
public void stop() | public void stop() | ||||
{ | { | ||||
//Undeploy all the tasks by killing ExecutionFrame??? | |||||
//TODO - Undeploy all the tasks by killing ExecutionFrame??? | |||||
} | } | ||||
/** | /** | ||||
* Dispose engine. | * Dispose engine. | ||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | */ | ||||
public void dispose() | public void dispose() | ||||
{ | { | ||||
m_extensionManager = null; | |||||
m_aspectManager = null; | |||||
m_roleManager = null; | |||||
m_converterRegistry = null; | |||||
m_converter = null; | |||||
m_executor = null; | |||||
// Dispose any disposable components | |||||
for( Iterator iterator = m_components.iterator(); iterator.hasNext(); ) | |||||
{ | |||||
Component component = (Component)iterator.next(); | |||||
if( component instanceof Disposable ) | |||||
{ | |||||
( (Disposable)component ).dispose(); | |||||
} | |||||
} | |||||
// Ditch everything | |||||
m_components = null; | |||||
m_deployer = null; | m_deployer = null; | ||||
m_configurer = null; | |||||
m_componentManager = null; | m_componentManager = null; | ||||
m_parameters = null; | m_parameters = null; | ||||
m_defaults = null; | m_defaults = null; | ||||
m_homeDir = null; | m_homeDir = null; | ||||
m_binDir = null; | |||||
m_libDir = null; | |||||
m_taskLibDir = null; | m_taskLibDir = null; | ||||
} | } | ||||
@@ -236,137 +209,55 @@ public class DefaultEmbeddor | |||||
defaults.setParameter( "myrmidon.bin.path", "bin" ); | defaults.setParameter( "myrmidon.bin.path", "bin" ); | ||||
defaults.setParameter( "myrmidon.lib.path", "lib" ); | defaults.setParameter( "myrmidon.lib.path", "lib" ); | ||||
//create all the default properties for components | |||||
final String PREFIX = "org.apache.myrmidon.components."; | |||||
defaults.setParameter( AspectManager.ROLE, PREFIX + "aspect.DefaultAspectManager" ); | |||||
defaults.setParameter( RoleManager.ROLE, PREFIX + "role.DefaultRoleManager" ); | |||||
defaults.setParameter( MasterConverter.ROLE, PREFIX + "converter.DefaultMasterConverter" ); | |||||
defaults.setParameter( ConverterRegistry.ROLE, PREFIX + "converter.DefaultConverterRegistry" ); | |||||
defaults.setParameter( TypeManager.ROLE, PREFIX + "type.DefaultTypeManager" ); | |||||
defaults.setParameter( Executor.ROLE, | |||||
//"org.apache.myrmidon.components.executor.DefaultExecutor" ); | |||||
//"org.apache.myrmidon.components.executor.PrintingExecutor" ); | |||||
PREFIX + "executor.AspectAwareExecutor" ); | |||||
// Default workspace implementation | |||||
defaults.setParameter( Workspace.ROLE, PREFIX + "workspace.DefaultWorkspace" ); | defaults.setParameter( Workspace.ROLE, PREFIX + "workspace.DefaultWorkspace" ); | ||||
defaults.setParameter( Deployer.ROLE, PREFIX + "deployer.DefaultDeployer" ); | |||||
defaults.setParameter( Configurer.ROLE, PREFIX + "configurer.DefaultConfigurer" ); | |||||
defaults.setParameter( ExtensionManager.ROLE, PREFIX + "extensions.DefaultExtensionManager" ); | |||||
return defaults; | return defaults; | ||||
} | } | ||||
/** | |||||
* Create a ComponentManager containing all components in engine. | |||||
* | |||||
* @return the ComponentManager | |||||
*/ | |||||
private DefaultComponentManager createComponentManager() | |||||
{ | |||||
final DefaultComponentManager componentManager = new DefaultComponentManager(); | |||||
componentManager.put( MasterConverter.ROLE, m_converter ); | |||||
//Following components required when Myrmidon is used as build tool | |||||
componentManager.put( Embeddor.ROLE, this ); | |||||
//Following components required when Myrmidon allows user deployment of tasks etal. | |||||
componentManager.put( RoleManager.ROLE, m_roleManager ); | |||||
componentManager.put( Deployer.ROLE, m_deployer ); | |||||
componentManager.put( ExtensionManager.ROLE, m_extensionManager ); | |||||
//Following components used when want to types (ie tasks/mappers etc) | |||||
componentManager.put( TypeManager.ROLE, m_typeManager ); | |||||
componentManager.put( ConverterRegistry.ROLE, m_converterRegistry ); | |||||
componentManager.put( AspectManager.ROLE, m_aspectManager ); | |||||
//Following components required when allowing Container tasks | |||||
componentManager.put( Configurer.ROLE, m_configurer ); | |||||
componentManager.put( Executor.ROLE, m_executor ); | |||||
return componentManager; | |||||
} | |||||
/** | /** | ||||
* Create all required components. | * Create all required components. | ||||
* | |||||
* @exception Exception if an error occurs | |||||
*/ | */ | ||||
private void createComponents() | private void createComponents() | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
String component = null; | |||||
component = getParameter( ConverterRegistry.ROLE ); | |||||
m_converterRegistry = (ConverterRegistry)createComponent( component, ConverterRegistry.class ); | |||||
component = getParameter( ExtensionManager.ROLE ); | |||||
m_extensionManager = (ExtensionManager)createComponent( component, ExtensionManager.class ); | |||||
component = getParameter( MasterConverter.ROLE ); | |||||
m_converter = (MasterConverter)createComponent( component, MasterConverter.class ); | |||||
component = getParameter( Configurer.ROLE ); | |||||
m_configurer = (Configurer)createComponent( component, Configurer.class ); | |||||
component = getParameter( TypeManager.ROLE ); | |||||
m_typeManager = (TypeManager)createComponent( component, TypeManager.class ); | |||||
component = getParameter( RoleManager.ROLE ); | |||||
m_roleManager = (RoleManager)createComponent( component, RoleManager.class ); | |||||
component = getParameter( AspectManager.ROLE ); | |||||
m_aspectManager = (AspectManager)createComponent( component, AspectManager.class ); | |||||
component = getParameter( Deployer.ROLE ); | |||||
m_deployer = (Deployer)createComponent( component, Deployer.class ); | |||||
component = getParameter( Executor.ROLE ); | |||||
m_executor = (Executor)createComponent( component, Executor.class ); | |||||
createComponent( ConverterRegistry.class, PREFIX + "converter.DefaultConverterRegistry" ); | |||||
createComponent( ExtensionManager.class, PREFIX + "extensions.DefaultExtensionManager" ); | |||||
createComponent( MasterConverter.class, PREFIX + "converter.DefaultMasterConverter" ); | |||||
createComponent( Configurer.class, PREFIX + "configurer.DefaultConfigurer" ); | |||||
createComponent( TypeManager.class, PREFIX + "type.DefaultTypeManager" ); | |||||
createComponent( RoleManager.class, PREFIX + "role.DefaultRoleManager" ); | |||||
createComponent( AspectManager.class, PREFIX + "aspect.DefaultAspectManager" ); | |||||
createComponent( Deployer.class, PREFIX + "deployer.DefaultDeployer" ); | |||||
createComponent( ClassLoaderManager.class, PREFIX + "deployer.DefaultClassLoaderManager" ); | |||||
createComponent( Executor.class, PREFIX + "executor.AspectAwareExecutor" ); | |||||
} | } | ||||
/** | /** | ||||
* Setup all the components. (ir run all required lifecycle methods). | |||||
* | |||||
* @exception Exception if an error occurs | |||||
* Creates a component. | |||||
*/ | */ | ||||
private void setupComponents() | |||||
private void createComponent( Class roleType, String defaultImpl ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
setupComponent( m_extensionManager ); | |||||
setupComponent( m_roleManager ); | |||||
setupComponent( m_aspectManager ); | |||||
setupComponent( m_converterRegistry ); | |||||
setupComponent( m_converter ); | |||||
setupComponent( m_executor ); | |||||
setupComponent( m_deployer ); | |||||
setupComponent( m_configurer ); | |||||
final String role = roleType.getName(); | |||||
final String className = m_parameters.getParameter( role, defaultImpl ); | |||||
final Component component = createComponent( className, roleType ); | |||||
m_componentManager.put( role, component ); | |||||
m_components.add( component ); | |||||
} | } | ||||
/** | /** | ||||
* Setup an individual component. | |||||
* Setup all the components. (ir run all required lifecycle methods). | |||||
* | * | ||||
* @param component the component | |||||
* @exception Exception if an error occurs | * @exception Exception if an error occurs | ||||
*/ | */ | ||||
private void setupComponent( final Component component ) | |||||
private void setupComponents() | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
setupLogger( component ); | |||||
if( component instanceof Composable ) | |||||
for( Iterator iterator = m_components.iterator(); iterator.hasNext(); ) | |||||
{ | { | ||||
( (Composable)component ).compose( m_componentManager ); | |||||
} | |||||
if( component instanceof Parameterizable ) | |||||
{ | |||||
( (Parameterizable)component ).parameterize( m_parameters ); | |||||
} | |||||
if( component instanceof Initializable ) | |||||
{ | |||||
( (Initializable)component ).initialize(); | |||||
final Component component = (Component)iterator.next(); | |||||
setupObject( component, m_parameters ); | |||||
} | } | ||||
} | } | ||||
@@ -382,9 +273,6 @@ public class DefaultEmbeddor | |||||
m_homeDir = ( new File( filepath ) ).getAbsoluteFile(); | m_homeDir = ( new File( filepath ) ).getAbsoluteFile(); | ||||
checkDirectory( m_homeDir, "home" ); | checkDirectory( m_homeDir, "home" ); | ||||
filepath = getParameter( "myrmidon.bin.path" ); | |||||
m_binDir = resolveDirectory( filepath, "bin-dir" ); | |||||
filepath = getParameter( "myrmidon.lib.path" ); | filepath = getParameter( "myrmidon.lib.path" ); | ||||
m_taskLibDir = resolveDirectory( filepath, "task-lib-dir" ); | m_taskLibDir = resolveDirectory( filepath, "task-lib-dir" ); | ||||
} | } | ||||
@@ -453,7 +341,7 @@ public class DefaultEmbeddor | |||||
* @return the created object | * @return the created object | ||||
* @exception Exception if an error occurs | * @exception Exception if an error occurs | ||||
*/ | */ | ||||
private Object createComponent( final String component, final Class clazz ) | |||||
private Component createComponent( final String component, final Class clazz ) | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
try | try | ||||
@@ -465,8 +353,13 @@ public class DefaultEmbeddor | |||||
final String message = REZ.getString( "bad-type.error", component, clazz.getName() ); | final String message = REZ.getString( "bad-type.error", component, clazz.getName() ); | ||||
throw new Exception( message ); | throw new Exception( message ); | ||||
} | } | ||||
if( !( object instanceof Component) ) | |||||
{ | |||||
final String message = REZ.getString( "bad-type.error", component, Component.class.getName() ); | |||||
throw new Exception( message ); | |||||
} | |||||
return object; | |||||
return (Component)object; | |||||
} | } | ||||
catch( final IllegalAccessException iae ) | catch( final IllegalAccessException iae ) | ||||
{ | { | ||||
@@ -487,6 +380,32 @@ public class DefaultEmbeddor | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Sets-up an object by running it through the log-enable, compose, | |||||
* parameterise and initialise lifecycle stages. | |||||
*/ | |||||
private void setupObject( final Object object, | |||||
final Parameters parameters ) | |||||
throws Exception | |||||
{ | |||||
setupLogger( object ); | |||||
if( object instanceof Composable ) | |||||
{ | |||||
( (Composable)object ).compose( m_componentManager ); | |||||
} | |||||
if( object instanceof Parameterizable ) | |||||
{ | |||||
( (Parameterizable)object ).parameterize( parameters ); | |||||
} | |||||
if( object instanceof Initializable ) | |||||
{ | |||||
( (Initializable)object ).initialize(); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Deploys all type libraries in a directory. | * Deploys all type libraries in a directory. | ||||
*/ | */ | ||||
@@ -5,13 +5,11 @@ | |||||
<data-type name="path" classname="org.apache.tools.ant.types.Path" /> | <data-type name="path" classname="org.apache.tools.ant.types.Path" /> | ||||
<task name="path" classname="org.apache.myrmidon.framework.TypeInstanceTask" /> | <task name="path" classname="org.apache.myrmidon.framework.TypeInstanceTask" /> | ||||
</types> | |||||
<converters> | |||||
<converter | <converter | ||||
classname="org.apache.tools.ant.types.converters.StringToPathConverter" | classname="org.apache.tools.ant.types.converters.StringToPathConverter" | ||||
source="java.lang.String" | source="java.lang.String" | ||||
destination="org.apache.tools.ant.types.Path" | destination="org.apache.tools.ant.types.Path" | ||||
/> | |||||
</converters> | |||||
/> | |||||
</types> | |||||
</ant-lib> | </ant-lib> |
@@ -18,10 +18,6 @@ | |||||
</XDtClass:ifHasClassTag> | </XDtClass:ifHasClassTag> | ||||
</XDtClass:forAllClasses> | </XDtClass:forAllClasses> | ||||
</types> | |||||
<converters> | |||||
<XDtClass:forAllClasses type="org.apache.myrmidon.converter.Converter"> | <XDtClass:forAllClasses type="org.apache.myrmidon.converter.Converter"> | ||||
<XDtClass:ifHasClassTag tagName="ant:converter"> | <XDtClass:ifHasClassTag tagName="ant:converter"> | ||||
<converter classname="<XDtClass:fullClassName/>" | <converter classname="<XDtClass:fullClassName/>" | ||||
@@ -30,6 +26,6 @@ | |||||
</XDtClass:ifHasClassTag> | </XDtClass:ifHasClassTag> | ||||
</XDtClass:forAllClasses> | </XDtClass:forAllClasses> | ||||
</converters> | |||||
</types> | |||||
</ant-lib> | </ant-lib> |
@@ -18,6 +18,7 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.aut.vfs.impl.DefaultFileSystemManager; | import org.apache.aut.vfs.impl.DefaultFileSystemManager; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* File system test cases, which verifies the structure and naming | * File system test cases, which verifies the structure and naming | ||||
@@ -28,7 +29,8 @@ import org.apache.aut.vfs.impl.DefaultFileSystemManager; | |||||
* | * | ||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public abstract class AbstractFileSystemTest extends TestCase | |||||
public abstract class AbstractFileSystemTest | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
protected FileObject m_baseFolder; | protected FileObject m_baseFolder; | ||||
protected DefaultFileSystemManager m_manager; | protected DefaultFileSystemManager m_manager; | ||||
@@ -63,7 +65,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
/** | /** | ||||
* Returns the URI for the base folder. | * Returns the URI for the base folder. | ||||
*/ | */ | ||||
protected abstract String getBaseFolderURI(); | |||||
protected abstract String getBaseFolderURI() throws Exception; | |||||
/** | /** | ||||
* Sets up the test | * Sets up the test | ||||
@@ -160,7 +162,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using a compound name to find a child | // Try using a compound name to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "a/b", NameScope.CHILD ); | |||||
name.resolveName( "a/b", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -170,7 +172,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using a empty name to find a child | // Try using a empty name to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "", NameScope.CHILD ); | |||||
name.resolveName( "", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -180,7 +182,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using '.' to find a child | // Try using '.' to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( ".", NameScope.CHILD ); | |||||
name.resolveName( ".", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -190,7 +192,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using '..' to find a child | // Try using '..' to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "..", NameScope.CHILD ); | |||||
name.resolveName( "..", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -280,14 +282,6 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
assertSameName( childPath, baseName, "a/b/../../some-child" ); | assertSameName( childPath, baseName, "a/b/../../some-child" ); | ||||
} | } | ||||
/** | |||||
* Tests relative name resolution, relative to the root file. | |||||
*/ | |||||
public void testNameResolutionRoot() throws Exception | |||||
{ | |||||
FileName rootName = m_baseFolder.getRoot().getName(); | |||||
} | |||||
/** | /** | ||||
* Walks the folder structure, asserting it contains exactly the | * Walks the folder structure, asserting it contains exactly the | ||||
* expected files and folders. | * expected files and folders. | ||||
@@ -27,7 +27,7 @@ public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemT | |||||
/** | /** | ||||
* Returns the URI for the area to do tests in. | * Returns the URI for the area to do tests in. | ||||
*/ | */ | ||||
protected abstract String getWriteFolderURI(); | |||||
protected abstract String getWriteFolderURI() throws Exception; | |||||
/** | /** | ||||
* Sets up a scratch folder for the test to use. | * Sets up a scratch folder for the test to use. | ||||
@@ -16,33 +16,29 @@ import java.io.File; | |||||
*/ | */ | ||||
public class LocalFileSystemTest extends AbstractWritableFileSystemTest | public class LocalFileSystemTest extends AbstractWritableFileSystemTest | ||||
{ | { | ||||
private File m_baseDir; | |||||
public LocalFileSystemTest( String name ) | public LocalFileSystemTest( String name ) | ||||
{ | { | ||||
super( name ); | super( name ); | ||||
String baseDir = System.getProperty( "test.local.dir" ); | |||||
m_baseDir = new File( baseDir ); | |||||
} | } | ||||
/** | /** | ||||
* Returns the URI for the base folder. | * Returns the URI for the base folder. | ||||
*/ | */ | ||||
protected String getBaseFolderURI() | protected String getBaseFolderURI() | ||||
throws Exception | |||||
{ | { | ||||
String testDir = new File( m_baseDir, "read-tests" ).getAbsolutePath(); | |||||
String uri = "file:/" + testDir; | |||||
return uri; | |||||
final File testDir = getTestResource( "basedir" ); | |||||
return testDir.toURL().toString(); | |||||
} | } | ||||
/** | /** | ||||
* Returns the URI for the area to do tests in. | * Returns the URI for the area to do tests in. | ||||
*/ | */ | ||||
protected String getWriteFolderURI() | protected String getWriteFolderURI() | ||||
throws Exception | |||||
{ | { | ||||
String testDir = new File( m_baseDir, "write-tests" ).getAbsolutePath(); | |||||
String uri = "file:/" + testDir; | |||||
return uri; | |||||
final File testDir = getTestResource( "write-tests" ); | |||||
return testDir.toURL().toString(); | |||||
} | } | ||||
/** | /** | ||||
@@ -26,8 +26,7 @@ public class ZipFileSystemTest extends AbstractReadOnlyFileSystemTest | |||||
*/ | */ | ||||
protected String getBaseFolderURI() | protected String getBaseFolderURI() | ||||
{ | { | ||||
String zipFileName = System.getProperty( "test.zip.file" ); | |||||
String zipFile = new File( zipFileName ).getAbsolutePath(); | |||||
File zipFile = getTestResource( "test.zip" ); | |||||
String uri = "zip:" + zipFile + "!basedir"; | String uri = "zip:" + zipFile + "!basedir"; | ||||
return uri; | return uri; | ||||
} | } | ||||
@@ -0,0 +1,71 @@ | |||||
/* | |||||
* 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; | |||||
import junit.framework.TestCase; | |||||
import java.io.File; | |||||
/** | |||||
* A base class for Myrmidon tests. Provides utility methods for locating | |||||
* test resources. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public abstract class AbstractMyrmidonTest | |||||
extends TestCase | |||||
{ | |||||
private final File m_testBaseDir; | |||||
public AbstractMyrmidonTest( String name ) | |||||
{ | |||||
super( name ); | |||||
final String baseDirProp = System.getProperty( "test.basedir" ); | |||||
String packagePath = getClass().getName(); | |||||
int idx = packagePath.lastIndexOf('.'); | |||||
packagePath = packagePath.substring(0, idx); | |||||
packagePath = packagePath.replace('.', File.separatorChar); | |||||
m_testBaseDir = new File( baseDirProp, packagePath ).getAbsoluteFile(); | |||||
} | |||||
/** | |||||
* Locates a test resource. | |||||
*/ | |||||
protected File getTestResource( final String name ) | |||||
{ | |||||
return new File( m_testBaseDir, name ); | |||||
} | |||||
/** | |||||
* Asserts that an exception contains the expected message. | |||||
* | |||||
* TODO - should take the expected exception, rather than the message, | |||||
* to check the entire cause chain. | |||||
*/ | |||||
protected void assertSameMessage( final String message, final Throwable throwable ) | |||||
{ | |||||
assertEquals( message, throwable.getMessage() ); | |||||
} | |||||
/** | |||||
* Compares 2 objects for equality, nulls are equal. Used by the test | |||||
* classes' equals() methods. | |||||
*/ | |||||
public static boolean equals( final Object o1, final Object o2 ) | |||||
{ | |||||
if( o1 == null && o2 == null ) | |||||
{ | |||||
return true; | |||||
} | |||||
if( o1 == null || o2 == null ) | |||||
{ | |||||
return false; | |||||
} | |||||
return o1.equals( o2 ); | |||||
} | |||||
} |
@@ -28,6 +28,8 @@ import org.apache.myrmidon.components.configurer.DefaultConfigurer; | |||||
import org.apache.myrmidon.components.converter.DefaultConverterRegistry; | import org.apache.myrmidon.components.converter.DefaultConverterRegistry; | ||||
import org.apache.myrmidon.components.converter.DefaultMasterConverter; | import org.apache.myrmidon.components.converter.DefaultMasterConverter; | ||||
import org.apache.myrmidon.components.deployer.DefaultDeployer; | import org.apache.myrmidon.components.deployer.DefaultDeployer; | ||||
import org.apache.myrmidon.components.deployer.DefaultClassLoaderManager; | |||||
import org.apache.myrmidon.components.deployer.ClassLoaderManager; | |||||
import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | ||||
import org.apache.myrmidon.components.role.DefaultRoleManager; | import org.apache.myrmidon.components.role.DefaultRoleManager; | ||||
import org.apache.myrmidon.components.type.DefaultTypeManager; | import org.apache.myrmidon.components.type.DefaultTypeManager; | ||||
@@ -41,6 +43,7 @@ import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
import org.apache.myrmidon.interfaces.type.TypeException; | import org.apache.myrmidon.interfaces.type.TypeException; | ||||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | ||||
import org.apache.myrmidon.converter.Converter; | import org.apache.myrmidon.converter.Converter; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* A base class for tests for the default components. | * A base class for tests for the default components. | ||||
@@ -48,7 +51,7 @@ import org.apache.myrmidon.converter.Converter; | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public abstract class AbstractComponentTest | public abstract class AbstractComponentTest | ||||
extends TestCase | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
private DefaultComponentManager m_componentManager; | private DefaultComponentManager m_componentManager; | ||||
private Logger m_logger; | private Logger m_logger; | ||||
@@ -117,6 +120,11 @@ public abstract class AbstractComponentTest | |||||
m_componentManager.put( Deployer.ROLE, component ); | m_componentManager.put( Deployer.ROLE, component ); | ||||
components.add( component ); | components.add( component ); | ||||
final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager(); | |||||
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() ); | |||||
m_componentManager.put( ClassLoaderManager.ROLE, classLoaderMgr ); | |||||
components.add( classLoaderMgr ); | |||||
component = new DefaultExtensionManager(); | component = new DefaultExtensionManager(); | ||||
m_componentManager.put( ExtensionManager.ROLE, component ); | m_componentManager.put( ExtensionManager.ROLE, component ); | ||||
components.add( component ); | components.add( component ); | ||||
@@ -162,32 +170,4 @@ public abstract class AbstractComponentTest | |||||
factory.addNameClassMapping( converterClass.getName(), converterClass.getName() ); | factory.addNameClassMapping( converterClass.getName(), converterClass.getName() ); | ||||
getTypeManager().registerType( Converter.class, converterClass.getName(), factory ); | getTypeManager().registerType( Converter.class, converterClass.getName(), factory ); | ||||
} | } | ||||
/** | |||||
* Asserts that an exception contains the expected message. | |||||
* | |||||
* TODO - should take the expected exception, rather than the message, | |||||
* to check the entire cause chain. | |||||
*/ | |||||
protected void assertSameMessage( final String message, final Throwable throwable ) | |||||
{ | |||||
assertEquals( message, throwable.getMessage() ); | |||||
} | |||||
/** | |||||
* Compares 2 objects for equality, nulls are equal. Used by the test | |||||
* classes' equals() methods. | |||||
*/ | |||||
public static boolean equals( final Object o1, final Object o2 ) | |||||
{ | |||||
if( o1 == null && o2 == null ) | |||||
{ | |||||
return true; | |||||
} | |||||
if( o1 == null || o2 == null ) | |||||
{ | |||||
return false; | |||||
} | |||||
return o1.equals( o2 ); | |||||
} | |||||
} | } |
@@ -16,6 +16,11 @@ import org.apache.myrmidon.interfaces.deployer.TypeDefinition; | |||||
import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | ||||
import org.apache.myrmidon.interfaces.role.RoleManager; | import org.apache.myrmidon.interfaces.role.RoleManager; | ||||
import org.apache.myrmidon.interfaces.type.TypeFactory; | import org.apache.myrmidon.interfaces.type.TypeFactory; | ||||
import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
import org.apache.myrmidon.interfaces.type.TypeException; | |||||
import org.apache.myrmidon.converter.ConverterException; | |||||
import org.apache.myrmidon.converter.Converter; | |||||
import java.io.File; | |||||
/** | /** | ||||
* Test cases for the default deployer. | * Test cases for the default deployer. | ||||
@@ -25,7 +30,12 @@ import org.apache.myrmidon.interfaces.type.TypeFactory; | |||||
public class DefaultDeployerTest | public class DefaultDeployerTest | ||||
extends AbstractComponentTest | extends AbstractComponentTest | ||||
{ | { | ||||
private static final String TEST_TYPE1_NAME = "test-type1"; | |||||
private static final String DATA_TYPE_ROLE = "data-type"; | |||||
private Deployer m_deployer; | private Deployer m_deployer; | ||||
private RoleManager m_roleManager; | |||||
private MasterConverter m_converter; | |||||
public DefaultDeployerTest( final String name ) | public DefaultDeployerTest( final String name ) | ||||
{ | { | ||||
@@ -40,6 +50,12 @@ public class DefaultDeployerTest | |||||
{ | { | ||||
super.setUp(); | super.setUp(); | ||||
m_deployer = (Deployer)getComponentManager().lookup( Deployer.ROLE ); | m_deployer = (Deployer)getComponentManager().lookup( Deployer.ROLE ); | ||||
m_converter = (MasterConverter)getComponentManager().lookup( MasterConverter.ROLE ); | |||||
// Add some core roles | |||||
m_roleManager = (RoleManager)getComponentManager().lookup( RoleManager.ROLE ); | |||||
m_roleManager.addNameRoleMapping( DATA_TYPE_ROLE, DataType.ROLE ); | |||||
m_roleManager.addNameRoleMapping( "converter", Converter.ROLE ); | |||||
} | } | ||||
/** | /** | ||||
@@ -47,27 +63,26 @@ public class DefaultDeployerTest | |||||
*/ | */ | ||||
public void testSingleType() throws Exception | public void testSingleType() throws Exception | ||||
{ | { | ||||
final String roleName = "data-type"; | |||||
final String typeName = "test-type1"; | |||||
final String typeName = TEST_TYPE1_NAME; | |||||
final String classname = TestType1.class.getName(); | final String classname = TestType1.class.getName(); | ||||
// Determine the shorthand for the DataType role | // Determine the shorthand for the DataType role | ||||
final RoleManager roleManager = (RoleManager)getComponentManager().lookup( RoleManager.ROLE ); | |||||
roleManager.addNameRoleMapping( roleName, DataType.ROLE ); | |||||
// Create the type definition | // Create the type definition | ||||
final TypeDefinition typeDef = new TypeDefinition( typeName, roleName, classname ); | |||||
final TypeDefinition typeDef = new TypeDefinition( typeName, DATA_TYPE_ROLE, classname ); | |||||
// Deploy the type | |||||
final ClassLoader classLoader = getClass().getClassLoader(); | final ClassLoader classLoader = getClass().getClassLoader(); | ||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | ||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered( ); | |||||
// Deploy the type | |||||
typeDeployer.deployType( typeDef ); | typeDeployer.deployType( typeDef ); | ||||
// Create an instance | |||||
// Check the type has been registered | |||||
final TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | final TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | ||||
final Object result = typeFactory.create( typeName ); | final Object result = typeFactory.create( typeName ); | ||||
// Check the type | |||||
assertTrue( result instanceof TestType1 ); | assertTrue( result instanceof TestType1 ); | ||||
} | } | ||||
@@ -84,16 +99,99 @@ public class DefaultDeployerTest | |||||
final ConverterDefinition typeDef = | final ConverterDefinition typeDef = | ||||
new ConverterDefinition( classname, source, destClass ); | new ConverterDefinition( classname, source, destClass ); | ||||
// Deploy the type | |||||
final ClassLoader classLoader = getClass().getClassLoader(); | final ClassLoader classLoader = getClass().getClassLoader(); | ||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | ||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered( ); | |||||
// Deploy the type | |||||
typeDeployer.deployType( typeDef ); | typeDeployer.deployType( typeDef ); | ||||
// Try to convert from string to test type | // Try to convert from string to test type | ||||
final MasterConverter converter = (MasterConverter)getComponentManager().lookup( MasterConverter.ROLE ); | |||||
final Object result = converter.convert( TestType1.class, "some-string", null ); | |||||
// Check the type | |||||
final Object result = m_converter.convert( TestType1.class, "some-string", null ); | |||||
assertTrue( result instanceof TestType1 ); | assertTrue( result instanceof TestType1 ); | ||||
} | } | ||||
/** | |||||
* Tests deployment of types from a typelib descriptor. | |||||
*/ | |||||
public void testLibDescriptor() throws Exception | |||||
{ | |||||
final File typelib = getTestResource( "test.atl" ); | |||||
assertTrue( "File " + typelib + " does not exist", typelib.exists() ); | |||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( typelib ); | |||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered(); | |||||
// Deploy all the types from the descriptor | |||||
typeDeployer.deployAll(); | |||||
// Make sure the test types have been deployed | |||||
assertTypesRegistered(); | |||||
} | |||||
/** | |||||
* Ensures that the test types have not ben deployed. | |||||
*/ | |||||
private void assertTypesNotRegistered() throws Exception | |||||
{ | |||||
// Check the data-type | |||||
TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | |||||
try | |||||
{ | |||||
typeFactory.create( TEST_TYPE1_NAME ); | |||||
fail(); | |||||
} | |||||
catch( TypeException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
// Check the custom role implementation | |||||
typeFactory = getTypeManager().getFactory( TestRole1.class ); | |||||
try | |||||
{ | |||||
typeFactory.create( TEST_TYPE1_NAME ); | |||||
fail(); | |||||
} | |||||
catch( TypeException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
// Check the converter | |||||
try | |||||
{ | |||||
m_converter.convert( TestType1.class, "some string", null ); | |||||
fail(); | |||||
} | |||||
catch( ConverterException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
} | |||||
/** | |||||
* Ensures the types from the test typelib descriptor have been correctly | |||||
* deployed. | |||||
*/ | |||||
private void assertTypesRegistered( ) throws Exception | |||||
{ | |||||
// Check the data-type | |||||
TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | |||||
Object object = typeFactory.create( TEST_TYPE1_NAME ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
// Check the custom role implementation | |||||
typeFactory = getTypeManager().getFactory( TestRole1.class ); | |||||
object = typeFactory.create( TEST_TYPE1_NAME ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
// Check the converter | |||||
object = m_converter.convert( TestType1.class, "some string", null ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
} | |||||
} | } |
@@ -0,0 +1,18 @@ | |||||
/* | |||||
* 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.components.deployer; | |||||
/** | |||||
* A test role interface. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public interface TestRole1 | |||||
{ | |||||
String ROLE = TestRole1.class.getName(); | |||||
} |
@@ -15,6 +15,6 @@ import org.apache.myrmidon.framework.DataType; | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public class TestType1 | public class TestType1 | ||||
implements DataType | |||||
implements DataType, TestRole1 | |||||
{ | { | ||||
} | } |
@@ -10,15 +10,16 @@ package org.apache.myrmidon.interfaces.type; | |||||
import java.io.File; | import java.io.File; | ||||
import java.net.URL; | import java.net.URL; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* These are unit tests that test the basic operation of TypeFactorys. | |||||
* These are unit tests that test the basic operation of TypeFactories. | |||||
* | * | ||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class TypeFactoryTest | public class TypeFactoryTest | ||||
extends TestCase | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
private final static String TYPE_NAME1 = "my-type1"; | private final static String TYPE_NAME1 = "my-type1"; | ||||
private final static String TYPE_NAME2 = "my-type2"; | private final static String TYPE_NAME2 = "my-type2"; | ||||
@@ -27,9 +28,6 @@ public class TypeFactoryTest | |||||
private final static String TYPE_CLASSNAME1 = TYPE_CLASS1.getName(); | private final static String TYPE_CLASSNAME1 = TYPE_CLASS1.getName(); | ||||
private final static String TYPE_CLASSNAME2 = TYPE_CLASS2.getName(); | private final static String TYPE_CLASSNAME2 = TYPE_CLASS2.getName(); | ||||
private final static String TYPE_JAR = | |||||
"src/testcases/org/apache/myrmidon/interfaces/type/types.jar".replace( '/', File.separatorChar ); | |||||
public TypeFactoryTest( final String name ) | public TypeFactoryTest( final String name ) | ||||
{ | { | ||||
super( name ); | super( name ); | ||||
@@ -64,11 +62,10 @@ public class TypeFactoryTest | |||||
public void testReloadingTypeFactory() | public void testReloadingTypeFactory() | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
final File file = new File( TYPE_JAR ); | |||||
assertTrue( "Support Jar exists", file.exists() ); | |||||
final File file = getTestResource( "types.jar" ); | |||||
assertTrue( "Support Jar " + file + " exists", file.exists() ); | |||||
final URL[] classpath = new URL[]{file.toURL()}; | final URL[] classpath = new URL[]{file.toURL()}; | ||||
final ClassLoader classLoader = getClass().getClassLoader(); | |||||
final ReloadingTypeFactory factory = new ReloadingTypeFactory( classpath, null ); | final ReloadingTypeFactory factory = new ReloadingTypeFactory( classpath, null ); | ||||
factory.addNameClassMapping( TYPE_NAME1, TYPE_CLASSNAME1 ); | factory.addNameClassMapping( TYPE_NAME1, TYPE_CLASSNAME1 ); | ||||
@@ -18,6 +18,7 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.aut.vfs.impl.DefaultFileSystemManager; | import org.apache.aut.vfs.impl.DefaultFileSystemManager; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* File system test cases, which verifies the structure and naming | * File system test cases, which verifies the structure and naming | ||||
@@ -28,7 +29,8 @@ import org.apache.aut.vfs.impl.DefaultFileSystemManager; | |||||
* | * | ||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public abstract class AbstractFileSystemTest extends TestCase | |||||
public abstract class AbstractFileSystemTest | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
protected FileObject m_baseFolder; | protected FileObject m_baseFolder; | ||||
protected DefaultFileSystemManager m_manager; | protected DefaultFileSystemManager m_manager; | ||||
@@ -63,7 +65,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
/** | /** | ||||
* Returns the URI for the base folder. | * Returns the URI for the base folder. | ||||
*/ | */ | ||||
protected abstract String getBaseFolderURI(); | |||||
protected abstract String getBaseFolderURI() throws Exception; | |||||
/** | /** | ||||
* Sets up the test | * Sets up the test | ||||
@@ -160,7 +162,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using a compound name to find a child | // Try using a compound name to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "a/b", NameScope.CHILD ); | |||||
name.resolveName( "a/b", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -170,7 +172,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using a empty name to find a child | // Try using a empty name to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "", NameScope.CHILD ); | |||||
name.resolveName( "", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -180,7 +182,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using '.' to find a child | // Try using '.' to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( ".", NameScope.CHILD ); | |||||
name.resolveName( ".", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -190,7 +192,7 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
// Try using '..' to find a child | // Try using '..' to find a child | ||||
try | try | ||||
{ | { | ||||
FileName name2 = name.resolveName( "..", NameScope.CHILD ); | |||||
name.resolveName( "..", NameScope.CHILD ); | |||||
assertTrue( false ); | assertTrue( false ); | ||||
} | } | ||||
catch( FileSystemException e ) | catch( FileSystemException e ) | ||||
@@ -280,14 +282,6 @@ public abstract class AbstractFileSystemTest extends TestCase | |||||
assertSameName( childPath, baseName, "a/b/../../some-child" ); | assertSameName( childPath, baseName, "a/b/../../some-child" ); | ||||
} | } | ||||
/** | |||||
* Tests relative name resolution, relative to the root file. | |||||
*/ | |||||
public void testNameResolutionRoot() throws Exception | |||||
{ | |||||
FileName rootName = m_baseFolder.getRoot().getName(); | |||||
} | |||||
/** | /** | ||||
* Walks the folder structure, asserting it contains exactly the | * Walks the folder structure, asserting it contains exactly the | ||||
* expected files and folders. | * expected files and folders. | ||||
@@ -27,7 +27,7 @@ public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemT | |||||
/** | /** | ||||
* Returns the URI for the area to do tests in. | * Returns the URI for the area to do tests in. | ||||
*/ | */ | ||||
protected abstract String getWriteFolderURI(); | |||||
protected abstract String getWriteFolderURI() throws Exception; | |||||
/** | /** | ||||
* Sets up a scratch folder for the test to use. | * Sets up a scratch folder for the test to use. | ||||
@@ -16,33 +16,29 @@ import java.io.File; | |||||
*/ | */ | ||||
public class LocalFileSystemTest extends AbstractWritableFileSystemTest | public class LocalFileSystemTest extends AbstractWritableFileSystemTest | ||||
{ | { | ||||
private File m_baseDir; | |||||
public LocalFileSystemTest( String name ) | public LocalFileSystemTest( String name ) | ||||
{ | { | ||||
super( name ); | super( name ); | ||||
String baseDir = System.getProperty( "test.local.dir" ); | |||||
m_baseDir = new File( baseDir ); | |||||
} | } | ||||
/** | /** | ||||
* Returns the URI for the base folder. | * Returns the URI for the base folder. | ||||
*/ | */ | ||||
protected String getBaseFolderURI() | protected String getBaseFolderURI() | ||||
throws Exception | |||||
{ | { | ||||
String testDir = new File( m_baseDir, "read-tests" ).getAbsolutePath(); | |||||
String uri = "file:/" + testDir; | |||||
return uri; | |||||
final File testDir = getTestResource( "basedir" ); | |||||
return testDir.toURL().toString(); | |||||
} | } | ||||
/** | /** | ||||
* Returns the URI for the area to do tests in. | * Returns the URI for the area to do tests in. | ||||
*/ | */ | ||||
protected String getWriteFolderURI() | protected String getWriteFolderURI() | ||||
throws Exception | |||||
{ | { | ||||
String testDir = new File( m_baseDir, "write-tests" ).getAbsolutePath(); | |||||
String uri = "file:/" + testDir; | |||||
return uri; | |||||
final File testDir = getTestResource( "write-tests" ); | |||||
return testDir.toURL().toString(); | |||||
} | } | ||||
/** | /** | ||||
@@ -26,8 +26,7 @@ public class ZipFileSystemTest extends AbstractReadOnlyFileSystemTest | |||||
*/ | */ | ||||
protected String getBaseFolderURI() | protected String getBaseFolderURI() | ||||
{ | { | ||||
String zipFileName = System.getProperty( "test.zip.file" ); | |||||
String zipFile = new File( zipFileName ).getAbsolutePath(); | |||||
File zipFile = getTestResource( "test.zip" ); | |||||
String uri = "zip:" + zipFile + "!basedir"; | String uri = "zip:" + zipFile + "!basedir"; | ||||
return uri; | return uri; | ||||
} | } | ||||
@@ -0,0 +1,71 @@ | |||||
/* | |||||
* 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; | |||||
import junit.framework.TestCase; | |||||
import java.io.File; | |||||
/** | |||||
* A base class for Myrmidon tests. Provides utility methods for locating | |||||
* test resources. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public abstract class AbstractMyrmidonTest | |||||
extends TestCase | |||||
{ | |||||
private final File m_testBaseDir; | |||||
public AbstractMyrmidonTest( String name ) | |||||
{ | |||||
super( name ); | |||||
final String baseDirProp = System.getProperty( "test.basedir" ); | |||||
String packagePath = getClass().getName(); | |||||
int idx = packagePath.lastIndexOf('.'); | |||||
packagePath = packagePath.substring(0, idx); | |||||
packagePath = packagePath.replace('.', File.separatorChar); | |||||
m_testBaseDir = new File( baseDirProp, packagePath ).getAbsoluteFile(); | |||||
} | |||||
/** | |||||
* Locates a test resource. | |||||
*/ | |||||
protected File getTestResource( final String name ) | |||||
{ | |||||
return new File( m_testBaseDir, name ); | |||||
} | |||||
/** | |||||
* Asserts that an exception contains the expected message. | |||||
* | |||||
* TODO - should take the expected exception, rather than the message, | |||||
* to check the entire cause chain. | |||||
*/ | |||||
protected void assertSameMessage( final String message, final Throwable throwable ) | |||||
{ | |||||
assertEquals( message, throwable.getMessage() ); | |||||
} | |||||
/** | |||||
* Compares 2 objects for equality, nulls are equal. Used by the test | |||||
* classes' equals() methods. | |||||
*/ | |||||
public static boolean equals( final Object o1, final Object o2 ) | |||||
{ | |||||
if( o1 == null && o2 == null ) | |||||
{ | |||||
return true; | |||||
} | |||||
if( o1 == null || o2 == null ) | |||||
{ | |||||
return false; | |||||
} | |||||
return o1.equals( o2 ); | |||||
} | |||||
} |
@@ -28,6 +28,8 @@ import org.apache.myrmidon.components.configurer.DefaultConfigurer; | |||||
import org.apache.myrmidon.components.converter.DefaultConverterRegistry; | import org.apache.myrmidon.components.converter.DefaultConverterRegistry; | ||||
import org.apache.myrmidon.components.converter.DefaultMasterConverter; | import org.apache.myrmidon.components.converter.DefaultMasterConverter; | ||||
import org.apache.myrmidon.components.deployer.DefaultDeployer; | import org.apache.myrmidon.components.deployer.DefaultDeployer; | ||||
import org.apache.myrmidon.components.deployer.DefaultClassLoaderManager; | |||||
import org.apache.myrmidon.components.deployer.ClassLoaderManager; | |||||
import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | ||||
import org.apache.myrmidon.components.role.DefaultRoleManager; | import org.apache.myrmidon.components.role.DefaultRoleManager; | ||||
import org.apache.myrmidon.components.type.DefaultTypeManager; | import org.apache.myrmidon.components.type.DefaultTypeManager; | ||||
@@ -41,6 +43,7 @@ import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
import org.apache.myrmidon.interfaces.type.TypeException; | import org.apache.myrmidon.interfaces.type.TypeException; | ||||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | ||||
import org.apache.myrmidon.converter.Converter; | import org.apache.myrmidon.converter.Converter; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* A base class for tests for the default components. | * A base class for tests for the default components. | ||||
@@ -48,7 +51,7 @@ import org.apache.myrmidon.converter.Converter; | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public abstract class AbstractComponentTest | public abstract class AbstractComponentTest | ||||
extends TestCase | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
private DefaultComponentManager m_componentManager; | private DefaultComponentManager m_componentManager; | ||||
private Logger m_logger; | private Logger m_logger; | ||||
@@ -117,6 +120,11 @@ public abstract class AbstractComponentTest | |||||
m_componentManager.put( Deployer.ROLE, component ); | m_componentManager.put( Deployer.ROLE, component ); | ||||
components.add( component ); | components.add( component ); | ||||
final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager(); | |||||
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() ); | |||||
m_componentManager.put( ClassLoaderManager.ROLE, classLoaderMgr ); | |||||
components.add( classLoaderMgr ); | |||||
component = new DefaultExtensionManager(); | component = new DefaultExtensionManager(); | ||||
m_componentManager.put( ExtensionManager.ROLE, component ); | m_componentManager.put( ExtensionManager.ROLE, component ); | ||||
components.add( component ); | components.add( component ); | ||||
@@ -162,32 +170,4 @@ public abstract class AbstractComponentTest | |||||
factory.addNameClassMapping( converterClass.getName(), converterClass.getName() ); | factory.addNameClassMapping( converterClass.getName(), converterClass.getName() ); | ||||
getTypeManager().registerType( Converter.class, converterClass.getName(), factory ); | getTypeManager().registerType( Converter.class, converterClass.getName(), factory ); | ||||
} | } | ||||
/** | |||||
* Asserts that an exception contains the expected message. | |||||
* | |||||
* TODO - should take the expected exception, rather than the message, | |||||
* to check the entire cause chain. | |||||
*/ | |||||
protected void assertSameMessage( final String message, final Throwable throwable ) | |||||
{ | |||||
assertEquals( message, throwable.getMessage() ); | |||||
} | |||||
/** | |||||
* Compares 2 objects for equality, nulls are equal. Used by the test | |||||
* classes' equals() methods. | |||||
*/ | |||||
public static boolean equals( final Object o1, final Object o2 ) | |||||
{ | |||||
if( o1 == null && o2 == null ) | |||||
{ | |||||
return true; | |||||
} | |||||
if( o1 == null || o2 == null ) | |||||
{ | |||||
return false; | |||||
} | |||||
return o1.equals( o2 ); | |||||
} | |||||
} | } |
@@ -16,6 +16,11 @@ import org.apache.myrmidon.interfaces.deployer.TypeDefinition; | |||||
import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | ||||
import org.apache.myrmidon.interfaces.role.RoleManager; | import org.apache.myrmidon.interfaces.role.RoleManager; | ||||
import org.apache.myrmidon.interfaces.type.TypeFactory; | import org.apache.myrmidon.interfaces.type.TypeFactory; | ||||
import org.apache.myrmidon.interfaces.type.TypeManager; | |||||
import org.apache.myrmidon.interfaces.type.TypeException; | |||||
import org.apache.myrmidon.converter.ConverterException; | |||||
import org.apache.myrmidon.converter.Converter; | |||||
import java.io.File; | |||||
/** | /** | ||||
* Test cases for the default deployer. | * Test cases for the default deployer. | ||||
@@ -25,7 +30,12 @@ import org.apache.myrmidon.interfaces.type.TypeFactory; | |||||
public class DefaultDeployerTest | public class DefaultDeployerTest | ||||
extends AbstractComponentTest | extends AbstractComponentTest | ||||
{ | { | ||||
private static final String TEST_TYPE1_NAME = "test-type1"; | |||||
private static final String DATA_TYPE_ROLE = "data-type"; | |||||
private Deployer m_deployer; | private Deployer m_deployer; | ||||
private RoleManager m_roleManager; | |||||
private MasterConverter m_converter; | |||||
public DefaultDeployerTest( final String name ) | public DefaultDeployerTest( final String name ) | ||||
{ | { | ||||
@@ -40,6 +50,12 @@ public class DefaultDeployerTest | |||||
{ | { | ||||
super.setUp(); | super.setUp(); | ||||
m_deployer = (Deployer)getComponentManager().lookup( Deployer.ROLE ); | m_deployer = (Deployer)getComponentManager().lookup( Deployer.ROLE ); | ||||
m_converter = (MasterConverter)getComponentManager().lookup( MasterConverter.ROLE ); | |||||
// Add some core roles | |||||
m_roleManager = (RoleManager)getComponentManager().lookup( RoleManager.ROLE ); | |||||
m_roleManager.addNameRoleMapping( DATA_TYPE_ROLE, DataType.ROLE ); | |||||
m_roleManager.addNameRoleMapping( "converter", Converter.ROLE ); | |||||
} | } | ||||
/** | /** | ||||
@@ -47,27 +63,26 @@ public class DefaultDeployerTest | |||||
*/ | */ | ||||
public void testSingleType() throws Exception | public void testSingleType() throws Exception | ||||
{ | { | ||||
final String roleName = "data-type"; | |||||
final String typeName = "test-type1"; | |||||
final String typeName = TEST_TYPE1_NAME; | |||||
final String classname = TestType1.class.getName(); | final String classname = TestType1.class.getName(); | ||||
// Determine the shorthand for the DataType role | // Determine the shorthand for the DataType role | ||||
final RoleManager roleManager = (RoleManager)getComponentManager().lookup( RoleManager.ROLE ); | |||||
roleManager.addNameRoleMapping( roleName, DataType.ROLE ); | |||||
// Create the type definition | // Create the type definition | ||||
final TypeDefinition typeDef = new TypeDefinition( typeName, roleName, classname ); | |||||
final TypeDefinition typeDef = new TypeDefinition( typeName, DATA_TYPE_ROLE, classname ); | |||||
// Deploy the type | |||||
final ClassLoader classLoader = getClass().getClassLoader(); | final ClassLoader classLoader = getClass().getClassLoader(); | ||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | ||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered( ); | |||||
// Deploy the type | |||||
typeDeployer.deployType( typeDef ); | typeDeployer.deployType( typeDef ); | ||||
// Create an instance | |||||
// Check the type has been registered | |||||
final TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | final TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | ||||
final Object result = typeFactory.create( typeName ); | final Object result = typeFactory.create( typeName ); | ||||
// Check the type | |||||
assertTrue( result instanceof TestType1 ); | assertTrue( result instanceof TestType1 ); | ||||
} | } | ||||
@@ -84,16 +99,99 @@ public class DefaultDeployerTest | |||||
final ConverterDefinition typeDef = | final ConverterDefinition typeDef = | ||||
new ConverterDefinition( classname, source, destClass ); | new ConverterDefinition( classname, source, destClass ); | ||||
// Deploy the type | |||||
final ClassLoader classLoader = getClass().getClassLoader(); | final ClassLoader classLoader = getClass().getClassLoader(); | ||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | final TypeDeployer typeDeployer = m_deployer.createDeployer( classLoader ); | ||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered( ); | |||||
// Deploy the type | |||||
typeDeployer.deployType( typeDef ); | typeDeployer.deployType( typeDef ); | ||||
// Try to convert from string to test type | // Try to convert from string to test type | ||||
final MasterConverter converter = (MasterConverter)getComponentManager().lookup( MasterConverter.ROLE ); | |||||
final Object result = converter.convert( TestType1.class, "some-string", null ); | |||||
// Check the type | |||||
final Object result = m_converter.convert( TestType1.class, "some-string", null ); | |||||
assertTrue( result instanceof TestType1 ); | assertTrue( result instanceof TestType1 ); | ||||
} | } | ||||
/** | |||||
* Tests deployment of types from a typelib descriptor. | |||||
*/ | |||||
public void testLibDescriptor() throws Exception | |||||
{ | |||||
final File typelib = getTestResource( "test.atl" ); | |||||
assertTrue( "File " + typelib + " does not exist", typelib.exists() ); | |||||
final TypeDeployer typeDeployer = m_deployer.createDeployer( typelib ); | |||||
// Make sure the test types have not been deployed | |||||
assertTypesNotRegistered(); | |||||
// Deploy all the types from the descriptor | |||||
typeDeployer.deployAll(); | |||||
// Make sure the test types have been deployed | |||||
assertTypesRegistered(); | |||||
} | |||||
/** | |||||
* Ensures that the test types have not ben deployed. | |||||
*/ | |||||
private void assertTypesNotRegistered() throws Exception | |||||
{ | |||||
// Check the data-type | |||||
TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | |||||
try | |||||
{ | |||||
typeFactory.create( TEST_TYPE1_NAME ); | |||||
fail(); | |||||
} | |||||
catch( TypeException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
// Check the custom role implementation | |||||
typeFactory = getTypeManager().getFactory( TestRole1.class ); | |||||
try | |||||
{ | |||||
typeFactory.create( TEST_TYPE1_NAME ); | |||||
fail(); | |||||
} | |||||
catch( TypeException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
// Check the converter | |||||
try | |||||
{ | |||||
m_converter.convert( TestType1.class, "some string", null ); | |||||
fail(); | |||||
} | |||||
catch( ConverterException e ) | |||||
{ | |||||
// TODO - check error message | |||||
} | |||||
} | |||||
/** | |||||
* Ensures the types from the test typelib descriptor have been correctly | |||||
* deployed. | |||||
*/ | |||||
private void assertTypesRegistered( ) throws Exception | |||||
{ | |||||
// Check the data-type | |||||
TypeFactory typeFactory = getTypeManager().getFactory( DataType.class ); | |||||
Object object = typeFactory.create( TEST_TYPE1_NAME ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
// Check the custom role implementation | |||||
typeFactory = getTypeManager().getFactory( TestRole1.class ); | |||||
object = typeFactory.create( TEST_TYPE1_NAME ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
// Check the converter | |||||
object = m_converter.convert( TestType1.class, "some string", null ); | |||||
assertTrue( object instanceof TestType1 ); | |||||
} | |||||
} | } |
@@ -0,0 +1,18 @@ | |||||
/* | |||||
* 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.components.deployer; | |||||
/** | |||||
* A test role interface. | |||||
* | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||||
*/ | |||||
public interface TestRole1 | |||||
{ | |||||
String ROLE = TestRole1.class.getName(); | |||||
} |
@@ -15,6 +15,6 @@ import org.apache.myrmidon.framework.DataType; | |||||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | ||||
*/ | */ | ||||
public class TestType1 | public class TestType1 | ||||
implements DataType | |||||
implements DataType, TestRole1 | |||||
{ | { | ||||
} | } |
@@ -10,15 +10,16 @@ package org.apache.myrmidon.interfaces.type; | |||||
import java.io.File; | import java.io.File; | ||||
import java.net.URL; | import java.net.URL; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
/** | /** | ||||
* These are unit tests that test the basic operation of TypeFactorys. | |||||
* These are unit tests that test the basic operation of TypeFactories. | |||||
* | * | ||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class TypeFactoryTest | public class TypeFactoryTest | ||||
extends TestCase | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
private final static String TYPE_NAME1 = "my-type1"; | private final static String TYPE_NAME1 = "my-type1"; | ||||
private final static String TYPE_NAME2 = "my-type2"; | private final static String TYPE_NAME2 = "my-type2"; | ||||
@@ -27,9 +28,6 @@ public class TypeFactoryTest | |||||
private final static String TYPE_CLASSNAME1 = TYPE_CLASS1.getName(); | private final static String TYPE_CLASSNAME1 = TYPE_CLASS1.getName(); | ||||
private final static String TYPE_CLASSNAME2 = TYPE_CLASS2.getName(); | private final static String TYPE_CLASSNAME2 = TYPE_CLASS2.getName(); | ||||
private final static String TYPE_JAR = | |||||
"src/testcases/org/apache/myrmidon/interfaces/type/types.jar".replace( '/', File.separatorChar ); | |||||
public TypeFactoryTest( final String name ) | public TypeFactoryTest( final String name ) | ||||
{ | { | ||||
super( name ); | super( name ); | ||||
@@ -64,11 +62,10 @@ public class TypeFactoryTest | |||||
public void testReloadingTypeFactory() | public void testReloadingTypeFactory() | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
final File file = new File( TYPE_JAR ); | |||||
assertTrue( "Support Jar exists", file.exists() ); | |||||
final File file = getTestResource( "types.jar" ); | |||||
assertTrue( "Support Jar " + file + " exists", file.exists() ); | |||||
final URL[] classpath = new URL[]{file.toURL()}; | final URL[] classpath = new URL[]{file.toURL()}; | ||||
final ClassLoader classLoader = getClass().getClassLoader(); | |||||
final ReloadingTypeFactory factory = new ReloadingTypeFactory( classpath, null ); | final ReloadingTypeFactory factory = new ReloadingTypeFactory( classpath, null ); | ||||
factory.addNameClassMapping( TYPE_NAME1, TYPE_CLASSNAME1 ); | factory.addNameClassMapping( TYPE_NAME1, TYPE_CLASSNAME1 ); | ||||