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