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 }