bloritsch    2002/09/16 13:05:39

  Modified:    container/src/java/org/apache/excalibur/container/classloader
                        ComponentClassLoader.java
               
container/src/test/org/apache/excalibur/container/classloader/test
                        ComponentClassLoaderTestCase.java
  Added:       container/src/java/org/apache/excalibur/container/classloader
                        JarEntries.java JarScanner.java
  Log:
  separate out the scanner code into a helper class
  
  Revision  Changes    Path
  1.5       +10 -87    
jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/ComponentClassLoader.java
  
  Index: ComponentClassLoader.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/ComponentClassLoader.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ComponentClassLoader.java 12 Sep 2002 15:10:00 -0000      1.4
  +++ ComponentClassLoader.java 16 Sep 2002 20:05:39 -0000      1.5
  @@ -8,15 +8,8 @@
   
   package org.apache.excalibur.container.classloader;
   
  -import java.util.HashSet;
  -import java.util.Iterator;
  -import java.util.Map;
   import java.util.Set;
  -import java.util.jar.Attributes;
   
  -import java.io.IOException;
  -
  -import java.net.JarURLConnection;
   import java.net.URL;
   import java.net.URLClassLoader;
   import java.net.URLStreamHandlerFactory;
  @@ -32,14 +25,7 @@
    */
   public class ComponentClassLoader extends URLClassLoader
   {
  -    protected static final String AVALON = "Avalon";
  -    protected static final String BLOCK = AVALON + "-Block";
  -    protected static final String TYPE = "Type";
  -    protected static final String SERVICE = "Service";
  -
  -    private final Set m_blocks;
  -    private final Set m_types;
  -    private final Set m_services;
  +    private final JarEntries m_entries;
   
       /**
        * Constructs a new <code>ComponentClassLoader</code> and extracts a list
  @@ -68,14 +54,11 @@
                                    URLStreamHandlerFactory urlHandlerFactory )
       {
           super( classPath, parent, urlHandlerFactory );
  -
  -        m_blocks = new HashSet();
  -        m_types = new HashSet();
  -        m_services = new HashSet();
  +        m_entries = new JarEntries();
   
           for ( int i = 0; i < classPath.length; i++ )
           {
  -            scan( classPath[i] );
  +            m_entries.merge( JarScanner.scan( classPath[i] ) );
           }
       }
   
  @@ -87,7 +70,7 @@
       public void addURL( URL classPath )
       {
           super.addURL( classPath );
  -        scan ( classPath );
  +        m_entries.merge( JarScanner.scan( classPath ) );
       }
   
       /**
  @@ -96,7 +79,8 @@
        */
       public String[] getBlockEntries()
       {
  -        return (String[]) m_blocks.toArray( new String[ m_blocks.size() ] );
  +        Set blocks = m_entries.getBlockEntries();
  +        return (String[]) blocks.toArray( new String[ blocks.size() ] );
       }
   
       /**
  @@ -105,7 +89,8 @@
        */
       public String[] getTypeEntries()
       {
  -        return (String[]) m_types.toArray( new String[ m_types.size() ] );
  +        Set types = m_entries.getTypeEntries();
  +        return (String[]) types.toArray( new String[ types.size() ] );
       }
   
       /**
  @@ -113,70 +98,8 @@
        */
       public String[] getServiceEntries()
       {
  -        return (String[]) m_services.toArray( new String[ m_services.size() 
] );
  +        Set services = m_entries.getServiceEntries();
  +        return (String[]) services.toArray( new String[ services.size() ] );
       }
   
  -    /**
  -     * The logic to look through the manifest entries in the JAR url passed
  -     * in.  It is used to populate the sets of Services, Types, and Blocks.
  -     */
  -    protected void scan( URL jarLocation )
  -    {
  -        try
  -        {
  -            final JarURLConnection jar = (JarURLConnection)
  -                new URL( "jar:" + jarLocation.toString() + "!/" 
).openConnection();
  -
  -            final Map manifest = jar.getManifest().getEntries();
  -            final Iterator it = manifest.keySet().iterator();
  -
  -            while ( it.hasNext() )
  -            {
  -                final String entry = (String) it.next();
  -                final Attributes attributes = (Attributes)manifest.get( 
entry );
  -                final Iterator attrIt = attributes.keySet().iterator();
  -
  -                while( attrIt.hasNext() )
  -                {
  -                    final String attrName = attrIt.next().toString();
  -
  -                    if ( attrName.equals( BLOCK ) &&
  -                        attributes.getValue( attrName ).equals( "true" ) )
  -                    {
  -                        m_blocks.add( cleanName( entry ) );
  -                    }
  -                    else if ( attrName.equals( AVALON ) )
  -                    {
  -                        final String attrVal = attributes.getValue( attrName 
);
  -
  -                        if ( attrVal.equals( TYPE ) )
  -                        {
  -                            m_types.add( cleanName( entry ) );
  -                        }
  -                        else if ( attrVal.equals( SERVICE ) )
  -                        {
  -                            m_services.add( cleanName( entry ) );
  -                        }
  -                        else
  -                        {
  -                            // TODO: Handle error condition
  -                        }
  -                    }
  -                }
  -            }
  -        }
  -        catch ( IOException ioe )
  -        {
  -            // TODO: Handle error condition
  -        }
  -    }
  -
  -    /**
  -     * Strips the ".class" ending off of a Type/Block/Service name.
  -     */
  -    private final String cleanName( String name )
  -    {
  -        int end = name.indexOf( ".class" );
  -        return name.substring( 0, ( end >= 0 ) ? end : name.length() );
  -    }
   }
  
  
  
  1.1                  
jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/JarEntries.java
  
  Index: JarEntries.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.container.classloader;
  
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.Set;
  
  /**
   * A ClassLoader that lists all the entries of a particular type.  Using
   * this classloader we can resolve all the Avalon types and services,
   * and iterate through the list.  In all other ways, this
   * <code>ClassLoader</code> behaves identically to the
   * @link{java.net.URLClassLoader}
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public class JarEntries
  {
      private final Set m_blocks;
      private final Set m_types;
      private final Set m_services;
  
      /**
       * Constructs a new <code>ComponentClassLoader</code> and extracts a list
       * of services and components.
       */
      public JarEntries()
      {
          m_blocks = new HashSet();
          m_types = new HashSet();
          m_services = new HashSet();
      }
  
      /**
       * Allow JarScanner to add Block entries to this class.
       */
      protected void addBlockEntry( String entry )
      {
          m_blocks.add( entry );
      }
  
      /**
       * Allow JarScanner to add Type entries to this class.
       */
      protected void addTypeEntry( String entry )
      {
          m_types.add( entry );
      }
  
      /**
       * Allow JarScanner to add Service entries to this class.
       */
      protected void addServiceEntry( String entry )
      {
          m_services.add( entry );
      }
  
      /**
       * Get an array of the block names.  These are treated separately from
       * the generic <code>Type</code>
       */
      public Set getBlockEntries()
      {
          return Collections.unmodifiableSet( m_blocks );
      }
  
      /**
       * Get an array of the type names.  These are treated separately from
       * the Phoenix specific <code>Block</code>
       */
      public Set getTypeEntries()
      {
          return Collections.unmodifiableSet( m_types );
      }
  
      /**
       * Get an array of the service names.
       */
      public Set getServiceEntries()
      {
          return Collections.unmodifiableSet( m_services );
      }
  
      /**
       * Merge two different JarEntries into one
       */
      public void merge( JarEntries entries )
      {
          m_blocks.addAll( entries.getBlockEntries() );
          m_types.addAll( entries.getTypeEntries() );
          m_services.addAll( entries.getServiceEntries() );
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/JarScanner.java
  
  Index: JarScanner.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.container.classloader;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  import java.util.jar.Attributes;
  
  import java.io.IOException;
  
  import java.net.JarURLConnection;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.URLStreamHandlerFactory;
  
  /**
   * A ClassLoader that lists all the entries of a particular type.  Using
   * this classloader we can resolve all the Avalon types and services,
   * and iterate through the list.  In all other ways, this
   * <code>ClassLoader</code> behaves identically to the
   * @link{java.net.URLClassLoader}
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public final class JarScanner
  {
      protected static final String AVALON = "Avalon";
      protected static final String BLOCK = AVALON + "-Block";
      protected static final String TYPE = "Type";
      protected static final String SERVICE = "Service";
  
      private JarScanner()
      {}
  
      /**
       * The logic to look through the manifest entries in the JAR url passed
       * in.  It is used to populate the sets of Services, Types, and Blocks.
       */
      public static JarEntries scan( URL jarLocation )
      {
          JarEntries entries = new JarEntries();
  
          try
          {
              final JarURLConnection jar = (JarURLConnection)
                  new URL( "jar:" + jarLocation.toString() + "!/" 
).openConnection();
  
              final Map manifest = jar.getManifest().getEntries();
              final Iterator it = manifest.keySet().iterator();
  
              while ( it.hasNext() )
              {
                  final String entry = (String) it.next();
                  final Attributes attributes = (Attributes)manifest.get( entry 
);
                  final Iterator attrIt = attributes.keySet().iterator();
  
                  while( attrIt.hasNext() )
                  {
                      final String attrName = attrIt.next().toString();
  
                      if ( attrName.equals( BLOCK ) &&
                          attributes.getValue( attrName ).equals( "true" ) )
                      {
                          entries.addBlockEntry( cleanName( entry ) );
                      }
                      else if ( attrName.equals( AVALON ) )
                      {
                          final String attrVal = attributes.getValue( attrName 
);
  
                          if ( attrVal.equals( TYPE ) )
                          {
                              entries.addTypeEntry( cleanName( entry ) );
                          }
                          else if ( attrVal.equals( SERVICE ) )
                          {
                              entries.addServiceEntry( cleanName( entry ) );
                          }
                          else
                          {
                              // TODO: Handle error condition
                          }
                      }
                  }
              }
          }
          catch ( IOException ioe )
          {
              // TODO: Handle error condition
          }
  
          return entries;
      }
  
      /**
       * Strips the ".class" ending off of a Type/Block/Service name.
       */
      private static final String cleanName( String name )
      {
          int end = name.indexOf( ".class" );
          return name.substring( 0, ( end >= 0 ) ? end : name.length() );
      }
  }
  
  
  
  1.5       +62 -1     
