1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.xdbm.search.impl;
21  
22  
23  import java.io.File;
24  import java.util.HashSet;
25  import java.util.Set;
26  
27  import org.apache.commons.io.FileUtils;
28  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
29  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmStore;
30  import org.apache.directory.server.core.entry.ServerEntry;
31  import org.apache.directory.server.schema.SerializableComparator;
32  import org.apache.directory.server.schema.bootstrap.ApacheSchema;
33  import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
34  import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
35  import org.apache.directory.server.schema.bootstrap.CollectiveSchema;
36  import org.apache.directory.server.schema.bootstrap.CoreSchema;
37  import org.apache.directory.server.schema.bootstrap.Schema;
38  import org.apache.directory.server.schema.bootstrap.SystemSchema;
39  import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
40  import org.apache.directory.server.schema.registries.DefaultOidRegistry;
41  import org.apache.directory.server.schema.registries.DefaultRegistries;
42  import org.apache.directory.server.schema.registries.OidRegistry;
43  import org.apache.directory.server.schema.registries.Registries;
44  import org.apache.directory.server.xdbm.Store;
45  import org.apache.directory.server.xdbm.IndexCursor;
46  import org.apache.directory.server.xdbm.search.Optimizer;
47  import org.apache.directory.server.xdbm.tools.StoreUtils;
48  import org.apache.directory.shared.ldap.constants.SchemaConstants;
49  import org.apache.directory.shared.ldap.filter.ExprNode;
50  import org.apache.directory.shared.ldap.filter.FilterParser;
51  import org.junit.*;
52  import static org.junit.Assert.*;
53  import org.slf4j.Logger;
54  import org.slf4j.LoggerFactory;
55  
56  
57  /**
58   * 
59   * Tests the cursor functionality with deeply nested filters.
60   *
61   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
62   * @version $Rev$, $Date$
63   */
64  public class NestedFilterTest
65  {
66      private static final Logger LOG = LoggerFactory.getLogger( NestedFilterTest.class.getSimpleName() );
67  
68      File wkdir;
69      Store<ServerEntry> store;
70      Registries registries = null;
71      AttributeTypeRegistry attributeRegistry;
72      EvaluatorBuilder evaluatorBuilder;
73      CursorBuilder cursorBuilder;
74      Optimizer optimizer;
75  
76      
77      public NestedFilterTest() throws Exception
78      {
79          // setup the standard registries
80          BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
81          OidRegistry oidRegistry = new DefaultOidRegistry();
82          registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
83          SerializableComparator.setRegistry( registries.getComparatorRegistry() );
84  
85          // load essential bootstrap schemas
86          Set<Schema> bootstrapSchemas = new HashSet<Schema>();
87          bootstrapSchemas.add( new ApachemetaSchema() );
88          bootstrapSchemas.add( new ApacheSchema() );
89          bootstrapSchemas.add( new CoreSchema() );
90          bootstrapSchemas.add( new SystemSchema() );
91          bootstrapSchemas.add( new CollectiveSchema() );
92          loader.loadWithDependencies( bootstrapSchemas, registries );
93          attributeRegistry = registries.getAttributeTypeRegistry();
94      }
95  
96      
97      @Before
98      public void createStore() throws Exception
99      {
100         destryStore();
101 
102         // setup the working directory for the store
103         wkdir = File.createTempFile( getClass().getSimpleName(), "db" );
104         wkdir.delete();
105         wkdir = new File( wkdir.getParentFile(), getClass().getSimpleName() );
106         wkdir.mkdirs();
107 
108         // initialize the store
109         store = new JdbmStore<ServerEntry>();
110         store.setName( "example" );
111         store.setCacheSize( 10 );
112         store.setWorkingDirectory( wkdir );
113         store.setSyncOnWrite( false );
114 
115         store.addIndex( new JdbmIndex( SchemaConstants.OU_AT_OID ) );
116         store.addIndex( new JdbmIndex( SchemaConstants.CN_AT_OID ) );
117         StoreUtils.loadExampleData( store, registries );
118         
119         evaluatorBuilder = new EvaluatorBuilder( store, registries );
120         cursorBuilder = new CursorBuilder( store, evaluatorBuilder );
121         optimizer = new DefaultOptimizer( store );
122         
123         LOG.debug( "Created new store" );
124     }
125 
126     
127     @After
128     public void destryStore() throws Exception
129     {
130         if ( store != null )
131         {
132             store.destroy();
133         }
134 
135         store = null;
136         if ( wkdir != null )
137         {
138             FileUtils.deleteDirectory( wkdir );
139         }
140 
141         wkdir = null;
142     }
143 
144     
145     @Test
146     public void testNestedAndnOr() throws Exception
147     {
148         String filter = "(|(&(cn=J*)(sn=w*))(ou=apache))";
149 
150         ExprNode exprNode = FilterParser.parse( filter );
151         optimizer.annotate( exprNode );
152         
153         IndexCursor<?,ServerEntry> cursor = cursorBuilder.build( exprNode );
154      
155         assertTrue( cursor.next() );
156         assertTrue( cursor.available() );
157         assertEquals( 5, ( long ) cursor.get().getId() );
158         assertEquals( "walker", cursor.get().getValue() );
159         
160         assertTrue( cursor.next() );
161         assertTrue( cursor.available() );
162         assertEquals( 7, ( long ) cursor.get().getId() );
163         assertEquals( "apache", cursor.get().getValue() );
164 
165         assertTrue( cursor.next() );
166         assertTrue( cursor.available() );
167         assertEquals( 9, ( long ) cursor.get().getId() );
168         assertEquals( "apache", cursor.get().getValue() );
169 
170         assertFalse( cursor.next() );
171     }
172     
173     
174     @Test
175     public void testNestedAndnNot() throws Exception
176     {
177         String filter = "(&(&(cn=Jo*)(sn=w*))(!(ou=apache)))";
178 
179         ExprNode exprNode = FilterParser.parse( filter );
180         optimizer.annotate( exprNode );
181         
182         IndexCursor<?,ServerEntry> cursor = cursorBuilder.build( exprNode );
183 
184         assertTrue( cursor.next() );
185         assertTrue( cursor.available() );
186         assertEquals( 5, ( long ) cursor.get().getId() );
187         assertEquals( "walker", cursor.get().getValue() );
188 
189         assertFalse( cursor.next() );
190     }
191     
192 
193     @Test
194     public void testNestedNotnOrnAnd() throws Exception
195     {
196         String filter = "(&(|(postalCode=5)(postalCode=6))(!(ou=sales)))";
197 
198         ExprNode exprNode = FilterParser.parse( filter );
199         optimizer.annotate( exprNode );
200         
201         IndexCursor<?,ServerEntry> cursor = cursorBuilder.build( exprNode );
202         
203         assertTrue( cursor.next() );
204         assertTrue( cursor.available() );
205         assertEquals( 7, ( long ) cursor.get().getId() );
206         assertEquals( "2.5.4.11=apache,2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
207         
208         assertTrue( cursor.next() );
209         assertTrue( cursor.available() );
210         assertEquals( 8, ( long ) cursor.get().getId() );
211         assertEquals( "2.5.4.3=jack daniels,2.5.4.11=engineering,2.5.4.10=good times co.", cursor.get().getValue() );
212         
213         assertFalse( cursor.next() );
214     }
215 
216     
217     @Test
218     public void testNestedOrnNot() throws Exception
219     {
220         String filter = "(!(|(|(cn=Jo*)(sn=w*))(!(ou=apache))))";
221 
222         ExprNode exprNode = FilterParser.parse( filter );
223         optimizer.annotate( exprNode );
224         
225         IndexCursor<?,ServerEntry> cursor = cursorBuilder.build( exprNode );
226     }
227 }