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 }