Previous | Next | Trail Map | Building a Service Provider | Adding URL Support

URL Context Factory

A URL context factory is a special object factory that creates contexts for resolving URL strings. Like all object factories, it is a class that implements the ObjectFactory(in the API reference documentation) interface. A URL context factory must not only satisfy all of the requirements specified for object factories as stated in the Object Factories (in the Java Objects and the Directory trail) lesson. It also must adhere to the following rules. If the factory receives any other type of object argument to getObjectInstance(), then its behavior is implementation-dependent.

The first rule applies to supporting the resolution of URL strings from the InitialContext(in the API reference documentation)--this is described later in this lesson. The second and third rules apply to supporting the resolution of URL strings embedded in a Reference--this is also described later in this lesson. As indicated by the second and third rules, a URL context factory is not only a producer of context objects. It can produce any type of object named by a URL string.

Class Name's Naming Convention

The URL context factory's class name must use the following naming convention so that it can be located by the JNDI framework:
package_prefix.scheme_id.scheme_idURLContextFactory
where For example, the class name tut.foo.fooURLContextFactory is for the foo URL scheme; it has the package prefix "tut". In another example, the class name com.sun.jndi.url.ldap.ldapURLContextFactory is for the ldap URL scheme; it has the package prefix "com.sun.jndi.url". Notice that package_prefix must not be empty.

Sample Implementation

This section offers an example of how to implement a URL context factory. This example is for illustrative purposes and is not meant to be prescriptive.

The example is for the foo URL scheme, which has the syntax

foo:name in the HierCtx namespace
HierCtx is an in-memory hierarchical namespace implementation. To make it work with the URL example, you need to create a static namespace that can be accessed by using a static method on the HierCtx class. Using a foo URL string, you can name the objects in this static namespace.

Like all object factories, a URL context factory must be public and have a public constructor that accepts no arguments.

public class fooURLContextFactory implements ObjectFactory {
    public fooURLContextFactory() {
    }
    ...
}

This factory's implementation of getObjectInstance() fairly well follows the three rules listed previously. The implementations of these rules use the following utility to create a context from the context implementation fooURLContext.

protected Context getURLContext(Hashtable env) {
    return new fooURLContext(env);
}
An actual implementation may or may not choose this strategy of using one context implementation to satisfy all three requirements. It is perfectly acceptable to have a factory that uses different context implementations.

In the following examples, urlInfo is the object argument to getObjectInstance().

For the first rule, you simply return the root fooURLContext.

if (urlInfo == null) {
    return createURLContext(env);
}

For the second rule, you use the root fooURLContext to look up and return the object named by the URL string.

if (urlInfo instanceof String) {
    Context urlCtx = createURLContext(env);
    try {
        return urlCtx.lookup((String)urlInfo);
    } finally {
        urlCtx.close();
    }
} 
Notice that before the method returns, it closes the root fooURLContext. In this particular example, this step is not really necessary because fooURLContext doesn't maintain any connections or resources. However, doing this is good practice so as to ensure that implementations that do maintain connections or resources are cleaned up properly.

For the third rule, you iterate over the array of URL strings until you find one that succeeds. You save one of the exceptions encountered along the way in case all of the URL strings fail and you need to indicate why.

if (urlInfo instanceof String[]) {

    // Try each URL until lookup() succeeds for one of them.
    // If all URLs fail, throw one of the exceptions arbitrarily.
    String[] urls = (String[])urlInfo;
    if (urls.length == 0) {
        throw (new ConfigurationException("fooURLContextFactory: empty URL array"));
    }
    Context urlCtx = createURLContext(env);
    try {
	NamingException ne = null;
	for (int i = 0; i < urls.length; i++) {
	    try {
	        return urlCtx.lookup(urls[i]);
	    } catch (NamingException e) {
	        ne = e;
	    }
        }
        throw ne;
    } finally {
        urlCtx.close();
    }
}


Previous | Next | Trail Map | Building a Service Provider | Adding URL Support