jakarta-avalon-excalibur/container/src/test/org/apache/excalibur/container/classloader/test/ComponentClassLoaderTestCase.java
  
  Index: ComponentClassLoaderTestCase.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/container/src/test/org/apache/excalibur/container/classloader/test/ComponentClassLoaderTestCase.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ComponentClassLoaderTestCase.java 12 Sep 2002 15:25:28 -0000      1.4
  +++ ComponentClassLoaderTestCase.java 16 Sep 2002 20:05:39 -0000      1.5
  @@ -12,7 +12,8 @@
   import java.net.URL;
   import java.util.Set;
   import java.util.HashSet;
  -import org.apache.excalibur.container.classloader.ComponentClassLoader;
  +import java.util.Iterator;
  +import org.apache.excalibur.container.classloader.*;
   
   /**
   * A testcase for the @link{ComponentClassLoader}.
  @@ -58,6 +59,18 @@
           assertEquals( loader.getTypeEntries().length, 0 );
       }
   
  +    public void testEmptyManifestJarScanner()
  +    {
  +        URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/empty.jar" );
  +        assertTrue( jar != null );
  +
  +        JarEntries entries = JarScanner.scan( jar );
  +
  +        assertEquals( entries.getServiceEntries().size(), 0 );
  +        assertEquals( entries.getBlockEntries().size(), 0 );
  +        assertEquals( entries.getTypeEntries().size(), 0 );
  +    }
  +
       public void testBlocksManifest()
       {
           URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  @@ -73,6 +86,22 @@
           }
       }
   
  +    public void testBlocksManifestJarScanner()
  +    {
  +        URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  +        assertTrue( jar != null );
  +        JarEntries entries = JarScanner.scan( jar );
  +
  +        Set blocks = entries.getBlockEntries();
  +        assertEquals( m_blocks.size(), blocks.size() );
  +
  +        Iterator it = blocks.iterator();
  +        while( it.hasNext() )
  +        {
  +            assertTrue( m_blocks.contains( it.next() ) );
  +        }
  +    }
  +
       public void testServicesManifest()
       {
           URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  @@ -88,6 +117,22 @@
           }
       }
   
  +    public void testServicesManifestJarScanner()
  +    {
  +        URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  +        assertTrue( jar != null );
  +        JarEntries entries = JarScanner.scan( jar );
  +
  +        Set services = entries.getServiceEntries();
  +        assertEquals( m_services.size(), services.size() );
  +
  +        Iterator it = services.iterator();
  +        while( it.hasNext() )
  +        {
  +            assertTrue( m_services.contains( it.next() ) );
  +        }
  +    }
  +
       public void testTypesManifest()
       {
           URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  @@ -100,6 +145,22 @@
           for ( int i = 0; i < types.length; i++ )
           {
               assertTrue( m_types.contains( types[i] ) );
  +        }
  +    }
  +
  +    public void testTypesManifestJarScanner()
  +    {
  +        URL jar = this.getClass().getClassLoader().getResource( 
"org/apache/excalibur/container/classloader/full.jar" );
  +        assertTrue( jar != null );
  +        JarEntries entries = JarScanner.scan( jar );
  +
  +        Set types = entries.getTypeEntries();
  +        assertEquals( m_types.size(), types.size() );
  +
  +        Iterator it = types.iterator();
  +        while( it.hasNext() )
  +        {
  +            assertTrue( m_types.contains( it.next() ) );
           }
       }
   }
  
  
  

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

Reply via email to