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 static org.junit.Assert.*;
24  
25  import java.io.File;
26  import java.util.HashSet;
27  import java.util.Set;
28  
29  import org.apache.commons.io.FileUtils;
30  import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
31  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
32  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmStore;
33  import org.apache.directory.server.core.entry.ServerEntry;
34  import org.apache.directory.server.schema.SerializableComparator;
35  import org.apache.directory.server.schema.bootstrap.ApacheSchema;
36  import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
37  import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
38  import org.apache.directory.server.schema.bootstrap.CollectiveSchema;
39  import org.apache.directory.server.schema.bootstrap.CoreSchema;
40  import org.apache.directory.server.schema.bootstrap.Schema;
41  import org.apache.directory.server.schema.bootstrap.SystemSchema;
42  import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
43  import org.apache.directory.server.schema.registries.DefaultOidRegistry;
44  import org.apache.directory.server.schema.registries.DefaultRegistries;
45  import org.apache.directory.server.schema.registries.OidRegistry;
46  import org.apache.directory.server.schema.registries.Registries;
47  import org.apache.directory.server.xdbm.ForwardIndexEntry;
48  import org.apache.directory.server.xdbm.Store;
49  import org.apache.directory.server.xdbm.IndexCursor;
50  import org.apache.directory.server.xdbm.search.Evaluator;
51  import org.apache.directory.server.xdbm.tools.StoreUtils;
52  import org.apache.directory.shared.ldap.constants.SchemaConstants;
53  import org.apache.directory.shared.ldap.filter.ExprNode;
54  import org.apache.directory.shared.ldap.filter.FilterParser;
55  import org.apache.directory.shared.ldap.filter.NotNode;
56  import org.apache.directory.shared.ldap.filter.SubstringNode;
57  import org.junit.*;
58  import org.slf4j.Logger;
59  import org.slf4j.LoggerFactory;
60  
61  
62  /**
63   * 
64   * Test cases for NotCursor.
65   *
66   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
67   * @version $Rev$, $Date$
68   */
69  public class NotCursorTest
70  {
71      private static final Logger LOG = LoggerFactory.getLogger( NotCursorTest.class.getSimpleName() );
72  
73      File wkdir;
74      Store<ServerEntry> store;
75      Registries registries = null;
76      AttributeTypeRegistry attributeRegistry;
77      EvaluatorBuilder evaluatorBuilder;
78      CursorBuilder cursorBuilder;
79  
80      public NotCursorTest() throws Exception
81      {
82          // setup the standard registries
83          BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
84          OidRegistry oidRegistry = new DefaultOidRegistry();
85          registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
86          SerializableComparator.setRegistry( registries.getComparatorRegistry() );
87  
88          // load essential bootstrap schemas
89          Set<Schema> bootstrapSchemas = new HashSet<Schema>();
90          bootstrapSchemas.add( new ApachemetaSchema() );
91          bootstrapSchemas.add( new ApacheSchema() );
92          bootstrapSchemas.add( new CoreSchema() );
93          bootstrapSchemas.add( new SystemSchema() );
94          bootstrapSchemas.add( new CollectiveSchema() );
95          loader.loadWithDependencies( bootstrapSchemas, registries );
96          attributeRegistry = registries.getAttributeTypeRegistry();
97      }
98  
99  
100     @Before
101     public void createStore() throws Exception
102     {
103         destryStore();
104 
105         // setup the working directory for the store
106         wkdir = File.createTempFile( getClass().getSimpleName(), "db" );
107         wkdir.delete();
108         wkdir = new File( wkdir.getParentFile(), getClass().getSimpleName() );
109         wkdir.mkdirs();
110 
111         // initialize the store
112         store = new JdbmStore<ServerEntry>();
113         store.setName( "example" );
114         store.setCacheSize( 10 );
115         store.setWorkingDirectory( wkdir );
116         store.setSyncOnWrite( false );
117 
118         store.addIndex( new JdbmIndex( SchemaConstants.OU_AT_OID ) );
119         store.addIndex( new JdbmIndex( SchemaConstants.CN_AT_OID ) );
120         StoreUtils.loadExampleData( store, registries );
121         
122         evaluatorBuilder = new EvaluatorBuilder( store, registries );
123         cursorBuilder = new CursorBuilder( store, evaluatorBuilder );
124         
125         LOG.debug( "Created new store" );
126     }
127 
128     
129     @After
130     public void destryStore() throws Exception
131     {
132         if ( store != null )
133         {
134             store.destroy();
135         }
136 
137         store = null;
138         if ( wkdir != null )
139         {
140             FileUtils.deleteDirectory( wkdir );
141         }
142 
143         wkdir = null;
144     }
145 
146     
147     @Test
148     public void testNotCursor() throws Exception
149     {
150         String filter = "(!(cn=J*))";
151 
152         ExprNode exprNode = FilterParser.parse( filter );
153         
154         IndexCursor<?, ServerEntry> cursor = cursorBuilder.build( exprNode );
155         
156         assertFalse( cursor.available() );
157         
158         cursor.beforeFirst();
159         
160         assertTrue( cursor.next() );
161         assertTrue( cursor.available() );
162         assertEquals( 1, ( long ) cursor.get().getId() );
163         assertEquals( "2.5.4.10=good times co.", cursor.get().getValue() );
164         
165         assertTrue( cursor.next() );
166         assertTrue( cursor.available() );
167         assertEquals( 7, ( long ) cursor.get().getId() );
168         assertEquals( "2.5.4.11=apache,2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
169         
170         assertTrue( cursor.next() );
171         assertTrue( cursor.available() );
172         assertEquals( 3, ( long ) cursor.get().getId() );
173         assertEquals( "2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
174         
175         assertTrue( cursor.next() );
176         assertTrue( cursor.available() );
177         assertEquals( 4, ( long ) cursor.get().getId() );
178         assertEquals( "2.5.4.11=engineering,2.5.4.10=good times co.", cursor.get().getValue() );
179         
180         assertTrue( cursor.next() );
181         assertTrue( cursor.available() );
182         assertEquals( 2, ( long ) cursor.get().getId() );
183         assertEquals( "2.5.4.11=sales,2.5.4.10=good times co.", cursor.get().getValue() );
184         
185         assertFalse( cursor.next() );
186         assertFalse( cursor.available() );
187         
188         cursor.close();
189         assertTrue( cursor.isClosed() );
190     }
191     
192     
193     @Test
194     public void testNotCursorWithManualFilter() throws Exception
195     {
196         NotNode notNode = new NotNode();
197         
198         ExprNode exprNode = new SubstringNode( "cn", "J", null );
199         Evaluator<? extends ExprNode, ServerEntry> eval = new SubstringEvaluator( ( SubstringNode ) exprNode, store, registries );
200         notNode.addNode( exprNode );
201         
202         NotCursor cursor = new NotCursor( store, eval ); //cursorBuilder.build( andNode );
203         
204         assertTrue( cursor.next() );
205         assertTrue( cursor.available() );
206         assertEquals( 1, ( long ) cursor.get().getId() );
207         assertEquals( "2.5.4.10=good times co.", cursor.get().getValue() );
208         
209         cursor.first();
210         
211         assertTrue( cursor.next() );
212         assertTrue( cursor.available() );
213         assertEquals( 7, ( long ) cursor.get().getId() );
214         assertEquals( "2.5.4.11=apache,2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
215         
216         assertTrue( cursor.next() );
217         assertTrue( cursor.available() );
218         assertEquals( 3, ( long ) cursor.get().getId() );
219         assertEquals( "2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
220         
221         assertTrue( cursor.next() );
222         assertTrue( cursor.available() );
223         assertEquals( 4, ( long ) cursor.get().getId() );
224         assertEquals( "2.5.4.11=engineering,2.5.4.10=good times co.", cursor.get().getValue() );
225         
226         assertTrue( cursor.next() );
227         assertTrue( cursor.available() );
228         assertEquals( 2, ( long ) cursor.get().getId() );
229         assertEquals( "2.5.4.11=sales,2.5.4.10=good times co.", cursor.get().getValue() );
230         
231         assertFalse( cursor.next() );
232         assertFalse( cursor.available() );
233 
234         cursor.afterLast();
235         
236         assertTrue( cursor.previous() );
237         assertTrue( cursor.available() );
238         assertEquals( 2, ( long ) cursor.get().getId() );
239         assertEquals( "2.5.4.11=sales,2.5.4.10=good times co.", cursor.get().getValue() );
240         
241         cursor.last();
242         assertTrue( cursor.previous() );
243         assertTrue( cursor.available() );
244         assertEquals( 4, ( long ) cursor.get().getId() );
245         assertEquals( "2.5.4.11=engineering,2.5.4.10=good times co.", cursor.get().getValue() );
246         
247         assertTrue( cursor.previous() );
248         assertTrue( cursor.available() );
249         assertEquals( 3, ( long ) cursor.get().getId() );
250         assertEquals( "2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
251         
252         assertTrue( cursor.previous() );
253         assertTrue( cursor.available() );
254         assertEquals( 7, ( long ) cursor.get().getId() );
255         assertEquals( "2.5.4.11=apache,2.5.4.11=board of directors,2.5.4.10=good times co.", cursor.get().getValue() );
256         
257         assertTrue( cursor.previous() );
258         assertTrue( cursor.available() );
259         assertEquals( 1, ( long ) cursor.get().getId() );
260         assertEquals( "2.5.4.10=good times co.", cursor.get().getValue() );
261         
262         assertFalse( cursor.previous() );
263         assertFalse( cursor.available() );
264         
265         assertTrue( cursor.isElementReused() );
266  
267         try 
268         {
269             cursor.get();
270             fail( "should fail with InvalidCursorPositionException" );
271         }
272         catch( InvalidCursorPositionException ice ) { }
273         
274         try
275         {
276             cursor.after( new ForwardIndexEntry<Object,ServerEntry>() );
277             fail( "should fail with UnsupportedOperationException " );
278         }
279         catch( UnsupportedOperationException uoe ) {}
280         
281         try
282         {
283             cursor.before( new ForwardIndexEntry<Object,ServerEntry>() );
284             fail( "should fail with UnsupportedOperationException " );
285         }
286         catch( UnsupportedOperationException uoe ) {}
287     }
288 
289 }