| Directory Operations

## Hybrid Naming and Directory Operations

> The Naming Concepts lesson discussed how you can use `bind()`, `rebind()`, and `createSubcontext()` in the `Context` interface to create bindings and subcontexts. The `DirContext` interface contains overloaded versions of these methods that accept attributes. You can use these `DirContext` methods to associate attributes with the object at the time that the binding or subcontext is added to the namespace. For example, you might create a `Person` object and bind it to the namespace and at the same time associate attributes about that `Person` object.

> > Before you go on: The examples in this lesson require that you make additions to the schema. You must either turn off schema-checking in the LDAP server or add the schema that accompanies this tutorial to the server. Both of these tasks are typically performed by the directory server's administrator. See the Preparations lesson.

> > OpenLDAP: In versions of the LDAP provider prior to the Java 2 SDK, v1.4, these examples will not work against the OpenLDAP directory server because these versions of the LDAP provider do not include the new entry's relative distinguished name (RDN) in the set of attributes to add. To workaround the problem, you must modify the examples to supply the RDN of the entry (i.e., the "ou" attribute) as an attribute in the `Attributes` parameter.

> #### Creating a Context That Has Attributes

> To create a context that has attributes, you supply to `DirContext.createSubcontext()` the name of the context that you want to create and its attributes.

> >     // Create attributes to be associated with the new context
> >     Attributes attrs = new BasicAttributes(true); // case-ignore
> >     Attribute objclass = new BasicAttribute("objectclass");
> >     objclass.add("top");
> >     objclass.add("organizationalUnit");
> >     attrs.put(objclass);

> >     // Create the context
> >     Context result = ctx.createSubcontext("ou=Fruits", attrs);

> This example creates a new context called `"ou=Fruits"` that has an attribute `"objectclass"` with two values, `"top"` and `"organizationalUnit"`, in the context `ctx`. If you list the context `ctx`, then you will see that it now contains an entry for `"ou=Fruits"`.

> >     # java Create
> >     ou=Groups: javax.naming.directory.DirContext
> >     ou=People: javax.naming.directory.DirContext
> >     ou=Fruits: javax.naming.directory.DirContext

> #### Adding a Binding That Has Attributes

> `DirContext.bind()` is used to add a binding that has attributes to a context. It accepts as arguments the name of the object, the object to be bound, and a set of attributes.

> >     // Create the object to be bound
> >     Fruit fruit = new Fruit("orange");

> >     // Create attributes to be associated with the object
> >     Attributes attrs = new BasicAttributes(true); // case-ignore
> >     Attribute objclass = new BasicAttribute("objectclass");
> >     objclass.add("top");
> >     objclass.add("organizationalUnit");
> >     attrs.put(objclass);

> >     // Perform bind
> >     ctx.bind("ou=favorite, ou=Fruits", fruit, attrs);

> This example creates an object of class `Fruit` and binds it to the name `"ou=favorite"` into the context named `"ou=Fruits"`, relative to `ctx`. This binding has the `"objectclass"` attribute. If you subsequently looked up the name `"ou=favorite, ou=Fruits"` in `ctx`, then you would get the `fruit` object. If you then got the attributes of `"ou=favorite, ou=Fruits"`, you would get those attributes with which the object was created. Following is this example's output.

> >     # java Bind
> >     orange
> >     attribute: objectclass
> >     value: top
> >     value: organizationalUnit
> >     value: javaObject
> >     value: javaNamingReference
> >     attribute: javaclassname
> >     value: Fruit
> >     attribute: javafactory
> >     value: FruitFactory
> >     attribute: javareferenceaddress
> >     value: #0#fruit#orange
> >     attribute: ou
> >     value: favorite

> The extra attributes and attribute values shown are used to store information about the object (`fruit`). These extra attributes are discussed in more detail in the Java Objects and the Directory trail.

> If you were to run this example twice, then the second attempt would fail with a `NameAlreadyBoundException`. This is because the name `"ou=favorite"` is already bound in the `"ou=Fruits"` context. For the second attempt to succeed, you would have to use `rebind()`.

> #### Replacing a Binding That Has Attributes

> `DirContext.rebind()` is used to add or replace a binding and its attributes. It accepts the same arguments as `bind()`. However, `rebind()`'s semantics require that if the name is already bound, then it will be unbound and the newly given object and attributes will be bound.

> >     // Create the object to be bound
> >     Fruit fruit = new Fruit("lemon");

> >     // Create attributes to be associated with the object
> >     Attributes attrs = new BasicAttributes(true); // case-ignore
> >     Attribute objclass = new BasicAttribute("objectclass");
> >     objclass.add("top");
> >     objclass.add("organizationalUnit");
> >     attrs.put(objclass);

> >     // Perform bind
> >     ctx.rebind("ou=favorite, ou=Fruits", fruit, attrs);

> When you run this example, it replaces the binding that the `bind()` example created.

> >     # java Rebind
> >     lemon
> >     attribute: objectclass
> >     value: top
> >     value: organizationalUnit
> >     value: javaObject
> >     value: javaNamingReference
> >     attribute: javaclassname
> >     value: Fruit
> >     attribute: javafactory
> >     value: FruitFactory
> >     attribute: javareferenceaddress
> >     value: #0#fruit#lemon
> >     attribute: ou
> >     value: favorite

| Directory Operations