001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.server.xdbm;
021    
022    
023    import org.apache.directory.server.schema.registries.Registries;
024    import org.apache.directory.server.core.entry.ServerEntry;
025    import org.apache.directory.shared.ldap.name.LdapDN;
026    import org.apache.directory.shared.ldap.name.Rdn;
027    import org.apache.directory.shared.ldap.entry.ModificationOperation;
028    import org.apache.directory.shared.ldap.entry.Modification;
029    
030    import java.io.File;
031    import java.util.Set;
032    import java.util.Iterator;
033    import java.util.List;
034    
035    
036    /**
037     * Represents an entry store based on the Table, Index, and MasterTable
038     * database structure.
039     *
040     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041     * @version $$Rev$$
042     */
043    public interface Store<E>
044    {
045        /*
046         * W H Y   H A V E   A   S T O R E   I N T E R F A C E  ?
047         * ------------------------------------------------------
048         *
049         * Some may question why we have this Store interface when the Partition
050         * interface abstracts away partition implementation details in the server
051         * core.  This is due to a complicated chicken and egg problem with the
052         * additional need to abstract stores for the SearchEngine.  This way the
053         * SearchEngine and it's default implementation can be independent of the
054         * Partition interface.  Once this is achieved the default SearchEngine
055         * implementation can be removed from the core.  This will allow for
056         * better modularization, with the ability to easily substitute new
057         * SearchEngine implementations into ApacheDS.
058         *
059         *
060         * H I S T O R Y
061         * -------------
062         *
063         * Originally the JdbmStore class came about due to a cyclic dependency.
064         * The bootstrap-partition module is created by the bootstrap-plugin
065         * module.  The core depends on the bootstrap-partition module to
066         * bootstrap the server.  The bootstrap-partition module depends on the
067         * bootstrap-plugin which builds a JdbmStore stuffing it with all the
068         * information needed for the server to bootstrap.  The bootstrap-plugin
069         * hence must be built before it can generate the bootstrap-partition and
070         * it cannot have a dependency on the core.  We could not use the
071         * JdbmPartition because it depends on the Partition interface and this
072         * is an integral part of the core.  If we did then there would be a
073         * cyclic dependency between modules in the apacheds pom.  To avoid this
074         * the JdbmStore class was created and the guts of the JDBM partition were
075         * put into the jdbm-store module.  This jdbm-store module does not depend
076         * on core and can be used by the bootstrap-plugin to build the
077         * bootstrap-partition.
078         *
079         * Hence it's project dependencies that drove the creation of the
080         * JdbmStore class.  Later we realized, the default SeachEngine used by
081         * all Table, Index, MasterTable scheme based partitions depends on
082         * BTreePartition which depends on Partition.  We would like to remove
083         * this search engine out of the core so it can easily be swapped out,
084         * but most importantly so we can have the search depend on any kind of
085         * store.  There's no reason why the SearchEngine should depend on a
086         * Partition (store with search capabilities) when it just needs a simple
087         * store and it's indices to conduct search operations.
088         */
089    
090    
091        /**
092         * Sets the working directory for the store
093         */
094        void setWorkingDirectory( File workingDirectory );
095    
096    
097        /**
098         * @return The current working directory for the store
099         */
100        File getWorkingDirectory();
101    
102    
103        /**
104         * Stores the list of user index
105         * @param userIndices The list of user index
106         */
107        void setUserIndices( Set<Index<?,E>> userIndices );
108    
109    
110        /**
111         * @return The list of user index
112         */
113        Set<Index<?,E>> getUserIndices();
114    
115    
116        void setSuffixDn( String suffixDn );
117    
118    
119        String getSuffixDn();
120    
121    
122        /**
123         * Sets the flag telling the server to flush on disk when some
124         * modification has been done.
125         * @param isSyncOnWrite A boolean set to true if we have to flush on disk 
126         * when a modification occurs
127         */
128        void setSyncOnWrite( boolean isSyncOnWrite );
129    
130    
131        /**
132         * @return <code>true</code> if we write to disk for every modification 
133         */
134        boolean isSyncOnWrite();
135    
136    
137        /**
138         * Sets the cache size for this store
139         * @param cacheSize The cache size
140         */
141        void setCacheSize( int cacheSize );
142    
143    
144        /**
145         * @return The cache size
146         */
147        int getCacheSize();
148    
149    
150        /**
151         * Sets the store's name
152         * @param name The store's name
153         */
154        void setName( String name );
155    
156    
157        /**
158         * @return The store's name
159         */
160        String getName();
161    
162    
163        /**
164         * Initialize the JDBM storage system.
165         *
166         * @param registries the schema registries
167         * @throws Exception on failure to lookup elements in registries
168         * @throws Exception on failure to create database files
169         */
170        void init( Registries registries ) throws Exception;
171    
172    
173        /**
174         * Close the parttion : we have to close all the userIndices and the master table.
175         *
176         * @throws Exception lazily thrown on any closer failures to avoid leaving
177         * open files
178         */
179        void destroy() throws Exception;
180    
181    
182        /**
183         * Gets whether the store is initialized.
184         *
185         * @return true if the partition store is initialized
186         */
187        boolean isInitialized();
188    
189    
190        /**
191         * This method is called when the synch thread is waking up, to write
192         * the modified data.
193         *
194         * @throws Exception on failures to sync database files to disk
195         */
196        void sync() throws Exception;
197    
198    
199        /**
200         * Adds a user index to the list of index for this store
201         * @param index The index to add
202         * @throws Exception If the addition failed
203         */
204        void addIndex( Index<?,E> index ) throws Exception;
205    
206    
207        //------------------------------------------------------------------------
208        // System index
209        //------------------------------------------------------------------------
210        /**
211         * @return The Presence system index
212         */
213        Index<String,E> getPresenceIndex();
214    
215    
216        /**
217         * Set the Presence index
218         * @param index The Presence index
219         * @throws Exception If the addition failed
220         */
221        void setPresenceIndex( Index<String,E> index ) throws Exception;
222    
223    
224        /**
225         * @return The OneLevel system index
226         */
227        Index<Long,E> getOneLevelIndex();
228    
229    
230        /**
231         * Set the OneLevel index
232         * @param index The OneLevel index
233         * @throws Exception If the addition failed
234         */
235        void setOneLevelIndex( Index<Long,E> index ) throws Exception;
236    
237    
238        /**
239         * @return The SubLevel system index
240         */
241        Index<Long,E> getSubLevelIndex();
242    
243    
244        /**
245         * Set the SubLevel index
246         * @param index The SubLevel index
247         * @throws Exception If the addition failed
248         */
249        void setSubLevelIndex( Index<Long,E> index ) throws Exception;
250    
251    
252        /**
253         * @return The Alias system index
254         */
255        Index<String,E> getAliasIndex();
256    
257    
258        /**
259         * Set the Alias index
260         * @param index The Alias index
261         * @throws Exception If the addition failed
262         */
263        void setAliasIndex( Index<String,E> index ) throws Exception;
264    
265    
266        /**
267         * @return The OneAlias system index
268         */
269        Index<Long,E> getOneAliasIndex();
270    
271    
272        /**
273         * Set the OneAlias index
274         * @param index The OneAlias index
275         * @throws Exception If the addition failed
276         */
277        void setOneAliasIndex( Index<Long,E> index ) throws Exception;
278    
279    
280        /**
281         * @return The SubAlias system index
282         */
283        Index<Long,E> getSubAliasIndex();
284    
285    
286        /**
287         * Set the SubAlias index
288         * @param index The SubAlias index
289         * @throws Exception If the addition failed
290         */
291        void setSubAliasIndex( Index<Long,E> index ) throws Exception;
292    
293    
294        /**
295         * @return The UpDN system index
296         */
297        Index<String,E> getUpdnIndex();
298    
299    
300        /**
301         * Set the UpDn index
302         * @param index The UpDn index
303         * @throws Exception If the addition failed
304         */
305        void setUpdnIndex( Index<String,E> index ) throws Exception;
306    
307    
308        /**
309         * @return The Ndn system index
310         */
311        Index<String,E> getNdnIndex();
312    
313    
314        /**
315         * Set the NDN index
316         * @param index The NDN index
317         * @throws Exception If the addition failed
318         */
319        void setNdnIndex( Index<String,E> index ) throws Exception;
320    
321    
322        /**
323         * @return The ObjectClass system index
324         */
325        Index<String,E> getObjectClassIndex();
326    
327        /**
328         * Set the ObjectClass index
329         * @param index The ObjectClass index
330         * @throws Exception If the addition failed
331         */
332        void setObjectClassIndex( Index<String,E> index ) throws Exception;
333    
334        
335        /**
336         * @return The EntryUUID system index
337         */
338        Index<byte[],E> getEntryUuidIndex();
339    
340        /**
341         * Set the EntryUUID index
342         * @param index The EntryUUID index
343         * @throws Exception If the addition failed
344         */
345        void setEntryUuidIndex( Index<byte[],E> index ) throws Exception;
346    
347        
348        /**
349         * @return The EntryCSN system index
350         */
351        Index<String,E> getEntryCsnIndex();
352    
353        /**
354         * Set the EntryCSN index
355         * @param index The EntryCSN index
356         * @throws Exception If the addition failed
357         */
358        void setEntryCsnIndex( Index<String,E> index ) throws Exception;
359    
360        //------------------------------------------------------------------------
361        // End of the system index
362        //------------------------------------------------------------------------
363        
364        /**
365         * An iterator build on top of the User's index
366         */
367        Iterator<String> userIndices();
368    
369    
370        /**
371         * An iterator build on top of the System's index
372         */
373        Iterator<String> systemIndices();
374    
375    
376        /**
377         * Tells if an index is already present in the User's index list
378         * @param id The index we are looking for
379         * @return <code>true</code> if the index is already present in the
380         * User's index list 
381         * @throws Exception If something went wrong
382         */
383        boolean hasUserIndexOn( String id ) throws Exception;
384    
385    
386        /**
387         * Tells if an index is already present in the System's index list
388         * @param id The index we are looking for
389         * @return <code>true</code> if the index is already present in the
390         * System's index list 
391         * @throws Exception If something went wrong
392         */
393        boolean hasSystemIndexOn( String id ) throws Exception;
394    
395    
396        /**
397         * Get the user index associated with the given name
398         * @param id The index name we are looking for
399         * @return The associated user index
400         * @throws IndexNotFoundException If the index does not exist
401         */
402        Index<?,E> getUserIndex( String id ) throws IndexNotFoundException;
403    
404    
405        /**
406         * Get the user index associated with the given name
407         * @param id The index name we are looking for
408         * @return The associated user index
409         * @throws IndexNotFoundException If the index does not exist
410         */
411        Index<?,E> getSystemIndex( String id ) throws IndexNotFoundException;
412    
413    
414        Long getEntryId( String dn ) throws Exception;
415    
416    
417        String getEntryDn( Long id ) throws Exception;
418    
419    
420        /**
421         * Gets the Long id of an entry's parent using the child entry's
422         * normalized dn. Note that the suffix entry returns 0, which does not
423         * map to any entry.
424         *
425         * @param dn the normalized distinguished name of the child
426         * @return the id of the parent entry or zero if the suffix entry the
427         * normalized suffix dn string is used
428         * @throws Exception on failures to access the underlying store
429         */
430        Long getParentId( String dn ) throws Exception;
431    
432    
433        Long getParentId( Long childId ) throws Exception;
434    
435    
436        String getEntryUpdn( Long id ) throws Exception;
437    
438    
439        String getEntryUpdn( String dn ) throws Exception;
440    
441    
442        int count() throws Exception;
443    
444    
445        /**
446         * Add an entry into the store. 
447         * 
448         * @param entry The entry to add
449         * 
450         * @throws Exception If the addition failed.
451         */
452        void add( ServerEntry entry ) throws Exception;
453    
454    
455        ServerEntry lookup( Long id ) throws Exception;
456    
457    
458        /**
459         * Delete the entry associated with a given Id
460         * @param id The id of the entry to delete
461         * @throws Exception If the deletion failed
462         */
463        void delete( Long id ) throws Exception;
464    
465    
466        /**
467         * Gets an IndexEntry Cursor over the child nodes of an entry.
468         *
469         * @param id the id of the parent entry
470         * @return an IndexEntry Cursor over the child entries
471         * @throws Exception on failures to access the underlying store
472         */
473        IndexCursor<Long,E> list( Long id ) throws Exception;
474    
475    
476        int getChildCount( Long id ) throws Exception;
477    
478    
479        LdapDN getSuffix();
480    
481    
482        LdapDN getUpSuffix();
483    
484    
485        void setProperty( String propertyName, String propertyValue ) throws Exception;
486    
487    
488        String getProperty( String propertyName ) throws Exception;
489    
490    
491        void modify( LdapDN dn, ModificationOperation modOp, ServerEntry mods ) throws Exception;
492    
493    
494        void modify( LdapDN dn, List<Modification> mods ) throws Exception;
495    
496    
497        /**
498         * Changes the relative distinguished name of an entry specified by a
499         * distinguished name with the optional removal of the old Rdn attribute
500         * value from the entry.  Name changes propagate down as dn changes to the
501         * descendants of the entry where the Rdn changed.
502         *
503         * An Rdn change operation does not change parent child relationships.  It
504         * merely propagates a name change at a point in the DIT where the Rdn is
505         * changed. The change propagates down the subtree rooted at the
506         * distinguished name specified.
507         *
508         * @param dn the normalized distinguished name of the entry to alter
509         * @param newRdn the new Rdn to set
510         * @param deleteOldRdn whether or not to remove the old Rdn attr/val
511         * @throws Exception if there are any errors propagating the name changes
512         */
513        void rename( LdapDN dn, Rdn newRdn, boolean deleteOldRdn ) throws Exception;
514    
515    
516        void move( LdapDN oldChildDn, LdapDN newParentDn, Rdn newRdn, boolean deleteOldRdn ) throws Exception;
517    
518    
519        void move( LdapDN oldChildDn, LdapDN newParentDn ) throws Exception;
520    
521    
522        void initRegistries( Registries registries );
523    }