Class DiscoverClass


  • public class DiscoverClass
    extends java.lang.Object

    Discover class that implements a given service interface, with discovery and configuration features similar to that employed by standard Java APIs such as JAXP.

    In the context of this package, a service interface is defined by a Service Provider Interface (SPI). The SPI is expressed as a Java interface, abstract class, or (base) class that defines an expected programming interface.

    DiscoverClass provides the find methods for locating a class that implements a service interface (SPI). Each form of find varies slightly, but they all perform the same basic function. The DiscoverClass.find methods proceed as follows:

    • Get the name of an implementation class. The name is the first non-null value obtained from the following resources:
      • The value of the (scoped) system property whose name is the same as the SPI's fully qualified class name (as given by SPI.class.getName()). The ScopedProperties class provides a way to bind properties by classloader, in a secure hierarchy similar in concept to the way classloader find class and resource files. See ScopedProperties for more details.

        If the ScopedProperties are not set by users, then behaviour is equivalent to System.getProperty().

      • The value of a Properties properties property, if provided as a parameter, whose name is the same as the SPI's fully qualifed class name (as given by SPI.class.getName()).
      • The value obtained using the JDK1.3+ 'Service Provider' specification (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html) to locate a service named SPI.class.getName(). This is implemented internally, so there is not a dependency on JDK 1.3+.
    • If the name of the implementation class is non-null, load that class. The class loaded is the first class loaded by the following sequence of class loaders:
      • Thread Context Class Loader
      • DiscoverSingleton's Caller's Class Loader
      • SPI's Class Loader
      • DiscoverSingleton's (this class or wrapper) Class Loader
      • System Class Loader
      An exception is thrown if the class cannot be loaded.
    • If the name of the implementation class is null, AND the default implementation class name (defaultImpl) is null, then an exception is thrown.
    • If the name of the implementation class is null, AND the default implementation class (defaultImpl) is non-null, then load the default implementation class. The class loaded is the first class loaded by the following sequence of class loaders:
      • SPI's Class Loader
      • DiscoverSingleton's (this class or wrapper) Class Loader
      • System Class Loader

      This limits the scope in which the default class loader can be found to the SPI, DiscoverSingleton, and System class loaders. The assumption here is that the default implementation is closely associated with the SPI or system, and is not defined in the user's application space.

      An exception is thrown if the class cannot be loaded.

    • Verify that the loaded class implements the SPI: an exception is thrown if the loaded class does not implement the SPI.

    IMPLEMENTATION NOTE - This implementation is modelled after the SAXParserFactory and DocumentBuilderFactory implementations (corresponding to the JAXP pluggability APIs) found in Apache Xerces.

    Version:
    $Revision: 480374 $ $Date: 2006-11-28 19:33:25 -0800 (Tue, 28 Nov 2006) $
    Author:
    Richard A. Sitze, Craig R. McClanahan, Costin Manolache
    • Constructor Summary

      Constructors 
      Constructor Description
      DiscoverClass()
      Create a class instance with dynamic environment (thread context class loader is determined on each call).
      DiscoverClass​(ClassLoaders classLoaders)
      Create a class instance with dynamic environment (thread context class loader is determined on each call).
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static java.lang.String[] discoverClassNames​(SPInterface spi, java.util.Properties properties)
      Discover names of SPI implementation Classes from properties.
      java.lang.Class find​(java.lang.Class spiClass)
      Find class implementing SPI.
      java.lang.Class find​(java.lang.Class spiClass, java.lang.String defaultImpl)
      Find class implementing SPI.
      java.lang.Class find​(java.lang.Class spiClass, java.lang.String propertiesFileName, java.lang.String defaultImpl)
      Find class implementing SPI.
      java.lang.Class find​(java.lang.Class spiClass, java.util.Properties properties)
      Find class implementing SPI.
      java.lang.Class find​(java.lang.Class spiClass, java.util.Properties properties, java.lang.String defaultImpl)
      Find class implementing SPI.
      static java.lang.Class find​(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl)
      Find class implementing SPI.
      ClassLoaders getClassLoaders​(java.lang.Class spiClass)  
      static java.lang.String getManagedProperty​(java.lang.String propertyName)
      Load the class whose name is given by the value of a (Managed) System Property.
      java.lang.Object newInstance​(java.lang.Class spiClass)
      Create new instance of class implementing SPI.
      java.lang.Object newInstance​(java.lang.Class spiClass, java.lang.String defaultImpl)
      Create new instance of class implementing SPI.
      java.lang.Object newInstance​(java.lang.Class spiClass, java.lang.String propertiesFileName, java.lang.String defaultImpl)
      Create new instance of class implementing SPI.
      java.lang.Object newInstance​(java.lang.Class spiClass, java.util.Properties properties)
      Create new instance of class implementing SPI.
      java.lang.Object newInstance​(java.lang.Class spiClass, java.util.Properties properties, java.lang.String defaultImpl)
      Create new instance of class implementing SPI.
      static java.lang.Object newInstance​(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl)
      Create new instance of class implementing SPI.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • nullDefaultImpl

        public static final DefaultClassHolder nullDefaultImpl
        Readable placeholder for a null value.
      • nullProperties

        public static final PropertiesHolder nullProperties
        Readable placeholder for a null value.
    • Constructor Detail

      • DiscoverClass

        public DiscoverClass()
        Create a class instance with dynamic environment (thread context class loader is determined on each call). Dynamically construct class loaders on each call.
      • DiscoverClass

        public DiscoverClass​(ClassLoaders classLoaders)
        Create a class instance with dynamic environment (thread context class loader is determined on each call). Cache static list of class loaders for each call.
    • Method Detail

      • getClassLoaders

        public ClassLoaders getClassLoaders​(java.lang.Class spiClass)
      • find

        public java.lang.Class find​(java.lang.Class spiClass)
                             throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • find

        public java.lang.Class find​(java.lang.Class spiClass,
                                    java.util.Properties properties)
                             throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • find

        public java.lang.Class find​(java.lang.Class spiClass,
                                    java.lang.String defaultImpl)
                             throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        defaultImpl - Default implementation name.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • find

        public java.lang.Class find​(java.lang.Class spiClass,
                                    java.util.Properties properties,
                                    java.lang.String defaultImpl)
                             throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation,.
        defaultImpl - Default implementation class.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • find

        public java.lang.Class find​(java.lang.Class spiClass,
                                    java.lang.String propertiesFileName,
                                    java.lang.String defaultImpl)
                             throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        propertiesFileName - Used to determine name of SPI implementation,.
        defaultImpl - Default implementation class.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • find

        public static java.lang.Class find​(ClassLoaders loaders,
                                           SPInterface spi,
                                           PropertiesHolder properties,
                                           DefaultClassHolder defaultImpl)
                                    throws DiscoveryException
        Find class implementing SPI.
        Parameters:
        spi - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation,.
        defaultImpl - Default implementation class.
        Returns:
        Class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded, or if the resulting class does not implement (or extend) the SPI.
      • newInstance

        public java.lang.Object newInstance​(java.lang.Class spiClass)
                                     throws DiscoveryException,
                                            java.lang.InstantiationException,
                                            java.lang.IllegalAccessException,
                                            java.lang.NoSuchMethodException,
                                            java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • newInstance

        public java.lang.Object newInstance​(java.lang.Class spiClass,
                                            java.util.Properties properties)
                                     throws DiscoveryException,
                                            java.lang.InstantiationException,
                                            java.lang.IllegalAccessException,
                                            java.lang.NoSuchMethodException,
                                            java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • newInstance

        public java.lang.Object newInstance​(java.lang.Class spiClass,
                                            java.lang.String defaultImpl)
                                     throws DiscoveryException,
                                            java.lang.InstantiationException,
                                            java.lang.IllegalAccessException,
                                            java.lang.NoSuchMethodException,
                                            java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        defaultImpl - Default implementation.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • newInstance

        public java.lang.Object newInstance​(java.lang.Class spiClass,
                                            java.util.Properties properties,
                                            java.lang.String defaultImpl)
                                     throws DiscoveryException,
                                            java.lang.InstantiationException,
                                            java.lang.IllegalAccessException,
                                            java.lang.NoSuchMethodException,
                                            java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
        defaultImpl - Default implementation.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • newInstance

        public java.lang.Object newInstance​(java.lang.Class spiClass,
                                            java.lang.String propertiesFileName,
                                            java.lang.String defaultImpl)
                                     throws DiscoveryException,
                                            java.lang.InstantiationException,
                                            java.lang.IllegalAccessException,
                                            java.lang.NoSuchMethodException,
                                            java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spiClass - Service Provider Interface Class.
        propertiesFileName - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
        defaultImpl - Default implementation.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • newInstance

        public static java.lang.Object newInstance​(ClassLoaders loaders,
                                                   SPInterface spi,
                                                   PropertiesHolder properties,
                                                   DefaultClassHolder defaultImpl)
                                            throws DiscoveryException,
                                                   java.lang.InstantiationException,
                                                   java.lang.IllegalAccessException,
                                                   java.lang.NoSuchMethodException,
                                                   java.lang.reflect.InvocationTargetException
        Create new instance of class implementing SPI.
        Parameters:
        spi - Service Provider Interface Class.
        properties - Used to determine name of SPI implementation, and passed to implementation.init() method if implementation implements Service interface.
        defaultImpl - Default implementation.
        Returns:
        Instance of a class implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found, if the class cannot be loaded and instantiated, or if the resulting class does not implement (or extend) the SPI.
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.NoSuchMethodException
        java.lang.reflect.InvocationTargetException
      • discoverClassNames

        public static java.lang.String[] discoverClassNames​(SPInterface spi,
                                                            java.util.Properties properties)

        Discover names of SPI implementation Classes from properties. The names are the non-null values, in order, obtained from the following resources:

        • ManagedProperty.getProperty(SPI.class.getName());
        • properties.getProperty(SPI.class.getName());
        Parameters:
        properties - Properties that may define the implementation class name(s).
        Returns:
        String[] Name of classes implementing the SPI.
        Throws:
        DiscoveryException - Thrown if the name of a class implementing the SPI cannot be found.
      • getManagedProperty

        public static java.lang.String getManagedProperty​(java.lang.String propertyName)
        Load the class whose name is given by the value of a (Managed) System Property.
        Parameters:
        propertName - the name of the system property whose value is the name of the class to load.
        See Also:
        ManagedProperties