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 java.io.File;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.Set;
027    
028    import org.apache.directory.shared.ldap.entry.Modification;
029    import org.apache.directory.shared.ldap.entry.ModificationOperation;
030    import org.apache.directory.shared.ldap.entry.ServerEntry;
031    import org.apache.directory.shared.ldap.name.DN;
032    import org.apache.directory.shared.ldap.name.RDN;
033    import org.apache.directory.shared.ldap.schema.SchemaManager;
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, ID>
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         * Sets the working directory for the store
092         */
093        void setWorkingDirectory( File workingDirectory );
094    
095    
096        /**
097         * @return The current working directory for the store
098         */
099        File getWorkingDirectory();
100    
101    
102        /**
103         * Stores the list of user index
104         * @param userIndices The list of user index
105         */
106        void setUserIndices( Set<Index<?, E, ID>> userIndices );
107    
108    
109        /**
110         * @return The list of user index
111         */
112        Set<Index<?, E, ID>> getUserIndices();
113    
114    
115        void setSuffixDn( String suffixDn );
116    
117    
118        String getSuffixDn();
119    
120    
121        /**
122         * Sets the flag telling the server to flush on disk when some
123         * modification has been done.
124         * @param isSyncOnWrite A boolean set to true if we have to flush on disk 
125         * when a modification occurs
126         */
127        void setSyncOnWrite( boolean isSyncOnWrite );
128    
129    
130        /**
131         * @return <code>true</code> if we write to disk for every modification 
132         */
133        boolean isSyncOnWrite();
134    
135    
136        /**
137         * Sets the cache size for this store
138         * @param cacheSize The cache size
139         */
140        void setCacheSize( int cacheSize );
141    
142    
143        /**
144         * @return The cache size
145         */
146        int getCacheSize();
147    
148    
149        /**
150         * Sets the store's name
151         * @param name The store's name
152         */
153        void setName( String name );
154    
155    
156        /**
157         * @return The store's name
158         */
159        String getName();
160    
161    
162        /**
163         * Initialize the JDBM storage system.
164         *
165         * @param schemaManager the schema schemaManager
166         * @throws Exception on failure to lookup elements in schemaManager
167         * @throws Exception on failure to create database files
168         */
169        void init( SchemaManager schemaManager ) throws Exception;
170    
171    
172        /**
173         * Close the parttion : we have to close all the userIndices and the master table.
174         *
175         * @throws Exception lazily thrown on any closer failures to avoid leaving
176         * open files
177         */
178        void destroy() throws Exception;
179    
180    
181        /**
182         * Gets whether the store is initialized.
183         *
184         * @return true if the partition store is initialized
185         */
186        boolean isInitialized();
187    
188    
189        /**
190         * This method is called when the synch thread is waking up, to write
191         * the modified data.
192         *
193         * @throws Exception on failures to sync database files to disk
194         */
195        void sync() throws Exception;
196    
197    
198        /**
199         * Adds a user index to the list of index for this store
200         * @param index The index to add
201         * @throws Exception If the addition failed
202         */
203        void addIndex( Index<?, E, ID> index ) throws Exception;
204    
205    
206        //------------------------------------------------------------------------
207        // System index
208        //------------------------------------------------------------------------
209        /**
210         * @return The Presence system index
211         */
212        Index<String, E, ID> getPresenceIndex();
213    
214    
215        /**
216         * Set the Presence index
217         * @param index The Presence index
218         * @throws Exception If the addition failed
219         */
220        void setPresenceIndex( Index<String, E, ID> index ) throws Exception;
221    
222    
223        /**
224         * @return The OneLevel system index
225         */
226        Index<ID, E, ID> getOneLevelIndex();
227    
228    
229        /**
230         * Set the OneLevel index
231         * @param index The OneLevel index
232         * @throws Exception If the addition failed
233         */
234        void setOneLevelIndex( Index<ID, E, ID> index ) throws Exception;
235    
236    
237        /**
238         * @return The SubLevel system index
239         */
240        Index<ID, E, ID> getSubLevelIndex();
241    
242    
243        /**
244         * Set the SubLevel index
245         * @param index The SubLevel index
246         * @throws Exception If the addition failed
247         */
248        void setSubLevelIndex( Index<ID, E, ID> index ) throws Exception;
249    
250    
251        /**
252         * @return The Alias system index
253         */
254        Index<String, E, ID> getAliasIndex();
255    
256    
257        /**
258         * Set the Alias index
259         * @param index The Alias index
260         * @throws Exception If the addition failed
261         */
262        void setAliasIndex( Index<String, E, ID> index ) throws Exception;
263    
264    
265        /**
266         * @return The OneAlias system index
267         */
268        Index<ID, E, ID> getOneAliasIndex();
269    
270    
271        /**
272         * Set the OneAlias index
273         * @param index The OneAlias index
274         * @throws Exception If the addition failed
275         */
276        void setOneAliasIndex( Index<ID, E, ID> index ) throws Exception;
277    
278    
279        /**
280         * @return The SubAlias system index
281         */
282        Index<ID, E, ID> getSubAliasIndex();
283    
284    
285        /**
286         * Set the SubAlias index
287         * @param index The SubAlias index
288         * @throws Exception If the addition failed
289         */
290        void setSubAliasIndex( Index<ID, E, ID> index ) throws Exception;
291    
292    
293        /**
294         * @return The UpDN system index
295         */
296        Index<String, E, ID> getUpdnIndex();
297    
298    
299        /**
300         * Set the UpDn index
301         * @param index The UpDn index
302         * @throws Exception If the addition failed
303         */
304        void setUpdnIndex( Index<String, E, ID> index ) throws Exception;
305    
306    
307        /**
308         * @return The Ndn system index
309         */
310        Index<String, E, ID> getNdnIndex();
311    
312    
313        /**
314         * Set the NDN index
315         * @param index The NDN index
316         * @throws Exception If the addition failed
317         */
318        void setNdnIndex( Index<String, E, ID> index ) throws Exception;
319    
320    
321        /**
322         * @return The ObjectClass system index
323         */
324        Index<String, E, ID> getObjectClassIndex();
325    
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, ID> index ) throws Exception;
333    
334    
335        /**
336         * @return The EntryUUID system index
337         */
338        Index<String, E, ID> getEntryUuidIndex();
339    
340    
341        /**
342         * Set the EntryUUID index
343         * @param index The EntryUUID index
344         * @throws Exception If the addition failed
345         */
346        void setEntryUuidIndex( Index<String, E, ID> index ) throws Exception;
347    
348    
349        /**
350         * @return The EntryCSN system index
351         */
352        Index<String, E, ID> getEntryCsnIndex();
353    
354    
355        /**
356         * Set the EntryCSN index
357         * @param index The EntryCSN index
358         * @throws Exception If the addition failed
359         */
360        void setEntryCsnIndex( Index<String, E, ID> index ) throws Exception;
361    
362    
363        //------------------------------------------------------------------------
364        // End of the system index
365        //------------------------------------------------------------------------
366    
367        /**
368         * An iterator build on top of the User's index
369         */
370        Iterator<String> userIndices();
371    
372    
373        /**
374         * An iterator build on top of the System's index
375         */
376        Iterator<String> systemIndices();
377    
378    
379        /**
380         * Tells if an index is already present in the User's <strong>or</strong> System's index list
381         * @param id The index we are looking for
382         * @return <code>true</code> if the index is already present in the
383         * User's <strong>or</strong> System's index list 
384         * @throws Exception If something went wrong
385         */
386        boolean hasIndexOn( String id ) throws Exception;
387    
388    
389        /**
390         * Tells if an index is already present in the User's index list
391         * @param id The index we are looking for
392         * @return <code>true</code> if the index is already present in the
393         * User's index list 
394         * @throws Exception If something went wrong
395         */
396        boolean hasUserIndexOn( String id ) throws Exception;
397    
398    
399        /**
400         * Tells if an index is already present in the System's index list
401         * @param id The index we are looking for
402         * @return <code>true</code> if the index is already present in the
403         * System's index list 
404         * @throws Exception If something went wrong
405         */
406        boolean hasSystemIndexOn( String id ) throws Exception;
407    
408    
409        /**
410         * Get the user <strong>or</strong> system index associated with the given name
411         * @param id The index name we are looking for
412         * @return The associated user <strong>or</strong> system index
413         * @throws IndexNotFoundException If the index does not exist
414         */
415        Index<?, E, ID> getIndex( String id ) throws IndexNotFoundException;
416    
417    
418        /**
419         * Get the user index associated with the given name
420         * @param id The index name we are looking for
421         * @return The associated user index
422         * @throws IndexNotFoundException If the index does not exist
423         */
424        Index<?, E, ID> getUserIndex( String id ) throws IndexNotFoundException;
425    
426    
427        /**
428         * Get the system index associated with the given name
429         * @param id The index name we are looking for
430         * @return The associated system index
431         * @throws IndexNotFoundException If the index does not exist
432         */
433        Index<?, E, ID> getSystemIndex( String id ) throws IndexNotFoundException;
434    
435    
436        ID getEntryId( String dn ) throws Exception;
437    
438    
439        String getEntryDn( ID id ) throws Exception;
440    
441    
442        /**
443         * Gets the Long id of an entry's parent using the child entry's
444         * normalized dn. Note that the suffix entry returns 0, which does not
445         * map to any entry.
446         *
447         * @param dn the normalized distinguished name of the child
448         * @return the id of the parent entry or zero if the suffix entry the
449         * normalized suffix dn string is used
450         * @throws Exception on failures to access the underlying store
451         */
452        ID getParentId( String dn ) throws Exception;
453    
454    
455        ID getParentId( ID childId ) throws Exception;
456    
457    
458        String getEntryUpdn( ID id ) throws Exception;
459    
460    
461        String getEntryUpdn( String dn ) throws Exception;
462    
463    
464        int count() throws Exception;
465    
466    
467        /**
468         * Add an entry into the store. 
469         * 
470         * @param entry The entry to add
471         * 
472         * @throws Exception If the addition failed.
473         */
474        void add( ServerEntry entry ) throws Exception;
475    
476    
477        ServerEntry lookup( ID id ) throws Exception;
478    
479    
480        /**
481         * Delete the entry associated with a given Id
482         * @param id The id of the entry to delete
483         * @throws Exception If the deletion failed
484         */
485        void delete( ID id ) throws Exception;
486    
487    
488        /**
489         * Gets an IndexEntry Cursor over the child nodes of an entry.
490         *
491         * @param id the id of the parent entry
492         * @return an IndexEntry Cursor over the child entries
493         * @throws Exception on failures to access the underlying store
494         */
495        IndexCursor<ID, E, ID> list( ID id ) throws Exception;
496    
497    
498        int getChildCount( ID id ) throws Exception;
499    
500    
501        DN getSuffix();
502    
503    
504        DN getUpSuffix();
505    
506    
507        void setProperty( String propertyName, String propertyValue ) throws Exception;
508    
509    
510        String getProperty( String propertyName ) throws Exception;
511    
512    
513        void modify( DN dn, ModificationOperation modOp, ServerEntry mods ) throws Exception;
514    
515    
516        void modify( DN dn, List<Modification> mods ) throws Exception;
517    
518    
519        /**
520         * Changes the relative distinguished name of an entry specified by a
521         * distinguished name with the optional removal of the old RDN attribute
522         * value from the entry.  Name changes propagate down as dn changes to the
523         * descendants of the entry where the RDN changed.
524         *
525         * An RDN change operation does not change parent child relationships.  It
526         * merely propagates a name change at a point in the DIT where the RDN is
527         * changed. The change propagates down the subtree rooted at the
528         * distinguished name specified.
529         *
530         * @param dn the normalized distinguished name of the entry to alter
531         * @param newRdn the new RDN to set
532         * @param deleteOldRdn whether or not to remove the old RDN attr/val
533         * @throws Exception if there are any errors propagating the name changes
534         */
535        void rename( DN dn, RDN newRdn, boolean deleteOldRdn ) throws Exception;
536    
537    
538        void move( DN oldChildDn, DN newParentDn, RDN newRdn, boolean deleteOldRdn ) throws Exception;
539    
540    
541        void move( DN oldChildDn, DN newParentDn ) throws Exception;
542    
543    
544        /**
545         * Gets the default ID.
546         *
547         * @return the default ID.
548         */
549        ID getDefaultId() throws Exception;
550    }