You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/07/03 21:08:55 UTC
cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel Container.java ContainerClassLoader.java DefaultContainer.java DefaultContainer.xinfo DefaultKernel.java DefaultKernel.xinfo Fileset.java Kernel.java Main.java Resources.properties Verifiable.java package.html
mcconnell 2002/07/03 12:08:55
Added: assembly/src/java/org/apache/excalibur/merlin/kernel
Container.java ContainerClassLoader.java
DefaultContainer.java DefaultContainer.xinfo
DefaultKernel.java DefaultKernel.xinfo Fileset.java
Kernel.java Main.java Resources.properties
Verifiable.java package.html
Log:
Seperation of Kernel/Container/Registry
Revision Changes Path
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Container.java
Index: Container.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import org.apache.excalibur.containerkit.verifier.VerifyException;
/**
* A service that provides support for the management of a set of component types
* and factories.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public interface Container
{
/**
* Request the startup of the kernel.
*/
void startup() throws Exception;
/**
* Request the shutdown of the kernel.
*/
void shutdown();
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/ContainerClassLoader.java
Index: ContainerClassLoader.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.JarURLConnection;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.PackageManager;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.excalibur.merlin.registry.*;
/**
* Classloader for an assembly of components.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public class ContainerClassLoader extends URLClassLoader implements LogEnabled
{
//===================================================================
// static
//===================================================================
private static final Resources REZ =
ResourceManager.getPackageResources( ContainerClassLoader.class );
//===================================================================
// state
//===================================================================
private File[] m_stack;
/**
* List of names of block implementation classes.
*/
private final List m_blocks = new LinkedList();
private PackageManager m_manager;
private Logger m_logger;
//===================================================================
// constructor
//===================================================================
ContainerClassLoader( ClassLoader parent, Configuration classpath, Logger logger )
{
this( null, parent, classpath, logger );
}
ContainerClassLoader(
PackageRepository repository, ClassLoader parent, Configuration classpath, Logger logger )
{
super( new URL[ 0 ], parent );
m_logger = logger;
if( repository != null )
m_manager = new PackageManager( repository );
addClasspath( classpath );
}
public void addClasspath( Configuration classpath )
{
try
{
URL[] urls = Fileset.expandClasspath( classpath );
for( int i = 0; i < urls.length; i++ )
{
addURL( urls[ i ] );
}
String[] path = Fileset.urlsToStrings( urls );
final File[] extensions = getOptionalPackagesFor( path );
for( int i = 0; i < extensions.length; i++ )
{
addURL( extensions[ i ].toURL() );
}
}
catch( Throwable e )
{
final String error = "Unexpected exception while creating classloader";
throw new RegistryRuntimeException( error, e );
}
}
//===================================================================
// LogEnabled
//===================================================================
public void enableLogging( Logger logger )
{
m_logger = logger;
}
public Logger getLogger()
{
return m_logger;
}
//===================================================================
// ClassLoader
//===================================================================
/**
*
*/
protected void addURL( URL url )
{
try
{
super.addURL( url );
getLogger().debug("scanning: " + url );
String[] entries = getBlocksEntries( url );
for( int i=0; i<entries.length; i++ )
{
getLogger().debug("component: " + entries[i] );
m_blocks.add( entries[i] );
}
}
catch( Throwable e )
{
throw new CascadingRuntimeException(
"Unexpected error while attempting to add classloader URL: " + url, e );
}
}
//===================================================================
// ClassLoader extensions
//===================================================================
/**
* Returns TRUE is the component classname is know by the classloader.
* @return a component availablity status
*/
public boolean hasComponent( String classname )
{
return m_blocks.contains( classname );
}
/**
* Return the array of component implementation class names within the scope
* of the classloader.
* @return the block names array
*/
public String[] getComponentClassnames()
{
return (String[]) m_blocks.toArray( new String[0] );
}
//===================================================================
// internals
//===================================================================
/**
* Returns an array of <code>String</code>s corresponding to the set of classnames
* where each classname is a declared block within the supplied jar file.
* @param file a jar file
* @exception RegistryRuntimeException if a general exception occurs
*/
private String[] getBlocksEntries( URL base )
throws RegistryRuntimeException
{
Vector vector = new Vector();
try
{
final URL url = new URL( "jar:" + base.toString() + "!/" );
final JarURLConnection jar = (JarURLConnection)url.openConnection();
final Map map = jar.getManifest().getEntries();
final Iterator iterator = map.keySet().iterator();
while( iterator.hasNext() )
{
final String name = (String)iterator.next();
final Attributes attributes = (Attributes)map.get( name );
final Iterator it = attributes.keySet().iterator();
while( it.hasNext() )
{
final Object entry = it.next();
if( entry.toString().equals( "Avalon-Block" ) )
{
if( attributes.get( entry ).equals( "true" ) )
{
vector.add( name.substring( 0, name.indexOf( ".class" ) ) );
}
}
}
}
}
catch( IOException e )
{
final String error = "IO exception while attempt to read block manifest.";
throw new RegistryRuntimeException( error, e );
}
catch( Throwable e )
{
final String error = "Unexpected exception while inspecting manifest on file: ";
throw new RegistryRuntimeException( error + base, e );
}
finally
{
return (String[]) vector.toArray( new String[0] );
}
}
/**
* Retrieve the files for the optional packages required by
* the jars in ClassPath.
*
* @param classPath the Classpath array
* @return the files that need to be added to ClassLoader
*/
private File[] getOptionalPackagesFor( final String[] classPath )
throws Exception
{
if( m_manager == null )
{
ClassLoader parent = getParent();
if( parent != null )
{
if( parent instanceof ContainerClassLoader )
{
return ((ContainerClassLoader)parent).getOptionalPackagesFor( classPath );
}
}
else
{
return new File[0];
}
}
final Manifest[] manifests = getManifests( classPath );
final Extension[] available = Extension.getAvailable( manifests );
final Extension[] required = Extension.getRequired( manifests );
final ArrayList dependencies = new ArrayList();
final ArrayList unsatisfied = new ArrayList();
m_manager.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", new Integer( size ) );
throw new Exception( message );
}
final OptionalPackage[] packages =
(OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] );
return OptionalPackage.toFiles( packages );
}
private Manifest[] getManifests( final String[] classPath )
throws Exception
{
final ArrayList manifests = new ArrayList();
for( int i = 0; i < classPath.length; i++ )
{
final String element = classPath[ i ];
if( element.endsWith( ".jar" ) )
{
try
{
final URL url = new URL( "jar:" + element + "!/" );
final JarURLConnection connection = (JarURLConnection)url.openConnection();
final Manifest manifest = connection.getManifest();
manifests.add( manifest );
}
catch( final IOException ioe )
{
final String message = REZ.getString( "bad-classpath-entry", element );
getLogger().warn( message );
throw new Exception( message );
}
}
}
return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultContainer.java
Index: DefaultContainer.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import java.io.FileInputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.log.Hierarchy;
import org.apache.log.Priority;
import org.apache.log.output.io.StreamTarget;
import org.apache.excalibur.merlin.registry.DefaultRegistry;
import org.apache.excalibur.containerkit.verifier.VerifyException;
/**
* Default container implementation that manages a registry of componet providers and
* a registry of child containers.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public class DefaultContainer extends AbstractLogEnabled implements Container, Verifiable, Contextualizable, Configurable, Initializable
{
//=======================================================================
// static
//=======================================================================
/**
* Context key used to locate the application classloader.
*/
public static final String CLASSLOADER_KEY = "classloader";
/**
* Context key used to locate the application classloader.
*/
public static final String CONTAINER_KEY = "container";
//=======================================================================
// state
//=======================================================================
/**
* The container context.
*/
private Context m_context;
/**
* Configuration.
*/
private Configuration m_config;
/**
* The registry of components.
*/
private DefaultRegistry m_components;
/**
* The registry of embedded containers.
*/
private DefaultRegistry m_containers;
/**
* Classloader.
*/
private ContainerClassLoader m_classloader;
/**
* Parent container.
*/
private Container m_parent;
//=======================================================================
// Contextualizable
//=======================================================================
/**
* Service context from which the registry classloader is resolved.
* @param context a context value containing the key 'classloader'
*/
public void contextualize( Context context ) throws ContextException
{
m_context = context;
m_classloader = (ContainerClassLoader) context.get( CLASSLOADER_KEY );
try
{
m_parent = (Container) context.get( CONTAINER_KEY );
}
catch( ContextException e )
{
// no parent container
}
}
//=======================================================================
// Configurable
//=======================================================================
/**
* Invoked by the container to establish the registry configuration.
* @param config a component configuration
*/
public void configure( Configuration config)
{
m_config = config;
getLogger().debug("configuration");
}
//=======================================================================
// Initializable
//=======================================================================
/**
* Initalization of a <code>Container</code>.
* @exception Exception if an error occurs during initialization.
*/
public void initialize() throws Exception
{
m_components = createComponentRegistry( m_config.getChild( "components") );
m_containers = createContainerRegistry( m_config.getChild( "containers") );
}
//=======================================================================
// Verifiable
//=======================================================================
/**
* Method invoked by a parent container to request type and assembly validation of
* this container.
*
* @exception ValidationException if a validation failure occurs
*/
public void verify() throws VerifyException
{
m_components.verify();
m_containers.verify();
}
//=======================================================================
// DefaultContainer
//=======================================================================
private DefaultRegistry createComponentRegistry( Configuration config ) throws Exception
{
return createRegistry( m_classloader, config );
}
private DefaultRegistry createContainerRegistry( Configuration config ) throws Exception
{
final ContainerClassLoader loader = new ContainerClassLoader(
m_classloader,
config.getChild("classpath"),
getLogger().getChildLogger( config.getName())
);
return createRegistry( loader, config );
}
private DefaultRegistry createRegistry( final ContainerClassLoader loader, final Configuration config ) throws Exception
{
DefaultContext context = new DefaultContext();
context.put( DefaultRegistry.CLASSLOADER_KEY, loader );
context.put( DefaultRegistry.CONTAINER_KEY, this );
DefaultRegistry registry = new DefaultRegistry();
registry.enableLogging( getLogger().getChildLogger( config.getName() ) );
registry.contextualize( context );
registry.configure( config );
registry.initialize( );
return registry;
}
//=======================================================================
// Container
//=======================================================================
public void startup() throws Exception
{
getLogger().debug("startup");
//m_registry.execute();
}
public void shutdown()
{
getLogger().debug("shutdown");
//m_registry.dispose();
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultContainer.xinfo
Index: DefaultContainer.xinfo
===================================================================
<?xml version="1.0"?>
<!--
Copyright (C) The Apache Software Foundation. All rights reserved.
This software is published under the terms of the Apache Software License
version 1.1, a copy of which has been included with this distribution in
the LICENSE.txt file.
@author Stephen McConnell
@version 1.0 12/03/2001
-->
<component-info>
<component>
<name>container</name>
<version>1.0</version>
</component>
<context>
<entry key="classloader" type="org.apache.exccalibur.merlin.kernel.ContainerClassLoader" optional="false"/>
</context>
<services>
<service>
<service-ref type="org.apache.excalibur.merlin.kernel.Container" version="1.0"/>
</service>
</services>
</component-info>
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
Index: DefaultKernel.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import java.io.FileInputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.log.Hierarchy;
import org.apache.log.Priority;
import org.apache.log.output.io.StreamTarget;
import org.apache.excalibur.merlin.registry.DefaultRegistry;
/**
* Default kernel implementation.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public class DefaultKernel extends AbstractLogEnabled
implements Kernel, Configurable, Initializable
{
//=======================================================================
// state
//=======================================================================
private Configuration m_config;
private DefaultContainer m_container = new DefaultContainer();
//=======================================================================
// Configurable
//=======================================================================
/**
* Invoked by the container to establish the registry configuration.
* @param config a component configuration
*/
public void configure( Configuration config)
{
m_config = config;
getLogger().debug("configuration");
}
//=======================================================================
// Initializable
//=======================================================================
public void initialize() throws Exception
{
final ContainerClassLoader loader = new ContainerClassLoader(
new DefaultPackageRepository(
Fileset.expandExtensions( m_config.getChild( "extensions" ) )
),
Thread.currentThread().getContextClassLoader(),
m_config.getChild("classpath"),
getLogger().getChildLogger( m_config.getName())
);
DefaultContext context = new DefaultContext();
context.put( DefaultContainer.CLASSLOADER_KEY, loader );
m_container.enableLogging( getLogger().getChildLogger("container") );
m_container.contextualize( context );
m_container.configure( m_config );
m_container.initialize( );
}
//=======================================================================
// Startable
//=======================================================================
public void startup() throws Exception
{
m_container.startup();
}
public void shutdown()
{
m_container.shutdown();
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.xinfo
Index: DefaultKernel.xinfo
===================================================================
<?xml version="1.0"?>
<!--
Copyright (C) The Apache Software Foundation. All rights reserved.
This software is published under the terms of the Apache Software License
version 1.1, a copy of which has been included with this distribution in
the LICENSE.txt file.
@author Stephen McConnell
@version 1.0 12/03/2001
-->
<component-info>
<component>
<name>kernel</name>
<version>1.0</version>
</component>
<services>
<service>
<service-ref type="org.apache.excalibur.merlin.kernel.Kernel" version="1.0"/>
</service>
</services>
</component-info>
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Fileset.java
Index: Fileset.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import org.apache.avalon.framework.configuration.Configuration;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.File;
import java.util.Vector;
import java.util.StringTokenizer;
/**
* Provides support for general manipulation of configuration fragments
* related to classpath and fileset declarations.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
class Fileset
{
//=======================================================================
// static
//=======================================================================
public static File[] expandExtensions( Configuration conf )
{
Vector vector = new Vector();
Configuration[] dirsets = conf.getChildren("dirset");
for( int i=0; i<dirsets.length; i++ )
{
expandDirSetToVector( vector, dirsets[i] );
}
return (File[]) vector.toArray( new File[ vector.size() ] );
}
public static URL[] expandClasspath( Configuration conf )
{
Vector vector = new Vector();
Configuration[] filesets = conf.getChildren("fileset");
for( int i=0; i<filesets.length; i++ )
{
expandFileSetToVector( vector, filesets[i] );
}
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
public static URL[] expandFileSet( Configuration conf )
{
Vector vector = new Vector();
expandFileSetToVector( vector, conf );
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
private static void expandDirSetToVector( Vector vector, Configuration dirset )
{
File base = new File( dirset.getAttribute("dir", System.getProperty("user.dir") ) );
if( !base.isDirectory() )
throw new IllegalArgumentException("Base dir does not refer to a directory in path: " + base );
Configuration[] includes = dirset.getChildren("include");
for( int i=0; i<includes.length; i++ )
{
String name = includes[i].getAttribute("name", null );
if( name == null )
throw new IllegalArgumentException(
"Include does not contain the name attribute: " + includes[i].getLocation() );
File file = new File( base, name );
if( file.isDirectory() )
{
vector.add( file );
}
else
{
throw new IllegalArgumentException(
"Include dir does not refer to a directory: " + file + ", base: " + base );
}
}
}
private static void expandFileSetToVector( Vector vector, Configuration conf )
{
File base = new File( conf.getAttribute("dir", System.getProperty("user.dir") ) );
if( !base.isDirectory() )
throw new IllegalArgumentException("Base dir does not refer to a directory in path: " + base );
Configuration[] includes = conf.getChildren("include");
for( int i=0; i<includes.length; i++ )
{
String name = includes[i].getAttribute("name", null );
if( name == null )
throw new IllegalArgumentException(
"Include does not contain the name attribute: " + includes[i].getLocation() );
File file = new File( base, name );
if( !file.exists() )
throw new IllegalArgumentException(
"Include references file that does not exist: " + includes[i].getLocation() );
try
{
vector.add( file.toURL() );
}
catch( Throwable e )
{
throw new IllegalArgumentException(
"Could not convert include to a URL: " + includes[i].getLocation() );
}
}
}
public static String[] splitPath( String path, String token )
{
StringTokenizer tokenizer = new StringTokenizer( path, token );
Vector vector = new Vector();
while( tokenizer.hasMoreElements() )
{
vector.add( tokenizer.nextToken() );
}
return (String[]) vector.toArray( new String[ vector.size() ] );
}
public static File[] expandPath( String[] path )
{
Vector vector = new Vector();
for( int i=0; i<path.length; i++ )
{
File file = new File( path[i] );
vector.add( file );
if( file.isDirectory() )
{
expandDirectory( vector, file );
}
}
return (File[]) vector.toArray( new File[ vector.size() ] );
}
private static void expandDirectory( Vector vector, File dir )
{
if( !dir.isDirectory() ) return;
final File[] files = dir.listFiles();
for( int i=0; i<files.length; i++ )
{
File file = files[i];
vector.add( file );
if( file.isDirectory() )
{
expandDirectory( vector, file );
}
}
}
public static String[] urlsToStrings( URL[] urls )
{
Vector vector = new Vector();
for( int i=0; i<urls.length; i++ )
{
vector.add( urls[i].toString() );
}
return (String[]) vector.toArray( new String[ vector.size() ] );
}
public static URL[] fileToURL( File[] files ) throws MalformedURLException
{
Vector vector = new Vector();
for( int i=0; i<files.length; i++ )
{
vector.add( files[i].toURL() );
}
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Kernel.java
Index: Kernel.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
/**
* A service that provides support for the hosting of multiple containers.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public interface Kernel extends Container
{
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Main.java
Index: Main.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import java.io.FileInputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.log.Hierarchy;
import org.apache.log.Priority;
import org.apache.log.output.io.StreamTarget;
import org.apache.excalibur.merlin.registry.DefaultRegistry;
/**
* Application bootstrap.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public class Main
{
//=======================================================================
// static
//=======================================================================
private static final String DEFAULT_FORMAT =
"[%7.7{priority}] (%{category}): %{message}\\n%{throwable}";
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultRegistry.class );
/**
* Creation of a root type registry.
*/
public static void main( String[] args )
{
final DefaultKernel kernel = new DefaultKernel();
// get a configuration object containing the kernel profile
// from which we can establish the logger and extensions directory
String path = null;
Configuration config = null;
if( args.length > 0 )
{
path = args[0];
config = getProfile( new File( path ) );
}
else
{
throw new RuntimeException("Missing kernel configuration path argument.");
}
// create a bootstrap logger - this needs to be replaced with
// the Avalon Exvalibur Logkit package
final Logger logger = getLogger( config );
DefaultContext context = new DefaultContext();
try
{
kernel.enableLogging( logger );
kernel.configure( config );
kernel.initialize( );
}
catch( Throwable e )
{
logger.error("Unexpected error while processing kernel lifecycle.", e);
System.exit(0);
}
//
// add a shutdown hook so we can stop services and target and invoke shutdown
//
Runtime.getRuntime().addShutdownHook(
new Thread()
{
public void run()
{
kernel.shutdown();
}
}
);
// invoke the registry demo
try
{
kernel.startup();
}
catch( Throwable e )
{
logger.error("Kernel startup failure.", e );
System.exit(0);
}
}
private static Logger getLogger( Configuration config )
{
// create an internal logger for the registry
final Hierarchy hierarchy = createHierarchy(
Priority.getPriorityForName(
config.getChild("logger").getAttribute("priority","INFO")
)
);
return new LogKitLogger( hierarchy.getLoggerFor( "" ) );
}
private static Hierarchy createHierarchy( Priority priority )
{
try
{
Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
hierarchy.setDefaultLogTarget(
new StreamTarget( System.out, new AvalonFormatter( DEFAULT_FORMAT ) ) );
hierarchy.setDefaultPriority( priority );
return hierarchy;
}
catch( Throwable e )
{
final String error = "Unexpected exception while creating bootstrap logger.";
throw new CascadingRuntimeException( error, e );
}
}
private static Configuration getProfile( final File file )
{
try
{
DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
InputStream is = new FileInputStream( file );
if( is == null )
{
throw new RuntimeException(
"Could not load the configuration resource \"" + file + "\"" );
}
return builder.build( is );
}
catch( Throwable e )
{
final String error = "Unable to create configuration from file: " + file;
throw new CascadingRuntimeException( error, e );
}
}
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Resources.properties
Index: Resources.properties
===================================================================
xinfo-load=Creating ComponentInfo from {0}.
xinfo-missing=XINFO resource unavailable for class "{0}".
xinfo-parse-error=Error occured while parsing xinfo resource "{0}".
xinfo-nocreate=Failed to create ComponentInfo from resource "{0}" (Reason: {1}).
xinfo-props-error=Unable to construct attributes using key "{0}" (Reason: {1}).
cinfo-nocreate=Failed to create ComponentDescriptor from resource "{0}" (Reason: {1}).
cinfo-properties-error=Failed to create ComponentInfo attributes from resource "{0}" (Reason: {1}).
sinfo-noname=Missing name attribute in service declaration from resource "{0}".
sinfo-version=Bad service version in resource "(Reason: {0})".
sinfo-nocreate=Failed to create ServiceInfo from resource "{0}" (Reason: {1}).
dinfo-service-error="Could not create dependecy service delcaration (Reason: {0}).
dinfo-nocreate="Could not create dependecy delcaration from resource "{0}" (Reason: {1}).
missing.extension=Unable to locate an extension that is required by application.\n Extension Name: {0}\n Specification Vendor: {1}\n Specification Version: {2}\n Implementation Vendor: {3}\n Implementation Vendor-Id: {4}\n Implementation Version: {5}\n Implementation URL: {6}
unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader for application.
bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it impossible to load a manifest.
available-extensions=Available extensions: {0}
required-extensions=The list of required extensions for application includes: {0}
optional-packages-added=The list of "Optional Packages" added to the application include: {0}
classpath-entries=The list of classpath entrys for the application include: {0}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Verifiable.java
Index: Verifiable.java
===================================================================
/*
* 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.excalibur.merlin.kernel;
import org.apache.excalibur.containerkit.verifier.VerifyException;
/**
* A interface declaring operations related to type and assembly validation.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/03 19:08:54 $
*/
public interface Verifiable
{
/**
* Method invoked by a parent container to request type level validation of
* the container.
*
* @exception ValidationException if a validation failure occurs
*/
void verify() throws VerifyException;
}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/package.html
Index: package.html
===================================================================
<body>
<p>
The kernel package defines a top level {@link org.apache.excalibur.merlin.kernel.Kernel} that serves as a host to a root {@link org.apache.excalibur.merlin.kernel.Container} that provides support for container hierachy creation. The default kernel implementation handles the setup of the logging infrastructure, extension manager, and the root container.
</p>
<h3>Funtional Summary</h3>
<ul>
<li>Geneneric container architecture.
<li>Hierachical container composition.
</ul>
<h3>Key Features</h3>
<p>A primary objective of this container is to provide simple composition of applications and the management of service provission from parent to child containers with minimal administration overhead.</p>
<ul>
<li>Component-based architecture.
<li>Deployment as a stand-alone application or as an embedeed component.
<li>Fully configurable classpaths at the kernel and container levels.
<li>Support for cascading startup and shutdown.
<li>Protected classloader hierachy.
<li>Graceful management of interupts.
<li>Integral logging.
</ul>
<h3>Object Model</h3>
<p>An container is primarily a component type manager. Actual type management is handled by an embedded {@link org.apache.excalibur.merlin.registry.Registry} and the associated default implementation {@link org.apache.excalibur.merlin.registry.DefaultRegistry}. In addition to component type support, the container provides a framework from the creation of container hierachies. Services established in a parent container are available as potential candidate suppliers to component providers in sibling containers.
<h3>Package Structure (UML)</h3>
<!--<p><img src=doc-files/kernel.gif border=0></p>-->
</body>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>