Announcement Announcement Module
Collapse
No announcement yet.
Paged search results Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Paged search results

    Dear community,

    Quite recently, we implemented support for generic pre- and postprocessing of the DirContext through the interface DirContextProcessor and a corresponding search method in LdapTemplate:

    Code:
    public interface DirContextProcessor {
       public void preProcess(DirContext ctx) throws NamingException;
       public void postProcess(DirContext ctx) throws NamingException;
    }
    Code:
    public void search(SearchExecutor se, NameClassPairCallbackHandler handler,
       DirContextProcessor processor) throws DataAccessException;
    We then created a base class to simplify implementing custom DirContextProcessors that use request controls:

    Code:
    public abstract class AbstractRequestControlDirContextProcessor
          implements DirContextProcessor {
       public void preProcess(DirContext ctx) throws NamingException {
          ...
       }
       public abstract Control createRequestControl();
    }
    Spring LDAP now provides support for paged results by leveraging this concept. It does so by providing two classes: PagedResultsRequestControl and PagedResultsCookie. The PagedResultsRequestControl class creates a standard PagedResultsControl with the requested page size and adds it to the LdapContext. After the search, it gets the corresponding PagedResultsResponseControl from the LdapContext and retrieves two pieces of information from it: the estimated total result size and a cookie. This cookie contains information that the server needs the next time it is called with a PagedResultsControl. The wrapper class PagedResultsCookie is provided for storing this cookie.

    The following example shows how to achieve paged search results:

    Code:
    public class PagedSearchIntegrationTests extends
          AbstractDependencyInjectionSpringContextTests {
       private LdapTemplate tested;
       ...
       // LDAP contains 5 persons matching the filter. Page size is 3.
       // Expects two batches of 3 and 2 persons respectively.
       public void testPagedResult() {
          SearchExecutor searchExecutor = new SearchExecutor() {
             public NamingEnumeration executeSearch(DirContext ctx)
                   throws NamingException {
                SearchControls searchControls = new SearchControls();
                searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                return ctx.search("dc=example,dc=com",
                   "(&(objectclass=person)(cn=Some Person*))", searchControls);
             }
          };
    
          PersonAttributesMapper mapper = new PersonAttributesMapper();
          CollectingNameClassPairCallbackHandler callbackHandler =
             tested.new AttributesMapperCallbackHandler(mapper);
    
          PagedResultsRequestControl requestControl;
          requestControl = new PagedResultsRequestControl(3);
          tested.search(searchExecutor, callbackHandler, requestControl);
          PagedResultsCookie cookie = requestControl.getCookie();
          assertNotNull("Cookie should not be null yet", cookie.getCookie());
          assertEquals(3, callbackHandler.getList().size());
    
          // Prepare for second and last search
          requestControl = new PagedResultsRequestControl(3, cookie);
          tested.search(searchExecutor, callbackHandler, requestControl);
          cookie = requestControl.getCookie();
          assertNull("Cookie should be null now", cookie.getCookie());
          assertEquals(5, callbackHandler.getList().size());
       }
    This is all still in the Subversion trunk, but feel free to have a look at it. And if you end up developing support for a specific control, we could then discuss if it can be incorporated into the framework.

    We expect the next release to be out in October.

    Cheers,

  • #2
    Syntax question

    Hello,

    Excuse me but I don't understand this syntax :

    PersonAttributesMapper mapper = new PersonAttributesMapper();
    CollectingNameClassPairCallbackHandler callbackHandler =
    tested.new AttributesMapperCallbackHandler(mapper);

    Thank you for your explanation.

    Comment


    • #3
      The AttributesMapperCallbackHandler is an (non-static) inner class in LdapTemplate. Initialization of of a non-static inner class needs to be done with reference to an instance to the surrounding class, which is done using this syntax.

      As a side note, in the 1.2 version, the useful inner classes have been extracted to top-level classes, so you won't need to worry about this .

      Comment

      Working...
      X