commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rsi...@apache.org
Subject cvs commit: jakarta-commons/discovery/src/java/org/apache/commons/discovery DiscoveryException.java Discovery.java ClassFinder.java ClassLoaderUtils.java ServiceFinder.java ServiceException.java
Date Thu, 18 Jul 2002 18:32:34 GMT
rsitze      2002/07/18 11:32:34

  Modified:    discovery/src/test/org/apache/commons/discovery TestAll.java
               discovery/src/java/org/apache/commons/discovery
                        ClassFinder.java ClassLoaderUtils.java
  Added:       discovery/src/java/org/apache/commons/discovery
                        DiscoveryException.java Discovery.java
  Removed:     discovery/src/java/org/apache/commons/discovery
                        ServiceFinder.java ServiceException.java
  Log:
  Refactoring/cleanup
  
  Revision  Changes    Path
  1.3       +4 -4      jakarta-commons/discovery/src/test/org/apache/commons/discovery/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/test/org/apache/commons/discovery/TestAll.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestAll.java	9 Jul 2002 18:08:36 -0000	1.2
  +++ TestAll.java	18 Jul 2002 18:32:34 -0000	1.3
  @@ -92,13 +92,13 @@
       public void testServiceFinder1() {
           try {
               LogFactory factory =
  -                (LogFactory)ServiceFinder.find(LogFactory.class,
  +                (LogFactory)Discovery.find(LogFactory.class,
                                                  LogFactoryImpl.class.getName());
               Log log = factory.getLog(TestAll.class);
               log.info("got log!");
           } finally {
               LogFactory.releaseAll();
  -            ServiceFinder.releaseAll();
  +            Discovery.releaseAll();
           }
       }
       
  @@ -112,12 +112,12 @@
           
           try {
               LogFactory factory =
  -                (LogFactory)ServiceFinder.find(LogFactory.class, props);
  +                (LogFactory)Discovery.find(LogFactory.class, props);
               Log log = factory.getLog(TestAll.class);
               log.info("got log factory via service");
           } finally {
               LogFactory.releaseAll();
  -            ServiceFinder.releaseAll();
  +            Discovery.releaseAll();
           }
       }
   
  
  
  
  1.4       +5 -5      jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassFinder.java
  
  Index: ClassFinder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassFinder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ClassFinder.java	17 Jul 2002 22:03:06 -0000	1.3
  +++ ClassFinder.java	18 Jul 2002 18:32:34 -0000	1.4
  @@ -128,18 +128,18 @@
        * @param localOnly Use only local class loader
        *                  (do not try thread context class loader).
        *
  -     * @exception ServiceException if a suitable instance cannot be created,
  +     * @exception DiscoveryException if a suitable instance cannot be created,
        *                             or if the class created is not an instance
        *                             of <code>spi</code>
        */
       public Class findClass(String serviceImplName, boolean localOnly)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           Class clazz = ClassLoaderUtils.loadClass(serviceImplName,
                              localOnly ? localLoaders : allLoaders);
               
           if (clazz != null  &&  !spiContext.getSPI().isAssignableFrom(clazz)) {
  -            throw new ServiceException("Class " + serviceImplName +
  +            throw new DiscoveryException("Class " + serviceImplName +
                             " does not implement " + spiContext.getSPI().getName());
           }
           
  @@ -159,10 +159,10 @@
        * @param localOnly Use only local class loader
        *                  (do not try thread context class loader).
        *
  -     * @exception ServiceException if a suitable resource cannot be created.
  +     * @exception DiscoveryException if a suitable resource cannot be created.
        */
       public InputStream findResourceAsStream(String resourceName, boolean localOnly)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return ClassLoaderUtils.getResourceAsStream(spiContext.getSPI().getPackage().getName(),
                                                       resourceName,
  
  
  
  1.3       +18 -18    jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassLoaderUtils.java
  
  Index: ClassLoaderUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassLoaderUtils.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClassLoaderUtils.java	17 Jul 2002 22:03:06 -0000	1.2
  +++ ClassLoaderUtils.java	18 Jul 2002 18:32:34 -0000	1.3
  @@ -90,7 +90,7 @@
        * @param serviceImplName The name of the class to load.
        */
       private static Class rawLoadClass(String serviceImplName, ClassLoader loader)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           Class clazz = null;
           
  @@ -114,7 +114,7 @@
       public static Class loadClass(String serviceImplName,
                                     ClassLoader[] loaders,
                                     int length)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           Class clazz = null;
           
  @@ -140,7 +140,7 @@
        * @param serviceImplName The name of the class to load.
        */
       public static Class loadClass(String serviceImplName, ClassLoader[] loaders)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return loadClass(serviceImplName, loaders, loaders.length);
       }
  @@ -152,7 +152,7 @@
        * @param serviceImplName The name of the class to load.
        */
       public static Class loadClass(String serviceImplName, SPIContext spiContext)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return loadClass(serviceImplName, spiContext.getClassLoaders());
       }
  @@ -168,7 +168,7 @@
       public static InputStream getResourceAsStream(String resourceName,
                                                     ClassLoader[] loaders,
                                                     int length)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           InputStream stream = null;
           
  @@ -194,7 +194,7 @@
        * @param resourceName The name of the resource to load.
        */
       public static InputStream getResourceAsStream(String resourceName, ClassLoader[] loaders)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return getResourceAsStream(resourceName, loaders, loaders.length);
       }
  @@ -206,7 +206,7 @@
        * @param resourceName The name of the resource to load.
        */
       public static InputStream getResourceAsStream(String resourceName, SPIContext spiContext)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return getResourceAsStream(resourceName, spiContext.getClassLoaders());
       }
  @@ -226,7 +226,7 @@
                                                     String resourceName,
                                                     ClassLoader[] loaders,
                                                     int length)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           InputStream stream = getResourceAsStream(resourceName, loaders, length);
           
  @@ -255,7 +255,7 @@
       public static InputStream getResourceAsStream(String packageName,
                                                     String resourceName,
                                                     ClassLoader[] loaders)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return getResourceAsStream(packageName, resourceName, loaders, loaders.length);
       }
  @@ -273,7 +273,7 @@
       public static InputStream getResourceAsStream(String packageName,
                                                     String resourceName,
                                                     SPIContext spiContext)
  -        throws ServiceException
  +        throws DiscoveryException
       {
           return getResourceAsStream(packageName, resourceName, spiContext.getClassLoaders());
       }
  @@ -373,11 +373,11 @@
        * The system class loader is available for JDK 1.2
        * or later, if certain security conditions are met.
        * 
  -     * @exception ServiceException if a suitable class loader
  +     * @exception DiscoveryException if a suitable class loader
        *            cannot be identified.
        */
       public static ClassLoader findSystemClassLoader()
  -        throws ServiceException
  +        throws DiscoveryException
       {
           ClassLoader classLoader = null;
           
  @@ -390,7 +390,7 @@
                   classLoader =
                       BootstrapLoader.wrap((ClassLoader)method.invoke(null, null));
               } catch (IllegalAccessException e) {
  -                throw new ServiceException("Unexpected IllegalAccessException", e);
  +                throw new DiscoveryException("Unexpected IllegalAccessException", e);
               } catch (InvocationTargetException e) {
                   /**
                    * InvocationTargetException is thrown by 'invoke' when
  @@ -405,7 +405,7 @@
                   } else {
                       // Capture 'e.getTargetException()' exception for details
                       // alternate: log 'e.getTargetException()', and pass back 'e'.
  -                    throw new ServiceException
  +                    throw new DiscoveryException
                           ("Unexpected InvocationTargetException",
                            e.getTargetException());
                   }
  @@ -430,11 +430,11 @@
        * The thread context class loader is available for JDK 1.2
        * or later, if certain security conditions are met.
        * 
  -     * @exception ServiceException if a suitable class loader
  +     * @exception DiscoveryException if a suitable class loader
        * cannot be identified.
        */
       public static ClassLoader findThreadContextClassLoader()
  -        throws ServiceException
  +        throws DiscoveryException
       {
           ClassLoader classLoader = null;
           
  @@ -447,7 +447,7 @@
                   classLoader =
                       BootstrapLoader.wrap((ClassLoader)method.invoke(Thread.currentThread(),
null));
               } catch (IllegalAccessException e) {
  -                throw new ServiceException("Unexpected IllegalAccessException", e);
  +                throw new DiscoveryException("Unexpected IllegalAccessException", e);
               } catch (InvocationTargetException e) {
                   /**
                    * InvocationTargetException is thrown by 'invoke' when
  @@ -472,7 +472,7 @@
                   } else {
                       // Capture 'e.getTargetException()' exception for details
                       // alternate: log 'e.getTargetException()', and pass back 'e'.
  -                    throw new ServiceException
  +                    throw new DiscoveryException
                           ("Unexpected InvocationTargetException",
                            e.getTargetException());
                   }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/DiscoveryException.java
  
  Index: DiscoveryException.java
  ===================================================================
  /*
   * $Header$
   * $Revision$
   * $Date$
   *
   * ====================================================================
   *
   * 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;
  
  
  /**
   * <p>An exception that is thrown only if a suitable service
   * instance cannot be created by <code>ServiceFactory</code></p>
   * 
   * <p>Copied from LogConfigurationException<p>
   *
   * @author Craig R. McClanahan
   * @version $Revision$ $Date$
   */
  
  public class DiscoveryException extends RuntimeException {
  
  
      /**
       * Construct a new exception with <code>null</code> as its detail message.
       */
      public DiscoveryException() {
          super();
      }
  
      /**
       * Construct a new exception with the specified detail message.
       *
       * @param message The detail message
       */
      public DiscoveryException(String message) {
          super(message);
      }
  
      /**
       * Construct a new exception with the specified cause and a derived
       * detail message.
       *
       * @param cause The underlying cause
       */
      public DiscoveryException(Throwable cause) {
          this((cause == null) ? null : cause.toString(), cause);
      }
  
      /**
       * Construct a new exception with the specified detail message and cause.
       *
       * @param message The detail message
       * @param cause The underlying cause
       */
      public DiscoveryException(String message, Throwable cause) {
          super(message);
          this.cause = cause; // Two-argument version requires JDK 1.4 or later
      }
  
      /**
       * The underlying cause of this exception.
       */
      protected Throwable cause = null;
  
      /**
       * Return the underlying cause of this exception (if any).
       */
      public Throwable getCause() {
          return this.cause;
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/Discovery.java
  
  Index: Discovery.java
  ===================================================================
  /*
   * $Header$
   * $Revision$
   * $Date$
   *
   * ====================================================================
   *
   * 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.Hashtable;
  import java.util.Properties;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  
  
  /**
   * <p>Discover service instances,
   * with discovery and configuration features similar to that employed
   * by standard Java APIs such as JAXP.</p>
   *
   * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily
   * based on the SAXParserFactory and DocumentBuilderFactory implementations
   * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p>
   * 
   * @author Richard A. Sitze
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @version $Revision$ $Date$
   */
  public class Discovery {
      /**
       * Sets of previously encountered service interfaces (spis), keyed by the
       * interface (<code>Class</code>).  Each element is a ServiceCache.
       */
      private static final Hashtable service_caches = new Hashtable(13);
      
      /**
       * <p>Locate and instantiate a service.  The service implementation
       * class is located using the following ordered lookup:</p>
       * <ul>
       * <li>Try to load a class with the name obtained from the system
       *     property, having the same name as the spi class:
       *     <code>spiContext.getSPI().getName()</code>.</li>
       * 
       * <li>Try to load a class with the name obtained from the
       *     <code>properties</code> parameter, having the same
       *     name as the spi class: <code>spiContext.getSPI().getName()</code>.</li>
       * 
       * <li>Use the JDK1.3+ 'Service Provider' specification
       *     (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html)
       *     to locate a service named <code>spiContext.getSPI().getName()</code>.
       *     Implemented internally, so there is not a hard
       *     dependency on JDK 1.3+.</li>
       * 
       * <li>Fall back to a default implementation class, as specified by
       *     non-null <code>defaultImplName</code>.</li>
       * </ul>
       * 
       * <p>In most cases, after class NAME is found, then a
       * number of attempts are made to load the class using different
       * class loaders, in the following sequence:
       * <ul>
       * <li>Thread Context Class Loader</li>
       * <li>Caller's Class Loader</li>
       * <li>SPI's Class Loader</li>
       * <li>ServiceFinder's (this class) Class Loader</li>
       * <li>System Class Loader</li>
       * </ul>
       * 
       * <p>The default implementation is loaded using:
       * <ul>
       * <li>ServiceFinder's (this class) Class Loader</li>
       * <li>System Class Loader</li>
       * </ul>
       * 
       * @param ClassFinder  Represents the class loaders provided 
       *        by a root finder class, and the spiContext.
       * 
       * @param spiContext The SPI Context identifies the SPI and the
       *        thread context class loader.
       *        <code>spiContext.getSPI().getName()</code> id's the (property)
       *        name of the service implementation.  Presumed to be an interface,
       *        but there is nothing in the code that prevents it from
       *        being an abstract base class, or even a class.
       * 
       * @param properties used as one alternative to find name of service
       *        implementation class, with property name specified by
       *        <code>spi.getName()</code>.  If the implementation class found
       *        for <code>spi</code> implements the <code>Service</code>
       *        interface, then <code>spiInstance.init(properties)</code> is
       *        called.
       * 
       * @param defaultImplName Name of the default implementation class.
       *
       * @exception DiscoveryException if the implementation class
       *            is not available,
       *            cannot be instantiated,
       *            or is not an instance of <code>spi</code>.
       */
      private static Object find(ClassFinder classFinder,
                                 SPIContext spiContext,
                                 Properties properties,
                                 String defaultImplName)
          throws DiscoveryException
      {
          /**
           * Return previously registered service object (not class)
           * for this spi.  Try each class loader in succession.
           */
          Object service = null;
          ClassLoader[] allLoaders = classFinder.getAllLoaders();
  
          for (int idx = 0; service == null  &&  idx < allLoaders.length; idx++)
{
              service = get(spiContext.getSPI().getName(), allLoaders[idx]);
          }
  
          if (service != null) {        
              // First, try the system property
              Class clazz = classFinder.systemFindClass();
      
              if (clazz == null) {
                  // Second, try the properties parameter
                  if (properties != null)
                      clazz = classFinder.findClass(properties);
              
                  if (clazz == null) {
                      // Third, try to find a service by using the JDK1.3 jar
                      // discovery mechanism.
                      clazz = classFinder.jdk13FindClass();
                  
                      if (clazz == null) {
                          // Fourth, try the fallback implementation class
                          clazz = classFinder.findClass(defaultImplName, true);
                          
                          if (clazz == null) {
                              throw new DiscoveryException
                                  ("No implementation defined for " +
                                   spiContext.getSPI().getName());
                          }
                      }
                  }
              }
              
              if (clazz != null) {
                  try {
                      service = clazz.newInstance();
                      put(spiContext.getSPI().getName(), clazz.getClassLoader(), service);
                  } catch (Exception e) {
                      throw new DiscoveryException("Unable to instantiate " + spiContext.getSPI().getName(),
e);
                  }
                  
                  if (service instanceof Service) {
                      ((Service)service).init(properties);
                  }
              }
          }
  
          return service;
      }
      
      /**
       * <p>Locate and instantiate a service.  The service implementation
       * class is located using the following ordered lookup:</p>
       * <ul>
       * <li>Try to load a class with the name obtained from the system
       *     property, having the same name as the spi class:
       *     <code>spiContext.getSPI().getName()</code>.</li>
       * 
       * <li>Try to load a class with the name obtained from the
       *     <code>properties</code> parameter, having the same
       *     name as the spi class: <code>spiContext.getSPI().getName()</code>.</li>
       * 
       * <li>Use the JDK1.3+ 'Service Provider' specification
       *     (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html)
       *     to locate a service named <code>spiContext.getSPI().getName()</code>.
       *     Implemented internally, so there is not a hard
       *     dependency on JDK 1.3+.</li>
       * 
       * <li>Fall back to a default implementation class, as specified by
       *     non-null <code>defaultImplName</code>.</li>
       * </ul>
       * 
       * <p>In most cases, after class NAME is found, then a
       * number of attempts are made to load the class using different
       * class loaders, in the following sequence:
       * <ul>
       * <li>Thread Context Class Loader</li>
       * <li>Caller's Class Loader</li>
       * <li>SPI's Class Loader</li>
       * <li>ServiceFinder's (this class) Class Loader</li>
       * <li>System Class Loader</li>
       * </ul>
       * 
       * <p>The default implementation is loaded using:
       * <ul>
       * <li>ServiceFinder's (this class) Class Loader</li>
       * <li>System Class Loader</li>
       * </ul>
       * 
       * @param rootFinderClass  The root finder class.
       *        If a wrapper/factory class is used around 'ServiceFinder',
       *        then this will be that wrapper/factory class.
       * 
       * @param spiContext The SPI Context identifies the SPI and the
       *        thread context class loader.
       *        <code>spiContext.getSPI().getName()</code> id's the (property)
       *        name of the service implementation.  Presumed to be an interface,
       *        but there is nothing in the code that prevents it from
       *        being an abstract base class, or even a class.
       * 
       * @param properties used as one alternative to find name of service
       *        implementation class, with property name specified by
       *        <code>spi.getName()</code>.  If the implementation class found
       *        for <code>spi</code> implements the <code>Service</code>
       *        interface, then <code>spiInstance.init(properties)</code> is
       *        called.
       * 
       * @param defaultImplName Name of the default implementation class.
       *
       * @exception DiscoveryException if the implementation class
       *            is not available,
       *            cannot be instantiated,
       *            or is not an instance of <code>spi</code>.
       */
      public static Object find(Class rootFinderClass,
                                SPIContext spiContext,
                                Properties properties,
                                String defaultImplName)
          throws DiscoveryException
      {
          // thread context can change on each call,
          // so establish context for this one call.
          ClassFinder classFinder = new ClassFinder(spiContext, rootFinderClass);
          return find(classFinder, spiContext, properties, defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(ServiceFinder.class, spiContext, properties, defaultImplName)</code>.
       */
      public static Object find(SPIContext spiContext,
                                Properties properties,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(Discovery.class, spiContext, properties, defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(new SPIContext(spi), properties, defaultImplName)</code>.
       */
      public static Object find(Class rootFinderClass,
                                Class spi,
                                Properties properties,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(rootFinderClass, new SPIContext(spi), properties, defaultImplName);
      }
  
      /**
       * Equivalent to
       * <code>find(ServiceFinder.class, spi, properties, defaultImplName)</code>.
       */
      public static Object find(Class spi,
                                Properties properties,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(Discovery.class, spi, properties, defaultImplName);
      }
  
      /**
       * Load properties file, and call
       * <code>find(rootFinderClass, spiContext, properties, defaultImplName)</code>.
       */    
      public static Object find(Class rootFinderClass,
                                SPIContext spiContext,
                                String overloadPrefix,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          // thread context can change on each call,
          // so establish context for this one call.
          ClassFinder classFinder = new ClassFinder(spiContext, rootFinderClass);
  
          Properties properties = null;
          
          if (propertiesFileName != null) {
              try {
                  InputStream stream =
                      (overloadPrefix == null)
                      ? null
                      : classFinder.findResourceAsStream(overloadPrefix + "." + propertiesFileName,
false);
  
                  if (stream == null)    
                      stream = classFinder.findResourceAsStream(propertiesFileName, false);
      
                  if (stream != null) {
                      properties = new Properties();
                      try {
                          properties.load(stream);
                      } finally {
                          stream.close();
                      }
                  }
              } catch (IOException e) {
              } catch (SecurityException e) {
              }
          }
          
          return find(classFinder, spiContext, properties, defaultImplName);
      }
  
      /**
       * Load properties file, and call
       * <code>find(ServiceFinder.class, spiContext, propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(SPIContext spiContext,
                                String overloadPrefix,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(Discovery.class, spiContext, overloadPrefix, propertiesFileName, defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(rootFinderClass, new SPIContext(spi), propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(Class rootFinderClass,
                                Class spi,
                                String overloadPrefix,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(rootFinderClass, new SPIContext(spi), overloadPrefix, propertiesFileName,
defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(new SPIContext(spi), propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(Class spi,
                                String overloadPrefix,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(new SPIContext(spi), overloadPrefix, propertiesFileName, defaultImplName);
      }
  
      /**
       * Load properties file, and call
       * <code>find(rootFinderClass, spiContext, properties, defaultImplName)</code>.
       */    
      public static Object find(Class rootFinderClass,
                                SPIContext spiContext,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(rootFinderClass, spiContext, (String)null, propertiesFileName, defaultImplName);
      }
      
      /**
       * Load properties file, and call
       * <code>find(ServiceFinder.class, spiContext, propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(SPIContext spiContext,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(Discovery.class, spiContext, (String)null, propertiesFileName, defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(rootFinderClass, new SPIContext(spi), propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(Class rootFinderClass,
                                Class spi,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(rootFinderClass, new SPIContext(spi), propertiesFileName, defaultImplName);
      }
      
      /**
       * Equivalent to
       * <code>find(new SPIContext(spi), propertiesFileName, defaultImplName)</code>.
       */    
      public static Object find(Class spi,
                                String propertiesFileName,
                                String defaultImplName)
          throws DiscoveryException
      {
          return find(new SPIContext(spi), propertiesFileName, defaultImplName);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(rootFinderClass, spi, (Properties)null, defaultImplName);
       */
      public static Object find(Class rootFinderClass, Class spi, String defaultImplName)
          throws DiscoveryException
      {
          return find(rootFinderClass, spi, (Properties)null, defaultImplName);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(spi, (Properties)null, defaultImplName);
       */
      public static Object find(Class spi, String defaultImplName)
          throws DiscoveryException
      {
          return find(spi, (Properties)null, defaultImplName);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(rootFinderClass, spi, properties, null);
       */
      public static Object find(Class rootFinderClass, Class spi, Properties properties)
          throws DiscoveryException
      {
          return find(rootFinderClass, spi, properties, null);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(spi, properties, null);
       */
      public static Object find(Class spi, Properties properties)
          throws DiscoveryException
      {
          return find(spi, properties, null);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(rootFinderClass, spi, (Properties)null, null);
       */
      public static Object find(Class rootFinderClass, Class spi)
          throws DiscoveryException
      {
          return find(rootFinderClass, spi, (Properties)null, null);
      }
  
      /**
       * Find implementation of SPI.
       * Equivalent to find(spi, (Properties)null, null);
       */
      public static Object find(Class spi)
          throws DiscoveryException
      {
          return find(spi, (Properties)null, null);
      }
  
      /**
       * Release any internal references to previously created service instances,
       * after calling the instance method <code>release()</code> on each of them.
       *
       * This is useful environments like servlet containers,
       * which implement application reloading by throwing away a ClassLoader.
       * Dangling references to objects in that class loader would prevent
       * garbage collection.
       */
      public static void releaseAll() {
          synchronized (service_caches) {
              Enumeration cache = service_caches.elements();
              while (cache.hasMoreElements()) {
                  ((ServiceCache)cache.nextElement()).releaseAll();
              }
              service_caches.clear();
          }
      }
      
      /**
       * Release any internal references to previously created instances of SPI,
       * after calling the instance method <code>release()</code> on each of them.
       *
       * This is useful environments like servlet containers,
       * which implement application reloading by throwing away a ClassLoader.
       * Dangling references to objects in that class loader would prevent
       * garbage collection.
       */
      public static void releaseAll(Class spi) {
          if (spi != null) {
              synchronized (service_caches) {
                  ServiceCache cache = (ServiceCache)service_caches.get(spi.getName());
                  if (cache != null) {
                      cache.releaseAll();
                  }
              }
          }
      }
      
      /**
       * Get service keyed by spi & classLoader.
       * Special cases null bootstrap classloader (classLoader == null).
       */
      private static Object get(String spi, ClassLoader classLoader)
      {
          ServiceCache cache = (spi == null)
                               ? null
                               : (ServiceCache)service_caches.get(spi);
          
          return (cache == null)
                  ? null
                  : cache.get(classLoader);
      }
      
      /**
       * Put service keyed by spi & classLoader.
       * Special cases null bootstrap classloader (classLoader == null).
       */
      private static void put(String spi, ClassLoader classLoader, Object service)
      {
          if (spi != null  &&  service != null) {
              ServiceCache cache = (ServiceCache)service_caches.get(spi);
              
              if (cache == null) {
                  cache = new ServiceCache();
                  service_caches.put(spi, cache);
              }
              
              cache.put(classLoader, service);
          }
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message