CONTENTS | PREV | NEXT |
This section outlines a few application scenarios to help illustrate the capabilities enabled by JNDI.
The examples below are not meant to be prescriptive. There are often several ways to solve a problem, and JNDI is designed with flexibility in mind.
In secure systems, a user must authenticate himself to the computer, network, or service that he wishes to access. For example, logging into UNIX requires the user to supply a password. Similarly, use of SSL requires that the user supply his X.509 certificate. Such authentication information can be stored as attributes associated with each user in the directory. The system performing the authentication would look up the attribute (for example, "password") of the user and verify the authenticity using the information supplied by the user.
DirContext ctx = new InitialDirContext(); Attribute attr = ctx.getAttributes(userName).get("password"); String password = (String)attr.get();
A useful feature of an electronic mail system is a directory service that provides a mapping between users and email addresses. This allows mail users to search for the email address of a particular user. This is analogous to searching for an individual's telephone number in the phone book in order to dial his phone number. For example, when I want to send mail to John Smith in my department, I search for "John Smith" in the directory using a "search" widget in the mail application. The widget returns to me five entries of John Smith, from which I select the one that is in a building on my site and use the email address attribute associated with that entry.
NamingEnumeration matches = deptCtx.search("user", new BasicAttributes("name", "John Smith")); // use matches to construct a selectable list for end-user while (matches.hasMore()) { SearchResult item = (SearchResult) matches.next(); Attributes info = item.getAttributes(); /* display attributes */ ... }
The directory could also be used by users to set up personalized address books. For example, once I have located John Smith's email address, I might not want to search the directory again each time I send him mail. Instead, I can create a personal subtree in the directory in which I maintain entries that I frequently use, possibly by creating links to the existing entries.
Database applications can use the directory to locate database servers. For example, a financial application needs to get the stock quotes from a stock quote server using JDBC. This application can enable the user to select the stock quote server based on specification of some attributes (such as coverage of which markets and frequency of quote updates). The application searches the directory for quote servers that meet these attributes, and then retrieves the "location" attribute (a JDBC URL) of the selected quote server and connects to it.
NamingEnumeration matches = ctx.search("service/stockQuotes", "(&(market=NASDAQ)(updateFreqency<=300))", searchctls); while (matches.hasMore()) { SearchResult item = (SearchResult)matches.next(); Attribute location = item.getAttributes().get("location"); ... }
When using almost any kind of interactive application that asks a user to input names, the user's job is made easier if a namespace browser is available to him. The browser can either be built into the application and tailored to suit that application in particular, or it can be more general-purpose such as a typical web browser.
A very
simple example of a JNDI browser allows a user to "walk"
through a namespace, viewing the atomic names at each step along
the way. The browser prints a "*" to highlight the name
of each Context
, thus telling the user where he can
go next. 1
// Start at the top -- the initial context. Context ctx = new InitialContext(); while (ctx != null) { // display one level NamingEnumeration items = ctx.list(); while (items.hasMoreElements()) { NameClassPair item = (NameClassPair)items.next(); if (isContext(item.getClassName())) { System.out.print("*"); } else { System.out.print(" "); } System.out.println(" " + item.getName()); } // Take the next step down into the namespace. String target = input.readLine(); try { ctx = (Context)ctx.lookup(target); } catch (NamingException e) { // handle error } catch (ClassCastException e) { // not a context; cannot traverse } }
An important function of a printing service is to provide a means for its human users to easily discover and select printers in the network. An application that needs to print, or the machine on which it runs, should not have to be configured each time a new printer is added to the network. The scope of network access to printers may range from a workgroup to global. The printing service can use the directory to provide this capability.
Assume
that printers are represented by a Printer
interface.
One of the methods in it could be print()
which, when
given an InputStream
, will read data from
InputStream
and print it on the printer represented by
this instance of Printer.
interface Printer { void print(InputStream data) throws PrinterException; ... }
A user
selects a printer using a logical printer name, either explicitly
or through default settings. For example, the user might have
specified a default printer to use for all his applications, which
is overridden only when he explicitly specifies another printer to
use. The application that is accepting the print request takes the
printer name and looks it up in the directory service. The
application expects to receive as the result an object that
implements the Printer
interface.
void myAppPrint(String printerName, String fileName) throws IOException { try { DirContext ctx = new InitialDirContext(); Printer prt = (Printer) ctx.lookup(printerName); prt.print(new FileInputStream(fileName)); } catch (NamingException e){ System.err.println("Could not locate printer: " + e); } catch (ClassCastException e) { System.err.println(printerName + "does not name a printer"); } }
Selecting a printer by explicitly giving its
name is but one way of identifying a printer. The user can also use
the directory to see the different printers available (browsing),
or to search for printers with particular attributes. For example
the user can ask the directory to list all the printers on the
second floor of building 5 in the Mountain View campus, or search
for all color laser printers with 600dpi resolution. From the
application's perspective, just as lookup()
returned a
Printer
object, the list and search operations also
provide the same capability of returning Printer
objects that the application could use to submit print
requests.