You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rs...@apache.org on 2002/08/30 02:15:20 UTC

cvs commit: jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/classes DiscoverClasses.java ResourceClassDiscoverImpl.java

rsitze      2002/08/29 17:15:20

  Modified:    discovery/src/java/org/apache/commons/discovery
                        DiscoveryException.java ResourceIterator.java
               discovery/src/java/org/apache/commons/discovery/tools
                        ResourceUtils.java DiscoverClass.java
                        PropertiesHolder.java DiscoverSingleton.java
                        Service.java DefaultClassHolder.java
               discovery/src/test/org/apache/commons/discovery/test
                        TestAll.java
               discovery/src/java/org/apache/commons/discovery/ant
                        ServiceDiscoveryTask.java
  Added:       discovery/src/java/org/apache/commons/discovery
                        ResourceClassDiscover.java
                        ResourceNameDiscover.java ResourceName.java
                        ResourceClass.java Resource.java
                        ResourceNameIterator.java
                        ResourceClassIterator.java ResourceDiscover.java
               discovery/src/java/org/apache/commons/discovery/resource
                        ClassLoaders.java ResourceDiscoverImpl.java
                        DiscoverResources.java
               discovery/src/java/org/apache/commons/discovery/resource/names
                        NameDiscoverers.java ResourceNameDiscoverImpl.java
                        DiscoverNamesInSystemProperties.java
                        DiscoverServiceNames.java DiscoverNamesInFile.java
                        DiscoverNamesInDictionary.java
                        DiscoverNamesInManagedProperties.java
               discovery/src/java/org/apache/commons/discovery/resource/classes
                        DiscoverClasses.java ResourceClassDiscoverImpl.java
  Removed:     discovery/src/java/org/apache/commons/discovery
                        DiscoverServicesResources.java
                        DiscoverChainLink.java
                        DiscoverDictionaryResources.java
                        DiscoverFiledResources.java
                        DiscoverManagedProperties.java ResourceInfo.java
                        ClassLoaders.java DiscoverSystemProperties.java
                        Discover.java DiscoverResources.java
                        DiscoverClasses.java
                        DiscoverClassLoaderResources.java
  Log:
  Reorg, finished loose ends.
  
  I removed ServiceInfo & ClassInfo, merged everything into ResourceInfo.
  
  In the end, I just couldn't handle the loose coupling between types...
  I tried.. I really did.  The code was broke, it was difficult to debug..
  to many if's to catch 'problems'... so I broke it back out.
  ResourceInfo has become ResourceName, Resource, and ResourceClass.
  I've got specialized iterators for each, and discovery for each.
  Type-safe iterators exposed all bugs in my use of the code.
  
  So, yes it's "complex" to look at, but it's easier to use.  Could help
  with complexity by proper documentation... some object diagrams
  would really help.  Any volenteers for that?
  
  Revision  Changes    Path
  1.4       +7 -3      jakarta-commons/discovery/src/java/org/apache/commons/discovery/DiscoveryException.java
  
  Index: DiscoveryException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/DiscoveryException.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DiscoveryException.java	23 Aug 2002 21:56:09 -0000	1.3
  +++ DiscoveryException.java	30 Aug 2002 00:15:19 -0000	1.4
  @@ -125,9 +125,13 @@
       
       public String toString() {
           String ls = System.getProperty("line.separator");
  -        return super.toString() + ls +
  -               "*****" + ls +
  -               stackToString(cause);
  +        String str = super.toString();
  +        if (cause != null) {
  +            str = str + ls +
  +                  "*****" + ls +
  +                  stackToString(cause);
  +        }
  +        return str;
       }
   
       private static String stackToString(Throwable e){
  
  
  
  1.2       +6 -12     jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceIterator.java
  
  Index: ResourceIterator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceIterator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ResourceIterator.java	29 Aug 2002 05:36:36 -0000	1.1
  +++ ResourceIterator.java	30 Aug 2002 00:15:19 -0000	1.2
  @@ -59,21 +59,15 @@
   
   
   /**
  - * Let's see how this goes..
  - * 
    * @author Richard A. Sitze
    */
  -public interface ResourceIterator
  +public abstract class ResourceIterator implements ResourceNameIterator
   {
       /**
  -     * Specify set of class loaders to be used in searching.
        */
  -    public boolean hasNext();
  -
  -    /**
  -     * Specify a new class loader to be used in searching.
  -     * The order of loaders determines the order of the result.
  -     * It is recommended to add the most specific loaders first.
  -     */
  -    public ResourceInfo next();
  +    public abstract Resource nextResource();
  +    
  +    public ResourceName nextResourceName() {
  +        return nextResource();
  +    }
   }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceClassDiscover.java
  
  Index: ResourceClassDiscover.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  
  /**
   * @author Richard A. Sitze
   */
  public interface ResourceClassDiscover extends ResourceDiscover
  {
      /**
       * Locate class resources that are bound to <code>className</code>.
       * 
       * @return ResourceClassIterator
       */
      public ResourceClassIterator findResourceClasses(String className);
  
      /**
       * Locate class resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceClassIterator findResourceClasses(ResourceNameIterator className);
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceNameDiscover.java
  
  Index: ResourceNameDiscover.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  
  /**
   * Interface representing a mapping
   * from a set of source resource names
   * to a resultant set of resource names.
   * 
   * @author Richard A. Sitze
   * @author Costin Manolache
   */
  public interface ResourceNameDiscover
  {
      /**
       * Locate names of resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(String resourceName);
  
      /**
       * Locate names of resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames);
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceName.java
  
  Index: ResourceName.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  import java.util.Enumeration;
  import java.util.Vector;
  
  
  /**
   * 'Resource' located by discovery.
   * Naming of methods becomes a real pain ('getClass()')
   * so I've patterned this after ClassLoader...
   * 
   * I think it works well as it will give users a point-of-reference.
   * 
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @author Richard A. Sitze
   */
  public class ResourceName
  {
      protected String      name;
  
      public ResourceName(String resourceName) {
          this.name = resourceName;
      }
  
      /**
       * Get the value of resourceName.
       * @return value of resourceName.
       */
      public String getName() {
          return name;
      }
      
      public String toString() {
          return "Resource[" + getName() + "]";
      }
      
      public static ResourceName[] toArray(Enumeration enum) {
          Vector vector = new Vector();
          while (enum.hasMoreElements()) {
              ResourceName resourceInfo = (ResourceName)enum.nextElement();
              vector.add(resourceInfo);
          }
          ResourceName[] resources = new ResourceName[vector.size()];
          vector.copyInto(resources);
          
          return resources;
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceClass.java
  
  Index: ResourceClass.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  import java.net.URL;
  
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.logging.Log;
  
  
  /**
   * 'Resource' located by discovery.
   * Naming of methods becomes a real pain ('getClass()')
   * so I've patterned this after ClassLoader...
   * 
   * I think it works well as it will give users a point-of-reference.
   * 
   * @author Richard A. Sitze
   */
  public class ResourceClass extends Resource
  {
      private static Log log = DiscoveryLogFactory.newLog(ResourceClass.class);
      public static void setLog(Log _log) {
          log = _log;
      }
      protected Class       resourceClass;
  
      public ResourceClass(Class resourceClass, URL resource) {
          super(resourceClass.getName(), resource, resourceClass.getClassLoader());
          this.resourceClass = resourceClass;
      }
  
      public ResourceClass(String resourceName, URL resource, ClassLoader loader) {
          super(resourceName, resource, loader);
          this.resourceClass = resourceClass;
      }
      
      /**
       * Get the value of resourceClass.
       * @return value of resourceClass.
       */
      public Class loadClass() {
          if (resourceClass == null  &&  getClassLoader() != null) {
              if (log.isDebugEnabled())
                  log.debug("getResourceClass: Loading class '" + getName() + "' with " + getClassLoader());
  
              try {
                  resourceClass = getClassLoader().loadClass(getName());
              } catch (ClassNotFoundException e) {
                  resourceClass = null;
              }
          }
          return resourceClass;
      }
      
      public String toString() {
          return "LoadableClass[" + getName() +  ", " + getResource() + ", " + getClassLoader() + "]";
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/Resource.java
  
  Index: Resource.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  
  
  /**
   * 'Resource' located by discovery.
   * Naming of methods becomes a real pain ('getClass()')
   * so I've patterned this after ClassLoader...
   * 
   * I think it works well as it will give users a point-of-reference.
   * 
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @author Richard A. Sitze
   */
  public class Resource extends ResourceName
  {
      protected URL         resource;
      protected ClassLoader loader;
  
      public Resource(String resourceName, URL resource, ClassLoader loader) {
          super(resourceName);
          setResource(resource);
          setClassLoader(loader);
      }
  
      /**
       * Set the value of URL.
       * @param v  Value to assign to URL.
       */
      public void setResource(URL  resource) {
          this.resource = resource;
      }
      
      /**
       * Get the value of URL.
       * @return value of URL.
       */
      public URL getResource() {
          return resource;
      }
      
      /**
       * Get the value of URL.
       * @return value of URL.
       */
      public InputStream getResourceAsStream() {
          try {
              return resource.openStream();
          } catch (IOException e) {
              return null;  // ignore
          }
      }
      
      /**
       * Get the value of loader.
       * @return value of loader.
       */
      public ClassLoader getClassLoader() {
          return loader ;
      }
      
      /**
       * Set the value of loader.
       * @param v  Value to assign to loader.
       */
      public void setClassLoader(ClassLoader  loader) {
          this.loader = loader;
      }
      
      public String toString() {
          return "LoadableResourceInfo[" + getName() +  ", " + getResource() + ", " + getClassLoader() + "]";
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceNameIterator.java
  
  Index: ResourceNameIterator.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  
  /**
   * @author Richard A. Sitze
   */
  public interface ResourceNameIterator
  {
      /**
       */
      public boolean hasNext();
  
      /**
       */
      public ResourceName nextResourceName();
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceClassIterator.java
  
  Index: ResourceClassIterator.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  
  /**
   * @author Richard A. Sitze
   */
  public abstract class ResourceClassIterator extends ResourceIterator
  {
      /**
       */
      public abstract ResourceClass nextResourceClass();
  
      public Resource nextResource() {
          return nextResourceClass();
      }
      
      public ResourceName nextResourceName() {
          return nextResourceClass();
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceDiscover.java
  
  Index: ResourceDiscover.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery;
  
  
  /**
   * @author Richard A. Sitze
   */
  public interface ResourceDiscover extends ResourceNameDiscover
  {
      /**
       * Locate resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceIterator findResources(String resourceName);
  
      /**
       * Locate resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceIterator findResources(ResourceNameIterator resourceNames);
  }
  
  
  
  1.4       +13 -44    jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/ResourceUtils.java
  
  Index: ResourceUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/ResourceUtils.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ResourceUtils.java	29 Aug 2002 05:36:37 -0000	1.3
  +++ ResourceUtils.java	30 Aug 2002 00:15:19 -0000	1.4
  @@ -63,14 +63,13 @@
   
   import java.io.IOException;
   import java.io.InputStream;
  -import java.net.URL;
   import java.util.Properties;
   
  -import org.apache.commons.discovery.ClassLoaders;
  -import org.apache.commons.discovery.DiscoverClassLoaderResources;
   import org.apache.commons.discovery.DiscoveryException;
  -import org.apache.commons.discovery.ResourceInfo;
  +import org.apache.commons.discovery.Resource;
   import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.resource.ClassLoaders;
  +import org.apache.commons.discovery.resource.DiscoverResources;
   
   
   /**
  @@ -115,13 +114,13 @@
        * 
        * @param resourceName The name of the resource to load.
        */
  -    public static URL getResource(Class spi,
  -                                  String resourceName,
  -                                  ClassLoaders loaders)
  +    public static Resource getResource(Class spi,
  +                                       String resourceName,
  +                                       ClassLoaders loaders)
           throws DiscoveryException
       {
  -        DiscoverClassLoaderResources explorer = new DiscoverClassLoaderResources(loaders);
  -        ResourceIterator resources = explorer.find(resourceName);
  +        DiscoverResources explorer = new DiscoverResources(loaders);
  +        ResourceIterator resources = explorer.findResources(resourceName);
           
           if (spi != null  &&
               !resources.hasNext()  &&
  @@ -133,43 +132,13 @@
                * package name of the spi.
                */
               resourceName = getPackageName(spi).replace('.','/') + "/" + resourceName;
  -            resources = explorer.find(resourceName);
  +            resources = explorer.findResources(resourceName);
           }
           
           return resources.hasNext()
  -               ? ((ResourceInfo)resources.next()).getResource()
  +               ? resources.nextResource()
                  : null;
       }
  -
  -    /**
  -     * Load the resource <code>resourceName</code>.
  -     * Try each classloader in succession,
  -     * until first succeeds, or all fail.
  -     * If all fail and <code>resouceName</code> is not absolute
  -     * (doesn't start with '/' character), then retry with
  -     * <code>packageName/resourceName</code> after changing all
  -     * '.' to '/'.
  -     * 
  -     * @param resourceName The name of the resource to load.
  -     */
  -    public static InputStream getResourceAsStream(Class spi,
  -                                                  String resourceName,
  -                                                  ClassLoaders loaders)
  -        throws DiscoveryException
  -    {
  -        URL url = getResource(spi, resourceName, loaders);
  -        InputStream stream = null;
  -        
  -        if (url != null) {
  -            try {
  -                stream = url.openStream();
  -            } catch (IOException e) {
  -                stream = null;  // ignore
  -            }
  -        }
  -        
  -        return stream;
  -    }
       
       /**
        * Load named property file, optionally qualifed by spi's package name
  @@ -204,9 +173,9 @@
           if (propertiesFileName != null) {
               try {
                   InputStream stream =
  -                    ResourceUtils.getResourceAsStream(spi,
  -                                                         propertiesFileName,
  -                                                         classLoaders);
  +                    getResource(spi,
  +                                propertiesFileName,
  +                                classLoaders).getResourceAsStream();
       
                   if (stream != null) {
                       properties = new Properties();
  
  
  
  1.4       +16 -12    jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DiscoverClass.java
  
  Index: DiscoverClass.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DiscoverClass.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DiscoverClass.java	29 Aug 2002 05:36:37 -0000	1.3
  +++ DiscoverClass.java	30 Aug 2002 00:15:19 -0000	1.4
  @@ -65,12 +65,13 @@
   import java.util.Properties;
   import java.util.Vector;
   
  -import org.apache.commons.discovery.ClassLoaders;
  -import org.apache.commons.discovery.DiscoverClasses;
  -import org.apache.commons.discovery.DiscoverServicesResources;
   import org.apache.commons.discovery.DiscoveryException;
  -import org.apache.commons.discovery.ResourceInfo;
  -import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.ResourceClass;
  +import org.apache.commons.discovery.ResourceClassIterator;
  +import org.apache.commons.discovery.ResourceNameIterator;
  +import org.apache.commons.discovery.resource.ClassLoaders;
  +import org.apache.commons.discovery.resource.classes.DiscoverClasses;
  +import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
   
   
   /**
  @@ -365,11 +366,12 @@
           if (classNames.length > 0) {
               DiscoverClasses classDiscovery = new DiscoverClasses(loaders);
               
  -            ResourceIterator classes = classDiscovery.find(classNames[0]);
  +            ResourceClassIterator classes =
  +                classDiscovery.findResourceClasses(classNames[0]);
               
               // If it's set as a property.. it had better be there!
               if (classes.hasNext()) {
  -                ResourceInfo info = classes.next();
  +                ResourceClass info = classes.nextResourceClass();
                   try {
                       return info.loadClass();
                   } catch (Exception e) {
  @@ -377,10 +379,12 @@
                   }
               }
           } else {
  -            DiscoverServicesResources serviceDiscovery =
  -                new DiscoverServicesResources(loaders);
  -            
  -            ResourceIterator classes = serviceDiscovery.find(spi.getSPName());
  +            ResourceNameIterator classIter =
  +                (new DiscoverServiceNames(loaders)).findResourceNames(spi.getSPName());
  +
  +            ResourceClassIterator classes =
  +                (new DiscoverClasses(loaders)).findResourceClasses(classIter);
  +                
               
               if (!classes.hasNext()  &&  defaultImpl != null) {
                   return defaultImpl.getDefaultClass(spi, loaders);
  @@ -388,7 +392,7 @@
               
               // Services we iterate through until we find one that loads..
               while (classes.hasNext()) {
  -                ResourceInfo info = classes.next();
  +                ResourceClass info = classes.nextResourceClass();
                   try {
                       return info.loadClass();
                   } catch (Exception e) {
  
  
  
  1.2       +1 -1      jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/PropertiesHolder.java
  
  Index: PropertiesHolder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/PropertiesHolder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PropertiesHolder.java	23 Aug 2002 21:56:10 -0000	1.1
  +++ PropertiesHolder.java	30 Aug 2002 00:15:19 -0000	1.2
  @@ -63,7 +63,7 @@
   
   import java.util.Properties;
   
  -import org.apache.commons.discovery.ClassLoaders;
  +import org.apache.commons.discovery.resource.ClassLoaders;
   
   
   /**
  
  
  
  1.2       +1 -1      jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DiscoverSingleton.java
  
  Index: DiscoverSingleton.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DiscoverSingleton.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DiscoverSingleton.java	23 Aug 2002 21:56:10 -0000	1.1
  +++ DiscoverSingleton.java	30 Aug 2002 00:15:19 -0000	1.2
  @@ -64,9 +64,9 @@
   import java.util.HashMap;
   import java.util.Properties;
   
  -import org.apache.commons.discovery.ClassLoaders;
   import org.apache.commons.discovery.DiscoveryException;
   import org.apache.commons.discovery.jdk.JDKHooks;
  +import org.apache.commons.discovery.resource.ClassLoaders;
   
   
   /**
  
  
  
  1.4       +16 -13    jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/Service.java
  
  Index: Service.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/Service.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Service.java	29 Aug 2002 05:36:37 -0000	1.3
  +++ Service.java	30 Aug 2002 00:15:19 -0000	1.4
  @@ -59,10 +59,12 @@
   
   import java.util.Enumeration;
   
  -import org.apache.commons.discovery.ClassLoaders;
  -import org.apache.commons.discovery.DiscoverServicesResources;
  -import org.apache.commons.discovery.ResourceInfo;
  -import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.ResourceClass;
  +import org.apache.commons.discovery.ResourceClassIterator;
  +import org.apache.commons.discovery.ResourceNameIterator;
  +import org.apache.commons.discovery.resource.ClassLoaders;
  +import org.apache.commons.discovery.resource.classes.DiscoverClasses;
  +import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
   
   
   /**
  @@ -114,18 +116,19 @@
        *        If <code>null</code> then use ClassLoaders.getAppLoaders().
        */
       public static Enumeration providers(final SPInterface spi,
  -                                        ClassLoaders classLoaders)
  +                                        ClassLoaders loaders)
       {
  -        if (classLoaders == null) {
  -            classLoaders = ClassLoaders.getAppLoaders(spi.getSPClass(),
  -                                                      Service.class,
  -                                                      true);
  +        if (loaders == null) {
  +            loaders = ClassLoaders.getAppLoaders(spi.getSPClass(),
  +                                                 Service.class,
  +                                                 true);
           }
           
  -        DiscoverServicesResources serviceDiscovery =
  -            new DiscoverServicesResources(classLoaders);
  +        ResourceNameIterator servicesIter =
  +            (new DiscoverServiceNames(loaders)).findResourceNames(spi.getSPName());
   
  -        final ResourceIterator services = serviceDiscovery.find(spi.getSPName());
  +        final ResourceClassIterator services =
  +            (new DiscoverClasses(loaders)).findResourceClasses(servicesIter);
           
           return new Enumeration() {
               private Object object = null;
  @@ -145,7 +148,7 @@
   
               private Object getNextClassInstance() {
                   while (services.hasNext()) {
  -                    ResourceInfo info = services.next();
  +                    ResourceClass info = services.nextResourceClass();
                       try {
                           return spi.newInstance(info.loadClass());
                       } catch (Exception e) {
  
  
  
  1.4       +6 -6      jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DefaultClassHolder.java
  
  Index: DefaultClassHolder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/tools/DefaultClassHolder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultClassHolder.java	29 Aug 2002 05:36:37 -0000	1.3
  +++ DefaultClassHolder.java	30 Aug 2002 00:15:19 -0000	1.4
  @@ -61,10 +61,10 @@
   
   package org.apache.commons.discovery.tools;
   
  -import org.apache.commons.discovery.ClassLoaders;
  -import org.apache.commons.discovery.DiscoverClasses;
  -import org.apache.commons.discovery.ResourceInfo;
  -import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.ResourceClass;
  +import org.apache.commons.discovery.ResourceClassIterator;
  +import org.apache.commons.discovery.resource.classes.DiscoverClasses;
  +import org.apache.commons.discovery.resource.ClassLoaders;
   
   
   /**
  @@ -100,9 +100,9 @@
       public Class getDefaultClass(SPInterface spi, ClassLoaders loaders) {
           if (defaultClass == null) {
               DiscoverClasses classDiscovery = new DiscoverClasses(loaders);
  -            ResourceIterator classes = classDiscovery.find(getDefaultName());
  +            ResourceClassIterator classes = classDiscovery.findResourceClasses(getDefaultName());
               if (classes.hasNext()) {
  -                ResourceInfo info = classes.next();
  +                ResourceClass info = classes.nextResourceClass();
                   try {
                       defaultClass = info.loadClass();
                   } catch (Exception e) {
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/ClassLoaders.java
  
  Index: ClassLoaders.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource;
  
  import java.util.Vector;
  
  import org.apache.commons.discovery.jdk.JDKHooks;
  
  
  /**
   * There are many different contexts in which
   * loaders can be used.  This provides a holder
   * for a set of class loaders, so that they
   * don't have to be build back up everytime...
   *
   * @author Richard A. Sitze
   * @author Craig R. McClanahan
   * @author Costin Manolache
   */
  public class ClassLoaders
  {
      protected Vector classLoaders = new Vector();
      
      /** Construct a new class loader set
       */
      public ClassLoaders() {
      }
      
      public int size() {
          return classLoaders.size();
      }
      
      public ClassLoader get(int idx) {
          return (ClassLoader)classLoaders.elementAt(idx);
      }
  
      /**
       * Specify a new class loader to be used in searching.
       * The order of loaders determines the order of the result.
       * It is recommended to add the most specific loaders first.
       */
      public void put(ClassLoader classLoader) {
          if (classLoader != null) {
              classLoaders.addElement(classLoader);
          }
      }
      
  
      /**
       * Specify a new class loader to be used in searching.
       * The order of loaders determines the order of the result.
       * It is recommended to add the most specific loaders first.
       * 
       * @param prune if true, verify that the class loader is
       *              not an Ancestor (@see isAncestor) before
       *              adding it to our list.
       */
      public void put(ClassLoader classLoader, boolean prune) {
          if (classLoader != null  &&  !(prune && isAncestor(classLoader))) {
              classLoaders.addElement(classLoader);
          }
      }
      
      
      /**
       * Check to see if <code>classLoader</code> is an
       * ancestor of any contained class loader.
       * 
       * This can be used to eliminate redundant class loaders
       * IF all class loaders defer to parent class loaders
       * before resolving a class.
       * 
       * It may be that this is not always true.  Therefore,
       * this check is not done internally to eliminate
       * redundant class loaders, but left to the discretion
       * of the user.
       */
      public boolean isAncestor(final ClassLoader classLoader) {
          /* bootstrap classloader, at root of all trees! */
          if (classLoader == null)
              return true;
  
          for (int idx = 0; idx < size(); idx++) {
              for(ClassLoader walker = get(idx);
                  walker != null;
                  walker = walker.getParent())
              {
                  if (walker == classLoader) {
                      return true;
                  }
              }
          }
          return false;
      }
  
  
      /**
       * Utility method.  Returns a preloaded ClassLoaders instance
       * containing the following class loaders, in order:
       * 
       * <ul>
       *   <li>spi.getClassLoader</li>
       *   <li>seeker.getClassLoader</li>
       *   <li>System Class Loader</li>
       * </ul>
       * 
       * Note that the thread context class loader is NOT present.
       * This is a reasonable set of loaders to try if the resource to be found
       * should be restricted to a libraries containing the SPI and Factory.
       * 
       * @param spi WHAT is being looked for (an implementation of this class,
       *            a default property file related to this class).
       * @param factory WHO is performing the lookup.
       * @param prune Determines if ancestors are allowed to be loaded or not.
       */    
      public static ClassLoaders getLibLoaders(Class spi, Class factory, boolean prune) {
          ClassLoaders loaders = new ClassLoaders();
          
          loaders.put(spi.getClassLoader());
          loaders.put(factory.getClassLoader(), prune);
          loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), prune);
          
          return loaders;
      }
      
      /**
       * Utility method.  Returns a preloaded ClassLoaders instance
       * containing the following class loaders, in order:
       * 
       * <ul>
       *   <li>Thread Context Class Loader</li>
       *   <li>spi.getClassLoader</li>
       *   <li>seeker.getClassLoader</li>
       *   <li>System Class Loader</li>
       * </ul>
       * 
       * Note that the thread context class loader IS  present.
       * This is a reasonable set of loaders to try if the resource to be found
       * may be provided by an application.
       * 
       * @param spi WHAT is being looked for (an implementation of this class,
       *            a default property file related to this class).
       * @param factory WHO is performing the lookup (factory).
       * @param prune Determines if ancestors are allowed to be loaded or not.
       */    
      public static ClassLoaders getAppLoaders(Class spi, Class factory, boolean prune) {
          ClassLoaders loaders = new ClassLoaders();
  
          loaders.put(JDKHooks.getJDKHooks().getThreadContextClassLoader());
          loaders.put(spi.getClassLoader(), prune);
          loaders.put(factory.getClassLoader(), prune);
          loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), prune);
          
          return loaders;
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/ResourceDiscoverImpl.java
  
  Index: ResourceDiscoverImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource;
  
  import org.apache.commons.discovery.Resource;
  import org.apache.commons.discovery.ResourceDiscover;
  import org.apache.commons.discovery.ResourceIterator;
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.resource.names.ResourceNameDiscoverImpl;
  
  
  /**
   * Helper class for methods implementing the ResourceDiscover interface.
   * 
   * @author Richard A. Sitze
   */
  public abstract class ResourceDiscoverImpl
      extends ResourceNameDiscoverImpl
      implements ResourceDiscover
  {
      private ClassLoaders classLoaders;
  
      
      /**
       * Construct a new resource discoverer
       */
      public ResourceDiscoverImpl() {
          setClassLoaders(new ClassLoaders());
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public ResourceDiscoverImpl(ClassLoaders classLoaders) {
          setClassLoaders(classLoaders);
      }
  
      /**
       * Specify set of class loaders to be used in searching.
       */
      public void setClassLoaders(ClassLoaders loaders) {
          classLoaders = loaders;
      }
  
      /**
       * Specify a new class loader to be used in searching.
       * The order of loaders determines the order of the result.
       * It is recommended to add the most specific loaders first.
       */
      public void addClassLoader(ClassLoader loader) {
          classLoaders.put(loader);
      }
  
      protected ClassLoaders getClassLoaders() {
          return classLoaders;
      }
  
      /**
       * Locate names of resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(String resourceName) {
          return findResources(resourceName);
      }
  
      /**
       * Locate names of resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) {
          return findResources(resourceNames);
      }
  
      /**
       * Locate resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceIterator
       */
      public abstract ResourceIterator findResources(String resourceName);
  
      /**
       * Locate resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceIterator findResources(final ResourceNameIterator inputNames) {
          return new ResourceIterator() {
              private ResourceIterator resources = null;
              private Resource resource = null;
              
              public boolean hasNext() {
                  if (resource == null) {
                      resource = getNextResource();
                  }
                  return resource != null;
              }
              
              public Resource nextResource() {
                  Resource rsrc = resource;
                  resource = null;
                  return rsrc;
              }
              
              private Resource getNextResource() {
                  while (inputNames.hasNext() && (resources == null  ||  !resources.hasNext())) {
                      resources =
                          findResources(inputNames.nextResourceName().getName());
                  }
      
                  return (resources != null  &&  resources.hasNext())
                         ? resources.nextResource()
                         : null;
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/DiscoverResources.java
  
  Index: DiscoverResources.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource;
  
  import java.io.IOException;
  import java.net.URL;
  import java.util.Enumeration;
  
  import org.apache.commons.discovery.Resource;
  import org.apache.commons.discovery.ResourceDiscover;
  import org.apache.commons.discovery.ResourceIterator;
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.jdk.JDKHooks;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.logging.Log;
  
  
  /**
   * @author Richard A. Sitze
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @author James Strachan
   */
  public class DiscoverResources
      extends ResourceDiscoverImpl
      implements ResourceDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverResources.class);
      public static void setLog(Log _log) {
          log = _log;
      }
      
      /**
       * Construct a new resource discoverer
       */
      public DiscoverResources() {
          super();
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public DiscoverResources(ClassLoaders classLoaders) {
          super(classLoaders);
      }
  
      /**
       * @return ResourceIterator
       */
      public ResourceIterator findResources(final String resourceName) {
          if (log.isDebugEnabled())
              log.debug("find: resourceName='" + resourceName + "'");
  
          return new ResourceIterator() {
              private int idx = 0;
              private ClassLoader loader = null;
              private Enumeration resources = null;
              private Resource resource = null;
              
              public boolean hasNext() {
                  if (resource == null) {
                      resource = getNextResource();
                  }
                  return resource != null;
              }
              
              public ResourceName nextResourceName() {
                  return nextResource();
              }
              
              public Resource nextResource() {
                  Resource element = resource;
                  resource = null;
                  return element;
              }
              
              private Resource getNextResource() {
                  if (resources == null || !resources.hasMoreElements()) {
                      resources = getNextResources();
                  }
  
                  Resource resourceInfo;
                  if (resources != null) {
                      URL url = (URL)resources.nextElement();
  
                      if (log.isDebugEnabled())
                          log.debug("getNextResource: next URL='" + url + "'");
  
                      resourceInfo = new Resource(resourceName, url, loader);
                  } else {
                      resourceInfo = null;
                  }
                  
                  return resourceInfo;
              }
              
              private Enumeration getNextResources() {
                  while (idx < getClassLoaders().size()) {
                      loader = getClassLoaders().get(idx++);
                      if (log.isDebugEnabled())
                          log.debug("getNextResources: search using ClassLoader '" + loader + "'");
                      try {
                          Enumeration enum = JDKHooks.getJDKHooks().getResources(loader, resourceName);
                          if (enum != null && enum.hasMoreElements()) {
                              return enum;
                          }
                      } catch( IOException ex ) {
                          log.warn("getNextResources: Ignoring Exception", ex);
                      }
                  }
                  return null;
              }
          };
      }
  }
  
  
  
  1.3       +4 -4      jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestAll.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestAll.java	26 Aug 2002 21:57:56 -0000	1.2
  +++ TestAll.java	30 Aug 2002 00:15:20 -0000	1.3
  @@ -141,7 +141,7 @@
               ti = (TestInterface1)DiscoverSingleton.find(TestInterface1.class,
                                                           TestImpl1_2.class.getName());
   
  -            // factory should be cached LogFactoryImpl
  +            // factory should be cached
               assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(),
                          ti.getClass().getName().equals(TestImpl1_1.class.getName()));
           } finally {
  @@ -166,7 +166,7 @@
               ti = (TestInterface1)DiscoverSingleton.find(TestInterface1.class,
                                                           TestImpl1_2.class.getName());
   
  -            // factory should be cached LogFactoryImpl
  +            // factory should be cached
               assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(),
                          ti.getClass().getName().equals(TestImpl1_2.class.getName()));
           } finally {
  @@ -218,7 +218,7 @@
       }
       
   
  -    public void testFindGroupLogFactoryImplPropFileDefault() {
  +    public void testFindPropFileDefault() {
           org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
   
           TestInterface1 ti = null;
  @@ -236,7 +236,7 @@
           }
       }
   
  -    public void testFindGroupLogFactoryImplServiceFileDefault() {
  +    public void testFindServiceFileDefault() {
   //        org.apache.commons.discovery.log.SimpleLog.setLevel(org.apache.commons.discovery.log.SimpleLog.LOG_LEVEL_DEBUG);
           org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
   
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/NameDiscoverers.java
  
  Index: NameDiscoverers.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import java.util.Vector;
  
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.logging.Log;
  
  
  /**
   * Holder for multiple ResourceNameDiscover instances.
   * The result is the union of the results from each
   * (not a chained sequence, where results feed the next in line.
   *
   * @author Richard A. Sitze
   */
  public class NameDiscoverers
      extends ResourceNameDiscoverImpl
      implements ResourceNameDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(NameDiscoverers.class);
      public static void setLog(Log _log) {
          log = _log;
      }
  
      private Vector discoverers = new Vector();
      
      /**
       *  Construct a new resource name discoverer
       */
      public NameDiscoverers() {
      }
      
      /**
       * Specify an additional class loader to be used in searching.
       * The order of loaders determines the order of the result.
       * It is recommended to add the most specific loaders first.
       */
      public void addResourceNameDiscover(ResourceNameDiscover discover) {
          if (discover != null) {
              discoverers.addElement(discover);
          }
      }
  
      protected ResourceNameDiscover getResourceNameDiscover(int idx) {
          return (ResourceNameDiscover)discoverers.get(idx);
      }
  
      protected int size() {
          return discoverers.size();
      }
  
      /**
       * Set of results of all discoverers.
       * 
       * @return ResourceIterator
       */
      public ResourceNameIterator findResourceNames(final String resourceName) {
          if (log.isDebugEnabled())
              log.debug("find: resourceName='" + resourceName + "'");
  
          return new ResourceNameIterator() {
              private int idx = 0;
              private ResourceNameIterator iterator = null;
              
              public boolean hasNext() {
                  if (iterator == null  ||  !iterator.hasNext()) {
                      iterator = getNextIterator();
                      if (iterator == null) {
                          return false;
                      }
                  }
                  return iterator.hasNext();
              }
              
              public ResourceName nextResourceName() {
                  return iterator.nextResourceName();
              }
              
              private ResourceNameIterator getNextIterator() {
                  while (idx < size()) {
                      ResourceNameIterator iter =
                          getResourceNameDiscover(idx++).findResourceNames(resourceName);
  
                      if (iter.hasNext()) {
                          return iter;
                      }
                  }
                  return null;
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/ResourceNameDiscoverImpl.java
  
  Index: ResourceNameDiscoverImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  
  
  /**
   * Helper class for methods implementing the ResourceNameDiscover interface.
   * 
   * @author Richard A. Sitze
   */
  public abstract class ResourceNameDiscoverImpl implements ResourceNameDiscover
  {
      /**
       * Locate names of resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceNameIterator
       */
      public abstract ResourceNameIterator findResourceNames(String resourceName);
  
      /**
       * Locate names of resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(final ResourceNameIterator inputNames) {
          return new ResourceNameIterator() {
              private ResourceNameIterator resourceNames = null;
              private ResourceName resourceName = null;
              
              public boolean hasNext() {
                  if (resourceName == null) {
                      resourceName = getNextResourceName();
                  }
                  return resourceName != null;
              }
              
              public ResourceName nextResourceName() {
                  ResourceName name = resourceName;
                  resourceName = null;
                  return name;
              }
              
              private ResourceName getNextResourceName() {
                  while (inputNames.hasNext() && (resourceNames == null  ||  !resourceNames.hasNext())) {
                      resourceNames =
                          findResourceNames(inputNames.nextResourceName().getName());
                  }
      
                  return (resourceNames != null  &&  resourceNames.hasNext())
                         ? resourceNames.nextResourceName()
                         : null;
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInSystemProperties.java
  
  Index: DiscoverNamesInSystemProperties.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.logging.Log;
  
  
  /**
   * Recover resource name from System Properties.
   * 
   * @author Richard A. Sitze
   */
  public class DiscoverNamesInSystemProperties
      extends ResourceNameDiscoverImpl
      implements ResourceNameDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverNamesInSystemProperties.class);
      public static void setLog(Log _log) {
          log = _log;
      }
      
      /** Construct a new resource discoverer
       */
      public DiscoverNamesInSystemProperties() {
      }
  
      /**
       * @return Enumeration of ResourceInfo
       */
      public ResourceNameIterator findResourceNames(final String resourceName) {
          if (log.isDebugEnabled())
              log.debug("find: resourceName='" + resourceName + "'");
  
          return new ResourceNameIterator() {
              private String resource = System.getProperty(resourceName);
              
              public boolean hasNext() {
                  return resource != null;
              }
              
              public ResourceName nextResourceName() {
                  ResourceName element = new ResourceName(resource);
                  resource = null;
                  return element;
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/DiscoverServiceNames.java
  
  Index: DiscoverServiceNames.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import org.apache.commons.discovery.ResourceDiscover;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.resource.ClassLoaders;
  
  
  /**
   * Provide JDK 1.3 style service discovery...
   * 
   * The caller will first configure the discoverer by creating a
   * root Discoverer for the files.
   *
   * @author Richard A. Sitze
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @author James Strachan
   */
  public class DiscoverServiceNames
      extends DiscoverNamesInFile
      implements ResourceNameDiscover
  {
      protected static final String SERVICE_HOME = "META-INF/services/";
      
      /** Construct a new service discoverer
       */
      public DiscoverServiceNames() {
          super();
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public DiscoverServiceNames(ClassLoaders loaders) {
          super(loaders);
      }
      
      /** Construct a new service discoverer
       */
      public DiscoverServiceNames(ResourceDiscover discoverer) {
          super(discoverer);
      }
      
      /**
       * @return Enumeration of ServiceInfo
       */
      public ResourceNameIterator findResourceNames(String serviceName) {
          return super.findResourceNames(SERVICE_HOME + serviceName);
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInFile.java
  
  Index: DiscoverNamesInFile.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Vector;
  
  import org.apache.commons.discovery.Resource;
  import org.apache.commons.discovery.ResourceDiscover;
  import org.apache.commons.discovery.ResourceIterator;
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.discovery.resource.ClassLoaders;
  import org.apache.commons.discovery.resource.DiscoverResources;
  import org.apache.commons.logging.Log;
  
  
  
  /**
   * Discover ALL files of a given name, and return resource names
   * contained within the set of files:
   * <ul>
   *   <li>one resource name per line,</li>
   *   <li>whitespace ignored,</li>
   *   <li>comments begin with '#'</li>
   * </ul>
   * 
   * Default discoverer is DiscoverClassLoaderResources,
   * but it can be set to any other.
   *
   * @author Richard A. Sitze
   * @author Costin Manolache
   * @author James Strachan
   */
  public class DiscoverNamesInFile
      extends ResourceNameDiscoverImpl
      implements ResourceNameDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverNamesInFile.class);
      public static void setLog(Log _log) {
          log = _log;
      }
      
      private ResourceDiscover discoverResources;
      
      /**
       *  Construct a new resource discoverer
       */
      public DiscoverNamesInFile() {
          discoverResources = new DiscoverResources();
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public DiscoverNamesInFile(ClassLoaders loaders) {
          discoverResources = new DiscoverResources(loaders);
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public DiscoverNamesInFile(ResourceDiscover discoverer) {
          this.discoverResources = discoverer;
      }
  
      /**
       * Specify set of class loaders to be used in searching.
       */
      public void setDiscoverer(ResourceDiscover discover) {
          this.discoverResources = discover;
      }
  
      /**
       * To be used by downstream elements..
       */
      public ResourceDiscover getDiscover() {
          return discoverResources;
      }
  
      /**
       * @return Enumeration of ServiceInfo
       */
      public ResourceNameIterator findResourceNames(final String fileName) {
          if (log.isDebugEnabled())
              log.debug("find: fileName='" + fileName + "'");
  
          return new ResourceNameIterator() {
              private ResourceIterator files =
                  getDiscover().findResources(fileName);
  
              private int idx = 0;
              private Vector classNames = null;
              private ResourceName resource = null;
              
              public boolean hasNext() {
                  if (resource == null) {
                      resource = getNextClassName();
                  }
                  return resource != null;
              }
              
              public ResourceName nextResourceName() {
                  ResourceName element = resource;
                  resource = null;
                  return element;
              }
              
              private ResourceName getNextClassName() {
                  if (classNames == null || idx >= classNames.size()) {
                      classNames = getNextClassNames();
                      idx = 0;
                      if (classNames == null) {
                          return null;
                      }
                  }
  
                  String className = (String)classNames.get(idx++);
  
                  if (log.isDebugEnabled())
                      log.debug("getNextClassResource: next class='" + className + "'");
  
                  return new ResourceName(className);
              }
  
              private Vector getNextClassNames() {
                  while (files.hasNext()) {
                      Vector results = readServices(files.nextResource());
                      if (results != null  &&  results.size() > 0) {
                          return results;
                      }
                  }
                  return null;
              }
          };
      }
  
      /**
       * Read everything, no defering here..
       * Ensure that files are closed before we leave.
       */
      private Vector readServices(final Resource info) {
          Vector results = new Vector();
          
          InputStream is = info.getResourceAsStream();
          
          if( is != null ) {
              try {
                  try {
                      // This code is needed by EBCDIC and other
                      // strange systems.  It's a fix for bugs
                      // reported in xerces
                      BufferedReader rd;
                      try {
                          rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                      } catch (java.io.UnsupportedEncodingException e) {
                          rd = new BufferedReader(new InputStreamReader(is));
                      }
                      
                      try {
                          String serviceImplName;
                          while( (serviceImplName = rd.readLine()) != null) {
                              int idx = serviceImplName.indexOf('#');
                              if (idx >= 0) {
                                  serviceImplName = serviceImplName.substring(0, idx);
                              }
                              serviceImplName = serviceImplName.trim();
      
                              if (serviceImplName.length() != 0) {
                                  results.add(serviceImplName);
                              }
                          }
                      } finally {
                          rd.close();
                      }
                  } finally {
                      is.close();
                  }
              } catch (IOException e) {
                  // ignore
              }
          }
          
          return results;
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInDictionary.java
  
  Index: DiscoverNamesInDictionary.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import java.util.Dictionary;
  import java.util.Hashtable;
  
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.logging.Log;
  
  
  /**
   * Recover resources from a Dictionary.  This covers Properties as well,
   * since <code>Properties extends Hashtable extends Dictionary</code>.
   * 
   * The recovered value is expected to be either a <code>String</code>
   * or a <code>String[]</code>.
   * 
   * @author Richard A. Sitze
   */
  public class DiscoverNamesInDictionary
      extends ResourceNameDiscoverImpl
      implements ResourceNameDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverNamesInDictionary.class);
      public static void setLog(Log _log) {
          log = _log;
      }
  
      private Dictionary dictionary;
      
      /** Construct a new resource discoverer
       */
      public DiscoverNamesInDictionary() {
          setDictionary(new Hashtable());
      }
      
      /** Construct a new resource discoverer
       */
      public DiscoverNamesInDictionary(Dictionary dictionary) {
          setDictionary(dictionary);
      }
  
      protected Dictionary getDictionary() {
          return dictionary;
      }
  
      /**
       * Specify set of class loaders to be used in searching.
       */
      public void setDictionary(Dictionary table) {
          this.dictionary = dictionary;
      }
      
      public void addResource(String resourceName, String resource) {
          dictionary.put(resourceName, resource);
      }
      
      public void addResource(String resourceName, String[] resources) {
          dictionary.put(resourceName, resources);
      }
  
      /**
       * @return Enumeration of ResourceInfo
       */
      public ResourceNameIterator findResourceNames(final String resourceName) {
          if (log.isDebugEnabled())
              log.debug("find: resourceName='" + resourceName + "'");
  
          Object baseResource = dictionary.get(resourceName);
  
          final String[] resources;
          if (baseResource instanceof String) {
              resources = new String[] { (String)baseResource };
          } else if (baseResource instanceof String[]) {
              resources = (String[])baseResource;
          } else {
              resources = null;
          }
  
          return new ResourceNameIterator() {
              private int idx = 0;
              
              public boolean hasNext() {
                  return (resources != null && idx < resources.length);
              }
              
              public ResourceName nextResourceName() {
                  return new ResourceName(resources[idx++]);
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInManagedProperties.java
  
  Index: DiscoverNamesInManagedProperties.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.names;
  
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameDiscover;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.discovery.tools.ManagedProperties;
  import org.apache.commons.logging.Log;
  
  
  /**
   * Recover resource name from Managed Properties.
   * @see org.apache.commons.discovery.tools.ManagedProperties
   * 
   * @author Richard A. Sitze
   */
  public class DiscoverNamesInManagedProperties
      extends ResourceNameDiscoverImpl
      implements ResourceNameDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverNamesInManagedProperties.class);
      public static void setLog(Log _log) {
          log = _log;
      }
      
      /** Construct a new resource discoverer
       */
      public DiscoverNamesInManagedProperties() {
      }
  
      /**
       * @return Enumeration of ResourceInfo
       */
      public ResourceNameIterator findResourceNames(final String resourceName) {
          if (log.isDebugEnabled())
              log.debug("find: resourceName='" + resourceName + "'");
  
          return new ResourceNameIterator() {
              private String resource = ManagedProperties.getProperty(resourceName);
              
              public boolean hasNext() {
                  return resource != null;
              }
              
              public ResourceName nextResourceName() {
                  ResourceName element = new ResourceName(resource);
                  resource = null;
                  return element;
              }
          };
      }
  }
  
  
  
  1.4       +9 -9      jakarta-commons/discovery/src/java/org/apache/commons/discovery/ant/ServiceDiscoveryTask.java
  
  Index: ServiceDiscoveryTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ant/ServiceDiscoveryTask.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ServiceDiscoveryTask.java	29 Aug 2002 05:36:37 -0000	1.3
  +++ ServiceDiscoveryTask.java	30 Aug 2002 00:15:20 -0000	1.4
  @@ -59,10 +59,10 @@
   
   import java.util.Vector;
   
  -import org.apache.commons.discovery.DiscoverClassLoaderResources;
  -import org.apache.commons.discovery.ResourceInfo;
  -import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.ResourceName;
  +import org.apache.commons.discovery.ResourceNameIterator;
   import org.apache.commons.discovery.jdk.JDKHooks;
  +import org.apache.commons.discovery.resource.DiscoverResources;
   
   
   /**
  @@ -77,7 +77,7 @@
   {
       String name;
       int debug=0;
  -    ResourceInfo[] drivers = null;
  +    ResourceName[] drivers = null;
           
       public void setServiceName(String name ) {
           this.name=name;
  @@ -87,29 +87,29 @@
           this.debug=debug;
       }
   
  -    public ResourceInfo[] getServiceInfo() {
  +    public ResourceName[] getServiceInfo() {
           return drivers;
       }
   
       public void execute() throws Exception {
           System.out.println("XXX ");
           
  -        DiscoverClassLoaderResources disc = new DiscoverClassLoaderResources();
  +        DiscoverResources disc = new DiscoverResources();
           disc.addClassLoader( JDKHooks.getJDKHooks().getThreadContextClassLoader() );
           disc.addClassLoader( this.getClass().getClassLoader() );
           
  -        ResourceIterator enum = disc.find(name);
  +        ResourceNameIterator enum = disc.findResources(name);
   
           Vector vector = new Vector();
           while (enum.hasNext()) {
  -            ResourceInfo resourceInfo = enum.next();
  +            ResourceName resourceInfo = enum.nextResourceName();
               vector.add(resourceInfo);
               if( debug > 0 ) {
                   System.out.println("Found " + resourceInfo);
               }
           }
           
  -        drivers = new ResourceInfo[vector.size()];
  +        drivers = new ResourceName[vector.size()];
           vector.copyInto(drivers);
       }
           
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/classes/DiscoverClasses.java
  
  Index: DiscoverClasses.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.classes;
  
  import java.net.URL;
  import java.util.Vector;
  
  import org.apache.commons.discovery.Resource;
  import org.apache.commons.discovery.ResourceClass;
  import org.apache.commons.discovery.ResourceClassDiscover;
  import org.apache.commons.discovery.ResourceClassIterator;
  import org.apache.commons.discovery.ResourceIterator;
  import org.apache.commons.discovery.ResourceName;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.log.DiscoveryLogFactory;
  import org.apache.commons.discovery.resource.ClassLoaders;
  import org.apache.commons.logging.Log;
  
  
  /**
   * The findResources() method will check every loader.
   *
   * @author Richard A. Sitze
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @author James Strachan
   */
  public class DiscoverClasses
      extends ResourceClassDiscoverImpl
      implements ResourceClassDiscover
  {
      private static Log log = DiscoveryLogFactory.newLog(DiscoverClasses.class);
      public static void setLog(Log _log) {
          log = _log;
      }
  
      /** Construct a new resource discoverer
       */
      public DiscoverClasses() {
          super();
      }
      
      /** Construct a new resource discoverer
       */
      public DiscoverClasses(ClassLoaders classLoaders) {
          super(classLoaders);
      }
      
      public ResourceClassIterator findResourceClasses(final String className) {
          final String resourceName = className.replace('.','/') + ".class";
          
          if (log.isDebugEnabled())
              log.debug("find: className='" + className + "'");
  
          return new ResourceClassIterator() {
              private Vector history = new Vector();
              private int idx = 0;
              private ResourceClass resource = null;
              
              public boolean hasNext() {
                  if (resource == null) {
                      resource = getNextClass();
                  }
                  return resource != null;
              }
              
              public ResourceName nextResourceName() {
                  return nextResourceClass();
              }
              
              public Resource nextResource() {
                  return nextResourceClass();
              }
              
              public ResourceClass nextResourceClass() {
                  ResourceClass element = resource;
                  resource = null;
                  return element;
              }
              
              private ResourceClass getNextClass() {
                  while (idx < getClassLoaders().size()) {
                      ClassLoader loader = getClassLoaders().get(idx++);
                      URL url = loader.getResource(resourceName);
                      if (url != null) {
                          if (!history.contains(url)) {
                              history.addElement(url);
      
                              if (log.isDebugEnabled())
                                  log.debug("getNextClass: next URL='" + url + "'");
      
                              return new ResourceClass(className, url, loader);
                          }
                          if (log.isDebugEnabled())
                              log.debug("getNextClass: duplicate URL='" + url + "'");
                      } else {
                          if (log.isDebugEnabled())
                              log.debug("getNextClass: loader " + loader + ": '" + resourceName + "' not found");
                      }
                  }
                  return null;
              }
          };
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/resource/classes/ResourceClassDiscoverImpl.java
  
  Index: ResourceClassDiscoverImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.discovery.resource.classes;
  
  import org.apache.commons.discovery.ResourceClass;
  import org.apache.commons.discovery.ResourceClassDiscover;
  import org.apache.commons.discovery.ResourceClassIterator;
  import org.apache.commons.discovery.ResourceIterator;
  import org.apache.commons.discovery.ResourceNameIterator;
  import org.apache.commons.discovery.resource.ClassLoaders;
  import org.apache.commons.discovery.resource.ResourceDiscoverImpl;
  
  
  /**
   * @author Richard A. Sitze
   */
  public abstract class ResourceClassDiscoverImpl
      extends ResourceDiscoverImpl
      implements ResourceClassDiscover
  {
      /**
       * Construct a new resource discoverer
       */
      public ResourceClassDiscoverImpl() {
          super();
      }
      
      /**
       *  Construct a new resource discoverer
       */
      public ResourceClassDiscoverImpl(ClassLoaders classLoaders) {
          super(classLoaders);
      }
  
  
      /**
       * Locate names of resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(String resourceName) {
          return findResourceClasses(resourceName);
      }
  
      /**
       * Locate names of resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceNameIterator
       */
      public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) {
          return findResourceClasses(resourceNames);
      }
  
      /**
       * Locate resources that are bound to <code>resourceName</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceIterator findResources(String resourceName) {
          return findResourceClasses(resourceName);
      }
  
      /**
       * Locate resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceIterator findResources(ResourceNameIterator resourceNames) {
          return findResourceClasses(resourceNames);
      }
  
  
      /**
       * Locate class resources that are bound to <code>className</code>.
       * 
       * @return ResourceClassIterator
       */
      public abstract ResourceClassIterator findResourceClasses(String className);
  
      /**
       * Locate class resources that are bound to <code>resourceNames</code>.
       * 
       * @return ResourceIterator
       */
      public ResourceClassIterator findResourceClasses(final ResourceNameIterator inputNames) {
          return new ResourceClassIterator() {
              private ResourceClassIterator classes = null;
              private ResourceClass resource = null;
              
              public boolean hasNext() {
                  if (resource == null) {
                      resource = getNextResource();
                  }
                  return resource != null;
              }
              
              public ResourceClass nextResourceClass() {
                  ResourceClass rsrc = resource;
                  resource = null;
                  return rsrc;
              }
              
              private ResourceClass getNextResource() {
                  while (inputNames.hasNext() && (classes == null  ||  !classes.hasNext())) {
                      classes =
                          findResourceClasses(inputNames.nextResourceName().getName());
                  }
      
                  return (classes != null  &&  classes.hasNext())
                         ? classes.nextResourceClass()
                         : null;
              }
          };
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>