| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.server.xdbm; |
| |
| |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.directory.server.core.entry.ClonedServerEntry; |
| import org.apache.directory.server.core.interceptor.context.AddOperationContext; |
| import org.apache.directory.server.core.interceptor.context.BindOperationContext; |
| import org.apache.directory.server.core.interceptor.context.ModifyOperationContext; |
| import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext; |
| import org.apache.directory.server.core.interceptor.context.MoveOperationContext; |
| import org.apache.directory.server.core.interceptor.context.RenameOperationContext; |
| import org.apache.directory.server.core.interceptor.context.UnbindOperationContext; |
| import org.apache.directory.server.core.partition.impl.btree.BTreePartition; |
| import org.apache.directory.server.i18n.I18n; |
| import org.apache.directory.shared.ldap.entry.Entry; |
| import org.apache.directory.shared.ldap.exception.LdapAuthenticationNotSupportedException; |
| import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException; |
| import org.apache.directory.shared.ldap.message.ResultCodeEnum; |
| import org.apache.directory.shared.ldap.name.DN; |
| import org.apache.directory.shared.ldap.name.RDN; |
| |
| |
| /** |
| * Base class for XDBM partitions that use an {@link Store}. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| * @version $Rev$, $Date$ |
| */ |
| public abstract class AbstractXdbmPartition<ID extends Comparable<ID>> extends BTreePartition<ID> |
| { |
| |
| protected boolean optimizerEnabled = true; |
| |
| /** The store. */ |
| protected Store<Entry, ID> store; |
| |
| |
| protected AbstractXdbmPartition( Store<Entry, ID> store ) |
| { |
| this.store = store; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| protected void doDestroy() throws Exception |
| { |
| store.destroy(); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final boolean isInitialized() |
| { |
| return store.isInitialized(); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final void sync() throws Exception |
| { |
| store.sync(); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // C O N F I G U R A T I O N M E T H O D S |
| // ------------------------------------------------------------------------ |
| |
| public boolean isOptimizerEnabled() |
| { |
| return optimizerEnabled; |
| } |
| |
| |
| public void setOptimizerEnabled( boolean optimizerEnabled ) |
| { |
| this.optimizerEnabled = optimizerEnabled; |
| } |
| |
| |
| public void setSyncOnWrite( boolean syncOnWrite ) |
| { |
| store.setSyncOnWrite( syncOnWrite ); |
| } |
| |
| |
| public boolean isSyncOnWrite() |
| { |
| return store.isSyncOnWrite(); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // I N D E X M E T H O D S |
| // ------------------------------------------------------------------------ |
| |
| public final void addIndexOn( Index<? extends Object, Entry, ID> index ) throws Exception |
| { |
| store.addIndex( index ); |
| } |
| |
| |
| public final Index<ID, Entry, ID> getOneLevelIndex() |
| { |
| return store.getOneLevelIndex(); |
| } |
| |
| |
| public final Index<String, Entry, ID> getAliasIndex() |
| { |
| return store.getAliasIndex(); |
| } |
| |
| |
| public final Index<ID, Entry, ID> getOneAliasIndex() |
| { |
| return store.getOneAliasIndex(); |
| } |
| |
| |
| public final Index<ID, Entry, ID> getSubAliasIndex() |
| { |
| return store.getSubAliasIndex(); |
| } |
| |
| |
| public final Iterator<String> getUserIndices() |
| { |
| return store.userIndices(); |
| } |
| |
| |
| public final Iterator<String> getSystemIndices() |
| { |
| return store.systemIndices(); |
| } |
| |
| |
| public final boolean hasUserIndexOn( String id ) throws Exception |
| { |
| return store.hasUserIndexOn( id ); |
| } |
| |
| |
| public final boolean hasSystemIndexOn( String id ) throws Exception |
| { |
| return store.hasSystemIndexOn( id ); |
| } |
| |
| |
| /** |
| * @see org.apache.directory.server.core.partition.impl.btree.BTreePartition#getUserIndex(String) |
| */ |
| public final Index<? extends Object, Entry, ID> getUserIndex( String id ) throws IndexNotFoundException |
| { |
| return store.getUserIndex( id ); |
| } |
| |
| |
| /** |
| * @see BTreePartition#getEntryId(String) |
| */ |
| public final Index<? extends Object, Entry, ID> getSystemIndex( String id ) throws IndexNotFoundException |
| { |
| return store.getSystemIndex( id ); |
| } |
| |
| |
| public final ID getEntryId( DN dn ) throws Exception |
| { |
| return store.getEntryId( dn ); |
| } |
| |
| |
| public final DN getEntryDn( ID id ) throws Exception |
| { |
| return store.getEntryDn( id ); |
| } |
| |
| |
| public final int count() throws Exception |
| { |
| return store.count(); |
| } |
| |
| |
| public final void add( AddOperationContext addContext ) throws Exception |
| { |
| store.add( ( Entry ) ( ( ClonedServerEntry ) addContext.getEntry() ).getClonedEntry() ); |
| } |
| |
| |
| public final ClonedServerEntry lookup( ID id ) throws Exception |
| { |
| return new ClonedServerEntry( store.lookup( id ) ); |
| } |
| |
| |
| public final void delete( ID id ) throws Exception |
| { |
| store.delete( id ); |
| } |
| |
| |
| public final IndexCursor<ID, Entry, ID> list( ID id ) throws Exception |
| { |
| return store.list( id ); |
| } |
| |
| |
| public final int getChildCount( ID id ) throws Exception |
| { |
| return store.getChildCount( id ); |
| } |
| |
| |
| public final void setProperty( String propertyName, String propertyValue ) throws Exception |
| { |
| store.setProperty( propertyName, propertyValue ); |
| } |
| |
| |
| public final String getProperty( String propertyName ) throws Exception |
| { |
| return store.getProperty( propertyName ); |
| } |
| |
| |
| public final void modify( ModifyOperationContext modifyContext ) throws Exception |
| { |
| store.modify( modifyContext.getDn(), modifyContext.getModItems() ); |
| } |
| |
| |
| public final void rename( RenameOperationContext renameContext ) throws Exception |
| { |
| store.rename( renameContext.getDn(), renameContext.getNewRdn(), renameContext.getDelOldDn() ); |
| } |
| |
| |
| public final void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws Exception |
| { |
| checkIsValidMove( moveAndRenameContext.getDn(), moveAndRenameContext.getParent() ); |
| store.move( moveAndRenameContext.getDn(), moveAndRenameContext.getParent(), moveAndRenameContext.getNewRdn(), |
| moveAndRenameContext.getDelOldDn() ); |
| } |
| |
| |
| public final void move( MoveOperationContext moveContext ) throws Exception |
| { |
| checkIsValidMove( moveContext.getDn(), moveContext.getParent() ); |
| store.move( moveContext.getDn(), moveContext.getParent() ); |
| } |
| |
| |
| /** |
| * |
| * checks whether the moving of given entry is valid |
| * |
| * @param oldChildDn the entry's DN to be moved |
| * @param newParentDn new parent entry's DN |
| * @throws Exception |
| */ |
| private void checkIsValidMove( DN oldChildDn, DN newParentDn ) throws Exception |
| { |
| boolean invalid = false; |
| |
| DN newParentDNClone = ( DN ) newParentDn.clone(); |
| newParentDNClone.remove( newParentDNClone.size() - 1 ); |
| |
| if ( newParentDn.size() >= oldChildDn.size() ) |
| { |
| for ( int i = 0; i < oldChildDn.size(); i++ ) |
| { |
| RDN nameRdn = oldChildDn.getRdn( i ); |
| RDN ldapRdn = newParentDn.getRdn( i ); |
| |
| if ( nameRdn.compareTo( ldapRdn ) == 0 ) |
| { |
| invalid = true; |
| } |
| else |
| { |
| invalid = false; |
| break; |
| } |
| } |
| } |
| |
| if ( invalid ) |
| { |
| throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, |
| "cannot place an entry below itself" ); |
| } |
| |
| } |
| |
| |
| public final void bind( DN bindDn, byte[] credentials, List<String> mechanisms, String saslAuthId ) |
| throws Exception |
| { |
| if ( bindDn == null || credentials == null || mechanisms == null || saslAuthId == null ) |
| { |
| // do nothing just using variables to prevent yellow lights : bad :) |
| } |
| |
| // does nothing |
| throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED, I18n |
| .err( I18n.ERR_702 ) ); |
| } |
| |
| |
| public final void bind( BindOperationContext bindContext ) throws Exception |
| { |
| // does nothing |
| throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED, I18n |
| .err( I18n.ERR_702 ) ); |
| } |
| |
| |
| public final void unbind( UnbindOperationContext unbindContext ) throws Exception |
| { |
| } |
| |
| |
| public final Index<String, Entry, ID> getPresenceIndex() |
| { |
| return store.getPresenceIndex(); |
| } |
| |
| |
| public final Index<ID, Entry, ID> getSubLevelIndex() |
| { |
| return store.getSubLevelIndex(); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String toString() |
| { |
| return "Partition<" + id + ">"; |
| } |
| |
| } |