| Adding URL Support

## Supporting Subinterfaces

> An API user can pass a URL string to methods in the `InitialDirContext` class in the same way as for methods in the `InitialContext` class. To support this capability, the corresponding URL context implementation must support methods in the `DirContext` interface in addition to those in the `Context` interface, using the techniques described earlier in the URL Context Implementation section.

> If your URL context implementation also supports federation, then it should define an internal utility method for getting the continuation context for performing directory operations. Here is an example.

> >     protected DirContext getContinuationDirContext(Name n)
> >         throws NamingException {
> >         Object obj = lookup(n.get(0));
> >         CannotProceedException cpe = new CannotProceedException();
> >         cpe.setResolvedObj(obj);
> >         cpe.setEnvironment(myEnv);
> >         return DirectoryManager.getContinuationDirContext(cpe);
> >     }

> This method uses `DirectoryManager.getContinuationDirContext()` to get the continuation context. Overloads that accept `Name` use this utility in their implementations. Here is an example of how `getAttributes()` uses `getContinuationDirContext()`.

> >     public Attributes getAttributes(Name name, String[] attrIDs)
> >         throws NamingException  {
> >         if (name.size() == 1) {
> >     	return getAttributes(name.get(0), attrIDs);
> >         } else {
> >     	DirContext ctx = getContinuationDirContext(name);
> >     	try {
> >     	    return ctx.getAttributes(name.getSuffix(1), attrIDs);
> >     	} finally {
> >     	    ctx.close();
> >     	}
> >         }
> >     }

> The implementation of the overloads that accept string names uses a similar pattern to that used by methods of the `Context` interface. Instead of expecting a `Context` as the resolved object from the internal utility `getRootURLContext()`, the `DirContext` methods should expect a `DirContext`. Here is an example of the `getAttributes()` implementation.

> >     public Attributes getAttributes(String name, String[] attrIds)
> >          throws NamingException {
> >     	ResolveResult res = getRootURLContext(name, myEnv);
> >     	DirContext ctx = (DirContext)res.getResolvedObj();
> >             try {
> >     	    return ctx.getAttributes(res.getRemainingName(), attrIds);
> >             } finally {
> >     	    ctx.close();
> >             }
> >     }

> #### Supporting Nonstandard Subinterfaces

> Adding URL support for methods in the `DirContext` interface makes sense because that interface contains methods that process names. Adding URL support doesn't make sense for subinterfaces whose methods have nothing to do with names. For example, you need not provide URL support for methods in the `LdapContext` interface because none of its methods deal with names.

> Another reason that URL support might not be appropriate for some subinterfaces is that the model might not be appropriate. For example, the `EventContext` and `EventDirContext` interfaces contain methods that process names. However, these interfaces define a model in which listener registration is closely tied to the `Context` instance. This does not fit well with URLs, which are effectively absolute names that have no allegiance to a particular `Context` instance. (These two interfaces and the event model they support are described in the Event Notification lesson.)

> Other, possibly proprietary, subinterfaces might exist of `Context` for which it makes sense to provide URL support. For such cases, you should follow the guidelines given earlier in this lesson and in this section when building your URL context implementation. Namely, the overloads that accept `Name` should use `getContinuationContext()` (if the context implementation supports federation), whereas the overloads that accept string names should use a utility similar to `getRootURLContext()`.

> Here is an example. `BarContext` extends the `Context` interface by adding two new methods: `barMethod()`, which accepts a name argument, and `bazMethod()`, which does not. (A sample context implementation, `BarContextImpl`, which is based on the earlier `HierCtx` example, is supplied with this tutorial.) Its URL context implementation, `barURLContext`, implements the subinterface and extends from the earlier example `fooURLContext`. Here is `barURLContext`'s definition of its name-related method.

> >     public Object barMethod(Name name) throws NamingException {
> >         if (name.size() == 1) {
> >     	return barMethod(name.get(0));
> >         } else {
> >     	Context ctx = getContinuationContext(name);
> >     	if (!(ctx instanceof tut.BarContext)) {
> >     	    throw new NotContextException(
> >     		"Cannot continue operation on nonBarContext");
> >     	}
> >     	try {
> >     	    return ((tut.BarContext)ctx).barMethod(name.getSuffix(1));
> >     	} finally {
> >     	    ctx.close();
> >     	}
> >         }
> >     }

> >     public Object barMethod(String name) throws NamingException {
> >         ResolveResult res = getRootURLContext(name, myEnv);
> >         tut.BarContext ctx = (tut.BarContext)res.getResolvedObj();
> >         try {
> >     	return ctx.barMethod(res.getRemainingName());
> >         } finally {
> >     	ctx.close();
> >         }
> >     }

> Methods that are not name-related, such as `bazMethod()`, typically won't be called from the URL context because of how URL contexts are accessed (see the discussion later in this lesson). However, you still need to provide implementations for them to satisfy Java programming language requirements. You then need to provide a URL context factory for this URL context implementation, as described earlier in this lesson.

> You also should follow the instructions for extending the initial context described later in this lesson for supporting URLs for subinterfaces. This last step is not necessary for the `DirContext` subinterface. This is because an initial context class, `InitialDirContext`, already exists that directs `DirContext` calls that involve the URL string names to the appropriate URL context implementation.

| Adding URL Support