Oyentes de Eventos
Un oyente en JNDI está representado por el interface NamingListener.
Este es el interface raíz para los objetos que manejan eventos generados por el
JNDI. Normalmente, un objeto implementa un subinterface de NamingListener
en vez de implementarlo directamente.
El paquete javax.naming.event
contiene dos subinterfaces de NamingListener: ObjectChangeListener
y NamespaceChangeListener.
El paquete javax.naming.ldap
contiene un subinterface: UnsolicitedNotificationListener.
Este subinterface se explica en la sección Notificaciones
LDAP no solicitadas.
Manejar Errores
El inteface NamingListener no sólo sirve como interface raíz
sino que también especifica como se le notifican los errores a un oyente
registrado. Define un sólo método namingExceptionThrown().
El proveedor de servicios llama a este método cuando ocurre un error mientras
esta recolectando datos para generar eventos que el oyente está esperando. Por
ejemplo, el servidor podría haber caído offline y no recoger más datos en
esta parte del directorio. Cuando esto ocurre, el proveedor de servicio des-registra
al oyente y llama a namingExceptionThrown() sobre él para
notificarle el problema. Esto permite tomar acciones, como notificar al usuario
de la aplicación que debido a un problema no han ocurrido más eventos.
Puedes ir a la sección Registro de Oyentes para
ver más detalles sobre cómo manejar errores cuando se registran oyentes.
Manejar Cambios en el Espacio de Nombres
NamespaceChangeListener maneja eventos que afectan al espacio de
nombres, incluyendo la adición, eliminación y renombrado de un objeto. Un
objeto que implemente este interface debe proporcionar definiciones para los
tres métodos declarados en el interface, así como para namingExceptionThrown()
(del interface NamingListener).
Aquí tenemos un ejemplo de un NamespaceChangeListener.
public class SampleNCListener implements NamespaceChangeListener {
private String id;
public SampleNCListener(String id) {
this.id = id;
}
public void objectAdded(NamingEvent evt) {
System.out.println(id + ">>> added: " + evt.getNewBinding());
}
public void objectRemoved(NamingEvent evt) {
System.out.println(id + ">>> removed: " + evt.getOldBinding());
}
public void objectRenamed(NamingEvent evt) {
System.out.println(id + ">>> renamed: " + evt.getNewBinding() + " from " +
evt.getOldBinding());
}
public void namingExceptionThrown(NamingExceptionEvent evt) {
System.out.println(id + ">>> SampleNCListener got an exception");
evt.getException().printStackTrace();
}
}
Cuando se ha añadido un objeto, getOldBinding() siempre
devolverá null porque no era el espacio de nombres anterior al
que está siendo añadido. Cuando se ha eliminado unobjeto, getNewBinding()
siempre será null porque no estará en el espacio de nombres
después de haber sido eliminado. Podemos encontrar más detalles sobre las
uniones nuevas y viejas en la sección Eventos de Nombrado.
Manejar de Cambios en Objetos
ObjectChangeListener maneja eventos que afectan al contenido de
un objeto, por ejemplo, si una unión de un objeto ha sido reemplazada por otra
o uno de los atributos del objeto se ha eliminado o reemplazado.
Un objeto que implemente el interface ObjectChangeListener
debe proporcionar definiciones para objectChanged()
y para namingExceptionThrown() (desde el interface NamingListener).
Aquí tenemos un ejemplo de un ObjectChangeListener.
public class SampleOCListener implements ObjectChangeListener {
private String id;
public SampleOCListener(String id) {
this.id = id;
}
public void objectChanged(NamingEvent evt) {
System.out.println(id + ">>> object changed: " + evt.getNewBinding() +
" from " + evt.getOldBinding());
}
public void namingExceptionThrown(NamingExceptionEvent evt) {
System.out.println(id + ">>> SampleOCListener got an exception");
evt.getException().printStackTrace();
}
}
Aunque este ejemplo muestra las uniones nueva y vieja de un objeto modificado,
alguna parte de toda esta información podría no estar disponible si no la
suministra el proveedor de servicios o el servidor de nombres/directorios.
Puedes encontrar más detalles sobre las nuevas y viejas uniones en la sección Eventos
de Nombrado.
Observa que eliminar un objeto es un cambio en el espacio de nombres, no un
cambio en el contenido del objeto. Una aplicación interesada en las dos cosas
debería usar un oyente que implemente NamespaceChangeListener y
ObjectChangeListener, como se describe ahora.
Manejar más de un tipo de Cambios
Si estamos interesados en los cambios en el espacio de nombres y en el contenido
del objeto, deberíamos definir un oyente que implemente ambos interfaces. De
esta forma, el proveedor de servicios podría optimizar los recursos usados para
el registro y recolección de datos sobre ambos tipos de cambios con una sóla
petición al servidor. También reduce el número de oyentes que el proveedor
debe manejar y el tamaño del código de nuestra aplicación.
Aquí tenemos un ejemplo de un oyente
que implementa NamespaceChangeListener y ObjectChangeListener.
public class SampleListener
implements NamespaceChangeListener, ObjectChangeListener {
private String id;
public SampleListener(String id) {
this.id = id;
}
public void objectAdded(NamingEvent evt) {
System.out.println(id + ">>> added: " + evt.getNewBinding());
}
public void objectRemoved(NamingEvent evt) {
System.out.println(id + ">>> removed: " + evt.getOldBinding());
}
public void objectRenamed(NamingEvent evt) {
System.out.println(id + ">>> renamed: " + evt.getNewBinding() + " from " +
evt.getOldBinding());
}
public void objectChanged(NamingEvent evt) {
System.out.println(id + ">>> object changed: " + evt.getNewBinding() +
" from " + evt.getOldBinding());
}
public void namingExceptionThrown(NamingExceptionEvent evt) {
System.out.println(id + ">>> SampleNCListener got an exception");
evt.getException().printStackTrace();
}
}