Construir en Extensibilidad
Si hemos seguido los pasos descritos hasta ahora, deberíamos tener una implementación de
contexto completa y funcional. Sin embargo, como una implementación de contexto debería estar
cerrada en el sentido de los tipos de objetos que pueder ser
leídos y
almacenados usando la implementación de contexto
estaría limitado a lo que la implementación de contexto estuviera programada para aceptar. El
JNDI proporciona utilidades para hacer extensibles las implementaciones
de contexto. Estas utilidades permiten a los objetos que son pasados desde el programa ser
transformados antes de alcanzar la implementación de contexto, y permtie que los objetos leídos
desde el directorio sean transformados antes de llegar al programa.
Leer Objetos
La lección Factorías de Objetos
describe que un proveedor de servicio debería usar
NamingManager.getObjectInstance() o
DirectoryManager.getObjectInstance() antes de
devolver un objeto al programa de usuario desde uno de los siguientes métodos:
Abajo podemos ver cómo el ejemplo del
espacio de nombres con forma de árbol
llama a getObjectInstance() en su método
lookup(). Usa el método de la clase
NamingManager porque
HierCtx sólo implementa el interface
Context. Si una implementación de contexto implementa el
interface
DirContext, debería usar el de la clase
DirectoryManager. Puedes encontrar más detalles en la lección
Añadir Soporte de Directorio:
// Code that determined "inter" is the object bound to the
// atomic name "atom"
...
// Call getObjectInstance for using any object factories
try {
return NamingManager.getObjectInstance(inter,
new CompositeName().add(atom), this, myEnv);
} catch (Exception e) {
NamingException ne = new NamingException("getObjectInstance failed");
ne.setRootCause(e);
throw ne;
}
Deberíamos pasar a getObjectInstance() el nombre del objeto como
un nombre mixto y el contexto en el que se debería resolver ese nombre. Este no necesita ser
el contexto más profundo (es decir, el nombre no necesita ser atómico). También deberíamos
pasarle las propiedades de entorno del contexto en el caso de las factorías de objetos las
necesiten.
De forma similar, cuando devolvamos la enumeración generada por
Context.listBindings() , deberíamos llamar a
getObjectInstance() para el objeto de cada
Binding en la enumeración. Aquí tenemos la definición del
método
next() de la enumeración:
public Object next() throws NamingException {
String name = (String)names.nextElement();
Object obj = bindings.get(name);
try {
obj = NamingManager.getObjectInstance(obj,
new CompositeName().add(name), HierCtx.this,
HierCtx.this.myEnv);
} catch (Exception e) {
NamingException ne = new NamingException("getObjectInstance failed");
ne.setRootCause(e);
throw ne;
}
return new Binding(name, obj);
}
Este ejemplo muestra un aproximación estática, en la que se llama a
getObjectInstance() mientras creamos cada ejemplar de
Binding. Otra aproximación es definir nuestra propia subclase de
Binding y sobreescribir
Binding.getObject() para que llame a
getObjectInstance(). (El resultado de
getObjectInstance() podría almacenarse en un chaché para
evitar llamadas repetidas.)
Almacenar Objetos
La lección Factorías de Estado
describe como un proveedor de servicio debería usar
NamingManager.getStateToBind() o
DirectoryManager.getStateToBind() antes de almacenar
un objeto dado por el programa de usuario a uno de estos métodos:
Aquí tenemos como el ejemplo del espacio de
nombres con forma de árbol llama a getStateToBind()
en sus métodos bind() y rebind().
Usa el método de la clase NamingManager porque
HierCtx sólo implementa el interface
Context. Si una implementación de contexto implementa el
interface
DirContext , debería usar el de la clase
DirectoryManager. Puedes ver más detalles en la lección
Añadir Soporte de Directorio:
// Code that determines that this is the context in which
// to bind the atomic name "atom" to the object "obj"
...
// Call getStateToBind for using any state factories
obj = NamingManager.getStateToBind(obj,
new CompositeName().add(atom), this, myEnv);
// Add the object to the internal data structure
bindings.put(atom, obj);
Deberíamos pasar a getStateToBind() el nombre del objeto como
un nombre mixto y el contexto en el que se debería resolver ese nombre. Este no necesita ser
el contexto más profundo (es decir, el nombre no necesita ser atómico). También deberíamos
pasarle las propiedades de entorno del contexto en el caso de las factorías de objetos las
necesiten.
Observa que esta implementación es simplística porque el ejemplo puede almacenar cualquir tipo
de objeto. Una implementación más realista chequearía el resultado de
getStateToBind() para asegurarse de que el objeto es de un
tipo que él puede almacenar. Puedes ver más detalles en la lección
Factorías de Estado.