En esta página: Controles de Peticiones de Contexto 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
|