blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

State Factories

If object factories are used to convert objects from the service provider into Java objects then state factories are for converting java objects to objects for the underlying naming service or directory.

A service provider comes pre-configured with certain state factories and that's why we are able to store java objects into the naming/directory service.

Here is the working example from oracle tutorial.

/**
  * This class is used by the custom state/object factories example.
  * It is represents a Person object, which is represented in
  * an LDAP directory using the following schema:
  * ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
  *   MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
  */
public class Person {
 public String surname;
 public String commonName;
 public String passwd;
 public String phone;
 public String seeAlso;
 public String desc;

 public Person(String sn, String cn) {
  this(sn, cn, null, null, null, null);
 }

 public Person(String sn, String cn, String pw, String ph, String see,
   String d) {
  surname = sn;
  commonName = cn;
  passwd = pw;
  phone = ph;
  seeAlso = see;
  desc = d;
 }

 public String toString() {
  return "My name is " + surname + ", " + commonName + ".";
 }
}


DirObjectFactory implementation,

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.spi.DirObjectFactory;
import java.util.Hashtable;

/**
 * This is an object factory that returns a Person object given an Attributes
 * containing a person object class.
 */
public class PersonObjectFactory implements DirObjectFactory {
 public PersonObjectFactory() {
 }

 // DirObjectFactory version
 public Object getObjectInstance(Object obj, Name name, Context ctx,
   Hashtable env, Attributes attrs) throws Exception {

  // Only interested in Attributes with person objectclass
  // System.out.println("object factory: " + attrs);
  Attribute oc = (attrs != null ? attrs.get("objectclass") : null);
  if (oc != null && oc.contains("person")) {
   Attribute attr;
   String passwd = null;

   // Extract password
   attr = attrs.get("userPassword");
   if (attr != null) {
    passwd = new String((byte[]) attr.get());
   }

   Person per = new Person(
     (String) attrs.get("sn").get(),
     (String) attrs.get("cn").get(),
     passwd,
     (attr = attrs.get("telephoneNumber")) != null ? (String) attr
       .get() : null,
     (attr = attrs.get("seealso")) != null ? (String) attr.get()
       : null,
     (attr = attrs.get("description")) != null ? (String) attr
       .get() : null);

   return per;
  }
  return null;
 }

 // ObjectFactory version
 public Object getObjectInstance(Object obj, Name name, Context ctx,
   Hashtable env) throws Exception {

  // Don't do anything if we can't see the attributes
  return null;
 }
}


DirStateFactory implementation,

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.spi.DirStateFactory;
import java.util.Hashtable;

/**
 * This is a state factory that when given a Person object, returns an
 * Attributes representing the object.
 */
public class PersonStateFactory implements DirStateFactory {
 public PersonStateFactory() {
 }

 // DirStateFactory version
 public DirStateFactory.Result getStateToBind(Object obj, Name name,
   Context ctx, Hashtable env, Attributes inAttrs)
   throws NamingException {

  // Only interested in Person objects
  if (obj instanceof Person) {

   Attributes outAttrs;
   if (inAttrs == null) {
    outAttrs = new BasicAttributes(true);
   } else {
    outAttrs = (Attributes) inAttrs.clone();
   }

   // Set up object class
   if (outAttrs.get("objectclass") == null) {
    BasicAttribute oc = new BasicAttribute("objectclass", "person");
    oc.add("top");
    outAttrs.put(oc);
   }

   Person per = (Person) obj;
   // mandatory attributes
   if (per.surname != null) {
    outAttrs.put("sn", per.surname);
   } else {
    throw new SchemaViolationException("Person must have surname");
   }
   if (per.commonName != null) {
    outAttrs.put("cn", per.commonName);
   } else {
    throw new SchemaViolationException(
      "Person must have common name");
   }

   // optional attributes
   if (per.passwd != null) {
    outAttrs.put("userPassword", per.passwd);
   }
   if (per.phone != null) {
    outAttrs.put("telephoneNumber", per.phone);
   }
   if (per.seeAlso != null) {
    outAttrs.put("seeAlso", per.seeAlso);
   }
   if (per.desc != null) {
    outAttrs.put("description", per.desc);
   }

   // System.out.println("state factory: " + outAttrs);
   return new DirStateFactory.Result(null, outAttrs);
  }
  return null;
 }

 // StateFactory version
 public Object getStateToBind(Object obj, Name name, Context ctx,
   Hashtable env) throws NamingException {

  // non-Attributes version not relevant here
  return null;
 }
}

Test code,

// Set up environment for creating initial context
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:10389/o=csRepository");
env.put(Context.OBJECT_FACTORIES, "sample.PersonObjectFactory");
env.put(Context.STATE_FACTORIES, "sample.PersonStateFactory");

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

 // Create object to be bound
 Person john = new Person("Smith", "John Smith");

 // Perform bind
 ctx.rebind("cn=John Smith, ou=employees", john);

 // Read object back
 Person john2 = (Person) ctx.lookup("cn=John Smith, ou=employees");
 System.out.println(john2);

 // Close the context when we're done
 ctx.close();
} catch (NamingException e) {
 System.out.println("Operation failed: " + e);
}

Ouput:
My name is Smith, John Smith.

No comments:

Post a Comment