| Storing Objects in the Directory

## Objects with Attributes

> If the object that you're attempting to bind is neither `Serializable` nor `Referenceable`, then you can still bind it if it has attributes, provided that binding `DirContext` objects is a feature supported by the underlying service provider. Sun's LDAP service provider supports this feature.

> #### Interoperability

> Binding `DirContext` objects is especially useful for interoperability with non-Java applications. An object is represented by a set of attributes, which can be read and used by non-Java applications from the directory. The same attributes can also be read and interpreted by a JNDI service provider, which, in conjunction with an object factory, converts them into a Java object.

> For example, an object might have, as some of its attribute values, URLs that the JNDI service could use to generate an instance of a Java object that the application could use. These same URLs could be used also by non-Java applications.

> #### Binding an Object by Using Its Attributes

> The following example shows a `Drink` class that implements the `DirContext` interface. Most `DirContext` methods are not used by this example and so simply throw an `OperationNotSupportedException`.

> >     public class Drink implements DirContext {
> >         String type;
> >         Attributes myAttrs;

> >         public Drink(String d) {
> >     	type = d;
> >     	myAttrs = new BasicAttributes(true);  // Case ignore
> >     	Attribute oc = new BasicAttribute("objectclass");
> >     	oc.add("extensibleObject");
> >     	oc.add("top");

> >     	myAttrs.put(oc);
> >     	myAttrs.put("drinkType", d);
> >         }

> >         public Attributes getAttributes(String name) throws NamingException {
> >     	if (! name.equals("")) {
> >     	    throw new NameNotFoundException();
> >     	}
> >     	return (Attributes)myAttrs.clone();
> >         }

> >         public String toString() {
> >     	return type;
> >         }
> >     ...
> >     }

> The `Drink` class contains the `"objectclass"` and `"drinkType"` attributes. The `"objectclass"` attribute contains two values: `"top"` and `"extensibleObject"`. The `"drinkType"` attribute is set by using the string passed to the `Drink` constructor. For example, if the instance was created by using `new Drink("water")`, then its `"drinkType"` attribute will have the value `"water"`.

> The following example creates an instance of `Drink` and invokes `Context.bind()` to add it to the directory.

> >     // Create the object to be bound
> >     Drink dr = new Drink("water");

> >     // Perform the bind
> >     ctx.bind("cn=favDrink", dr);

> When the object is bound, its attributes are extracted and stored in the directory.

> When that object is subsequently looked up from the directory, its corresponding object factory will be used to return an instance of the object. The object factory is identified by the `Context.OBJECT_FACTORIES` environment property when the initial context for reading the object is created. Conversion details are described in the Object Factories lesson.

> >     Hashtable env = ...;
> >     // Add property so that the object factory can be found
> >     env.put(Context.OBJECT_FACTORIES, "DrinkFactory");

> >     // Create the initial context
> >     DirContext ctx = new InitialDirContext(env);

> >     // Read back the object
> >     Drink dr2 = (Drink) ctx.lookup("cn=favDrink");
> >     System.out.println(dr2);

> This produces the following output, `"water"`, produced by `Drink.toString()`.

> >     # java DirObj
> >     water

> From the perspective of the application using the JNDI, it is dealing only with `bind()` and `lookup()`. The service provider takes care of getting the attributes from the object and converting them to/from the actual object itself.

> Note that you can store a `DirContext` object in the directory only if the underlying service provider supports that.

| Storing Objects in the Directory