View Javadoc

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.core.partition.impl.btree.jdbm;
21  
22  
23  import org.apache.directory.server.core.DirectoryService;
24  import org.apache.directory.server.core.entry.ClonedServerEntry;
25  import org.apache.directory.server.core.entry.ServerEntry;
26  import org.apache.directory.server.core.interceptor.context.AddOperationContext;
27  import org.apache.directory.server.core.interceptor.context.BindOperationContext;
28  import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
29  import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
30  import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
31  import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
32  import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
33  import org.apache.directory.server.core.partition.Partition;
34  import org.apache.directory.server.core.partition.impl.btree.BTreePartition;
35  import org.apache.directory.server.xdbm.Index;
36  import org.apache.directory.server.xdbm.IndexCursor;
37  import org.apache.directory.server.xdbm.IndexNotFoundException;
38  import org.apache.directory.server.xdbm.Store;
39  import org.apache.directory.server.xdbm.search.impl.CursorBuilder;
40  import org.apache.directory.server.xdbm.search.impl.DefaultOptimizer;
41  import org.apache.directory.server.xdbm.search.impl.DefaultSearchEngine;
42  import org.apache.directory.server.xdbm.search.impl.EvaluatorBuilder;
43  import org.apache.directory.server.xdbm.search.impl.NoOpOptimizer;
44  import org.apache.directory.server.schema.registries.Registries;
45  import org.apache.directory.shared.ldap.exception.LdapAuthenticationNotSupportedException;
46  import org.apache.directory.shared.ldap.message.ResultCodeEnum;
47  import org.apache.directory.shared.ldap.name.LdapDN;
48  
49  import javax.naming.NamingException;
50  
51  import java.io.File;
52  import java.util.HashSet;
53  import java.util.Iterator;
54  import java.util.List;
55  import java.util.Set;
56  
57  
58  /**
59   * A {@link Partition} that stores entries in
60   * <a href="http://jdbm.sourceforge.net/">JDBM</a> database.
61   *
62   * @org.apache.xbean.XBean
63   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
64   * @version $Rev: 689396 $
65   */
66  public class JdbmPartition extends BTreePartition
67  {
68      private JdbmStore<ServerEntry> store;
69      private boolean optimizerEnabled = true;
70      private Set<Index<?,ServerEntry>> indexedAttributes;
71  
72      
73      // ------------------------------------------------------------------------
74      // C O N S T R U C T O R S
75      // ------------------------------------------------------------------------
76  
77  
78      /**
79       * Creates a store based on JDBM B+Trees.
80       */
81      public JdbmPartition()
82      {
83          store = new JdbmStore<ServerEntry>();
84          indexedAttributes = new HashSet<Index<?,ServerEntry>>();
85      }
86  
87  
88      // ------------------------------------------------------------------------
89      // C O N F I G U R A T I O N   M E T H O D S
90      // ------------------------------------------------------------------------
91  
92  
93      public String getSuffix()
94      {
95          return super.suffix;
96      }
97  
98  
99      public void setSuffix( String suffix )
100     {
101         super.suffix = suffix;
102     }
103 
104 
105     public void setIndexedAttributes( Set<Index<?,ServerEntry>> indexedAttributes )
106     {
107         this.indexedAttributes = indexedAttributes;
108     }
109 
110 
111     public Set<Index<?,ServerEntry>> getIndexedAttributes()
112     {
113         return indexedAttributes;
114     }
115 
116 
117     public boolean isOptimizerEnabled()
118     {
119         return optimizerEnabled;
120     }
121 
122 
123     public void setOptimizerEnabled( boolean optimizerEnabled )
124     {
125         this.optimizerEnabled = optimizerEnabled;
126     }
127 
128 
129     public void setSyncOnWrite( boolean syncOnWrite )
130     {
131         store.setSyncOnWrite( syncOnWrite );
132     }
133 
134 
135     public boolean isSyncOnWrite()
136     {
137         return store.isSyncOnWrite();
138     }
139 
140 
141     // ------------------------------------------------------------------------
142     // E N D   C O N F I G U R A T I O N   M E T H O D S
143     // ------------------------------------------------------------------------
144 
145 
146     public void setRegistries( Registries registries ) throws Exception
147     {
148         initRegistries( registries );
149     }
150 
151 
152     protected void initRegistries( Registries registries ) throws Exception
153     {
154         this.registries = registries;
155         store.initRegistries( registries );
156     }
157 
158 
159     @SuppressWarnings("unchecked")
160     public final void init( DirectoryService directoryService ) throws Exception
161     {
162         initRegistries( directoryService.getRegistries() );
163 
164         EvaluatorBuilder evaluatorBuilder = new EvaluatorBuilder( store, registries );
165         CursorBuilder cursorBuilder = new CursorBuilder( store, evaluatorBuilder );
166 
167         // setup optimizer and registries for parent
168         if ( ! optimizerEnabled )
169         {
170             optimizer = new NoOpOptimizer();
171         }
172         else
173         {
174             optimizer = new DefaultOptimizer<ServerEntry>( store );
175         }
176 
177         searchEngine = new DefaultSearchEngine( store, cursorBuilder, evaluatorBuilder, optimizer );
178         
179         // initialize the store
180         store.setCacheSize( cacheSize );
181         store.setName( id );
182         store.setSuffixDn( suffix );
183         store.setWorkingDirectory( new File( directoryService.getWorkingDirectory().getPath() + File.separator + id ) );
184 
185         Set<Index<?,ServerEntry>> userIndices = new HashSet<Index<?,ServerEntry>>();
186         
187         for ( Index<?,ServerEntry> obj : indexedAttributes )
188         {
189             Index<?,ServerEntry> index;
190 
191             if ( obj instanceof JdbmIndex )
192             {
193                 index = ( JdbmIndex<?,ServerEntry> ) obj;
194             }
195             else
196             {
197                 index = new JdbmIndex<Object,ServerEntry>();
198                 index.setAttributeId( obj.getAttributeId() );
199                 index.setCacheSize( obj.getCacheSize() );
200                 index.setWkDirPath( obj.getWkDirPath() );
201             }
202 
203             String oid = registries.getOidRegistry().getOid( index.getAttributeId() );
204             
205             if ( SYS_INDEX_OIDS.contains( registries.getOidRegistry().getOid( index.getAttributeId() ) ) )
206             {
207                 if ( oid.equals( Store.ALIAS ) )
208                 {
209                     store.setAliasIndex( ( Index<String,ServerEntry> ) index );
210                 }
211                 else if ( oid.equals( Store.PRESENCE ) )
212                 {
213                     store.setPresenceIndex( ( Index<String,ServerEntry> ) index );
214                 }
215                 else if ( oid.equals( Store.ONELEVEL ) )
216                 {
217                     store.setOneLevelIndex( ( Index<Long,ServerEntry> ) index );
218                 }
219                 else if ( oid.equals( Store.NDN ) )
220                 {
221                     store.setNdnIndex( ( Index<String,ServerEntry> ) index );
222                 }
223                 else if ( oid.equals( Store.ONEALIAS ) )
224                 {
225                     store.setOneAliasIndex( ( Index<Long,ServerEntry> ) index );
226                 }
227                 else if ( oid.equals( Store.SUBALIAS ) )
228                 {
229                     store.setSubAliasIndex( ( Index<Long,ServerEntry> ) index );
230                 }
231                 else if ( oid.equals( Store.UPDN ) )
232                 {
233                     store.setUpdnIndex( ( Index<String,ServerEntry> ) index );
234                 }
235                 else
236                 {
237                     throw new IllegalStateException( "Unrecognized system index " + oid );
238                 }
239             }
240             else
241             {
242                 userIndices.add( index );
243             }
244             
245             store.setUserIndices( userIndices );
246         }
247 
248         store.init( registries );
249     }
250 
251 
252     public final void destroy() throws Exception
253     {
254         store.destroy();
255     }
256 
257 
258     public final boolean isInitialized()
259     {
260         return store.isInitialized();
261     }
262 
263 
264     public final void sync() throws Exception
265     {
266         store.sync();
267     }
268 
269 
270     // ------------------------------------------------------------------------
271     // I N D E X   M E T H O D S
272     // ------------------------------------------------------------------------
273 
274 
275     public final void addIndexOn( Index<Long, ServerEntry> index ) throws Exception
276     {
277         store.addIndex( index );
278     }
279 
280 
281     public final Index<String, ServerEntry> getExistanceIndex()
282     {
283         return store.getPresenceIndex();
284     }
285 
286 
287     public final void setPresenceIndexOn( Index<String, ServerEntry> index ) throws Exception
288     {
289         store.setPresenceIndex( index );
290     }
291 
292 
293     public final Index<Long, ServerEntry> getOneLevelIndex()
294     {
295         return store.getOneLevelIndex();
296     }
297 
298 
299     public final void setOneLevelIndexOn( Index<Long, ServerEntry> index ) throws Exception
300     {
301         store.setOneLevelIndex( index );
302     }
303 
304 
305     public final Index<String, ServerEntry> getAliasIndex()
306     {
307         return store.getAliasIndex();
308     }
309 
310 
311     public final void setAliasIndexOn( Index<String, ServerEntry> index ) throws Exception
312     {
313         store.setAliasIndex( index );
314     }
315 
316 
317     public final Index<Long,ServerEntry> getOneAliasIndex()
318     {
319         return store.getOneAliasIndex();
320     }
321 
322 
323     public final void setOneAliasIndexOn( Index<Long,ServerEntry> index ) throws NamingException
324     {
325         store.setOneAliasIndex( ( Index<Long,ServerEntry> ) index );
326     }
327 
328 
329     public final Index<Long,ServerEntry> getSubAliasIndex()
330     {
331         return store.getSubAliasIndex();
332     }
333 
334 
335     public final void setSubAliasIndexOn( Index<Long,ServerEntry> index ) throws NamingException
336     {
337             store.setSubAliasIndex( ( Index<Long,ServerEntry> ) index );
338     }
339 
340 
341     public final Index<String,ServerEntry> getUpdnIndex()
342     {
343         return store.getUpdnIndex();
344     }
345 
346 
347     public final void setUpdnIndexOn( Index<String,ServerEntry> index ) throws NamingException
348     {
349         store.setUpdnIndex( ( Index<String,ServerEntry> ) index );
350     }
351 
352 
353     public final Index<String,ServerEntry> getNdnIndex()
354     {
355         return store.getNdnIndex();
356     }
357 
358 
359     public final void setNdnIndexOn( Index<String,ServerEntry> index ) throws NamingException
360     {
361         store.setNdnIndex( ( Index<String,ServerEntry> ) index );
362     }
363 
364 
365     public final Iterator<String> getUserIndices()
366     {
367         return store.userIndices();
368     }
369 
370 
371     public final Iterator<String> getSystemIndices()
372     {
373         return store.systemIndices();
374     }
375 
376 
377     public final boolean hasUserIndexOn( String id ) throws NamingException
378     {
379         return store.hasUserIndexOn( id );
380     }
381 
382 
383     public final boolean hasSystemIndexOn( String id ) throws NamingException
384     {
385         return store.hasSystemIndexOn( id );
386     }
387 
388 
389     /**
390      * @see org.apache.directory.server.core.partition.impl.btree.BTreePartition#getUserIndex(String)
391      */
392     public final Index<?,ServerEntry> getUserIndex( String id ) throws IndexNotFoundException
393     {
394         return store.getUserIndex( id );
395     }
396 
397 
398     /**
399      * @see BTreePartition#getEntryId(String)
400      */
401     public final Index<?,ServerEntry> getSystemIndex( String id ) throws IndexNotFoundException
402     {
403         return store.getSystemIndex( id );
404     }
405 
406 
407     public final Long getEntryId( String dn ) throws Exception
408     {
409         return store.getEntryId( dn );
410     }
411 
412 
413     public final String getEntryDn( Long id ) throws Exception
414     {
415         return store.getEntryDn( id );
416     }
417 
418 
419     public final Long getParentId( String dn ) throws Exception
420     {
421         return store.getParentId( dn );
422     }
423 
424 
425     public final Long getParentId( Long childId ) throws Exception
426     {
427         return store.getParentId( childId );
428     }
429 
430 
431     public final String getEntryUpdn( Long id ) throws Exception
432     {
433         return store.getEntryUpdn( id );
434     }
435 
436 
437     public final String getEntryUpdn( String dn ) throws Exception
438     {
439         return store.getEntryUpdn( dn );
440     }
441 
442 
443     public final int count() throws Exception
444     {
445         return store.count();
446     }
447 
448     
449     public final void add( AddOperationContext addContext ) throws Exception
450     {
451         store.add( addContext.getDn(), (ServerEntry)((ClonedServerEntry)addContext.getEntry()).getClonedEntry() );
452     }
453 
454 
455     public final ClonedServerEntry lookup( Long id ) throws Exception
456     {
457         return new ClonedServerEntry( store.lookup( id ) );
458     }
459 
460 
461     public final void delete( Long id ) throws Exception
462     {
463         store.delete( id );
464     }
465 
466 
467     public final IndexCursor<Long, ServerEntry> list( Long id ) throws Exception
468     {
469         return store.list( id );
470     }
471 
472 
473     public final int getChildCount( Long id ) throws Exception
474     {
475         return store.getChildCount( id );
476     }
477 
478 
479     public final LdapDN getSuffixDn()
480     {
481         return store.getSuffix();
482     }
483 
484     public final LdapDN getUpSuffixDn()
485     {
486         return store.getUpSuffix();
487     }
488 
489 
490     public final void setProperty( String propertyName, String propertyValue ) throws Exception
491     {
492         store.setProperty( propertyName, propertyValue );
493     }
494 
495 
496     public final String getProperty( String propertyName ) throws Exception
497     {
498         return store.getProperty( propertyName );
499     }
500 
501     
502     public final void modify( ModifyOperationContext modifyContext ) throws Exception
503     {
504         store.modify( modifyContext.getDn(), modifyContext.getModItems() );
505     }
506 
507     public final void rename( RenameOperationContext renameContext ) throws Exception
508     {
509         store.rename( renameContext.getDn(), renameContext.getNewRdn(), renameContext.getDelOldDn() );
510     }
511 
512 
513     public final void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws Exception
514     {
515         store.move( moveAndRenameContext.getDn(), 
516             moveAndRenameContext.getParent(), 
517             moveAndRenameContext.getNewRdn(), 
518             moveAndRenameContext.getDelOldDn() );
519     }
520 
521 
522     public final void move( MoveOperationContext moveContext ) throws Exception
523     {
524         store.move( moveContext.getDn(), moveContext.getParent() );
525     }
526 
527 
528     public final void bind( LdapDN bindDn, byte[] credentials, List<String> mechanisms, String saslAuthId ) throws Exception
529     {
530         if ( bindDn == null || credentials == null || mechanisms == null ||  saslAuthId == null )
531         {
532             // do nothing just using variables to prevent yellow lights : bad :)
533         }
534         
535         // does nothing
536         throw new LdapAuthenticationNotSupportedException(
537                 "Bind requests only tunnel down into partitions if there are no authenticators to handle the mechanism.\n"
538                         + "Check to see if you have correctly configured authenticators for the server.",
539                 ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
540     }
541     
542 
543     public final void bind( BindOperationContext bindContext ) throws Exception
544     {
545         // does nothing
546         throw new LdapAuthenticationNotSupportedException(
547             "Bind requests only tunnel down into partitions if there are no authenticators to handle the mechanism.\n"
548                 + "Check to see if you have correctly configured authenticators for the server.",
549             ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED );
550     }
551 
552 
553     public final void unbind( UnbindOperationContext unbindContext ) throws Exception
554     {
555     }
556 
557 
558     public Index<String, ServerEntry> getPresenceIndex()
559     {
560         return store.getPresenceIndex();
561     }
562 
563 
564     public Index<Long, ServerEntry> getSubLevelIndex()
565     {
566         return store.getSubLevelIndex();
567     }
568     
569     
570     /**
571      * @see Object#toString()
572      */
573     public String toString()
574     {
575         return "Partition<" + id + ">"; 
576     }
577 }