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.
discoverClassNames
public static String[] discoverClassNames(SPInterface spi,
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());
properties
- Properties that may define the implementation
class name(s).
- String[] Name of classes implementing the SPI.
find
public Class find(Class spiClass)
throws DiscoveryException
Find class implementing SPI.
spiClass
- Service Provider Interface Class.
- Class implementing the SPI.
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 Class find(Class spiClass,
Properties properties)
throws DiscoveryException
Find class implementing SPI.
spiClass
- Service Provider Interface Class.properties
- Used to determine name of SPI implementation.
- Class implementing the SPI.
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 Class find(Class spiClass,
Properties properties,
String defaultImpl)
throws DiscoveryException
Find class implementing SPI.
spiClass
- Service Provider Interface Class.properties
- Used to determine name of SPI implementation,.defaultImpl
- Default implementation class.
- Class implementing the SPI.
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 Class find(Class spiClass,
String defaultImpl)
throws DiscoveryException
Find class implementing SPI.
spiClass
- Service Provider Interface Class.defaultImpl
- Default implementation name.
- Class implementing the SPI.
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 Class find(Class spiClass,
String propertiesFileName,
String defaultImpl)
throws DiscoveryException
Find class implementing SPI.
spiClass
- Service Provider Interface Class.propertiesFileName
- Used to determine name of SPI implementation,.defaultImpl
- Default implementation class.
- Class implementing the SPI.
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 Class find(ClassLoaders loaders,
SPInterface spi,
PropertiesHolder properties,
DefaultClassHolder defaultImpl)
throws DiscoveryException
Find class implementing SPI.
spi
- Service Provider Interface Class.properties
- Used to determine name of SPI implementation,.defaultImpl
- Default implementation class.
- Class implementing the SPI.
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.
getClassLoaders
public ClassLoaders getClassLoaders(Class spiClass)
getManagedProperty
public static String getManagedProperty(String propertyName)
Load the class whose name is given by the value of a (Managed)
System Property.
newInstance
public Object newInstance(Class spiClass)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
spiClass
- Service Provider Interface Class.
- Instance of a class implementing the SPI.
newInstance
public Object newInstance(Class spiClass,
Properties properties)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
spiClass
- Service Provider Interface Class.properties
- Used to determine name of SPI implementation,
and passed to implementation.init() method if
implementation implements Service interface.
- Instance of a class implementing the SPI.
newInstance
public Object newInstance(Class spiClass,
Properties properties,
String defaultImpl)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
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.
- Instance of a class implementing the SPI.
newInstance
public Object newInstance(Class spiClass,
String defaultImpl)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
spiClass
- Service Provider Interface Class.defaultImpl
- Default implementation.
- Instance of a class implementing the SPI.
newInstance
public Object newInstance(Class spiClass,
String propertiesFileName,
String defaultImpl)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
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.
- Instance of a class implementing the SPI.
newInstance
public static Object newInstance(ClassLoaders loaders,
SPInterface spi,
PropertiesHolder properties,
DefaultClassHolder defaultImpl)
throws DiscoveryException,
InstantiationException,
IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
Create new instance of class implementing SPI.
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.
- Instance of a class implementing the SPI.