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

Relationship to the Initial Context

When the API user supplies a URL string to one of the methods in the InitialContext(in the API reference documentation) or InitialDirContext(in the API reference documentation) class, the JNDI extracts the URL scheme from the string and uses NamingManager.getURLContext()(in the API reference documentation) to find a URL context implementation that can process the URL string. This method uses the algorithm described earlier in this lesson.

If the JNDI successfully locates a URL context implementation, then it invokes the original context method by using the original arguments. This means that the complete URL string is passed on to the URL context implementation, where it is processed as described in the URL Context Implementation section of this lesson.

If the JNDI cannot locate a URL context implementation to use to process the URL string, then it assumes that the input name is not a URL string. It then passes the name to the underlying initial context implementation (that named by the Context.INITIAL_CONTEXT_FACTORY(in the API reference documentation) ("java.naming.factory.initial") environment property).

Supporting Subinterfaces

To provide URL support from the initial context to a Context(in the API reference documentation) subinterface, you need to define a new class that extends from InitialContext or one of its subclasses. See the discussion earlier in this lesson regarding factors to consider when deciding whether to add URL support for a subinterface.

For example, suppose that BarContext extends Context by adding two new methods: barMethod(), which accepts a name argument, and bazMethod(), which does not. This service has a URL scheme id of bar. (See its URL context implementation presented earlier in this lesson.) To define an initial context for this interface, you first specify its inheritance.

public class InitialBarContext 
    extends InitialContext implements BarContext
This class extends from the InitialContext and implements the new interface, BarContext.

Then you define some constructors that are suitable for the class. Typically, you should plan on at least two constructors, one that accepts no arguments and one that accepts the environment parameter.

public InitialBarContext() throws NamingException {
    super();
}

public InitialBarContext(Hashtable env) throws NamingException {
    super(env);
}
Next, you provide utility methods for both methods that process names and those that don't. For methods that process names, define a utility method that returns either a URL context or the default underlying initial context by inspecting the name argument. Most of the work for this is done by the protected method InitialContext.getURLOrDefaultInitCtx()(in the API reference documentation). The utility method needs only to check the type of the resulting context to make sure that it is compatible with that of the subinterface. You need two such methods, one for the string name and one for Name. Here is the string version.
protected BarContext getURLOrDefaultInitBarCtx(String name)
    throws NamingException {
    Context ctx = getURLOrDefaultInitCtx(name);
    if (!(ctx instanceof BarContext)) {
	throw new NoInitialContextException("Not a BarContext");
    }
    return (BarContext)ctx;
}
For methods that do not process names, define a utility method that returns the default underlying initial context. Most of the work for this is done by the protected method InitialContext.getDefaultInitCtx()(in the API reference documentation). The utility method needs only to check the type of the resulting context to make sure that it is compatible with that of the subinterface.
protected BarContext getDefaultInitBarCtx() throws NamingException {
    Context ctx = getDefaultInitCtx();
    if (!(ctx instanceof BarContext)) {
	throw new NoInitialContextException("Not a BarContext");
    }
    return (BarContext)ctx;
}
Once you have these methods, it is straightforward to provide implementations for all of the new methods. New name-related methods use getURLOrDefaultInitBarCtx(), whereas new non-name-related methods use getDefaultInitBarCtx(). Here are some examples.
public Object barMethod(String name) throws NamingException {
    return getURLOrDefaultInitBarCtx(name).barMethod(name);
}

public String bazMethod() throws NamingException {
    return getDefaultInitBarCtx().bazMethod();
}
To use this new initial context implementation, your program must import the new class. Here is an example that invokes one of the new methods using a bar URL.
tut.BarContext ctx = new tut.InitialBarContext();

// Invoke the BarContext-specific method with the URL
Object answer = ctx.barMethod("bar:/a");
Running this example produces the output
The answer is a


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