Sistema de Nombrado en Java (JNDI) y II

Podemos asociar controles de petici�n para enviarlas junto con peticiones LDAP emitidas por m�todos de Context usando LdapContext.setRequestControls(). Por ejemplo, podemos configurar los controles de peticiones de contexto para incluir un control que le diga al servidor que ordene los resultados de Context.list() y DirContext.search(), asumiendo que el servidor LDAP soporta ordenaci�n en el lado del servidor, como se muestra en este ejemplo:

// Create the initial context with no connection request controls
LdapContext ctx = new InitialLdapContext(env, null);

// Create the critical Sort control that sorts based on "cn"
Control[] ctxCtls = new Control[]{
    new SortControl(new String[]{"cn"}, Control.CRITICAL)
};

// Set the context's request controls to be ctxCtls
ctx.setRequestControls(ctxCtls);

// Perform the list, will sort by cn
NamingEnumeration answer = ctx.list("");

Una vez configurados, los controles permanecen activos para el ejemplar de Context hasta que sean reemplazados por los argumentos de otra llamada a setRequestControls(). Luego, despu�s de hacer la lista, podemos realizar una b�squeda usando el mismo ejemplar de Context; los resultados seguir�n siendo ordenados por el atributo "cn":

// Perform the search, which will still sort by "cn"
// because context request controls are still in effect
answer = ctx.search("ou=People", "(cn=*)", null);

Para decirle a un ejemplar de Context que no use ning�n control de petici�n, suministramos null como el argumento para setRequestControls():

// Set the context's request controls to be nothing
ctx.setRequestControls(null);

.�Encontrar los Controles de Peticiones de Contexto que est�n Activos

Para encontrar los controles de petici�n que est�n activos para un contexto, usamos LdapContext.getRequestControls(). Aqu� hay un ejemplo que configura los controles de petici�n para ser un control Sort y luego chequea los controles usando getRequestControls():

// Set the context's request controls to be ctxCtls
ctx.setRequestControls(ctxCtls);

// Check the controls that are in effect for context
Control[] reqCtls = ctx.getRequestControls();
if (reqCtls != null) {
    for (int i = 0; i < reqCtls.length; i++) {
        System.out.println(reqCtls[i]);
    }
}

Aqu� est� la salida producida por este ejemplo:

com.sun.jndi.ldap.ctl.SortControl@1fa4d711
com.sun.jndi.ldap.ManageReferralControl@1fa4d59d

Esta salida muestra tanto el control que fue a�adido (el control Sort) as� como un control Manage Referral que env�a el proveedor LDAP cuando las remisiones est�n siendo ignoradas (es decir, la propiedad de entorno Context.REFERRAL est� deseleccionada o configurada como "ignore"). Para evitar que el proveedor LDAP env�e este control, debemos configurar la propiedad Context.REFERRAL como "throw" o "follow". Puedes ver m�s detalles en la lecci�n Remisiones.

.�Ambito

Un control de petici�n de contexto permanece activo para todas las operaciones sobre ese ejemplar Context. Sin embargo, al contrario que las propiedades de entorno, un control de petici�n de contexto no heredado por los contextos derivados de este contexto. Por ejemplo, si realizamos una Context.lookup() y obtenemos un contexto, entonces ese contexto no tiene controles de peticion. Siempre debemos configurar expl�citamente los controles de peticiones de contexto usando setRequestControls(), excepto cuando se usa LdapContext.newInstance(), como se explica m�s adelante.

.�Programaci�n Multithread

Tener un control de petici�n de contexto activo para todos los m�todos llamados sobre un contexto pone un poco de desaf�o para que varios threads compartan un mismo contexto. Como siempre (independiente de los controles), dichos threads deben sincronizar sus accesos al contexto. Adem�s, deben asegurarse de que el contexto tiene el conjunto de controles de petici�n correcto.

Por ejemplo, para asegurar que un m�todo se ejecuta con los controles de petici�n correctos, debemos tener un c�digo que se parezca a este:

synchronized(ctx) {
    // Set the context's request controls to be myCtls
    ctx.setRequestControls(myCtls);

    // Perform the list by using the control
    NamingEnumeration answer = ctx.list("");

    // Do something useful with the answer

    // Get any response controls
    respCtls = ctx.getResponseControls();
}

Esto es muy enrebesado si queremos que un thread tenga controles de petici�n que persistan a trav�s de m�ltiples operacones. En lugar de hacer esto, podemos usar LdapContext.newInstance(). Este m�todo nos permite crear un clon del ejemplar de Context exisente, con los controles de petici�n inicializados a los suministrados en el argumento:

// Create a clone with the request controls set to newCtls
LdapContext cloneCtx = ctx.newInstance(newCtls);

Cuando despu�s actualicemos los controles de petici�n del clon, la actualizaciones no afectar�n al contexto original, y viceversa. Donde sea apropiado y posible, el clon compartir� recursos con el contexto original, como la conexi�n subyacente con el seridor LDAP.

Aqu� tenemos un ejemplo que usa newInstance() para crear un clon de un contexto e inicializa el clon con un control Sort. Luego realiza una b�squeda en cada contexto. Los resultados desde el clon est�n ordenados, mientras que los del original no lo est�n:

// Create the initial context with no connection request controls
LdapContext ctx = new InitialLdapContext(env, null);

// Create the critical Sort that sorts based on "cn"
Control[] ctxCtls = new Control[]{
    new SortControl(new String[]{"cn"}, Control.CRITICAL)
};

// Create a clone with request controls set to ctxCtls
LdapContext cloneCtx = ctx.newInstance(ctxCtls);

// Perform the search by using the original context
NamingEnumeration answer = ctx.search("", "(cn=*)", null);

// Enumerate the answers (not sorted)
System.out.println("-----> Unsorted");
while (answer.hasMore()) {
    System.out.println(((SearchResult)answer.next()).getName());
}

// Perform the search by using a clone context; sort by "cn"
answer = cloneCtx.search("", "(cn=*)", null);

System.out.println("-----> Sorted");
// Enumerate the answers (sorted)
while (answer.hasMore()) {
    System.out.println(((SearchResult)answer.next()).getName());
}

Aqu� est� la salida producida por el ejemplo:

# java NewInstance
-----> Unsorted
cn=Button
cn=Choice
cn=CheckboxGroup
cn=TextField
cn=CorbaHello
cn=RemoteHello
cn=RefHello
cn=Custom
cn=John Smith
-----> Sorted
cn=Button
cn=CheckboxGroup
cn=Choice
cn=CorbaHello
cn=Custom
cn=John Smith
cn=RefHello
cn=RemoteHello
cn=TextField

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR