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 2012/09/14 21:18:41 UTC

svn commit: r1384891 - in /directory/apacheds/branches/apacheds-mvbt: server-config/src/main/java/org/apache/directory/server/config/ xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/ xdbm-partition/src/main/java/org/a...

Author: elecharny
Date: Fri Sep 14 19:18:40 2012
New Revision: 1384891

URL: http://svn.apache.org/viewvc?rev=1384891&view=rev
Log:
o Moved the SchemaManager in the AbstractCursorTest class
o The cursorBuilder.build() method now takes a PartitionSearchResult instead of a set
o Refactored the DefaultSearchEngine to make it clearer
o Fixed the CursorBuilder to handle the Aliases
o Passed the SchemaManager as a parameter of the SearchEngine.computeResult() method

Modified:
    directory/apacheds/branches/apacheds-mvbt/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AbstractCursorTest.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AndCursorTest.java
    directory/apacheds/branches/apacheds-mvbt/xdbm-tools/src/main/java/org/apache/directory/server/core/partition/impl/btree/gui/PartitionFrame.java

Modified: directory/apacheds/branches/apacheds-mvbt/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java Fri Sep 14 19:18:40 2012
@@ -36,6 +36,7 @@ import java.util.Set;
 
 import org.apache.directory.server.config.beans.AdsBaseBean;
 import org.apache.directory.server.config.beans.ConfigBean;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.server.core.partition.impl.btree.AbstractBTreePartition;
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.xdbm.IndexEntry;
@@ -735,8 +736,12 @@ public class ConfigPartitionReader
         try
         {
             // Do the search
-            PartitionSearchResult searchResult = se.computeResult( baseDn, AliasDerefMode.NEVER_DEREF_ALIASES,
-                filter, scope );
+            SearchOperationContext searchContext = new SearchOperationContext( null );
+            searchContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES );
+            searchContext.setDn( baseDn );
+            searchContext.setFilter( filter );
+            searchContext.setScope( scope );
+            PartitionSearchResult searchResult = se.computeResult( schemaManager, searchContext );
 
             cursor = searchResult.getResultSet();
 

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Fri Sep 14 19:18:40 2012
@@ -62,7 +62,6 @@ import org.apache.directory.server.xdbm.
 import org.apache.directory.server.xdbm.search.evaluator.PassThroughEvaluator;
 import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.model.cursor.Cursor;
-import org.apache.directory.shared.ldap.model.cursor.Tuple;
 import org.apache.directory.shared.ldap.model.entry.Attribute;
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.entry.Modification;
@@ -76,10 +75,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.exception.LdapOperationErrorException;
 import org.apache.directory.shared.ldap.model.exception.LdapSchemaViolationException;
 import org.apache.directory.shared.ldap.model.exception.LdapUnwillingToPerformException;
-import org.apache.directory.shared.ldap.model.filter.ExprNode;
-import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
-import org.apache.directory.shared.ldap.model.message.SearchScope;
 import org.apache.directory.shared.ldap.model.name.Ava;
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.model.name.Rdn;
@@ -937,7 +933,7 @@ public abstract class AbstractBTreeParti
 
             dumpRdnIdx();
 
-            PartitionSearchResult searchResult = new PartitionSearchResult();
+            PartitionSearchResult searchResult = new PartitionSearchResult( schemaManager );
             Set<IndexEntry<String, String>> resultSet = new HashSet<IndexEntry<String, String>>();
 
             Cursor<IndexEntry<String, String>> childrenCursor = new ChildrenCursor( this, id, cursor );
@@ -968,7 +964,7 @@ public abstract class AbstractBTreeParti
 
             dumpRdnIdx();
 
-            PartitionSearchResult searchResult = new PartitionSearchResult();
+            PartitionSearchResult searchResult = new PartitionSearchResult( schemaManager );
             Set<IndexEntry<String, String>> resultSet = new HashSet<IndexEntry<String, String>>();
 
             Cursor<IndexEntry<String, String>> childrenCursor = new ChildrenCursor( this, id, cursor );
