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