Previous | Next | Trail Map | Java Objects and the Directory | Storing Objects in the Directory

Objects with Attributes

If the object that you're attempting to bind is neither serializable nor referenceable, you can still bind it if it has attributes, provided that binding DirContext(in the API reference documentation) objects is a feature supported by the underlying service provider. Sun's LDAP service provider supports this feature.

Interoperabilty

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, as some of its attribute values, an object might have URLs which the JNDI service provider, along with an object factory, could use to generate an instance of a Java object for use by the application. These same URLs could be used by non-Java applications.

Binding an Object Using Its Attributes

This example shows a Drink class which implements the DirContext interface. Most of the DirContext methods simply throw OperationNotSupportedException(in the API reference documentation) because they're not used by this example.

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 using the string passed to the Drink constructor. For example, if the instance was created using new Drink("water"), its "drinkType" attribute will have the value "water".

This example creates an instance of Drink and invokes Context.bind()(in the API reference documentation) to add it to the directory:

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

// Perform 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(in the API reference documentation) environment property when the initial context for reading the object is created. Conversion details are described in the Object Factories (in the Java Objects and the Directory trail) lesson.

Hashtable env = ...;
// So that object factory can be found
env.put(Context.OBJECT_FACTORIES, "DrinkFactory");

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

// Read object back
Drink dr2 = (Drink) ctx.lookup("cn=favDrink");
System.out.println(dr2);
This produces the output:
# java DirObj
water
The output "water" is produced by the Drink.toString() method.

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

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


Previous | Next | Trail Map | Java Objects and the Directory | Storing Objects in the Directory