Commit 794fc5e7 authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

[JM-1117] Paged result work.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10039 b35dd754-fafc-0310-a699-88a17e54d16e
parent 60b725d5
...@@ -135,14 +135,10 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -135,14 +135,10 @@ public class LdapGroupProvider implements GroupProvider {
if (groupCount != -1 && System.currentTimeMillis() < expiresStamp) { if (groupCount != -1 && System.currentTimeMillis() < expiresStamp) {
return groupCount; return groupCount;
} }
List<String> groups = manager.retrieveList( this.groupCount = manager.retrieveListCount(
manager.getGroupNameField(), manager.getGroupNameField(),
MessageFormat.format(manager.getGroupSearchFilter(), "*"), MessageFormat.format(manager.getGroupSearchFilter(), "*")
-1,
-1,
null
); );
this.groupCount = groups.size();
this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5; this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5;
return this.groupCount; return this.groupCount;
} }
......
...@@ -1493,17 +1493,17 @@ public class LdapManager { ...@@ -1493,17 +1493,17 @@ public class LdapManager {
ctx = getContext(baseDN); ctx = getContext(baseDN);
// Set up request controls, if appropriate. // Set up request controls, if appropriate.
List<Control> tmpRequestControls = new ArrayList<Control>(); List<Control> baseTmpRequestControls = new ArrayList<Control>();
if (!clientSideSort) { if (!clientSideSort) {
// Server side sort on username field. // Server side sort on username field.
tmpRequestControls.add(new SortControl(new String[]{attribute}, Control.NONCRITICAL)); baseTmpRequestControls.add(new SortControl(new String[]{attribute}, Control.NONCRITICAL));
} }
if (pageSize > 0) { if (pageSize > 0) {
// Server side paging. // Server side paging.
tmpRequestControls.add(new PagedResultsControl(pageSize, Control.NONCRITICAL)); baseTmpRequestControls.add(new PagedResultsControl(pageSize, Control.NONCRITICAL));
} }
Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]); Control[] baseRequestControls = baseTmpRequestControls.toArray(new Control[baseTmpRequestControls.size()]);
ctx.setRequestControls(requestControls); ctx.setRequestControls(baseRequestControls);
SearchControls searchControls = new SearchControls(); SearchControls searchControls = new SearchControls();
// See if recursive searching is enabled. Otherwise, only search one level. // See if recursive searching is enabled. Otherwise, only search one level.
...@@ -1522,19 +1522,22 @@ public class LdapManager { ...@@ -1522,19 +1522,22 @@ public class LdapManager {
skip = startIndex; skip = startIndex;
lastRes = startIndex + numResults; lastRes = startIndex + numResults;
} }
byte[] cookie = null; byte[] cookie;
int count = 0; int count = 0;
// Run through all pages of results (one page is also possible ;) ) // Run through all pages of results (one page is also possible ;) )
do { do {
cookie = null;
NamingEnumeration answer = ctx.search("", searchFilter, searchControls); NamingEnumeration answer = ctx.search("", searchFilter, searchControls);
// Examine all of the results on this page // Examine all of the results on this page
while (answer.hasMoreElements()) { while (answer.hasMoreElements()) {
count++; count++;
if (skip > -1 && count < skip) { if (skip > 0 && count <= skip) {
answer.next();
continue; continue;
} }
if (lastRes > -1 && count > lastRes) { if (lastRes != -1 && count > lastRes) {
answer.next();
break; break;
} }
...@@ -1560,26 +1563,38 @@ public class LdapManager { ...@@ -1560,26 +1563,38 @@ public class LdapManager {
// Close the enumeration. // Close the enumeration.
answer.close(); answer.close();
// Re-activate paged results; affects nothing if no paging support // Re-activate paged results; affects nothing if no paging support
ctx.setRequestControls(new Control[]{ List<Control> tmpRequestControls = new ArrayList<Control>();
new PagedResultsControl(pageSize, cookie, Control.CRITICAL) }); if (!clientSideSort) {
} while (cookie != null); // Server side sort on username field.
tmpRequestControls.add(new SortControl(new String[]{attribute}, Control.NONCRITICAL));
}
if (pageSize > 0) {
// Server side paging.
tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
}
Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
ctx.setRequestControls(requestControls);
} while (cookie != null && (lastRes == -1 || count <= lastRes));
// Add groups found in alternate DN // Add groups found in alternate DN
if (count <= lastRes && alternateBaseDN != null) { if (alternateBaseDN != null && (lastRes == -1 || count <= lastRes)) {
ctx2 = getContext(alternateBaseDN); ctx2 = getContext(alternateBaseDN);
ctx2.setRequestControls(requestControls); ctx2.setRequestControls(baseRequestControls);
NamingEnumeration answer = ctx2.search("", searchFilter, searchControls);
cookie = null;
// Run through all pages of results (one page is also possible ;) ) // Run through all pages of results (one page is also possible ;) )
do { do {
cookie = null;
NamingEnumeration answer = ctx2.search("", searchFilter, searchControls);
// Examine all of the results on this page // Examine all of the results on this page
while (answer.hasMoreElements()) { while (answer.hasMoreElements()) {
count++; count++;
if (skip > -1 && count < skip) { if (skip > 0 && count <= skip) {
answer.next();
continue; continue;
} }
if (lastRes > -1 && count > lastRes) { if (lastRes != -1 && count > lastRes) {
answer.next();
break; break;
} }
...@@ -1593,28 +1608,45 @@ public class LdapManager { ...@@ -1593,28 +1608,45 @@ public class LdapManager {
results.add(result); results.add(result);
} }
// Examine the paged results control response // Examine the paged results control response
Control[] controls = ctx.getResponseControls(); Control[] controls = ctx2.getResponseControls();
if (controls != null) { if (controls != null) {
for (Control control : controls) { for (Control control : controls) {
if (control instanceof PagedResultsResponseControl) { if (control instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control; PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
cookie = prrc.getCookie(); cookie = prrc.getCookie();
// Re-activate paged results
ctx2.setRequestControls(new Control[]{
new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
break;
} }
} }
} }
// Close the enumeration. // Close the enumeration.
answer.close(); answer.close();
} while (cookie != null); // Re-activate paged results; affects nothing if no paging support
List<Control> tmpRequestControls = new ArrayList<Control>();
if (!clientSideSort) {
// Server side sort on username field.
tmpRequestControls.add(new SortControl(new String[]{attribute}, Control.NONCRITICAL));
}
if (pageSize > 0) {
// Server side paging.
tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
}
Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
ctx2.setRequestControls(requestControls);
} while (cookie != null && (lastRes == -1 || count <= lastRes));
} }
// If client-side sorting is enabled, sort. // If client-side sorting is enabled, sort and trim.
if (clientSideSort) { if (clientSideSort) {
Collections.sort(results); Collections.sort(results);
if (startIndex != -1 || numResults != -1) {
if (startIndex == -1) {
startIndex = 0;
}
if (numResults == -1) {
numResults = results.size();
}
int endIndex = Math.min(startIndex + numResults, results.size()-1);
results = results.subList(startIndex, endIndex);
}
} }
} }
catch (Exception e) { catch (Exception e) {
...@@ -1638,5 +1670,134 @@ public class LdapManager { ...@@ -1638,5 +1670,134 @@ public class LdapManager {
return results; return results;
} }
// TODO: Create a count version of this so we don't pull all of the information into a huge array for no reason /**
* Generic routine for retrieving the number of available results from the LDAP server that
* match the passed search filter. This routine also accounts for paging settings and
* alternate DNs.
*
* The passed in filter string needs to be pre-prepared! In other words, nothing will be changed
* in the string before it is used as a string.
*
* @param attribute LDAP attribute to be pulled from each result and used in the query.
* Typically pulled from this manager.
* @param searchFilter Filter to use to perform the search. Typically pulled from this manager.
* @return The number of entries that match the filter.
*/
public Integer retrieveListCount(String attribute, String searchFilter) {
int pageSize = JiveGlobals.getXMLProperty("ldap.pagedResultsSize", -1);
LdapContext ctx = null;
LdapContext ctx2 = null;
Integer count = 0;
try {
ctx = getContext(baseDN);
// Set up request controls, if appropriate.
List<Control> baseTmpRequestControls = new ArrayList<Control>();
if (pageSize > 0) {
// Server side paging.
baseTmpRequestControls.add(new PagedResultsControl(pageSize, Control.NONCRITICAL));
}
Control[] baseRequestControls = baseTmpRequestControls.toArray(new Control[baseTmpRequestControls.size()]);
ctx.setRequestControls(baseRequestControls);
SearchControls searchControls = new SearchControls();
// See if recursive searching is enabled. Otherwise, only search one level.
if (isSubTreeSearch()) {
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
}
else {
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
}
searchControls.setReturningAttributes(new String[] { attribute });
byte[] cookie;
// Run through all pages of results (one page is also possible ;) )
do {
cookie = null;
NamingEnumeration answer = ctx.search("", searchFilter, searchControls);
// Examine all of the results on this page
while (answer.hasMoreElements()) {
answer.next();
count++;
}
// Examine the paged results control response
Control[] controls = ctx.getResponseControls();
if (controls != null) {
for (Control control : controls) {
if (control instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
cookie = prrc.getCookie();
}
}
}
// Close the enumeration.
answer.close();
// Re-activate paged results; affects nothing if no paging support
List<Control> tmpRequestControls = new ArrayList<Control>();
if (pageSize > 0) {
// Server side paging.
tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
}
Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
ctx.setRequestControls(requestControls);
} while (cookie != null);
// Add groups found in alternate DN
if (alternateBaseDN != null) {
ctx2 = getContext(alternateBaseDN);
ctx2.setRequestControls(baseRequestControls);
// Run through all pages of results (one page is also possible ;) )
do {
cookie = null;
NamingEnumeration answer = ctx2.search("", searchFilter, searchControls);
// Examine all of the results on this page
while (answer.hasMoreElements()) {
answer.next();
count++;
}
// Examine the paged results control response
Control[] controls = ctx2.getResponseControls();
if (controls != null) {
for (Control control : controls) {
if (control instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
cookie = prrc.getCookie();
}
}
}
// Close the enumeration.
answer.close();
// Re-activate paged results; affects nothing if no paging support
List<Control> tmpRequestControls = new ArrayList<Control>();
if (pageSize > 0) {
// Server side paging.
tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
}
Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
ctx2.setRequestControls(requestControls);
} while (cookie != null);
}
}
catch (Exception e) {
Log.error(e);
}
finally {
try {
if (ctx != null) {
ctx.setRequestControls(null);
ctx.close();
}
if (ctx2 != null) {
ctx2.setRequestControls(null);
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
}
return count;
}
} }
\ No newline at end of file
...@@ -135,14 +135,10 @@ public class LdapUserProvider implements UserProvider { ...@@ -135,14 +135,10 @@ public class LdapUserProvider implements UserProvider {
if (userCount != -1 && System.currentTimeMillis() < expiresStamp) { if (userCount != -1 && System.currentTimeMillis() < expiresStamp) {
return userCount; return userCount;
} }
List<String> users = manager.retrieveList( this.userCount = manager.retrieveListCount(
manager.getUsernameField(), manager.getUsernameField(),
MessageFormat.format(manager.getSearchFilter(), "*"), MessageFormat.format(manager.getSearchFilter(), "*")
-1,
-1,
null
); );
this.userCount = users.size();
this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5; this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5;
return this.userCount; return this.userCount;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment