Java Enterprise in a Nutshell (In a Nutshell (OReilly))

9.7. Creating and Destroying Contexts

With JNDI, you can create a context in a naming system using the createSubcontext( ) method of an existing Context. All you have to specify in this call is the name of the new subcontext. Note that Context doesn't provide a public constructor; creating a new context requires a parent Context (such as an InitialContext) whose createSubcontext( ) method we can call.

When you call createSubcontext( ), the JNDI service provider you are using looks at the class of the Context whose method you are calling. Based on this class and the provider's own internal logic, the provider creates a new object of a particular class. You don't get to pick the class of this object; the provider has all the control over the class of the object it creates (you do, however, have control over the class of object that is created when using directory services, as we'll see shortly). The documentation for a service provider should tell you what kinds of objects createSubcontext( ) can create. Note that whatever object the provider creates, it always implements Context; there is no way to use JNDI to create an object that doesn't implement Context.

For example, if we are using the Sun filesystem provider and our current Context is a directory, calling createSubcontext( ) causes the provider to create a directory, not a file. This makes sense, as a directory can have subordinates and thus implements Context. There is actually no way to create a file using the JNDI API and the filesystem provider; you have to drop out of JNDI to do this, as we'll see in the next section.

Example 9-8 shows the implementation of a create command for NamingShell that demonstrates how to use createSubcontext( ).

Example 9-8. The create command

import java.util.Vector; import javax.naming.*; public class create implements Command { public void execute(Context c, Vector v) throws CommandException { // Check to see if we have the name we need to create a context if (v.isEmpty( )) throw new CommandException(new Exception( ), "No name specified"); String name = (String)v.firstElement( ); try { c.createSubcontext(name); System.out.println("Created " + name); } catch (NoPermissionException npe) { throw new CommandException(npe, "You don't have permission to create " + name + " at this context"); } catch (NamingException ne) { throw new CommandException(ne, "Couldn't create " + name); } } public void help( ) { System.out.println("Usage: create [name]"); } }

Here is the create command, in conjunction with the cd and list commands we've already seen:

/% create test Created test /% cd test Current context now test test% create another Created another test% list another (type javax.naming.Context)

The destroySubcontext( ) method of Context destroys a context, as you might expect from its name. Again, you have to specify the name of the context to be destroyed; you can't destroy the current object by specifying an empty name. Calling the destroySubcontext( ) method on a Context from the Sun filesystem provider is analogous to removing a directory in the filesystem.

Example 9-9 shows the implementation of a destroy command for NamingShell. Note that it contains several catch statements, to handle such exceptions as insufficient permission to destroy a context, trying to destroy an object that doesn't implement the Context interface, and trying to destroy an object that has children.

Example 9-9. The destroy command

import java.util.Vector; import javax.naming.*; public class destroy implements Command { public void execute(Context c, Vector v) throws CommandException { // Check to see if we have the name we need if (v.isEmpty( )) throw new CommandException(new Exception( ), "No name specified"); String name = (String)v.firstElement( ); try { c.destroySubcontext(name); System.out.println("Destroyed " + name); } catch (NameNotFoundException nnfe) { throw new CommandException(nnfe, "Couldn't find " + name); } catch (NotContextException nce) { throw new CommandException(nce, name + " is not a Context and couldn't be destroyed"); } catch (ContextNotEmptyException cnee) { throw new CommandException(cnee, name + " is not empty and couldn't be destroyed"); } catch (NamingException ne) { throw new CommandException(ne, name + " couldn't be destroyed"); } } public void help( ) { System.out.println("Usage: destroy [name]"); } }

Категории