@@ -1002,15 +998,12 @@ public abstract class AbstractBTreeParti
     {
         try
         {
-            SearchScope scope = searchContext.getScope();
-            Dn dn = searchContext.getDn();
-            AliasDerefMode derefMode = searchContext.getAliasDerefMode();
-            ExprNode filter = searchContext.getFilter();
 
-            PartitionSearchResult searchResult = searchEngine.computeResult( dn, derefMode, filter, scope );
+            PartitionSearchResult searchResult = searchEngine.computeResult( schemaManager, searchContext );
 
-            return new BaseEntryFilteringCursor( new EntryCursorAdaptor( this, searchResult ),
-                searchContext );
+            Cursor<Entry> result = new EntryCursorAdaptor( this, searchResult );
+
+            return new BaseEntryFilteringCursor( result, searchContext );
         }
         catch ( LdapException le )
         {

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java Fri Sep 14 19:18:40 2012
@@ -20,18 +20,24 @@
 package org.apache.directory.server.xdbm.search;
 
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.directory.server.xdbm.IndexEntry;
 import org.apache.directory.shared.ldap.model.cursor.SetCursor;
 import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 
 
 /**
  * A class containing the result of a search :
  * <ul>
- * <li>A set of cadidate UUIDs</li>
- * <li>A hierarchy of evaualtors to use to validate the candidates</li>
+ * <li>A set of candidate UUIDs</li>
+ * <li>A set of aliased entry if we have any</li>
+ * <li>A flag telling if we are dereferencing aliases or not</li>
+ * <li>A hierarchy of evaluators to use to validate the candidates</li>
  * </ul>
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -40,15 +46,28 @@ public class PartitionSearchResult
     /** The set of candidate UUIDs selected by the search */
     private SetCursor<IndexEntry<String, String>> resultSet;
 
+    /** The set of candidate UUIDs */
+    private Set<String> candidateSet;
+
+    /** The flag indicating if we are dereferencing the aliases. Default to Never. */
+    private AliasDerefMode aliasDerefMode = AliasDerefMode.NEVER_DEREF_ALIASES;
+
+    /** The list of aliased entries that still have to be dereferenced */
+    private List<String> aliasedIds;
+
     /** The evaluator to validate the candidates */
     private Evaluator<? extends ExprNode> evaluator;
 
+    /** The SchemaManager */
+    private SchemaManager schemaManager;
+
 
     /**
      * Create a PartitionSearchResult instance
      */
-    public PartitionSearchResult()
+    public PartitionSearchResult( SchemaManager schemaManager )
     {
+        this.schemaManager = schemaManager;
     }
 
 
@@ -71,6 +90,24 @@ public class PartitionSearchResult
 
 
     /**
+     * @return the candidateSet
+     */
+    public Set<String> getCandidateSet()
+    {
+        return candidateSet;
+    }
+
+
+    /**
+     * @param candidateSet the candidateSet to set
+     */
+    public void setCandidateSet( Set<String> set )
+    {
+        candidateSet = set;
+    }
+
+
+    /**
      * @return the evaluator
      */
     public Evaluator<? extends ExprNode> getEvaluator()
@@ -89,6 +126,92 @@ public class PartitionSearchResult
 
 
     /**
+     * @return the aliasedIds
+     */
+    public List<String> getAliasedIds()
+    {
+        return aliasedIds;
+    }
+
+
+    /**
+     * @param aliasedIds the aliasedIds to set
+     */
+    public void setAliasedIds( List<String> aliasedIds )
+    {
+        this.aliasedIds = aliasedIds;
+    }
+
+
+    /**
+     * @param aliasDerefMode the aliasDerefMode to set
+     */
+    public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
+    {
+        this.aliasDerefMode = aliasDerefMode;
+
+        if ( !isNeverDeref() )
+        {
+            aliasedIds = new ArrayList<String>();
+        }
+    }
+
+
+    /**
+     * @return True if the alias is never dereferenced
+     */
+    public boolean isNeverDeref()
+    {
+        return aliasDerefMode == AliasDerefMode.NEVER_DEREF_ALIASES;
+    }
+
+
+    /**
+     * @return True if the alias is always dereferenced
+     */
+    public boolean isAlwaysDeref()
+    {
+        return aliasDerefMode == AliasDerefMode.DEREF_ALWAYS;
+    }
+
+
+    /**
+     * @return True if the alias is dereferenced while searching
+     */
+    public boolean isDerefInSearching()
+    {
+        return aliasDerefMode == AliasDerefMode.DEREF_IN_SEARCHING;
+    }
+
+
+    /**
+     * @return True if the alias is dereferenced while finding
+     */
+    public boolean isDerefFinding()
+    {
+        return aliasDerefMode == AliasDerefMode.DEREF_FINDING_BASE_OBJ;
+    }
+
+
+    /**
+     * @return the schemaManager
+     */
+    public SchemaManager getSchemaManager()
+    {
+        return schemaManager;
+    }
+
+
+    /**
+     * @param schemaManager the schemaManager to set
+     */
+    public void setSchemaManager( SchemaManager schemaManager )
+    {
+        this.schemaManager = schemaManager;
+    }
+
+
+    /**
      * @see Object#toString()
      */
     public String toString()
@@ -96,7 +219,8 @@ public class PartitionSearchResult
         StringBuilder sb = new StringBuilder();
 
         sb.append( "Search result : \n" );
-        sb.append( evaluator );
+        sb.append( "Alias : " ).append( aliasDerefMode ).append( "\n" );
+        sb.append( "Evaluator : " ).append( evaluator ).append( "\n" );
 
         if ( resultSet == null )
         {

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java Fri Sep 14 19:18:40 2012
@@ -20,11 +20,10 @@
 package org.apache.directory.server.xdbm.search;
 
 
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.shared.ldap.model.constants.JndiPropertyConstants;
 import org.apache.directory.shared.ldap.model.filter.ExprNode;
-import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
-import org.apache.directory.shared.ldap.model.message.SearchScope;
-import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 
 
 /**
@@ -74,15 +73,13 @@ public interface SearchEngine
      * Conducts a search on a database. It returns a set of UUID we found for the 
      * given filter.
      * 
-     * @param base the search base
-     * @param aliasDerefMode the alias dereferencing mode to use
-     * @param filter the search filter AST root
-     * @param scope the Scope
+     * @param The SchemaManager instance
+     * @param searchContext the search context
      * @return A set of UUID representing the full result, up to he sizeLimit
      * @throws Exception if the search fails
      */
-    PartitionSearchResult computeResult( Dn base, AliasDerefMode aliasDerefMode, ExprNode filter,
-        SearchScope scope ) throws Exception;
+    PartitionSearchResult computeResult( SchemaManager schemaManager, SearchOperationContext searchContext )
+        throws Exception;
 
 
     /**

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java Fri Sep 14 19:18:40 2012
@@ -31,6 +31,7 @@ import org.apache.directory.server.xdbm.
 import org.apache.directory.server.xdbm.ParentIdAndRdn;
 import org.apache.directory.server.xdbm.SingletonIndexCursor;
 import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.server.xdbm.search.PartitionSearchResult;
 import org.apache.directory.server.xdbm.search.cursor.ApproximateCursor;
 import org.apache.directory.server.xdbm.search.cursor.ChildrenCursor;
 import org.apache.directory.server.xdbm.search.cursor.DescendantCursor;
@@ -50,6 +51,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.filter.ScopeNode;
 import org.apache.directory.shared.ldap.model.filter.SubstringNode;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
+import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.model.name.Rdn;
 import org.apache.directory.shared.ldap.model.schema.AttributeType;
 import org.apache.directory.shared.ldap.model.schema.MatchingRule;
@@ -85,7 +87,7 @@ public class CursorBuilder
     }
 
 
-    public <T> long build( ExprNode node, Set<String> uuidSet ) throws Exception
+    public <T> long build( ExprNode node, PartitionSearchResult searchResult ) throws Exception
     {
         Object count = node.get( "count" );
 
@@ -99,44 +101,44 @@ public class CursorBuilder
         /* ---------- LEAF NODE HANDLING ---------- */
 
             case APPROXIMATE:
-                return computeApproximate( ( ApproximateNode<T> ) node, uuidSet );
+                return computeApproximate( ( ApproximateNode<T> ) node, searchResult );
 
             case EQUALITY:
-                return computeEquality( ( EqualityNode<T> ) node, uuidSet );
+                return computeEquality( ( EqualityNode<T> ) node, searchResult );
 
             case GREATEREQ:
-                return computeGreaterEq( ( GreaterEqNode<T> ) node, uuidSet );
+                return computeGreaterEq( ( GreaterEqNode<T> ) node, searchResult );
 
             case LESSEQ:
-                return computeLessEq( ( LessEqNode<T> ) node, uuidSet );
+                return computeLessEq( ( LessEqNode<T> ) node, searchResult );
 
             case PRESENCE:
-                return computePresence( ( PresenceNode ) node, uuidSet );
+                return computePresence( ( PresenceNode ) node, searchResult );
 
             case SCOPE:
-                if ( ( ( ScopeNode<String> ) node ).getScope() == SearchScope.ONELEVEL )
+                if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
                 {
-                    return computeOneLevelScope( ( ScopeNode<String> ) node, uuidSet );
+                    return computeOneLevelScope( ( ScopeNode ) node, searchResult );
                 }
                 else
                 {
-                    return computeSubLevelScope( ( ScopeNode<String> ) node, uuidSet );
+                    return computeSubLevelScope( ( ScopeNode ) node, searchResult );
                 }
 
             case SUBSTRING:
-                return computeSubstring( ( SubstringNode ) node, uuidSet );
+                return computeSubstring( ( SubstringNode ) node, searchResult );
 
                 /* ---------- LOGICAL OPERATORS ---------- */
 
             case AND:
-                return computeAnd( ( AndNode ) node, uuidSet );
+                return computeAnd( ( AndNode ) node, searchResult );
 
             case NOT:
                 // Always return infinite, except if the resulting eva 
-                return computeNot( ( NotNode ) node, uuidSet );
+                return computeNot( ( NotNode ) node, searchResult );
 
             case OR:
-                return computeOr( ( OrNode ) node, uuidSet );
+                return computeOr( ( OrNode ) node, searchResult );
 
                 /* ----------  NOT IMPLEMENTED  ---------- */
 
@@ -155,7 +157,7 @@ public class CursorBuilder
      * we have an index for the AT.
      */
 
-    private <T> long computeApproximate( ApproximateNode<T> node, Set<String> uuidSet )
+    private <T> long computeApproximate( ApproximateNode<T> node, PartitionSearchResult searchResult )
         throws Exception
     {
         ApproximateCursor<T> cursor = new ApproximateCursor<T>( db,
@@ -163,6 +165,7 @@ public class CursorBuilder
                 .build( node ) );
 
         int nbResults = 0;
+        Set<String> uuidSet = searchResult.getCandidateSet();
 
         while ( cursor.next() )
         {
@@ -187,7 +190,7 @@ public class CursorBuilder
      * Computes the set of candidates for an Equality filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private <T> long computeEquality( EqualityNode<T> node, Set<String> uuidSet )
+    private <T> long computeEquality( EqualityNode<T> node, PartitionSearchResult searchResult )
         throws Exception
     {
         AttributeType attributeType = node.getAttributeType();
@@ -200,6 +203,7 @@ public class CursorBuilder
             // Get the cursor using the index
             Index<T, Entry, String> userIndex = ( Index<T, Entry, String> ) db.getIndex( attributeType );
             Cursor<IndexEntry<T, String>> userIdxCursor = userIndex.forwardCursor( value.getValue() );
+            Set<String> uuidSet = searchResult.getCandidateSet();
 
             // And loop on it
             while ( userIdxCursor.next() )
@@ -232,7 +236,7 @@ public class CursorBuilder
      * Computes the set of candidates for an GreateEq filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private <T> long computeGreaterEq( GreaterEqNode<T> node, Set<String> uuidSet )
+    private <T> long computeGreaterEq( GreaterEqNode<T> node, PartitionSearchResult searchResult )
         throws Exception
     {
         AttributeType attributeType = node.getAttributeType();
@@ -251,6 +255,7 @@ public class CursorBuilder
             indexEntry.setKey( value.getValue() );
 
             userIdxCursor.before( indexEntry );
+            Set<String> uuidSet = searchResult.getCandidateSet();
 
             // And loop on it
             while ( userIdxCursor.next() )
@@ -283,7 +288,7 @@ public class CursorBuilder
      * Computes the set of candidates for an LessEq filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private <T> long computeLessEq( LessEqNode<T> node, Set<String> uuidSet )
+    private <T> long computeLessEq( LessEqNode<T> node, PartitionSearchResult searchResult )
         throws Exception
     {
         AttributeType attributeType = node.getAttributeType();
@@ -302,6 +307,7 @@ public class CursorBuilder
             indexEntry.setKey( value.getValue() );
 
             userIdxCursor.after( indexEntry );
+            Set<String> uuidSet = searchResult.getCandidateSet();
 
             // And loop on it
             while ( userIdxCursor.previous() )
@@ -334,7 +340,7 @@ public class CursorBuilder
      * Computes the set of candidates for a Presence filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private <T> long computePresence( PresenceNode node, Set<String> uuidSet )
+    private <T> long computePresence( PresenceNode node, PartitionSearchResult searchResult )
         throws Exception
     {
         AttributeType attributeType = node.getAttributeType();
@@ -349,6 +355,7 @@ public class CursorBuilder
 
             // Position the index on the element we should start from
             IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
+            Set<String> uuidSet = searchResult.getCandidateSet();
 
             // And loop on it
             while ( presenceCursor.next() )
@@ -381,7 +388,7 @@ public class CursorBuilder
      * Computes the set of candidates for a OneLevelScope filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private long computeOneLevelScope( ScopeNode<String> node, Set<String> uuidSet )
+    private long computeOneLevelScope( ScopeNode node, PartitionSearchResult searchResult )
         throws Exception
     {
         int nbResults = 0;
@@ -395,6 +402,7 @@ public class CursorBuilder
         rdnCursor.before( startingPos );
 
         Cursor<IndexEntry<String, String>> scopeCursor = new ChildrenCursor( db, node.getBaseId(), rdnCursor );
+        Set<String> candidateSet = searchResult.getCandidateSet();
 
         // Fetch all the UUIDs if we have an index
         // And loop on it
@@ -404,11 +412,43 @@ public class CursorBuilder
 
             String uuid = indexEntry.getId();
 
-            if ( !uuidSet.contains( uuid ) )
+            // If the entry is an alias, and we asked for it to be dereferenced,
+            // we will dereference the alias
+            if ( searchResult.isAlwaysDeref() || searchResult.isDerefInSearching() )
             {
-                // The UUID is not present in the Set, we add it
-                uuidSet.add( uuid );
-                nbResults++;
+                String aliasedDn = db.getAliasIndex().reverseLookup( uuid );
+
+                if ( aliasedDn != null )
+                {
+                    String aliasedId = db.getEntryId( new Dn( searchResult.getSchemaManager(), aliasedDn ) );
+
+                    // This is an alias. Add it to the set of candidates to process, if it's not already
+                    // present in the candidate set 
+                    if ( !candidateSet.contains( aliasedId ) )
+                    {
+                        candidateSet.add( aliasedId );
+                        nbResults++;
+                    }
+                }
+                else
+                {
+                    // This is not an alias
+                    if ( !candidateSet.contains( uuid ) )
+                    {
+                        // The UUID is not present in the Set, we add it
+                        candidateSet.add( uuid );
+                        nbResults++;
+                    }
+                }
+            }
+            else
+            {
+                if ( !candidateSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    candidateSet.add( uuid );
+                    nbResults++;
+                }
             }
         }
 
@@ -422,7 +462,7 @@ public class CursorBuilder
      * Computes the set of candidates for a SubLevelScope filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private long computeSubLevelScope( ScopeNode<String> node, Set<String> uuidSet )
+    private long computeSubLevelScope( ScopeNode node, PartitionSearchResult searchResult )
         throws Exception
     {
         // If we are searching from the partition DN, better get out.
@@ -449,6 +489,7 @@ public class CursorBuilder
         String parentId = parentIdAndRdn.getParentId();
 
         Cursor<IndexEntry<String, String>> scopeCursor = new DescendantCursor( db, baseId, parentId, rdnCursor );
+        Set<String> candidateSet = searchResult.getCandidateSet();
 
         // Fetch all the UUIDs if we have an index
         // And loop on it
@@ -458,11 +499,51 @@ public class CursorBuilder
 
             String uuid = indexEntry.getId();
 
-            if ( !uuidSet.contains( uuid ) )
+            // If the entry is an alias, and we asked for it to be dereferenced,
+            // we will dereference the alias
+            if ( searchResult.isAlwaysDeref() || searchResult.isDerefInSearching() )
             {
-                // The UUID is not present in the Set, we add it
-                uuidSet.add( uuid );
-                nbResults++;
+                String aliasedDn = db.getAliasIndex().reverseLookup( uuid );
+
+                if ( aliasedDn != null )
+                {
+                    String aliasedId = db.getEntryId( new Dn( searchResult.getSchemaManager(), aliasedDn ) );
+
+                    // This is an alias. Add it to the set of candidates to process, if it's not already
+                    // present in the candidate set 
+                    if ( !candidateSet.contains( aliasedId ) )
+                    {
+                        candidateSet.add( aliasedId );
+                        nbResults++;
+
+                        ScopeNode newScopeNode = new ScopeNode(
+                            node.getDerefAliases(),
+                            new Dn( searchResult.getSchemaManager(), aliasedDn ),
+                            aliasedId,
+                            node.getScope() );
+
+                        nbResults += computeSubLevelScope( newScopeNode, searchResult );
+                    }
+                }
+                else
+                {
+                    // This is not an alias
+                    if ( !candidateSet.contains( uuid ) )
+                    {
+                        // The UUID is not present in the Set, we add it
+                        candidateSet.add( uuid );
+                        nbResults++;
+                    }
+                }
+            }
+            else
+            {
+                if ( !candidateSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    candidateSet.add( uuid );
+                    nbResults++;
+                }
             }
         }
 
@@ -476,7 +557,7 @@ public class CursorBuilder
      * Computes the set of candidates for an Substring filter. We will feed the set only if
      * we have an index for the AT.
      */
-    private long computeSubstring( SubstringNode node, Set<String> uuidSet )
+    private long computeSubstring( SubstringNode node, PartitionSearchResult searchResult )
         throws Exception
     {
         AttributeType attributeType = node.getAttributeType();
@@ -524,6 +605,8 @@ public class CursorBuilder
                 regexp = null;
             }
 
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
             // And loop on it
             while ( cursor.next() )
             {
@@ -567,7 +650,7 @@ public class CursorBuilder
      * @return Cursor over candidates satisfying disjunction expression
      * @throws Exception on db access failures
      */
-    private <T> long computeOr( OrNode node, Set<String> uuidSet ) throws Exception
+    private <T> long computeOr( OrNode node, PartitionSearchResult searchResult ) throws Exception
     {
         List<ExprNode> children = node.getChildren();
 
@@ -594,7 +677,7 @@ public class CursorBuilder
                 }
             }
 
-            long nbResults = build( child, uuidSet );
+            long nbResults = build( child, searchResult );
 
             if ( nbResults == Long.MAX_VALUE )
             {
@@ -618,7 +701,7 @@ public class CursorBuilder
      * @return Cursor over the conjunction expression
      * @throws Exception on db access failures
      */
-    private long computeAnd( AndNode node, Set<String> uuidSet ) throws Exception
+    private long computeAnd( AndNode node, PartitionSearchResult searchResult ) throws Exception
     {
         int minIndex = 0;
         long minValue = Long.MAX_VALUE;
@@ -658,7 +741,7 @@ public class CursorBuilder
 
         // Once found we return the number of candidates for this child
         ExprNode minChild = children.get( minIndex );
-        long nbResults = build( minChild, uuidSet );
+        long nbResults = build( minChild, searchResult );
 
         return nbResults;
     }
@@ -671,7 +754,7 @@ public class CursorBuilder
      * @return Cursor over the conjunction expression
      * @throws Exception on db access failures
      */
-    private long computeNot( NotNode node, Set<String> uuidSet ) throws Exception
+    private long computeNot( NotNode node, PartitionSearchResult searchResult ) throws Exception
     {
         final List<ExprNode> children = node.getChildren();
 

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java Fri Sep 14 19:18:40 2012
@@ -23,6 +23,7 @@ package org.apache.directory.server.xdbm
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor;
 import org.apache.directory.server.i18n.I18n;
@@ -42,6 +43,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 
 
 /**
@@ -101,66 +103,59 @@ public class DefaultSearchEngine impleme
     /**
      * {@inheritDoc}
      */
-    public PartitionSearchResult computeResult( Dn base, AliasDerefMode aliasDerefMode, ExprNode filter,
-        SearchScope scope ) throws Exception
+    public PartitionSearchResult computeResult( SchemaManager schemaManager, SearchOperationContext searchContext )
+        throws Exception
     {
-        Dn effectiveBase;
-        String baseId = db.getEntryId( base );
-        PartitionSearchResult searchSet = new PartitionSearchResult();
+        SearchScope scope = searchContext.getScope();
+        Dn baseDn = searchContext.getDn();
+        AliasDerefMode aliasDerefMode = searchContext.getAliasDerefMode();
+        ExprNode filter = searchContext.getFilter();
+
+        // Compute the UUID of the baseDN entry
+        String baseId = db.getEntryId( baseDn );
+
+        // Prepare the instance containing the search result
+        PartitionSearchResult searchResult = new PartitionSearchResult( schemaManager );
         Set<IndexEntry<String, String>> resultSet = new HashSet<IndexEntry<String, String>>();
 
         // Check that we have an entry, otherwise we can immediately get out
         if ( baseId == null )
         {
-            if ( ( ( Partition ) db ).getSuffixDn().equals( base ) )
+            if ( ( ( Partition ) db ).getSuffixDn().equals( baseDn ) )
             {
                 // The context entry is not created yet, return an empty result
-                searchSet.setResultSet( resultSet );
+                searchResult.setResultSet( resultSet );
 
-                return searchSet;
+                return searchResult;
             }
             else
             {
                 // The search base doesn't exist
-                throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_648, base ) );
+                throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_648, baseDn ) );
             }
         }
 
-        String aliasedBase = db.getAliasIndex().reverseLookup( baseId );
-
         // --------------------------------------------------------------------
         // Determine the effective base with aliases
         // --------------------------------------------------------------------
+        String aliasedBase = db.getAliasIndex().reverseLookup( baseId );
+        Dn effectiveBase = baseDn;
+        String effectiveBaseId = baseId;
 
-        /*
-         * If the base is not an alias or if alias dereferencing does not
-         * occur on finding the base then we set the effective base to the
-         * given base.
-         */
-        if ( ( null == aliasedBase ) || !aliasDerefMode.isDerefFindingBase() )
+        if ( ( aliasedBase != null ) && aliasDerefMode.isDerefFindingBase() )
         {
-            effectiveBase = base;
-        }
-        /*
-         * If the base is an alias and alias dereferencing does occur on
-         * finding the base then we set the effective base to the alias target
-         * got from the alias index.
-         */
-        else
-        {
-            effectiveBase = new Dn( aliasedBase );
+            /*
+             * If the base is an alias and alias dereferencing does occur on
+             * finding the base, or always then we set the effective base to the alias target
+             * got from the alias index.
+             */
+            effectiveBase = new Dn( schemaManager, aliasedBase );
+            effectiveBaseId = db.getEntryId( effectiveBase );
         }
 
         // --------------------------------------------------------------------
         // Specifically Handle Object Level Scope
         // --------------------------------------------------------------------
-        String effectiveBaseId = baseId;
-
-        if ( effectiveBase != base )
-        {
-            effectiveBaseId = db.getEntryId( effectiveBase );
-        }
-
         if ( scope == SearchScope.OBJECT )
         {
             IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
@@ -169,26 +164,19 @@ public class DefaultSearchEngine impleme
             Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( filter );
 
             // Fetch the entry, as we have only one
-            Entry entry = null;
-
-            if ( effectiveBase != base )
-            {
-                entry = db.lookup( indexEntry.getId() );
-            }
-            else
-            {
-                entry = db.lookup( indexEntry.getId(), effectiveBase );
-            }
+            Entry entry = db.lookup( indexEntry.getId(), effectiveBase );
 
             indexEntry.setEntry( entry );
             resultSet.add( indexEntry );
 
-            searchSet.setEvaluator( evaluator );
-            searchSet.setResultSet( resultSet );
+            searchResult.setEvaluator( evaluator );
+            searchResult.setResultSet( resultSet );
 
-            return searchSet;
+            return searchResult;
         }
 
+        // This is not a BaseObject scope search.
+
         // Add the scope node using the effective base to the filter
         BranchNode root = new AndNode();
         ExprNode node = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId, scope );
@@ -200,8 +188,35 @@ public class DefaultSearchEngine impleme
         Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( root );
 
         Set<String> uuidSet = new HashSet<String>();
+        searchResult.setAliasDerefMode( aliasDerefMode );
+        searchResult.setCandidateSet( uuidSet );
+
+        long nbResults = cursorBuilder.build( root, searchResult );
 
-        long nbResults = cursorBuilder.build( root, uuidSet );
+        // Check if we have found aliases
+        /*
+        if ( searchResult.getAliasedIds().size() > 0 )
+        {
+            for ( String aliasedId : searchResult.getAliasedIds() )
+            {
+                // We have some. Deal with them accordingly to the requested mode
+                if ( searchResult.isAlwaysDeref() )
+                {
+                    // We have to dereference each alias
+
+                }
+                else if ( searchResult.isDerefFinding() )
+                {
+
+                }
+                else
+                // This is when we dereference in searching
+                {
+
+                }
+            }
+        }
+        */
 
         if ( nbResults < Long.MAX_VALUE )
         {
@@ -231,10 +246,10 @@ public class DefaultSearchEngine impleme
             }
         }
 
-        searchSet.setEvaluator( evaluator );
-        searchSet.setResultSet( resultSet );
+        searchResult.setEvaluator( evaluator );
+        searchResult.setResultSet( resultSet );
 
-        return searchSet;
+        return searchResult;
     }
 
 

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AbstractCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AbstractCursorTest.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AbstractCursorTest.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AbstractCursorTest.java Fri Sep 14 19:18:40 2012
@@ -36,6 +36,7 @@ import org.apache.directory.server.xdbm.
 import org.apache.directory.shared.ldap.model.cursor.Cursor;
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 
 
 /**
@@ -48,6 +49,7 @@ public class AbstractCursorTest
     protected EvaluatorBuilder evaluatorBuilder;
     protected CursorBuilder cursorBuilder;
     protected Store store;
+    protected static SchemaManager schemaManager;
 
 
     /**
@@ -61,12 +63,13 @@ public class AbstractCursorTest
     {
         Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( root );
 
-        PartitionSearchResult searchResult = new PartitionSearchResult();
+        PartitionSearchResult searchResult = new PartitionSearchResult( schemaManager );
         Set<IndexEntry<String, String>> resultSet = new HashSet<IndexEntry<String, String>>();
 
         Set<String> uuids = new HashSet<String>();
+        searchResult.setCandidateSet( uuids );
 
-        long candidates = cursorBuilder.build( root, uuids );
+        long candidates = cursorBuilder.build( root, searchResult );
 
         if ( candidates < Long.MAX_VALUE )
         {

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AndCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AndCursorTest.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AndCursorTest.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/search/impl/AndCursorTest.java Fri Sep 14 19:18:40 2012
@@ -39,7 +39,6 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.filter.ExprNode;
 import org.apache.directory.shared.ldap.model.filter.FilterParser;
 import org.apache.directory.shared.ldap.model.name.Dn;
-import org.apache.directory.shared.ldap.model.schema.SchemaManager;
 import org.apache.directory.shared.ldap.schemaextractor.SchemaLdifExtractor;
 import org.apache.directory.shared.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
 import org.apache.directory.shared.ldap.schemaloader.LdifSchemaLoader;
@@ -65,7 +64,6 @@ public class AndCursorTest extends Abstr
     private static final Logger LOG = LoggerFactory.getLogger( AndCursorTest.class.getSimpleName() );
 
     File wkdir;
-    private static SchemaManager schemaManager;
 
 
     @BeforeClass

Modified: directory/apacheds/branches/apacheds-mvbt/xdbm-tools/src/main/java/org/apache/directory/server/core/partition/impl/btree/gui/PartitionFrame.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-mvbt/xdbm-tools/src/main/java/org/apache/directory/server/core/partition/impl/btree/gui/PartitionFrame.java?rev=1384891&r1=1384890&r2=1384891&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-mvbt/xdbm-tools/src/main/java/org/apache/directory/server/core/partition/impl/btree/gui/PartitionFrame.java (original)
+++ directory/apacheds/branches/apacheds-mvbt/xdbm-tools/src/main/java/org/apache/directory/server/core/partition/impl/btree/gui/PartitionFrame.java Fri Sep 14 19:18:40 2012
@@ -59,6 +59,7 @@ import javax.swing.tree.TreeNode;
 import javax.swing.tree.TreePath;
 
 import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.server.core.partition.impl.btree.AbstractBTreePartition;
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.xdbm.Index;
@@ -650,13 +651,19 @@ public class PartitionFrame extends JFra
         }
 
         int limitMax = Integer.MAX_VALUE;
+
         if ( !limit.equals( FilterDialog.UNLIMITED ) )
         {
             limitMax = Integer.parseInt( limit );
         }
 
-        PartitionSearchResult searchResult = partition.getSearchEngine().computeResult( new Dn( base ),
-            AliasDerefMode.DEREF_ALWAYS, root, searchScope );
+        SearchOperationContext searchContext = new SearchOperationContext( null );
+        searchContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+        searchContext.setDn( new Dn( base ) );
+        searchContext.setFilter( root );
+        searchContext.setScope( searchScope );
+
+        PartitionSearchResult searchResult = partition.getSearchEngine().computeResult( schemaManager, searchContext );
 
         Cursor cursor = searchResult.getResultSet();