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.util.Iterator;
024 import java.util.List;
025
026 import org.apache.directory.server.core.entry.ClonedServerEntry;
027 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
028 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
029 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
030 import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
031 import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
032 import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
033 import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
034 import org.apache.directory.server.core.partition.impl.btree.BTreePartition;
035 import org.apache.directory.server.i18n.I18n;
036 import org.apache.directory.shared.ldap.entry.ServerEntry;
037 import org.apache.directory.shared.ldap.exception.LdapAuthenticationNotSupportedException;
038 import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
039 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
040 import org.apache.directory.shared.ldap.name.DN;
041 import org.apache.directory.shared.ldap.name.RDN;
042
043
044 /**
045 * Base class for XDBM partitions that use an {@link Store}.
046 *
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 * @version $Rev$, $Date$
049 */
050 public abstract class AbstractXdbmPartition<ID> extends BTreePartition<ID>
051 {
052
053 protected boolean optimizerEnabled = true;
054
055 /** The store. */
056 protected Store<ServerEntry, ID> store;
057
058
059 protected AbstractXdbmPartition( Store<ServerEntry, ID> store )
060 {
061 this.store = store;
062 }
063
064
065 /**
066 * {@inheritDoc}
067 */
068 protected void doDestroy() throws Exception
069 {
070 store.destroy();
071 }
072
073
074 /**
075 * {@inheritDoc}
076 */
077 public final boolean isInitialized()
078 {
079 return store.isInitialized();
080 }
081
082
083 /**
084 * {@inheritDoc}
085 */
086 public final void sync() throws Exception
087 {
088 store.sync();
089 }
090
091
092 // ------------------------------------------------------------------------
093 // C O N F I G U R A T I O N M E T H O D S
094 // ------------------------------------------------------------------------
095
096 public boolean isOptimizerEnabled()
097 {
098 return optimizerEnabled;
099 }
100
101
102 public void setOptimizerEnabled( boolean optimizerEnabled )
103 {
104 this.optimizerEnabled = optimizerEnabled;
105 }
106
107
108 public void setSyncOnWrite( boolean syncOnWrite )
109 {
110 store.setSyncOnWrite( syncOnWrite );
111 }
112
113
114 public boolean isSyncOnWrite()
115 {
116 return store.isSyncOnWrite();
117 }
118
119
120 // ------------------------------------------------------------------------
121 // I N D E X M E T H O D S
122 // ------------------------------------------------------------------------
123
124 public final void addIndexOn( Index<? extends Object, ServerEntry, ID> index ) throws Exception
125 {
126 store.addIndex( index );
127 }
128
129
130 public final Index<String, ServerEntry, ID> getExistenceIndex()
131 {
132 return store.getPresenceIndex();
133 }
134
135
136 /**
137 * @org.apache.xbean.Property hidden="true"
138 */
139 public final void setPresenceIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
140 {
141 store.setPresenceIndex( index );
142 }
143
144
145 public final Index<ID, ServerEntry, ID> getOneLevelIndex()
146 {
147 return store.getOneLevelIndex();
148 }
149
150
151 /**
152 * @org.apache.xbean.Property hidden="true"
153 */
154 public final void setOneLevelIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
155 {
156 store.setOneLevelIndex( index );
157 }
158
159
160 public final Index<String, ServerEntry, ID> getAliasIndex()
161 {
162 return store.getAliasIndex();
163 }
164
165
166 /**
167 * @org.apache.xbean.Property hidden="true"
168 */
169 public final void setAliasIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
170 {
171 store.setAliasIndex( index );
172 }
173
174
175 public final Index<ID, ServerEntry, ID> getOneAliasIndex()
176 {
177 return store.getOneAliasIndex();
178 }
179
180
181 /**
182 * @org.apache.xbean.Property hidden="true"
183 */
184 public final void setOneAliasIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
185 {
186 store.setOneAliasIndex( index );
187 }
188
189
190 public final Index<ID, ServerEntry, ID> getSubAliasIndex()
191 {
192 return store.getSubAliasIndex();
193 }
194
195
196 /**
197 * @org.apache.xbean.Property hidden="true"
198 */
199 public final void setSubAliasIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
200 {
201 store.setSubAliasIndex( index );
202 }
203
204
205 public final Index<String, ServerEntry, ID> getUpdnIndex()
206 {
207 return store.getUpdnIndex();
208 }
209
210
211 /**
212 * @org.apache.xbean.Property hidden="true"
213 */
214 public final void setUpdnIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
215 {
216 store.setUpdnIndex( index );
217 }
218
219
220 public final Index<String, ServerEntry, ID> getNdnIndex()
221 {
222 return store.getNdnIndex();
223 }
224
225
226 /**
227 * @org.apache.xbean.Property hidden="true"
228 */
229 public final void setNdnIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
230 {
231 store.setNdnIndex( index );
232 }
233
234
235 public final Iterator<String> getUserIndices()
236 {
237 return store.userIndices();
238 }
239
240
241 public final Iterator<String> getSystemIndices()
242 {
243 return store.systemIndices();
244 }
245
246
247 public final boolean hasUserIndexOn( String id ) throws Exception
248 {
249 return store.hasUserIndexOn( id );
250 }
251
252
253 public final boolean hasSystemIndexOn( String id ) throws Exception
254 {
255 return store.hasSystemIndexOn( id );
256 }
257
258
259 /**
260 * @see org.apache.directory.server.core.partition.impl.btree.BTreePartition#getUserIndex(String)
261 */
262 public final Index<? extends Object, ServerEntry, ID> getUserIndex( String id ) throws IndexNotFoundException
263 {
264 return store.getUserIndex( id );
265 }
266
267
268 /**
269 * @see BTreePartition#getEntryId(String)
270 */
271 public final Index<? extends Object, ServerEntry, ID> getSystemIndex( String id ) throws IndexNotFoundException
272 {
273 return store.getSystemIndex( id );
274 }
275
276
277 public final ID getEntryId( String dn ) throws Exception
278 {
279 return store.getEntryId( dn );
280 }
281
282
283 public final String getEntryDn( ID id ) throws Exception
284 {
285 return store.getEntryDn( id );
286 }
287
288
289 public final ID getParentId( String dn ) throws Exception
290 {
291 return store.getParentId( dn );
292 }
293
294
295 public final ID getParentId( ID childId ) throws Exception
296 {
297 return store.getParentId( childId );
298 }
299
300
301 public final String getEntryUpdn( ID id ) throws Exception
302 {
303 return store.getEntryUpdn( id );
304 }
305
306
307 public final String getEntryUpdn( String dn ) throws Exception
308 {
309 return store.getEntryUpdn( dn );
310 }
311
312
313 public final int count() throws Exception
314 {
315 return store.count();
316 }
317
318
319 public final void add( AddOperationContext addContext ) throws Exception
320 {
321 store.add( ( ServerEntry ) ( ( ClonedServerEntry ) addContext.getEntry() ).getClonedEntry() );
322 }
323
324
325 public final ClonedServerEntry lookup( ID id ) throws Exception
326 {
327 return new ClonedServerEntry( store.lookup( id ) );
328 }
329
330
331 public final void delete( ID id ) throws Exception
332 {
333 store.delete( id );
334 }
335
336
337 public final IndexCursor<ID, ServerEntry, ID> list( ID id ) throws Exception
338 {
339 return store.list( id );
340 }
341
342
343 public final int getChildCount( ID id ) throws Exception
344 {
345 return store.getChildCount( id );
346 }
347
348
349 public final void setProperty( String propertyName, String propertyValue ) throws Exception
350 {
351 store.setProperty( propertyName, propertyValue );
352 }
353
354
355 public final String getProperty( String propertyName ) throws Exception
356 {
357 return store.getProperty( propertyName );
358 }
359
360
361 public final void modify( ModifyOperationContext modifyContext ) throws Exception
362 {
363 store.modify( modifyContext.getDn(), modifyContext.getModItems() );
364 }
365
366
367 public final void rename( RenameOperationContext renameContext ) throws Exception
368 {
369 store.rename( renameContext.getDn(), renameContext.getNewRdn(), renameContext.getDelOldDn() );
370 }
371
372
373 public final void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws Exception
374 {
375 checkIsValidMove( moveAndRenameContext.getDn(), moveAndRenameContext.getParent() );
376 store.move( moveAndRenameContext.getDn(), moveAndRenameContext.getParent(), moveAndRenameContext.getNewRdn(),
377 moveAndRenameContext.getDelOldDn() );
378 }
379
380
381 public final void move( MoveOperationContext moveContext ) throws Exception
382 {
383 checkIsValidMove( moveContext.getDn(), moveContext.getParent() );
384 store.move( moveContext.getDn(), moveContext.getParent() );
385 }
386
387
388 /**
389 *
390 * checks whether the moving of given entry is valid
391 *
392 * @param oldChildDn the entry's DN to be moved
393 * @param newParentDn new parent entry's DN
394 * @throws Exception
395 */
396 private void checkIsValidMove( DN oldChildDn, DN newParentDn ) throws Exception
397 {
398 boolean invalid = false;
399
400 DN newParentDNClone = ( DN ) newParentDn.clone();
401 newParentDNClone.remove( newParentDNClone.size() - 1 );
402
403 if ( newParentDn.size() >= oldChildDn.size() )
404 {
405 for ( int i = 0; i < oldChildDn.size(); i++ )
406 {
407 RDN nameRdn = oldChildDn.getRdn( i );
408 RDN ldapRdn = newParentDn.getRdn( i );
409
410 if ( nameRdn.compareTo( ldapRdn ) == 0 )
411 {
412 invalid = true;
413 }
414 else
415 {
416 invalid = false;
417 break;
418 }
419 }
420 }
421
422 if ( invalid )
423 {
424 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
425 "cannot place an entry below itself" );
426 }
427
428 }
429
430
431 public final void bind( DN bindDn, byte[] credentials, List<String> mechanisms, String saslAuthId )
432 throws Exception
433 {
434 if ( bindDn == null || credentials == null || mechanisms == null || saslAuthId == null )
435 {
436 // do nothing just using variables to prevent yellow lights : bad :)
437 }
438
439 // does nothing
440 throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED,
441 I18n.err( I18n.ERR_702 ) );
442 }
443
444
445 public final void bind( BindOperationContext bindContext ) throws Exception
446 {
447 // does nothing
448 throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED,
449 I18n.err( I18n.ERR_702 ) );
450 }
451
452
453 public final void unbind( UnbindOperationContext unbindContext ) throws Exception
454 {
455 }
456
457
458 public final Index<String, ServerEntry, ID> getPresenceIndex()
459 {
460 return store.getPresenceIndex();
461 }
462
463
464 public final Index<ID, ServerEntry, ID> getSubLevelIndex()
465 {
466 return store.getSubLevelIndex();
467 }
468
469
470 /**
471 * {@inheritDoc}
472 */
473 public String toString()
474 {
475 return "Partition<" + id + ">";
476 }
477
478 }