directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1449316 - in /directory/apacheds/trunk: core-shared/src/main/java/org/apache/directory/server/core/shared/partition/ interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/ interceptors/schema/src/main/java...
Date Sat, 23 Feb 2013 13:39:33 GMT
Author: elecharny
Date: Sat Feb 23 13:39:32 2013
New Revision: 1449316

URL: http://svn.apache.org/r1449316
Log:
o Removed the (ObjectClass=*) from any filter
o Added a EmptyEvaluator and modified the evaluator, optimizer and searchengine to take care
of this modification
o The scope is always added after the other node in the filter

Added:
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/BaseLevelScopeEvaluator.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/EmptyEvaluator.java
Modified:
    directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
    directory/apacheds/trunk/interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
    directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
    directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/OneLevelScopeEvaluator.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/SubtreeScopeEvaluator.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java

Modified: directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
(original)
+++ directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
Sat Feb 23 13:39:32 2013
@@ -48,7 +48,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
 import org.apache.directory.api.ldap.model.exception.LdapOtherException;
 import org.apache.directory.api.ldap.model.filter.ExprNode;
-import org.apache.directory.api.ldap.model.filter.PresenceNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
 import org.apache.directory.api.ldap.model.message.SearchScope;
 import org.apache.directory.api.ldap.model.message.extended.NoticeOfDisconnect;
 import org.apache.directory.api.ldap.model.name.Dn;
@@ -439,7 +439,7 @@ public class DefaultPartitionNexus exten
     {
         Partition partition = getPartition( deleteContext.getDn() );
         Entry deletedEntry = partition.delete( deleteContext );
-        
+
         Entry entry = deleteContext.getEntry();
         Attribute csn = entry.get( ENTRY_CSN_AT );
         // can be null while doing subentry deletion
@@ -448,7 +448,7 @@ public class DefaultPartitionNexus exten
         {
             directoryService.setContextCsn( csn.getString() );
         }
-        
+
         return deletedEntry;
     }
 
@@ -476,7 +476,6 @@ public class DefaultPartitionNexus exten
     }
 
 
-
     /**
      * {@inheritDoc}
      */
@@ -526,12 +525,12 @@ public class DefaultPartitionNexus exten
         Partition partition = getPartition( modifyContext.getDn() );
 
         partition.modify( modifyContext );
-        
-        if( modifyContext.isPushToEvtInterceptor() )
+
+        if ( modifyContext.isPushToEvtInterceptor() )
         {
             directoryService.getInterceptor( InterceptorEnum.EVENT_INTERCEPTOR.getName()
).modify( modifyContext );
         }
-        
+
         Entry alteredEntry = modifyContext.getAlteredEntry();
 
         if ( alteredEntry != null )
@@ -550,7 +549,7 @@ public class DefaultPartitionNexus exten
         Partition partition = getPartition( moveContext.getDn() );
 
         partition.move( moveContext );
-        
+
         Entry entry = moveContext.getModifiedEntry();
         directoryService.setContextCsn( entry.get( ENTRY_CSN_AT ).getString() );
     }
@@ -563,7 +562,7 @@ public class DefaultPartitionNexus exten
     {
         Partition partition = getPartition( moveAndRenameContext.getDn() );
         partition.moveAndRename( moveAndRenameContext );
-        
+
         Entry entry = moveAndRenameContext.getModifiedEntry();
         directoryService.setContextCsn( entry.get( ENTRY_CSN_AT ).getString() );
     }
@@ -576,7 +575,7 @@ public class DefaultPartitionNexus exten
     {
         Partition partition = getPartition( renameContext.getDn() );
         partition.rename( renameContext );
-        
+
         Entry entry = renameContext.getModifiedEntry();
         directoryService.setContextCsn( entry.get( ENTRY_CSN_AT ).getString() );
     }
@@ -593,7 +592,8 @@ public class DefaultPartitionNexus exten
         if ( ( ids == null ) || ( ids.size() == 0 ) )
         {
             Entry rootDse = getRootDse( null );
-            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( rootDse
), searchContext, directoryService.getSchemaManager() );
+            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( rootDse
), searchContext,
+                directoryService.getSchemaManager() );
         }
 
         // -----------------------------------------------------------
