| What's in a Name?

## Compound Names

> A compound name is a name in a single naming system. Here's an example of a compound name:

> >     cn=homedir,cn=Jon Ruiz,ou=People

> This is the string representation of an LDAP name that contains three components:

> >     ou=People
> >     cn=Jon Ruiz
> >     cn=homedir

> #### Relationship of a Compound Name to a Composite Name

> When you pass a string name to a `Context` method, such as `lookup()`, the method expects a composite name. The composite name might have just one component. You may pass an LDAP string name, for instance to `lookup()`. The only restriction to keep in mind concerns whether the string name contains characters that conflict with the composite name syntax. In that case, those characters need to be properly escaped or quoted. For example, the compound name `cn=a/b` needs to be specified as `cn=a\/b` to prevent it from being interpreted as a composite name that has two components.

> When you pass a `Name` argument to a `Context` method, such as `lookup()`, the method can accept either a composite name or a compound name, as explained in a previous section. To have the argument interpreted as a composite name, use an instance of `CompositeName`.

> #### String Representations

> As shown in the previous example, a compound name consists of components. The components are separated according to the naming system's syntax. For example, in the LDAP, components are ordered from right to left and separated by a comma character (","). Thus the string representation of the following components

> >     ou=People
> >     cn=Jon Ruiz
> >     cn=homedir

> is

> >     cn=homedir,cn=Jon Ruiz,ou=People

> #### The `CompoundName` Class

> The `CompoundName` class is a convenience class for representing the structural form of a compound name. Its constructor accepts a string representation of the compound name and a set of properties that describe the naming syntax of the name. The set of properties and the `CompoundName` class are intended to be flexible enough to describe the syntaxes of most naming systems. However, implementors may choose to provide their own implementations of compound names that are either subclasses of `CompoundName` or any class that implements the `Name` interface.

> Typically, you use the `CompoundName` constructor only if you are writing a service provider. As an application developer, you usually encounter compound names (either `CompoundName` or direct implementations of `Name`) when you want to parse a name from a particular naming system.

> Here's an example that gets the name parser for a context in a naming system and uses the parser to parse a name from that naming system.

> >     NameParser parser = ctx.getNameParser("");
> >     Name compoundName = parser.parse(compoundStringName);

> #### Manipulating a Compound Name

> Notice that `NameParser.parse()` returns an object that implements the `Name` interface. This interface is implemented by both the `CompositeName` and `CompoundName` classes. This means that you can access and update the components of a compound name in a way similar to how you would a composite name.

> Following is example code that replaces the second component of a compound name and adds components to the head and tail of the name.

> >     // Get the parser for this namespace
> >     NameParser parser = ctx.getNameParser("");

> >     // Parse the name
> >     Name cn = parser.parse("cn=John,ou=People,ou=Marketing");

> >     // Remove the second component from the head
> >     System.out.println(cn.remove(1));          // ou=People

> >     // Add to the head (first)
> >     System.out.println(cn.add(0, "ou=East"));  // cn=John,ou=Marketing,ou=East

> >     // Add to the tail (last)
> >     System.out.println(cn.add("cn=HomeDir"));  // cn=HomeDir,cn=John,ou=Marketing,ou=East

> Running this program produces the following output.

> >     ou=People
> >     cn=John,ou=Marketing,ou=East
> >     cn=HomeDir,cn=John,ou=Marketing,ou=East

> Note that the notions of head and tail are independent of the name's syntax. For example, the LDAP syntax specifies that components are ordered right to left. This means that the rightmost component is the head and the leftmost component the tail. For such a name, a component added to the head (`"cn=East"`) is added to the right and a component added to the tail (`"cn=HomeDir"`) is added to the left.

> Following is the output produced by a modified version of the previous example. This example uses UNIX filename syntax instead of the LDAP syntax.

> >     People
> >     East/Marketing/John
> >     East/Marketing/John/HomeDir

> #### Compound Name as an Argument to Context Methods

> A `Name` instance that is not a `CompositeName` passed to methods in the `Context` and `DirContext` interfaces is treated as a compound name. Following is an example that looks up an LDAP entry by using a compound name. It first gets a context handle into an LDAP namespace. Then it obtains a parser for that namespace by calling `Context.getNameParser()`, which is then used to parse an LDAP string name into a compound name. The compound name is subsequently used in the `lookup()` call.

> >     // Create the initial context
> >     Context ctx = new InitialContext(env);

> >     // Get the parser for the namespace
> >     NameParser parser = ctx.getNameParser("");

> >     // Parse the string name into a compound name
> >     Name compound = parser.parse("cn=Jon Ruiz,ou=people");

> >     // Perform the lookup using the compound name
> >     Object obj = ctx.lookup(compound);

> #### Fully Qualified Compound Names

> Sometimes you want to obtain the fully qualified name of an object. For example, in the DNS, you might want to know a machine's fully qualified Internet name so that it can be used in Kerberos authentication or as an address for Internet mail delivery. In the LDAP, a fully qualified distinguished name might be inserted into an X.509 certificate or be given out as an e-mail address or as part of a URL.

> The use of this fully qualified name is typically outside the scope of the JNDI. That is, once the name is obtained, it is passed to and used in other subsystems rather than fed back into one of the JNDI APIs. Furthermore, the definition of fully qualified is determined by the service provider and/or underlying naming/directory system.

> The JNDI provides `Context.getNameInNamespace()` for obtaining an object's fully qualified name, relative to its own namespace. That is, the result is a name in the namespace served by the underlying naming system.

> Here's an example that looks up an entry (`"cn=Jon Ruiz, ou=people"`) and then invokes `getNameInNamespace()` to get its fully qualified LDAP name.

> >     // Create the initial context
> >     Context ctx = new InitialContext(env);

> >     // Perform the lookup
> >     Context jon = (Context)ctx.lookup("cn=Jon Ruiz,ou=people");

> >     String fullname = jon.getNameInNamespace();

> When you run this program, it produces the following output.

> >     cn=Jon Ruiz,ou=people,o=JNDItutorial

| What's in a Name?