* Handle a Paged Search request.
*/
private InternalSearchResponseDone doPagedSearch( LdapSession session, InternalSearchRequest req, PagedResultsControl control )
throws Exception
{
PagedResultsControl pagedSearchControl = ( PagedResultsControl )control;
PagedResultsControl pagedResultsControl = null;
// Get the size limits
// Don't bother setting size limits for administrators that don't ask for it
long serverLimit = getServerSizeLimit( session, req );
long requestLimit = req.getSizeLimit() == 0L ?
Long.MAX_VALUE : req.getSizeLimit();
long sizeLimit = min( serverLimit, requestLimit );
int pagedLimit = pagedSearchControl.getSize();
EntryFilteringCursor cursor = null;
PagedSearchContext pagedContext = null;
// We have the following cases :
// 1) The SIZE is 0 and the cookie is the same than the previous one : this
// is a abandon request for this paged search.
// 2) The cookie is empty : this is a new request. If the requested
// size is above the serverLimit and the request limit, this is a normal
// search
// 3) The cookie is not empty and the request is the same, we return
// the next SIZE elements
// 4) The cookie is not empty, but the request is not the same : this is
// a new request (we have to discard the cookie and do a new search from
// the beginning)
// 5) The SIZE is above the size-limit : the request is treated as if it
// was a simple search
// Case 1
if ( pagedLimit == 0L )
{
// An abandoned paged search
return abandonPagedSearch( session, req );
}
// Now, depending on the cookie, we will deal with case 2, 3, 4 and 5
byte [] cookie= pagedSearchControl.getCookie();
InternalLdapResult ldapResult = req.getResultResponse().getLdapResult();
if ( StringTools.isEmpty( cookie ) )
{
// This is a new search. We have a special case when the paged size
// is above the server size limit : in this case, we default to a
// standard search
if ( pagedLimit > sizeLimit )
{
// Normal search : create the cursor, and set pagedControl to false
try
{
// No cursor : do a search.
cursor = session.getCoreSession().search( req );
// Position the cursor at the beginning
cursor.beforeFirst();
// And read the entries
readResults( session, req, ldapResult, cursor, sizeLimit );
}
finally
{
try
{
cursor.close();
}
catch ( NamingException e )
{
LOG.error( I18n.err( I18n.ERR_168 ), e );
}
}
// If we had a cookie in the session, remove it
removeContext( session, pagedContext );
return ( InternalSearchResponseDone ) req.getResultResponse();
}
else
{
// Case 2 : create the context
pagedContext = new PagedSearchContext( req );
session.addPagedSearchContext( pagedContext );
cookie = pagedContext.getCookie();
pagedResultsControl = new PagedResultsControl();
pagedResultsControl.setCookie( cookie );
pagedResultsControl.setSize( 0 );
pagedResultsControl.setCritical( true );
// No cursor : do a search.
cursor = session.getCoreSession().search( req );
// Position the cursor at the beginning
cursor.beforeFirst();
// And stores the cursor into the session
pagedContext.setCursor( cursor );
}
}
else
{
// We have a cookie
// Either case 3, 4 or 5
int cookieValue = pagedSearchControl.getCookieValue();
pagedContext = session.getPagedSearchContext( cookieValue );
if ( pagedContext == null )
{
// We didn't found the cookie into the session : it must be invalid
// send an error.
ldapResult.setErrorMessage( "Invalid cookie for this PagedSearch request." );
ldapResult.setResultCode( ResultCodeEnum.UNWILLING_TO_PERFORM );
return ( InternalSearchResponseDone ) req.getResultResponse();
}
if ( pagedContext.hasSameRequest( req, session ) )
{
// Case 3 : continue the search
cursor = pagedContext.getCursor();
// get the cookie
cookie = pagedContext.getCookie();
pagedResultsControl = new PagedResultsControl();
pagedResultsControl.setCookie( cookie );
pagedResultsControl.setSize( 0 );
pagedResultsControl.setCritical( true );
}
else
{
// case 2 : create a new cursor
// We have to close the cursor
cursor = pagedContext.getCursor();
if ( cursor != null )
{
cursor.close();
}
// Now create a new context and stores it into the session
pagedContext = new PagedSearchContext( req );
session.addPagedSearchContext( pagedContext );
cookie = pagedContext.getCookie();
pagedResultsControl = new PagedResultsControl();
pagedResultsControl.setCookie( cookie );
pagedResultsControl.setSize( 0 );
pagedResultsControl.setCritical( true );
}
}
// Now, do the real search