I found the following good example for paging using the default
Please note, this can be compiled to .class object code, and can be run as groovy script as well. The pageSize sets the number of records what the Active Directory responds to our LDAP query:
#!/bin/env groovy
/**
*
* PagedResultsControlJndiClient.java/groovy
* Sample code to demostrate how Paged Results Control works.
*
* Based on
* http://www.forumeasy.com/forums/thread.jsp?tid=115756126876&fid=ldapprof2&highlight=LDAP+Search+Paged+Results+Control
* groovyzed by Tamas Szerb
**/
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.Hashtable;
public class PagedResultsControlJndiClient {
static final String PAGED_RESULT_CONTROL_OID = "1.2.840.113556.1.4.319";
public static void main(String[] args) {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// Note: Active Directory Server supports Paged Results Control
// SunOne does not supports Paged Results Control but it supports
// Virtual List View Control instead.
env.put(Context.PROVIDER_URL, "ldap://myAD.mydomain.com:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "administrator@mydomain.com");
env.put(Context.SECURITY_CREDENTIALS, "mypassword");
try {
/* Open an LDAP connection for the provided principal and credentials */
LdapContext ctx = new InitialLdapContext(env, null);
System.out.println("Initial binding done!");
/* Query the server to see if the paged result control is supported */
if(!isPagedResultControlSupported(ctx)){
System.out.println("The server does not support Paged Results Control.");
System.exit(1);
}
/* Activate paged results */
int pageSize = 10;
byte[] cookie = null;
int total;
//ctx.setRequestControls(
// new Control[]{new PagedResultsControl(pageSize, Control.CRITICAL)});
PagedResultsControl resultsControl = new PagedResultsControl(pageSize, Control.CRITICAL);
Control[] control = [resultsControl];
ctx.setRequestControls(control);
System.out.println("Paged control set!");
int count = 0;
while(true) {
count++;
System.err.println("Search loop count = " + count);
SearchControls ctls = new SearchControls();
//ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctls.setCountLimit(0);
// Perform the search
NamingEnumeration results = ctx.search("dc=mydomain,dc=com","(objectclass=*)", ctls);
try {
// Iterate over a batch of search results
while (results != null && results.hasMore()) {
// Display an entry
SearchResult entry = (SearchResult)results.next();
System.out.println("dn: " + entry.getName());
// fetching the attribute:
System.out.println("cn: " + entry.getAttributes().get("cn").get());
}
}
catch(Exception pe) {
System.out.println(pe.toString()); // Patial Result Exception
}
// Examine the paged results control response
Control[] controls = ctx.getResponseControls();
if(controls!=null) {
for(int k = 0; k<controls.length; k++) {
if(controls[k] instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl)controls[k];
total = prrc.getResultSize();
cookie = prrc.getCookie();
}
else {
// Handle other response controls (if any)
}
}
}
if(cookie==null) break;
// Re-activate paged results
//ctx.setRequestControls(new Control[]{
//new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
resultsControl = new PagedResultsControl(pageSize, cookie, Control.CRITICAL);
control = [resultsControl];
ctx.setRequestControls(control);
}
// Close the LDAP association
ctx.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Is paged result control supported?
*
* Query the rootDSE object to find out if the paged result control
* is supported.
*/
static boolean isPagedResultControlSupported(LdapContext ctx) throws NamingException {
SearchControls ctl = new SearchControls();
//ctl.setReturningAttributes(new String[]{"supportedControl"});
String[] tmp = ["supportedControl"];
ctl.setReturningAttributes(tmp);
ctl.setSearchScope(SearchControls.OBJECT_SCOPE);
/* search for the rootDSE object */
NamingEnumeration results = ctx.search("", "(objectClass=*)", ctl);
while(results.hasMore()) {
SearchResult entry = (SearchResult)results.next();
NamingEnumeration attrs = entry.getAttributes().getAll();
while (attrs.hasMore()) {
Attribute attr = (Attribute)attrs.next();
NamingEnumeration vals = attr.getAll();
while (vals.hasMore()) {
String value = (String)vals.next();
if(value.equals(PAGED_RESULT_CONTROL_OID))
return true;
}
}
}
return false;
}
}