@@ -622,14 +622,16 @@ public class DefaultPartitionNexus exten
         if ( noAttribute )
         {
             Entry serverEntry = new DefaultEntry( schemaManager, Dn.ROOT_DSE );
-            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( serverEntry
), searchContext, directoryService.getSchemaManager() );
+            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( serverEntry
), searchContext,
+                directoryService.getSchemaManager() );
         }
 
         // return everything
         if ( allUserAttributes && allOperationalAttributes )
         {
             Entry rootDse = getRootDse( null );
-            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( rootDse
), searchContext, directoryService.getSchemaManager() );
+            return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( rootDse
), searchContext,
+                directoryService.getSchemaManager() );
         }
 
         Entry serverEntry = new DefaultEntry( schemaManager, Dn.ROOT_DSE );
@@ -654,7 +656,8 @@ public class DefaultPartitionNexus exten
             }
         }
 
-        return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( serverEntry
), searchContext, directoryService.getSchemaManager() );
+        return new BaseEntryFilteringCursor( new SingletonCursor<Entry>( serverEntry
), searchContext,
+            directoryService.getSchemaManager() );
     }
 
 
@@ -714,9 +717,9 @@ public class DefaultPartitionNexus exten
         boolean isSearchAll = false;
 
         // We have to be careful, as we may have a filter which is not a PresenceFilter
-        if ( filter instanceof PresenceNode )
+        if ( filter instanceof ObjectClassNode )
         {
-            isSearchAll = ( ( PresenceNode ) filter ).getAttributeType().equals( OBJECT_CLASS_AT
);
+            isSearchAll = true;
         }
 
         if ( isObjectScope )
@@ -730,7 +733,8 @@ public class DefaultPartitionNexus exten
             else
             {
                 // Nothing to return in this case
-                return new BaseEntryFilteringCursor( new EmptyCursor<Entry>(), searchContext,
directoryService.getSchemaManager() );
+                return new BaseEntryFilteringCursor( new EmptyCursor<Entry>(), searchContext,
+                    directoryService.getSchemaManager() );
             }
         }
         else if ( isOnelevelScope )

Modified: directory/apacheds/trunk/interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
(original)
+++ directory/apacheds/trunk/interceptors/normalization/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
Sat Feb 23 13:39:32 2013
@@ -27,7 +27,13 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.entry.Value;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException;
+import org.apache.directory.api.ldap.model.filter.AndNode;
+import org.apache.directory.api.ldap.model.filter.BranchNode;
 import org.apache.directory.api.ldap.model.filter.ExprNode;
+import org.apache.directory.api.ldap.model.filter.NotNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
+import org.apache.directory.api.ldap.model.filter.OrNode;
+import org.apache.directory.api.ldap.model.filter.PresenceNode;
 import org.apache.directory.api.ldap.model.name.Ava;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.name.Rdn;
@@ -295,12 +301,94 @@ public class NormalizationInterceptor ex
             LOG.warn( "undefined filter based on undefined attributeType not evaluted at
all.  Returning empty enumeration." );
             return new BaseEntryFilteringCursor( new EmptyCursor<Entry>(), searchContext,
schemaManager );
         }
