donaldp     2002/10/06 22:25:54

  Added:       loader/src/java/org/apache/excalibur/loader/builder
                        LoaderBuilder.java LoaderResolver.java
  Log:
  Add in the start of the ClassLoader building code
  
  Revision  Changes    Path
  1.1                  
jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/LoaderBuilder.java
  
  Index: LoaderBuilder.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.loader.builder;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Map;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.excalibur.loader.metadata.ClassLoaderMetaData;
  import org.apache.excalibur.loader.metadata.ClassLoaderSetMetaData;
  import org.apache.excalibur.loader.metadata.FileSetMetaData;
  import org.apache.excalibur.loader.metadata.JoinMetaData;
  
  /**
   * This class is responsible for building the set of
   * actual {@link java.lang.ClassLoader}s out of the
   * {@link ClassLoaderSetMetaData} objects.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/10/07 05:25:54 $
   */
  public class LoaderBuilder
  {
      public Map buildClassLoaders( final ClassLoaderSetMetaData set,
                                    final LoaderResolver policy,
                                    final Map predefined )
          throws Exception
      {
          final HashMap classLoaders = new HashMap();
  
          addPredefined( set.getPredefined(), predefined, classLoaders );
          addAllClassLoaders( set, policy, classLoaders );
  
          return classLoaders;
      }
  
      private void addAllClassLoaders( final ClassLoaderSetMetaData set,
                                       final LoaderResolver policy,
                                       final Map classLoaders )
          throws Exception
      {
          final ClassLoaderMetaData[] classLoaderDefs = set.getClassLoaders();
          for( int i = 0; i < classLoaderDefs.length; i++ )
          {
              final String name = classLoaderDefs[ i ].getName();
              processClassLoader( name, set, policy, classLoaders );
              final ClassLoader classLoader =
                  buildRegularClassLoader( classLoaderDefs[ i ], policy, classLoaders 
);
              classLoaders.put( name, classLoader );
          }
      }
  
      private void processClassLoader( final String name,
                                       final ClassLoaderSetMetaData set,
                                       final LoaderResolver policy,
                                       final Map classLoaders )
          throws Exception
      {
          if( classLoaders.containsKey( name ) )
          {
              return;
          }
  
          final ClassLoaderMetaData regular = set.getClassLoader( name );
          if( null != regular )
          {
              //Make sure parent classloader is built
              processClassLoader( regular.getParent(),
                                  set,
                                  policy,
                                  classLoaders );
  
              final ClassLoader classLoader =
                  buildRegularClassLoader( regular, policy, classLoaders );
              classLoaders.put( name, classLoader );
          }
          else
          {
              final JoinMetaData join = set.getJoin( name );
  
              //Make sure all our dependencies are processed
              final String[] names = join.getClassloaders();
              for( int i = 0; i < names.length; i++ )
              {
                  processClassLoader( names[ i ], set, policy, classLoaders );
              }
              final ClassLoader classLoader =
                  buildJoinClassLoader( join, policy, classLoaders );
              classLoaders.put( name, classLoader );
          }
      }
  
      /**
       * Create a Join ClassLoader.
       *
       * @param join the metadata
       * @param policy the policy to use to resolve URLs etc
       * @param classLoaders the already created ClassLoaders
       * @return the created JoinClassLoader
       */
      private ClassLoader buildJoinClassLoader( final JoinMetaData join,
                                                final LoaderResolver policy,
                                                final Map classLoaders )
          throws Exception
      {
          final ArrayList list = new ArrayList();
          final String[] names = join.getClassloaders();
          for( int i = 0; i < names.length; i++ )
          {
              list.add( classLoaders.get( names[ i ] ) );
          }
  
          final ClassLoader[] elements =
              (ClassLoader[])list.toArray( new ClassLoader[ list.size() ] );
  
          return policy.createJoinClassLoader( elements );
      }
  
      /**
       * Build a regular classloader with entries, extensions
       * and filesets fully resolved.
       *
       * @param metaData the classloader definition
       * @param policy the policy to use when creating URLs/Extensions etc
       * @param classLoaders the already created ClassLoaders
       * @return the created ClassLoader
       * @throws Exception if unable to create ClassLoader
       */
      private ClassLoader buildRegularClassLoader( final ClassLoaderMetaData metaData,
                                                   final LoaderResolver policy,
                                                   final Map classLoaders )
          throws Exception
      {
          final ClassLoader parent =
              getParentClassLoader( metaData.getName(),
                                    metaData.getParent(),
                                    classLoaders );
          final ArrayList urlSet = new ArrayList();
  
          final String[] entrys = metaData.getEntrys();
          for( int i = 0; i < entrys.length; i++ )
          {
              final URL url = policy.resolveURL( entrys[ i ] );
              urlSet.add( url );
          }
  
          //Add all filesets defined for classloader
          final FileSetMetaData[] filesets = metaData.getFilesets();
          for( int i = 0; i < filesets.length; i++ )
          {
              final FileSetMetaData fileset = filesets[ i ];
              final String baseDirectory = fileset.getBaseDirectory();
              final String[] includes = fileset.getIncludes();
              final String[] excludes = fileset.getExcludes();
              final URL[] urls =
                  policy.resolveFileSet( baseDirectory,
                                         includes,
                                         excludes );
              for( int j = 0; j < urls.length; j++ )
              {
                  urlSet.add( urls[ j ] );
              }
          }
  
          final Extension[] extensions = metaData.getExtensions();
          for( int i = 0; i < extensions.length; i++ )
          {
              final URL url = policy.resolveExtension( extensions[ i ] );
              urlSet.add( url );
          }
  
          final URL[] urls = (URL[])urlSet.toArray( new URL[ urlSet.size() ] );
          return policy.createClassLoader( parent, urls );
      }
  
      /**
       * Return the parent classloader for a particular classloader.
       *
       * @param name the name of classloader that has the parent
       * @param parentName the parent classloaders name
       * @param classLoaders the set of defined classloaders
       * @return the parent classloader (if any)
       */
      private ClassLoader getParentClassLoader( final String name,
                                                final String parentName,
                                                final Map classLoaders )
      {
          final ClassLoader parent =
              (ClassLoader)classLoaders.get( parentName );
          if( null == parent )
          {
              final String message =
                  "Missing " + name + "'s parent ClassLoader " + parentName;
              throw new IllegalArgumentException( message );
          }
          return parent;
      }
  
      /**
       * Add all the predefined classloaders to the set of available
       * ClassLoaders.
       *
       * @param entrys the names of predefined classloaders
       * @param predefined the map containg predefined classloaders
       * @param classLoaders the destination map of classloaders
       */
      private void addPredefined( final String[] entrys,
                                  final Map predefined,
                                  final HashMap classLoaders )
      {
          for( int i = 0; i < entrys.length; i++ )
          {
              final String name = entrys[ i ];
              final ClassLoader classLoader =
                  (ClassLoader)predefined.get( name );
              if( null == classLoader )
              {
                  final String message =
                      "Missing predefined ClassLoader " + name;
                  throw new IllegalArgumentException( message );
              }
              classLoaders.put( name, classLoader );
          }
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/LoaderResolver.java
  
  Index: LoaderResolver.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.loader.builder;
  
  import java.net.URL;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * This is the class that clients provide to implement
   * a specific policy with respect to how ClassLoader
   * hierarchy is constructed.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/10/07 05:25:54 $
   */
  public interface LoaderResolver
  {
      /**
       * Resolve an Extension to a URL.
       * The URL that locates the "Optional Package" that
       * provides specified Extension.
       *
       * @param extension the extension
       * @return the URL that locates the "Optional Package" that
       *         provides specified Extension.
       * @throws Exception if unable to locate Extension
       */
      URL resolveExtension( Extension extension )
          throws Exception;
  
      /**
       * Resolve a string into a URL.
       * This allows resolvers to anchor URLs using relative URL
       * or by handling non-standard URL protocols
       * (such as "sar:/SAR-INF/lib/cornerstone.jar").
       *
       * @param location the location to transform into a URL
       * @return the URL
       * @throws Exception if unable to resolve URL
       */
      URL resolveURL( String location )
          throws Exception;
  
      /**
       * Resolve a fileset to a set of URLs.
       *
       * @param baseDirectory the Base directory of fileset
       * @return the set of URLs making up fileset
       * @throws Exception if unable to resolve fileset
       */
      URL[] resolveFileSet( String baseDirectory,
                            String[] includes,
                            String[] excludes )
          throws Exception;
  
      /**
       * Create a Join ClassLoader for specified ClassLoaders.
       *
       * @param classLoaders the ClassLoaders to "join"
       * @return the joined ClassLoader
       * @throws Exception if unable to create classloader
       */
      ClassLoader createJoinClassLoader( ClassLoader[] classLoaders )
          throws Exception;
  
      /**
       * Create a ClassLoader with specified parent and
       * containing specified URLs.
       *
       * @param parent the parent classloader
       * @param urls the URLs that the ClassLoader should contain
       * @return the newly created ClassLoader
       * @throws Exception if unable to create classloader
       */
      ClassLoader createClassLoader( ClassLoader parent, URL[] urls )
          throws Exception;
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to