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>