-        else
+
+        // We now have to remove the (ObjectClass=*) filter if it's present, and to add the
scope filter
+        ExprNode modifiedFilter = removeObjectClass( filter );
+
+        searchContext.setFilter( modifiedFilter );
+
+        // TODO Normalize the returned Attributes, storing the UP attributes to format the
returned values.
+        return next( searchContext );
+    }
+
+
+    /**
+     * Remove the (ObjectClass=*) node from brancheNode, if we have one.
+     */
+    private ExprNode handleBranchNode( ExprNode node, BranchNode newBranchNode )
+    {
+        int nbNodes = 0;
+
+        for ( ExprNode child : ( ( BranchNode ) node ).getChildren() )
         {
-            searchContext.setFilter( filter );
+            ExprNode modifiedNode = removeObjectClass( child );
 
-            // TODO Normalize the returned Attributes, storing the UP attributes to format
the returned values.
-            return next( searchContext );
+            if ( !( modifiedNode instanceof ObjectClassNode ) )
+            {
+                newBranchNode.addNode( modifiedNode );
+                nbNodes++;
+            }
+        }
+
+        switch ( nbNodes )
+        {
+            case 0:
+                // Unlikely... But (&(ObjectClass=*)) is still an option 
+                return ObjectClassNode.OBJECT_CLASS_NODE;
+
+            case 1:
+                if ( newBranchNode instanceof NotNode )
+                {
+                    return newBranchNode;
+                }
+                else
+                {
+                    // We can safely remove the AND/OR node and replace it with its first
child
+                    return newBranchNode.getFirstChild();
+                }
+
+            default:
+                return newBranchNode;
+        }
+    }
+
+
+    /**
+     * Remove the (ObjectClass=*) node from the filter, if we have one.
+     */
+    private ExprNode removeObjectClass( ExprNode node )
+    {
+        if ( ( node instanceof PresenceNode ) &&
+            ( ( ( PresenceNode ) node ).getAttributeType() == OBJECT_CLASS_AT ) )
+        {
+            // We can safely remove the node and return an undefined node
+            return ObjectClassNode.OBJECT_CLASS_NODE;
+        }
+        // --------------------------------------------------------------------
+        //                 H A N D L E   B R A N C H   N O D E S       
+        // --------------------------------------------------------------------
+        else if ( node instanceof AndNode )
+        {
+            AndNode newAndNode = new AndNode();
+
+            return handleBranchNode( node, newAndNode );
+        }
+        else if ( node instanceof OrNode )
+        {
+            OrNode newOrNode = new OrNode();
+
+            return handleBranchNode( node, newOrNode );
+        }
+        else if ( node instanceof NotNode )
+        {
+            NotNode newNotNode = new NotNode();
+
+            return handleBranchNode( node, newNotNode );
+        }
+        else
+        {
+            // Failover : we return the initial node as is
+            return node;
         }
     }
 

Modified: directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
(original)
+++ directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
Sat Feb 23 13:39:32 2013
@@ -56,6 +56,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.filter.ExtensibleNode;
 import org.apache.directory.api.ldap.model.filter.GreaterEqNode;
 import org.apache.directory.api.ldap.model.filter.LessEqNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
 import org.apache.directory.api.ldap.model.filter.PresenceNode;
 import org.apache.directory.api.ldap.model.filter.ScopeNode;
 import org.apache.directory.api.ldap.model.filter.SimpleNode;
@@ -75,7 +76,6 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.schema.registries.SchemaLoader;
 import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OctetStringSyntaxChecker;
 import org.apache.directory.api.util.Strings;
-import org.apache.directory.server.core.shared.SchemaService;
 import org.apache.directory.server.core.api.DirectoryService;
 import org.apache.directory.server.core.api.InterceptorEnum;
 import org.apache.directory.server.core.api.entry.ClonedServerEntry;
@@ -91,6 +91,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.server.core.api.partition.PartitionNexus;
+import org.apache.directory.server.core.shared.SchemaService;
 import org.apache.directory.server.i18n.I18n;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -412,6 +413,12 @@ public class SchemaInterceptor extends B
             throw new LdapException( message );
         }
 
+        if ( filter instanceof ObjectClassNode )
+        {
+            // Bypass (ObjectClass=*)
+            return;
+        }
+
         if ( filter.isLeaf() )
         {
             if ( filter instanceof EqualityNode )
@@ -461,7 +468,7 @@ public class SchemaInterceptor extends B
             else if ( filter instanceof ExtensibleNode )
             {
                 ExtensibleNode node = ( ( ExtensibleNode ) filter );
-                
+
                 // Todo : add the needed checks here
             }
             else if ( filter instanceof ApproximateNode )
@@ -753,7 +760,7 @@ public class SchemaInterceptor extends B
                         if ( ( newAttribute.size() == 0 ) && !newAttribute.isValid(
attributeType ) )
                         {
                             // This is an error.
-                            String msg = I18n.err( I18n.ERR_54, (Object[])null );
+                            String msg = I18n.err( I18n.ERR_54, ( Object[] ) null );
                             LOG.error( msg );
                             throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX,
msg );
                         }
@@ -863,7 +870,6 @@ public class SchemaInterceptor extends B
         check( dn, tempEntry );
     }
 
-
     /**
      * Filters objectClass attribute to inject top when not present.
      */
@@ -874,14 +880,14 @@ public class SchemaInterceptor extends B
          */
         public boolean accept( SearchOperationContext operationContext, Entry entry ) throws
