You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/12/15 02:29:29 UTC
svn commit: r726595 -
/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java
Author: elecharny
Date: Sun Dec 14 17:29:29 2008
New Revision: 726595
URL: http://svn.apache.org/viewvc?rev=726595&view=rev
Log:
Added some first code to deal with the most common cases of paged control
Modified:
directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java
Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java?rev=726595&r1=726594&r2=726595&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/SearchHandler.java Sun Dec 14 17:29:29 2008
@@ -372,19 +372,19 @@
}
- private SearchResponseDone readResults( LdapSession session, SearchRequest req,
- LdapResult ldapResult, EntryFilteringCursor cursor, int requestLimit, int serverLimit, boolean isPaged,
+ private void readResults( LdapSession session, SearchRequest req, LdapResult ldapResult,
+ EntryFilteringCursor cursor, int sizeLimit, int pagedLimit, boolean isPaged,
PagedSearchCookie cookieInstance, PagedResultsControl pagedResultsControl ) throws Exception
{
req.addAbandonListener( new SearchAbandonListener( ldapService, cursor ) );
setTimeLimitsOnCursor( req, session, cursor );
- LOG.debug( "using <{},{}> for size limit", requestLimit, serverLimit );
+ LOG.debug( "using <{},{}> for size limit", sizeLimit, pagedLimit );
int cookieValue = 0;
- int sizeLimit = min( requestLimit, serverLimit );
- int count = 0;
+ int count = cookieInstance.getCurrentPosition();
+ int pageCount = 0;
- while ( (count < sizeLimit ) && cursor.next() )
+ while ( ( count < sizeLimit ) && ( pageCount < pagedLimit ) && cursor.next() )
{
if ( session.getIoSession().isClosing() )
{
@@ -394,66 +394,72 @@
ClonedServerEntry entry = cursor.get();
session.getIoSession().write( generateResponse( session, req, entry ) );
count++;
+ pageCount++;
}
// DO NOT WRITE THE RESPONSE - JUST RETURN IT
ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
+
+ boolean hasMoreEntry = cursor.next();
+
+ if ( hasMoreEntry )
+ {
+ cursor.previous();
+ }
- if ( count < sizeLimit )
+ if ( !hasMoreEntry )
{
// That means we don't have anymore entry
- if ( isPaged )
+ // If we are here, it means we have returned all the entries
+ // We have to remove the cookie from the session
+ cookieValue = cookieInstance.getCookieValue();
+ PagedSearchCookie psCookie =
+ (PagedSearchCookie)session.getIoSession().removeAttribute( cookieValue );
+
+ // Close the cursor if there is one
+ if ( psCookie != null )
{
- // If we are here, it means we have returned all the entries
- // We have to remove the cookie from the session
- cookieValue = cookieInstance.getCookieValue();
- PagedSearchCookie psCookie =
- (PagedSearchCookie)session.getIoSession().removeAttribute( cookieValue );
+ cursor = psCookie.getCursor();
- // Close the cursor if there is one
- if ( psCookie != null )
+ if ( cursor != null )
{
- cursor = psCookie.getCursor();
-
- if ( cursor != null )
- {
- cursor.close();
- }
+ cursor.close();
}
-
- pagedResultsControl = new PagedResultsControl( 0, true );
- req.getResultResponse().add( pagedResultsControl );
}
+
+ pagedResultsControl = new PagedResultsControl( 0, true );
+ req.getResultResponse().add( pagedResultsControl );
- return ( SearchResponseDone ) req.getResultResponse();
+ return;
}
else
{
- // We have reached the limit
- if ( isPaged )
+ // We have reached one limit
+
+ if ( count < sizeLimit )
{
// We stop here. We have to add a ResponseControl
// DO NOT WRITE THE RESPONSE - JUST RETURN IT
ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
req.getResultResponse().add( pagedResultsControl );
- // Stores the cursor into the session
- cookieInstance.setCursor( cursor );
- return ( SearchResponseDone ) req.getResultResponse();
+ // Stores the cursor current position
+ cookieInstance.incrementCurrentPosition( pageCount );
+ return;
}
else
{
- // DO NOT WRITE THE RESPONSE - JUST RETURN IT
- if ( ( count >= sizeLimit ) && ( cursor.next() ) )
+ // Return an exception, close the cursor, and clean the session
+ ldapResult.setResultCode( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
+
+ if ( cursor != null )
{
- // Move backward on the cursor to restore the previous position, as we moved forward
- // to check if there is one more entry available
- cursor.previous();
- // Special case if the user has requested more elements than the request size limit
- ldapResult.setResultCode( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
+ cursor.close();
}
- return ( SearchResponseDone ) req.getResultResponse();
+ session.getIoSession().removeAttribute( cookieValue );
+
+ return;
}
}
}
@@ -503,18 +509,22 @@
/**
- * Handle a Paged Search.
+ * Handle a Paged Search request.
*/
private SearchResponseDone doPagedSearch( LdapSession session, SearchRequest req, PagedSearchControl control )
+ throws Exception
{
- return null;
- /*
PagedSearchControl pagedSearchControl = ( PagedSearchControl )control;
PagedResultsControl pagedResultsControl = null;
- int serverLimit = ldapService.getMaxSizeLimit() == 0 ?
- Integer.MAX_VALUE : ldapService.getMaxSizeLimit();
+
+ // Get the size limits
+ // Don't bother setting size limits for administrators that don't ask for it
+ int serverLimit = getServerSizeLimit( session, req );
+
int requestLimit = req.getSizeLimit() == 0 ?
Integer.MAX_VALUE : req.getSizeLimit();
+ int sizeLimit = min( serverLimit, requestLimit );
+
int pagedLimit = pagedSearchControl.getSize();
EntryFilteringCursor cursor = null;
PagedSearchCookie cookieInstance = null;
@@ -541,18 +551,26 @@
}
// Now, depending on the cookie, we will deal with case 2, 3, 4 and 5
- pagedLimit = pagedSearchControl.getSize();
byte [] cookie= pagedSearchControl.getCookie();
+ LdapResult ldapResult = req.getResultResponse().getLdapResult();
if ( StringTools.isEmpty( cookie ) )
{
- // This is a new search.
- if ( ( pagedLimit > serverLimit ) && ( pagedLimit > requestLimit ) )
+ // 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
{
- readResults( session, req, ldapResult, cursor, min( serverLimit, requestLimit ), true, cookieInstance, pagedResultsControl );
+ // No cursor : do a search.
+ cursor = session.getCoreSession().search( req );
+
+ // Position the cursor at the beginning
+ cursor.beforeFirst();
+
+ readResults( session, req, ldapResult, cursor, serverLimit, requestLimit, true, cookieInstance, pagedResultsControl );
}
finally
{
@@ -568,16 +586,29 @@
return ( SearchResponseDone ) req.getResultResponse();
}
- // Case 2 : create the cookie
- cookieInstance = new PagedSearchCookie( req );
- cookie = cookieInstance.getCookie();
- int cookieValue = cookieInstance.getCookieValue();
+ else
+ {
+ // Case 2 : create the cookie
+ cookieInstance = new PagedSearchCookie( req );
+ cookie = cookieInstance.getCookie();
+ int cookieValue = cookieInstance.getCookieValue();
+
+ session.getIoSession().setAttribute( cookieValue, cookieInstance );
+ pagedResultsControl = new PagedResultsControl( 0, cookie, true );
+
+ // No cursor : do a search.
+ cursor = session.getCoreSession().search( req );
- session.getIoSession().setAttribute( cookieValue, cookieInstance );
- pagedResultsControl = new PagedResultsControl( 0, cookie, true );
+ // Position the cursor at the beginning
+ cursor.beforeFirst();
+
+ // And stores the cursor into the session
+ cookieInstance.setCursor( cursor );
+ }
}
else
{
+ // We have a cookie
// Either case 3, 4 or 5
int cookieValue = pagedSearchControl.getCookieValue();
cookieInstance =
@@ -590,7 +621,6 @@
// get the cookie
cookie = cookieInstance.getCookie();
- sizeLimit = size;
pagedResultsControl = new PagedResultsControl( 0, cookie, true );
}
else
@@ -613,7 +643,32 @@
pagedResultsControl = new PagedResultsControl( 0, cookie, true );
}
}
- */
+
+ // Now, do the real search
+ /*
+ * Iterate through all search results building and sending back responses
+ * for each search result returned.
+ */
+ try
+ {
+ readResults( session, req, ldapResult, cursor, sizeLimit, pagedLimit, true, cookieInstance, pagedResultsControl );
+ }
+ catch ( Exception e )
+ {
+ if ( cursor != null )
+ {
+ try
+ {
+ cursor.close();
+ }
+ catch ( NamingException ne )
+ {
+ LOG.error( "failed on list.close()", ne );
+ }
+ }
+ }
+
+ return ( SearchResponseDone ) req.getResultResponse();
}
@@ -623,29 +678,6 @@
* returned so the persistent search mechanism can leverage this method
* along with standard search.<br>
* <br>
- * The loop will stop when we have found all the entries, or if we
- * have reached the limit, or if we have reached the paged limit. The
- * following table describes the different possibilities (SL = server limit,
- * RL = request limit, PL = paged limit)
- *
- * 1) SL=0, RL=0, PL=0 => no limit
- * 2) SL=0, RL=0, PL=x => loop until we have sent X entries, or until we don't have
- * any more entries to send
- * 3) SL=0, RL=x, PL=0 => loop until we don't have anymore entries, or break and
- * return an error if we reach the RL
- * 4) SL=x, RL=0, PL=0 => loop until we don't have anymore entries, or break and
- * return an error if we reach the SL
- * 5) SL=0, RL=x, PL=y => if x > y, default to case (1), otherwise default to
- * case (3)
- * 6) SL=x, RL=0, PL=y => if x > y, default to case (1), otherwise default to
- * case (4)
- * 7) SL=x, RL=y, PL=0 => loop until we don't have anymore entries, or break and
- * return an error if we reach the min(SL, RL)
- * 8) SL=x, RL=y, PL=z => if z < min(x, y=, default to case 1, otherwise loop until
- * we don't have anymore entries, or break and return an error if we reach the
- * min(SL, RL)
- *
- *
* @param session the LDAP session object for this request
* @param req the search request
* @return the result done
@@ -657,13 +689,6 @@
LdapResult ldapResult = req.getResultResponse().getLdapResult();
PagedResultsControl pagedResultsControl = null;
- // Get the size limits
- // Don't bother setting size limits for administrators that don't ask for it
- int serverLimit = getServerSizeLimit( session, req );
-
- int requestLimit = req.getSizeLimit() == 0 ?
- Integer.MAX_VALUE : req.getSizeLimit();
-
// Check if we are using the Paged Search Control
Object control = req.getControls().get( PagedSearchControl.CONTROL_OID );
@@ -675,7 +700,7 @@
// A normal search
// Check that we have a cursor or not.
- // No cursor : do a search.
+ // No cursor : do a search.
EntryFilteringCursor cursor = session.getCoreSession().search( req );
// Position the cursor at the beginning
@@ -687,7 +712,44 @@
*/
try
{
- readResults( session, req, ldapResult, cursor, requestLimit, serverLimit, false, null, pagedResultsControl );
+ // Get the size limits
+ // Don't bother setting size limits for administrators that don't ask for it
+ int serverLimit = getServerSizeLimit( session, req );
+
+ int requestLimit = req.getSizeLimit() == 0 ?
+ Integer.MAX_VALUE : req.getSizeLimit();
+
+ req.addAbandonListener( new SearchAbandonListener( ldapService, cursor ) );
+ setTimeLimitsOnCursor( req, session, cursor );
+ LOG.debug( "using <{},{}> for size limit", requestLimit, serverLimit );
+ int sizeLimit = min( requestLimit, serverLimit );
+ int count = 0;
+
+
+ while ( (count < sizeLimit ) && cursor.next() )
+ {
+ if ( session.getIoSession().isClosing() )
+ {
+ break;
+ }
+
+ ClonedServerEntry entry = cursor.get();
+ session.getIoSession().write( generateResponse( session, req, entry ) );
+ count++;
+ }
+
+ // DO NOT WRITE THE RESPONSE - JUST RETURN IT
+ ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
+
+ if ( ( count >= sizeLimit ) && ( cursor.next() ) )
+ {
+ // We have reached the limit
+ // Move backward on the cursor to restore the previous position, as we moved forward
+ // to check if there is one more entry available
+ cursor.previous();
+ // Special case if the user has requested more elements than the request size limit
+ ldapResult.setResultCode( ResultCodeEnum.SIZE_LIMIT_EXCEEDED );
+ }
}
finally
{