directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r723944 - /directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java
Date Sat, 06 Dec 2008 01:39:19 GMT
Author: elecharny
Date: Fri Dec  5 17:39:19 2008
New Revision: 723944

URL: http://svn.apache.org/viewvc?rev=723944&view=rev
Log:
Update the PagedSearchCookie, adding the needed informations to handle this control.

Modified:
    directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java

Modified: directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java?rev=723944&r1=723943&r2=723944&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java
(original)
+++ directory/apacheds/branches/apacheds-mina2/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/controls/PagedSearchCookie.java
Fri Dec  5 17:39:19 2008
@@ -19,108 +19,295 @@
  */
 package org.apache.directory.server.ldap.handlers.controls;
 
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.ldap.LdapSession;
+import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+import org.apache.directory.shared.asn1.ber.tlv.Value;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.message.SearchRequest;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
 
 /**
+ * The structure which stores the informations relative to the pagedSearch control.
+ * They are associated to a cookie, stored into the session and associated to an 
+ * instance of this class.
  * 
- * A container for the Page search cookie. We store multiple informations :
- *  - 
- *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
+ * @version $Rev:  $
  */
 public class PagedSearchCookie
 {
-    /** The total number of entries already returned */ 
-    private int cumulativeSize;
+    /** The previous search request */
+    private SearchRequest previousSearchRequest;
+    
+    /** The current position in the cursor */
+    private int currentPosition;
+    
+    /** The cookie key */
+    private byte[] cookie;
+    
+    /** The integer value for the cookie */
+    private int cookieInt;
+    
+    /** The associated cursor for the current search request */
+    private EntryFilteringCursor cursor;
+    
+    /**
+     * Creates a new instance of this class, storing the Searchrequest into it.
+     */
+    public PagedSearchCookie( SearchRequest searchRequest )
+    {
+        previousSearchRequest = searchRequest;
+        currentPosition = 0;
+        
+        // We compute a key for this cookie. It combines the search request
+        // and some time seed, in order to avoid possible collisions, as
+        // a user may send more than one PagedSearch on the same session.
+        cookieInt = (int)(System.nanoTime()*17) + searchRequest.getMessageId();
+        
+        cookie = Value.getBytes( cookieInt );
+    }
+    
     
-    /** The original MessageId */
-    private int messageId;
     /**
+     * Compute a new key for this cookie, based on the current searchRequest 
+     * hashCode and the current position. This value will be stored into the
+     * session, and will permit the retrieval of this instance.
      * 
-     * Creates a new instance of PagedSearchCookie.
-     *
+     * @return The new cookie's key
      */
-    public PagedSearchCookie()
+    public byte[] getCookie()
     {
-        cumulativeSize = 0;
-        messageId = -1;
+        return cookie;
     }
 
-
+    
     /**
-     * 
-     * Creates a new instance of PagedSearchCookie,
-     * deserializing the cookie.
-     * 
-     * @throws BufferUnderflowException if the buffer is not large enough to 
-     * contain correct values
-     *
+     * Compute a new cookie, if the previous one already exists. This
+     * is unlikely, as we are based on some time seed, but just in case, 
+     * this method will generate a new one.
+     * @return The new cookie
      */
-    public PagedSearchCookie( byte[] cookie ) throws BufferUnderflowException
+    public byte[] getNewCookie()
     {
-        ByteBuffer bb = ByteBuffer.allocate( cookie.length );
-        bb.put( cookie );
+        cookieInt = cookieInt + (int)(System.nanoTime()*17);
+        cookie = Value.getBytes( cookieInt );
         
-        cumulativeSize = bb.getInt();
-        messageId = bb.getInt();
+        return cookie;
     }
-
-
+    
+    
     /**
-     * @return The current number of entries returned since the first request 
+     * Build a set of OIDs from the list of attributes we have in the search request
      */
-    public int getCumulativeSize()
+    private Set<String> buildAttributeSet( SearchRequest request, LdapSession session,

+        AttributeTypeRegistry atRegistry )
     {
-        return cumulativeSize;
+        Set<String> requestSet = new HashSet<String>();
+        
+        // Build the set of attributeType from the attributes
+        for ( String attribute:request.getAttributes() )
+        {
+            try
+            {
+                AttributeType at = atRegistry.lookup( attribute );
+                requestSet.add( at.getOid() );
+            }
+            catch ( NamingException ne )
+            {
+                // Deal with special attributes : '*', '+' and '1.1'
+                if ( attribute.equals( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES ) ||
+                     attribute.equals( SchemaConstants.ALL_USER_ATTRIBUTES ) ||
+                     attribute.equals( SchemaConstants.NO_ATTRIBUTE ) )
+                {
+                    requestSet.add( attribute );
+                }
+                
+                // Otherwise, don't add the attribute to the set
+            }
+        }
+        
+        return requestSet;
     }
+    
+    /**
+     * Compare the previous search request and the new one, and return 
+     * true if they are equal. We compare every field but the MessageID.
+     * 
+     * @param request The new SearchRequest
+     * @return true if both request are equal.
+     */
+    public boolean hasSameRequest( SearchRequest request, LdapSession session )
+    {
+        // Compares the scope
+        if ( request.getScope() != previousSearchRequest.getScope() )
+        {
+            return false;
+        }
+        
+        // Compares the sizeLimit
+        if ( request.getSizeLimit() != previousSearchRequest.getSizeLimit() )
+        {
+            return false;
+        }
+
+        // Compares the timeLimit
+        if ( request.getTimeLimit() != previousSearchRequest.getTimeLimit() )
+        {
+            return false;
+        }
+        
+        // Compares the TypesOnly
+        if ( request.getTypesOnly() != previousSearchRequest.getTypesOnly() )
+        {
+            return false;
+        }
+        
+        // Compares the deref aliases mode
+        if ( request.getDerefAliases() != previousSearchRequest.getDerefAliases() )
+        {
+            return false;
+        }
+        
+        AttributeTypeRegistry atRegistry = 
+            session.getLdapServer().getDirectoryService().getRegistries().getAttributeTypeRegistry();
 
+        // Compares the attributes
+        if ( request.getAttributes() == null )
+        {
+            if ( previousSearchRequest.getAttributes() != null )
+            {
+                return false;
+            }
+        }
+        else
+        {
+            if ( previousSearchRequest.getAttributes() == null )
+            {
+                return false;
+            }
+            else
+            {
+                // We have to normalize the attributes in order to compare them
+                if ( request.getAttributes().size() != previousSearchRequest.getAttributes().size()
)
+                {
+                    return false;
+                }
+                
+                // Build the set of attributeType from both requests
+                Set<String> requestSet = buildAttributeSet( request, session, atRegistry
);
+                Set<String> previousRequestSet = buildAttributeSet( previousSearchRequest,
session, atRegistry );
+                
+                // Check that both sets have the same size again after having converted
+                // the attributes to OID
+                if ( requestSet.size() != previousRequestSet.size() )
+                {
+                    return false;
+                }
+                
+                for ( String attribute:requestSet )
+                {
+                    previousRequestSet.remove( attribute );
+                }
+                
+                // The other set must be empty
+                if ( !previousRequestSet.isEmpty() )
+                {
+                    return false;
+                }
+            }
+        }
+        
+        // Compare the baseDN
+        try
+        {
+            request.getBase().normalize( atRegistry.getNormalizerMapping() );
+            
+            if ( !previousSearchRequest.getBase().isNormalized() )
+            {
+                previousSearchRequest.getBase().normalize( atRegistry.getNormalizerMapping()
);
+            }
+            
+            if ( !request.getBase().equals( previousSearchRequest.getBase() ) )
+            {
+                return false;
+            }
+        }
+        catch ( NamingException ne )
+        {
+            return false;
+        }
+        
+        // Compare the filters
+        // Here, we assume the user hasn't changed the filter's order or content,
+        // as the filter is not normalized. This is a real problem, as the normalization
+        // phase is done in the interceptor chain, which is a bad decision wrt what we
+        // do here.
+        return request.getFilter().equals( previousSearchRequest.getFilter() );
+    }
 
+    
     /**
-     * Increment the cumulativeSize field with the number of
-     * entries returned with the last request
-     *
-     * @param size
+     * @return The current position in the cursor. This value is updated
+     * after each successful search request. 
      */
-    public void incrementCumulativeSize()
+    public int getCurrentPosition()
     {
-        cumulativeSize ++;
+        return currentPosition;
     }
+
     
+    /**
+     * Set the new current position, incrementing it with the 
+     * number of returned entries.
+     * 
+     * @param returnedEntries The number of returned entries
+     */
+    public void incrementCurrentPosition( int returnedEntries )
+    {
+        this.currentPosition += returnedEntries;
+    }
+
     
     /**
-     * @return The cookie associated messageId
+     * @return The previous search request
      */
-    public int getMessageId()
+    public SearchRequest getPreviousSearchRequest()
     {
-        return messageId;
+        return previousSearchRequest;
     }
 
 
     /**
-     * Assign the message ID to this cookie
-     *
-     * @param messageId The request message ID
+     * @return The associated cursor
      */
-    public void setMessageId( int messageId )
+    public EntryFilteringCursor getCursor()
     {
-        this.messageId = messageId;
+        return cursor;
     }
 
+
+    /**
+     * Set the new cursor for this search request
+     * @param cursor The associated cursor
+     */
+    public void setCursor( EntryFilteringCursor cursor )
+    {
+        this.cursor = cursor;
+    }
+    
     
     /**
-     * Serialize the cookie 
-     *
-     * @return A byte array containing the data returned to the client
+     * @see Object#toString()
      */
-    public byte[] serialize()
+    public String toString()
     {
-        ByteBuffer bb = ByteBuffer.allocate( 12 );
-        
-        bb.putInt( cumulativeSize );
-        bb.putInt( messageId );
-        
-        return bb.array();
+        return "PagedSearch cookie:" + StringTools.dumpBytes( cookie );
     }
 }



Mime
View raw message