![]() ![]() ![]() ![]() |
Controls and Extensions |
You can associate request controls to be sent along with LDAP requests emitted by context methods using LdapContext.setRequestControls(). For example, if you want the results of a Context.list()
or DirContext.search()
to be sorted, and the LDAP server supports server-side sorting, you can set the context's request controls to include a control for doing that, as shown in this example:
// Create initial context with no connection request controls LdapContext ctx = new InitialLdapContext(env, null); // Create critical Sort that sorts based on CN Control[] ctxCtls = new Control[]{ new SortControl(new String[]{"cn"}, Control.CRITICAL) }; // Set context's request controls to be ctxCtls ctx.setRequestControls(ctxCtls); // Perform list, will sort by cn NamingEnumeration answer = ctx.list("");Once set, the controls remain in effect for the context instance until they are replaced by another call to setRequestControls(). In the above example, after doing the list, you can perform a search using the same context instance and the results will be still be sorted by CN:
// Perform search, will still sort by cn // because context request controls are still in effect answer = ctx.search("ou=People", "(cn=*)", null);To tell a context instance not to use any request controls, supply null as the argument to setRequestControls():
// Set context's request controls to be nothing ctx.setRequestControls(null);Finding Out the Context Request Controls In Effect
To find out the request controls in effect for a context, you use the LdapContext.getRequestControls()method. Here is an example that sets the request controls to be a sort control and then checks the controls using getRequestControls():
Here is the output produced by this example:// Set context's request controls to be ctxCtls ctx.setRequestControls(ctxCtls); // Check what controls 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]); } }It shows both the control that we've added (the sort control), and a "manage referral" control that the LDAP provider sends when referrals are being ignored (that is, the Context.REFERRALcom.sun.jndi.ldap.ctl.SortControl@1fa4d711 com.sun.jndi.ldap.ManageReferralControl@1fa4d59denvironment property is unset or has been set to "ignore"). To stop the LDAP provider from sending this control, you must set the Context.REFERRAL property to "throw" or "follow".
Scope
A context's request controls remain in effect for all operations on the context instance. However, unlike environment properties, a context's request controls are not inherited by contexts derived from this context. For example, if you perform a Context.lookup()and got back a context, that context has no request controls. A context's request controls must always be explicitly set using setRequestControls() except when LdapContext.newInstance()
is used, as explained next.
Multithreaded Programming
The fact that a context's request controls are in effect for all methods invoked on the context poses a bit of a challenge to multiple threads sharing a context handle. As always (independent of controls), such threads must synchronize their access to the context. In addition, the threads must ensure that the context has the right request controls set. For example, to make sure that a method is executed with the right request controls, you might have code that looks as follows:This is cumbersome if you want a thread to have request controls that persist across multiple operations. Instead of doing this, you can use LdapContext.newInstance()synchronized(ctx) { // Set context's request controls to be myCtls ctx.setRequestControls(myCtls); // Perform list using control NamingEnumeration answer = ctx.list(""); // Do something useful with answer // Get any response controls respCtls = ctx.getResponseControls(); }. This method allows you to create a clone of the existing context instance, with the request controls initialized to those supplied in the argument:
When you subsequently update the request controls of the clone, the updates won't affect the original context, and vice versa. Where appropriate and possible, the clone will share resources with the original context, such as the underlying connection to the LDAP server.// Create clone with request controls set to newCtls LdapContext cloneCtx = ctx.newInstance(newCtls);Here is an example that uses newInstance() to create a clone of a context and initializes the clone with a sort control. It then performs a search in each context. The results from the clone are sorted while those from the original are not.
Here is the output produced by the example:// Create initial context with no connection request controls LdapContext ctx = new InitialLdapContext(env, null); // Create critical Sort that sorts based on CN Control[] ctxCtls = new Control[]{ new SortControl(new String[]{"cn"}, Control.CRITICAL) }; // Create clone with request controls set to ctxCtls LdapContext cloneCtx = ctx.newInstance(ctxCtls); // Perform search using original context NamingEnumeration answer = ctx.search("", "(cn=*)", null); // Enumerate answers (not sorted) System.out.println("-----> Unsorted"); while (answer.hasMore()) { System.out.println(((SearchResult)answer.next()).getName()); } // Perform search using clone context, sort by cn answer = cloneCtx.search("", "(cn=*)", null); System.out.println("-----> Sorted"); // Enumerate answers (sorted) while (answer.hasMore()) { System.out.println(((SearchResult)answer.next()).getName()); }#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
![]() ![]() ![]() ![]() |
Controls and Extensions |