LdapException
         {
-            ServerEntryUtils.filterContents( 
+            ServerEntryUtils.filterContents(
                 operationContext.getSession().getDirectoryService().getSchemaManager(),
                 operationContext, entry );
 
             return true;
         }
-        
-        
+
+
         /**
          * {@inheritDoc}
          */
@@ -1120,8 +1126,8 @@ public class SchemaInterceptor extends B
     public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
     {
         Entry entry = next( lookupContext );
-        
-        ServerEntryUtils.filterContents( 
+
+        ServerEntryUtils.filterContents(
             lookupContext.getSession().getDirectoryService().getSchemaManager(),
             lookupContext, entry );
 
@@ -1281,7 +1287,7 @@ public class SchemaInterceptor extends B
         // does not have any sub level)
         if ( searchContext.getScope() == SearchScope.OBJECT )
         {
-            // The filter can be an equality or a presence, but nothing else
+            // The filter can be an equality or (ObjectClass=*) but nothing else
             if ( filter instanceof SimpleNode )
             {
                 // We should get the value for the filter.
@@ -1313,28 +1319,23 @@ public class SchemaInterceptor extends B
                     Entry serverEntry = SchemaService.getSubschemaEntry( directoryService,
                         searchContext );
                     serverEntry.setDn( base );
-                    return new BaseEntryFilteringCursor( new SingletonCursor<Entry>(
serverEntry ), searchContext, schemaManager );
+                    return new BaseEntryFilteringCursor( new SingletonCursor<Entry>(
serverEntry ), searchContext,
+                        schemaManager );
                 }
                 else
                 {
                     return new BaseEntryFilteringCursor( new EmptyCursor<Entry>(),
searchContext, schemaManager );
                 }
             }
-            else if ( filter instanceof PresenceNode )
+            else if ( filter instanceof ObjectClassNode )
             {
-                PresenceNode node = ( PresenceNode ) filter;
-
-                // see if node attribute is objectClass
-                if ( node.getAttributeType().equals( OBJECT_CLASS_AT ) )
-                {
-                    // call.setBypass( true );
-                    Entry serverEntry = SchemaService.getSubschemaEntry( directoryService,
-                        searchContext );
-                    serverEntry.setDn( base );
-                    EntryFilteringCursor cursor = new BaseEntryFilteringCursor(
-                        new SingletonCursor<Entry>( serverEntry ), searchContext, schemaManager
);
-                    return cursor;
-                }
+                // This is (ObjectClass=*)
+                Entry serverEntry = SchemaService.getSubschemaEntry( directoryService,
+                    searchContext );
+                serverEntry.setDn( base );
+                EntryFilteringCursor cursor = new BaseEntryFilteringCursor(
+                    new SingletonCursor<Entry>( serverEntry ), searchContext, schemaManager
);
+                return cursor;
             }
         }
 

Modified: directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
(original)
+++ directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
Sat Feb 23 13:39:32 2013
@@ -48,6 +48,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
 import org.apache.directory.api.ldap.model.filter.EqualityNode;
 import org.apache.directory.api.ldap.model.filter.ExprNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
 import org.apache.directory.api.ldap.model.filter.PresenceNode;
 import org.apache.directory.api.ldap.model.message.AliasDerefMode;
 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
@@ -149,8 +150,8 @@ public class SubentryInterceptor extends
             // see if we can use objectclass if present
             return !entry.contains( OBJECT_CLASS_AT, SchemaConstants.SUBENTRY_OC );
         }
-        
-        
+
+
         /**
          * {@inheritDoc}
          */
@@ -180,8 +181,8 @@ public class SubentryInterceptor extends
             // see if we can use objectclass if present
             return entry.contains( OBJECT_CLASS_AT, SchemaConstants.SUBENTRY_OC );
         }
-        
-        
+
+
         /**
          * {@inheritDoc}
          */
@@ -364,7 +365,7 @@ public class SubentryInterceptor extends
     private void updateEntries( OperationEnum operation, CoreSession session, Dn subentryDn,
Dn apDn,
         SubtreeSpecification ss, Dn baseDn, List<Attribute> operationalAttributes )
throws LdapException
     {
-        ExprNode filter = new PresenceNode( OBJECT_CLASS_AT ); // (objectClass=*)
+        ExprNode filter = ObjectClassNode.OBJECT_CLASS_NODE; // (objectClass=*)
         SearchControls controls = new SearchControls();
         controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
         controls.setReturningAttributes( new String[]
@@ -447,7 +448,7 @@ public class SubentryInterceptor extends
     {
         CoreSession session = opContext.getSession();
         LookupOperationContext lookupContext = new LookupOperationContext( session, apDn,
-            SchemaConstants.ALL_ATTRIBUTES_ARRAY);
+            SchemaConstants.ALL_ATTRIBUTES_ARRAY );
 
         Entry administrationPoint = directoryService.getPartitionNexus().lookup( lookupContext
);
 
@@ -1574,11 +1575,11 @@ public class SubentryInterceptor extends
         }
 
         // DO NOT hide subentries for replication operations
-        if( searchContext.isSyncreplSearch() )
+        if ( searchContext.isSyncreplSearch() )
         {
             return cursor;
         }
-        
+
         // for subtree and one level scope we filter
         if ( !isSubentryVisible( searchContext ) )
         {

Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/BaseLevelScopeEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/BaseLevelScopeEvaluator.java?rev=1449316&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/BaseLevelScopeEvaluator.java
(added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/BaseLevelScopeEvaluator.java
Sat Feb 23 13:39:32 2013
@@ -0,0 +1,163 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.xdbm.search.evaluator;
+
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.filter.ScopeNode;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.server.xdbm.search.Evaluator;
+
+
+/**
+ * Evaluates base level scope assertions on candidates using an entry database.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BaseLevelScopeEvaluator<E> implements Evaluator<ScopeNode>
+{
+    /** The ScopeNode containing initial search scope constraints */
+    private final ScopeNode node;
+
+    /** The entry identifier of the scope base */
+    private final String baseId;
+
+    /** True if the scope requires alias dereferencing while searching */
+    private final boolean dereferencing;
+
+    /** the entry db storing entries */
+    private final Store db;
+
+
+    /**
+     * Creates a one level scope node Evaluator for search expressions.
+     *
+     * @param node the scope node
+     * @param db the database used to evaluate scope node
+     * @throws Exception on db access failure
+     */
+    public BaseLevelScopeEvaluator( Store db, ScopeNode node ) throws Exception
+    {
+        this.node = node;
+
+        this.db = db;
+        baseId = node.getBaseId();
+        dereferencing = node.getDerefAliases().isDerefInSearching() || node.getDerefAliases().isDerefAlways();
+    }
+
+
+    /**
+     * Asserts whether or not a candidate has one level scope while taking
+     * alias dereferencing into account.
+     *
+     * TODO - terribly inefficient - would benefit from exposing the id of an
+     * entry within the Entry
+     *
+     * {@inheritDoc}
+     */
+    public boolean evaluate( Entry candidate ) throws Exception
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_721 ) );
+    }
+
+
+    /**
+     * Asserts whether or not a candidate has one level scope while taking
+     * alias dereferencing into account.
+     *
+     * @param candidate the candidate to assert
+     * @return true if the candidate is within one level scope
+     * @throws Exception if db lookups fail
+     * @see org.apache.directory.server.xdbm.search.Evaluator#evaluate(IndexEntry)
+     */
+    public boolean evaluate( IndexEntry<?, String> indexEntry ) throws LdapException
+    {
+        Entry entry = indexEntry.getEntry();
+
+        // Fetch the entry
+        if ( null == entry )
+        {
+            entry = db.fetch( indexEntry.getId() );
+
+            if ( null == entry )
+            {
+                // The entry is not anymore present : get out
+                return false;
+            }
+
+            indexEntry.setEntry( entry );
+        }
+
+        return true;
+    }
+
+
+    public ScopeNode getExpression()
+    {
+        return node;
+    }
+
+
+    /**
+     * Gets the id of the search base associated with the ScopeNode expression.
+     *
+     * @return identifier of the search base
+     */
+    public String getBaseId()
+    {
+        return baseId;
+    }
+
+
+    /**
+     * Gets whether or not dereferencing is enabled for this evaluator.
+     *
+     * @return true if dereferencing is enabled, false otherwise
+     */
+    public boolean isDereferencing()
+    {
+        return dereferencing;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString( String tabs )
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( tabs ).append( "BaseLevelScopEvaluator : " ).append( node ).append( "\n"
);
+
+        return sb.toString();
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return toString( "" );
+    }
+}
\ No newline at end of file

Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/EmptyEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/EmptyEvaluator.java?rev=1449316&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/EmptyEvaluator.java
(added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/EmptyEvaluator.java
Sat Feb 23 13:39:32 2013
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.xdbm.search.evaluator;
+
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.filter.UndefinedNode;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.server.xdbm.search.Evaluator;
+
+
+/**
+ * An Evaluator that always return false, for the case we have no entry to return
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class EmptyEvaluator implements Evaluator<UndefinedNode>
+{
+    /** The backend */
+    private final Store db;
+
+
+    /**
+     * Create a new instance of the PassThroughEvaluator
+     * @throws Exception
+     */
+    public EmptyEvaluator( Store db )
+    {
+        this.db = db;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate( IndexEntry<?, String> indexEntry ) throws LdapException
+    {
+        return false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate( Entry entry ) throws Exception
+    {
+        return false;
+    }
+
+
+    /**
+     * Gets the expression used by this expression Evaluator.
+     *
+     * @return the AST for the expression
+     */
+    public UndefinedNode getExpression()
+    {
+        return null;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString( String tabs )
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( tabs ).append( "EmptyEvaluator\n" );
+
+        return sb.toString();
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return toString( "" );
+    }
+}
\ No newline at end of file

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/OneLevelScopeEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/OneLevelScopeEvaluator.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/OneLevelScopeEvaluator.java
(original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/OneLevelScopeEvaluator.java
Sat Feb 23 13:39:32 2013
@@ -97,10 +97,25 @@ public class OneLevelScopeEvaluator<E> i
      * @throws Exception if db lookups fail
      * @see org.apache.directory.server.xdbm.search.Evaluator#evaluate(IndexEntry)
      */
-    public boolean evaluate( IndexEntry<?, String> candidate ) throws LdapException
+    public boolean evaluate( IndexEntry<?, String> indexEntry ) throws LdapException
     {
-        ParentIdAndRdn parent = db.getRdnIndex().reverseLookup( candidate.getId() );
+        ParentIdAndRdn parent = db.getRdnIndex().reverseLookup( indexEntry.getId() );
         boolean isChild = parent.getParentId().equals( baseId );
+        Entry entry = indexEntry.getEntry();
+
+        // Fetch the entry
+        if ( null == entry )
+        {
+            entry = db.fetch( indexEntry.getId() );
+
+            if ( null == entry )
+            {
+                // The entry is not anymore present : get out
+                return false;
+            }
+
+            indexEntry.setEntry( entry );
+        }
 
         /*
          * The candidate id could be any entry in the db.  If search
@@ -117,7 +132,7 @@ public class OneLevelScopeEvaluator<E> i
          * candidate id is an alias, if so we reject it since aliases should
          * not be returned.
          */
-        if ( null != db.getAliasIndex().reverseLookup( candidate.getId() ) )
+        if ( null != db.getAliasIndex().reverseLookup( indexEntry.getId() ) )
         {
             return false;
         }
@@ -141,7 +156,7 @@ public class OneLevelScopeEvaluator<E> i
          * the lookup returns true accepting the candidate.  Otherwise the
          * candidate is rejected with a false return because it is not in scope.
          */
-        return db.getOneAliasIndex().forward( baseId, candidate.getId() );
+        return db.getOneAliasIndex().forward( baseId, indexEntry.getId() );
     }
 
 

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/SubtreeScopeEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/SubtreeScopeEvaluator.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/SubtreeScopeEvaluator.java
(original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/evaluator/SubtreeScopeEvaluator.java
Sat Feb 23 13:39:32 2013
@@ -158,9 +158,24 @@ public class SubtreeScopeEvaluator imple
      * @throws Exception if the index lookups fail.
      * @see Evaluator#evaluate(org.apache.directory.server.xdbm.IndexEntry)
      */
-    public boolean evaluate( IndexEntry<?, String> candidate ) throws LdapException
+    public boolean evaluate( IndexEntry<?, String> indexEntry ) throws LdapException
     {
-        String id = candidate.getId();
+        String id = indexEntry.getId();
+        Entry entry = indexEntry.getEntry();
+
+        // Fetch the entry
+        if ( null == entry )
+        {
+            entry = db.fetch( indexEntry.getId() );
+
+            if ( null == entry )
+            {
+                // The entry is not anymore present : get out
+                return false;
+            }
+
+            indexEntry.setEntry( entry );
+        }
 
         /*
          * This condition catches situations where the candidate is equal to 

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java
(original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java
Sat Feb 23 13:39:32 2013
@@ -236,8 +236,20 @@ public class DefaultOptimizer<E> impleme
 
         for ( ExprNode child : children )
         {
+            if ( ( count == 1 ) && ( child instanceof ScopeNode ) )
+            {
+                // We can stop here
+                break;
+            }
+
             annotate( child );
             count = Math.min( ( ( Long ) child.get( "count" ) ), count );
+
+            if ( count == 0 )
+            {
+                // No need to continue
+                break;
+            }
         }
 
         return count;
@@ -262,6 +274,12 @@ public class DefaultOptimizer<E> impleme
         {
             annotate( child );
             total += ( Long ) child.get( "count" );
+
+            if ( total == Long.MAX_VALUE )
+            {
+                // We can stop here withoit evaluating the following filters
+                break;
+            }
         }
 
         return total;

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
(original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
Sat Feb 23 13:39:32 2013
@@ -27,8 +27,8 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
 import org.apache.directory.api.ldap.model.filter.AndNode;
-import org.apache.directory.api.ldap.model.filter.BranchNode;
 import org.apache.directory.api.ldap.model.filter.ExprNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
 import org.apache.directory.api.ldap.model.filter.ScopeNode;
 import org.apache.directory.api.ldap.model.message.AliasDerefMode;
 import org.apache.directory.api.ldap.model.message.SearchScope;
@@ -44,6 +44,7 @@ import org.apache.directory.server.xdbm.
 import org.apache.directory.server.xdbm.search.Optimizer;
 import org.apache.directory.server.xdbm.search.PartitionSearchResult;
 import org.apache.directory.server.xdbm.search.SearchEngine;
+import org.apache.directory.server.xdbm.search.evaluator.BaseLevelScopeEvaluator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -165,12 +166,30 @@ public class DefaultSearchEngine impleme
         {
             IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
             indexEntry.setId( effectiveBaseId );
-            optimizer.annotate( filter );
-            Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( filter
);
 
             // Fetch the entry, as we have only one
             Entry entry = db.fetch( indexEntry.getId(), effectiveBase );
 
+            Evaluator<? extends ExprNode> evaluator = null;
+
+            if ( filter instanceof ObjectClassNode )
+            {
+                ScopeNode node = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId,
scope );
+                evaluator = new BaseLevelScopeEvaluator<Entry>( db, node );
+            }
+            else
+            {
+                optimizer.annotate( filter );
+                evaluator = evaluatorBuilder.build( filter );
+
+                // Special case if the filter selects no candidate
+                if ( evaluator == null )
+                {
+                    ScopeNode node = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId,
scope );
+                    evaluator = new BaseLevelScopeEvaluator<Entry>( db, node );
+                }
+            }
+
             indexEntry.setEntry( entry );
             resultSet.add( indexEntry );
 
@@ -183,10 +202,19 @@ public class DefaultSearchEngine impleme
         // 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
);
-        root.getChildren().add( node );
-        root.getChildren().add( filter );
+        ExprNode root = null;
+
+        if ( filter instanceof ObjectClassNode )
+        {
+            root = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId, scope );
+        }
+        else
+        {
+            root = new AndNode();
+            ( ( AndNode ) root ).getChildren().add( filter );
+            ExprNode node = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId,
scope );
+            ( ( AndNode ) root ).getChildren().add( node );
+        }
 
         // Annotate the node with the optimizer and return search enumeration.
         optimizer.annotate( root );

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java?rev=1449316&r1=1449315&r2=1449316&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java
(original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java
Sat Feb 23 13:39:32 2013
@@ -83,6 +83,7 @@ public class EvaluatorBuilder
     public <T> Evaluator<? extends ExprNode> build( ExprNode node ) throws Exception
     {
         Object count = node.get( "count" );
+
         if ( ( count != null ) && ( ( Long ) count == 0L ) )
         {
             return null;



Mime
View raw message