blob: 03b74e72b22354876d3a50607e8b61dad456b789 [file] [log] [blame]
/*
* 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.core.api.interceptor;
import java.util.HashSet;
import java.util.Set;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.DnFactory;
import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.api.LdapPrincipal;
import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext;
import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
import org.apache.directory.server.core.api.interceptor.context.GetRootDseOperationContext;
import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
import org.apache.directory.server.core.api.interceptor.context.OperationContext;
import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
import org.apache.directory.server.core.api.partition.PartitionNexus;
/**
* A easy-to-use implementation of {@link Interceptor}. All methods are
* implemented to pass the flow of control to next interceptor by defaults.
* Please override the methods you have concern in.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public abstract class BaseInterceptor implements Interceptor
{
/** The interceptor's name. Default to the class name */
private String name;
/** A reference to the DirectoryService instance */
protected DirectoryService directoryService;
/** A reference to the SchemaManager instance */
protected SchemaManager schemaManager;
/** The DN factory */
protected DnFactory dnFactory;
/** set of operational attribute types used for representing the password policy state of a user entry */
protected static final Set<AttributeType> PWD_POLICY_STATE_ATTRIBUTE_TYPES = new HashSet<AttributeType>();
/** The AccessControlSubentries AttributeType */
protected static AttributeType ACCESS_CONTROL_SUBENTRIES_AT;
/** A reference to the AdministrativeRole AT */
protected static AttributeType ADMINISTRATIVE_ROLE_AT;
/** The CollectiveAttributeSubentries AttributeType */
protected static AttributeType COLLECTIVE_ATTRIBUTE_SUBENTRIES_AT;
/** The CollectiveExclusions AttributeType */
protected static AttributeType COLLECTIVE_EXCLUSIONS_AT;
/** A storage for the createTimestamp attributeType */
protected static AttributeType CREATE_TIMESTAMP_AT;
/** A storage for the creatorsName attributeType */
protected static AttributeType CREATORS_NAME_AT;
/** A storage for the entryACI attributeType */
protected static AttributeType ENTRY_ACI_AT;
/** A reference to the EntryCSN AT */
protected static AttributeType ENTRY_CSN_AT;
/** A reference to the EntryDN AT */
protected static AttributeType ENTRY_DN_AT;
/** A reference to the EntryUUID AT */
protected static AttributeType ENTRY_UUID_AT;
/** A reference to the ModifiersName AT */
protected static AttributeType MODIFIERS_NAME_AT;
/** A reference to the ModifyTimestamp AT */
protected static AttributeType MODIFY_TIMESTAMP_AT;
/** The ObjectClass AttributeType */
protected static AttributeType OBJECT_CLASS_AT;
/** the subentry ACI attribute type */
protected static AttributeType SUBENTRY_ACI_AT;
/** A reference to the AccessControlSubentries AT */
protected static AttributeType SUBSCHEMA_SUBENTRY_AT;
/** A reference to the SubtreeSpecification AT */
protected static AttributeType SUBTREE_SPECIFICATION_AT;
/** A reference to the TriggerExecutionSubentries AT */
protected static AttributeType TRIGGER_EXECUTION_SUBENTRIES_AT;
/** A storage for the uniqueMember attributeType */
protected static AttributeType UNIQUE_MEMBER_AT;
/** A storage for the UserPassword attributeType */
protected static AttributeType USER_PASSWORD_AT;
/**
* The final interceptor which acts as a proxy in charge to dialog with the nexus partition.
*/
private final Interceptor FINAL_INTERCEPTOR = new Interceptor()
{
private PartitionNexus nexus;
public String getName()
{
return "FINAL";
}
public void init( DirectoryService directoryService )
{
this.nexus = directoryService.getPartitionNexus();
}
public void destroy()
{
// unused
}
/**
* {@inheritDoc}
*/
public void add( AddOperationContext addContext ) throws LdapException
{
nexus.add( addContext );
}
/**
* {@inheritDoc}
*/
public void bind( BindOperationContext bindContext ) throws LdapException
{
// Do nothing here : there is no support for the Bind operation in Partition
}
/**
* {@inheritDoc}
*/
public boolean compare( CompareOperationContext compareContext ) throws LdapException
{
return nexus.compare( compareContext );
}
/**
* {@inheritDoc}
*/
public void delete( DeleteOperationContext deleteContext ) throws LdapException
{
nexus.delete( deleteContext );
}
/**
* {@inheritDoc}
*/
public Entry getRootDse( GetRootDseOperationContext getRootDseContext ) throws LdapException
{
return nexus.getRootDse( getRootDseContext );
}
/**
* {@inheritDoc}
*/
public boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException
{
return nexus.hasEntry( hasEntryContext );
}
/**
* {@inheritDoc}
*/
public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
{
return nexus.lookup( lookupContext );
}
/**
* {@inheritDoc}
*/
public void modify( ModifyOperationContext modifyContext ) throws LdapException
{
nexus.modify( modifyContext );
}
/**
* {@inheritDoc}
*/
public void move( MoveOperationContext moveContext ) throws LdapException
{
nexus.move( moveContext );
}
/**
* {@inheritDoc}
*/
public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
{
nexus.moveAndRename( moveAndRenameContext );
}
/**
* {@inheritDoc}
*/
public void rename( RenameOperationContext renameContext ) throws LdapException
{
nexus.rename( renameContext );
}
/**
* {@inheritDoc}
*/
public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
{
return nexus.search( searchContext );
}
/**
* {@inheritDoc}
*/
public void unbind( UnbindOperationContext unbindContext ) throws LdapException
{
nexus.unbind( unbindContext );
}
};
/**
* default interceptor name is its class, preventing accidental duplication of interceptors by naming
* instances differently
* @return (default, class name) interceptor name
*/
public String getName()
{
return name;
}
/**
* Returns {@link LdapPrincipal} of current context.
*
* @param opContext TODO
* @return the authenticated principal
*/
public static LdapPrincipal getPrincipal( OperationContext opContext )
{
return opContext.getSession().getEffectivePrincipal();
}
/**
* Creates a new instance with a default name : the class name itself.
*/
protected BaseInterceptor()
{
name = getClass().getSimpleName();
}
/**
* Creates a new instance with a given name.
*
* @param name the Interceptor name
*/
protected BaseInterceptor( String name )
{
this.name = name;
}
/**
* Creates a new instance with a given name.
*
* @param name the Interceptor name
*/
protected BaseInterceptor( InterceptorEnum interceptor )
{
this.name = interceptor.getName();
}
/**
* This method does nothing by default.
* @throws Exception
*/
public void init( DirectoryService directoryService ) throws LdapException
{
// Initialize the fields that will be used by all the interceptors
this.directoryService = directoryService;
schemaManager = directoryService.getSchemaManager();
dnFactory = directoryService.getDnFactory();
// Init the At we use locally
ACCESS_CONTROL_SUBENTRIES_AT = schemaManager.getAttributeType( SchemaConstants.ACCESS_CONTROL_SUBENTRIES_AT );
ADMINISTRATIVE_ROLE_AT = schemaManager.getAttributeType( SchemaConstants.ADMINISTRATIVE_ROLE_AT );
COLLECTIVE_ATTRIBUTE_SUBENTRIES_AT = schemaManager
.getAttributeType( SchemaConstants.COLLECTIVE_ATTRIBUTE_SUBENTRIES_AT );
COLLECTIVE_EXCLUSIONS_AT = schemaManager.getAttributeType( SchemaConstants.COLLECTIVE_EXCLUSIONS_AT );
CREATORS_NAME_AT = schemaManager.getAttributeType( SchemaConstants.CREATORS_NAME_AT );
CREATE_TIMESTAMP_AT = schemaManager.getAttributeType( SchemaConstants.CREATE_TIMESTAMP_AT );
ENTRY_ACI_AT = schemaManager.getAttributeType( SchemaConstants.ENTRY_ACI_AT_OID );
ENTRY_CSN_AT = schemaManager.getAttributeType( SchemaConstants.ENTRY_CSN_AT );
ENTRY_DN_AT = schemaManager.getAttributeType( SchemaConstants.ENTRY_DN_AT );
ENTRY_UUID_AT = schemaManager.getAttributeType( SchemaConstants.ENTRY_UUID_AT );
MODIFIERS_NAME_AT = schemaManager.getAttributeType( SchemaConstants.MODIFIERS_NAME_AT );
MODIFY_TIMESTAMP_AT = schemaManager.getAttributeType( SchemaConstants.MODIFY_TIMESTAMP_AT );
OBJECT_CLASS_AT = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
SUBENTRY_ACI_AT = schemaManager.getAttributeType( SchemaConstants.SUBENTRY_ACI_AT_OID );
SUBSCHEMA_SUBENTRY_AT = schemaManager.getAttributeType( SchemaConstants.SUBSCHEMA_SUBENTRY_AT );
SUBTREE_SPECIFICATION_AT = schemaManager.getAttributeType( SchemaConstants.SUBTREE_SPECIFICATION_AT );
TRIGGER_EXECUTION_SUBENTRIES_AT = schemaManager
.getAttributeType( SchemaConstants.TRIGGER_EXECUTION_SUBENTRIES_AT );
UNIQUE_MEMBER_AT = schemaManager.getAttributeType( SchemaConstants.UNIQUE_MEMBER_AT_OID );
USER_PASSWORD_AT = schemaManager.getAttributeType( SchemaConstants.USER_PASSWORD_AT_OID );
FINAL_INTERCEPTOR.init( directoryService );
}
/**
* This method does nothing by default.
*/
public void destroy()
{
}
/**
* Computes the next interceptor to call for a given operation. If we find none,
* we return the proxy to the nexus.
*
* @param operationContext The operation context
* @return The next interceptor in the list for this operation
*/
protected Interceptor getNextInterceptor( OperationContext operationContext )
{
String currentInterceptor = operationContext.getNextInterceptor();
if ( currentInterceptor.equals( "FINAL" ) )
{
return FINAL_INTERCEPTOR;
}
Interceptor interceptor = directoryService.getInterceptor( currentInterceptor );
return interceptor;
}
// ------------------------------------------------------------------------
// Interceptor's Invoke Method
// ------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public void add( AddOperationContext addContext ) throws LdapException
{
// Do nothing
}
/**
* Calls the next interceptor for the add operation.
*
* @param addContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( AddOperationContext addContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( addContext );
interceptor.add( addContext );
}
/**
* {@inheritDoc}
*/
public void bind( BindOperationContext bindContext ) throws LdapException
{
// Do nothing
}
/**
* Calls the next interceptor for the bind operation.
*
* @param bindContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( BindOperationContext bindContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( bindContext );
interceptor.bind( bindContext );
}
public boolean compare( CompareOperationContext compareContext ) throws LdapException
{
// Return false in any case
return false;
}
/**
* Calls the next interceptor for the compare operation.
*
* @param compareContext The context in which we are executing this operation
* @return a boolean indicating if the comparison is successfull
* @throws LdapException If something went wrong
*/
protected final boolean next( CompareOperationContext compareContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( compareContext );
return interceptor.compare( compareContext );
}
/**
* {@inheritDoc}
*/
public void delete( DeleteOperationContext deleteContext ) throws LdapException
{
// Do nothing
}
/**
* Calls the next interceptor for the delete operation.
*
* @param deleteContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( DeleteOperationContext deleteContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( deleteContext );
interceptor.delete( deleteContext );
}
/**
* {@inheritDoc}
*/
public Entry getRootDse( GetRootDseOperationContext getRootDseContext ) throws LdapException
{
// Nothing to do
return null;
}
/**
* Calls the next interceptor for the getRootDse operation.
*
* @param getRootDseContext The context in which we are executing this operation
* @return the rootDSE
* @throws LdapException If something went wrong
*/
protected final Entry next( GetRootDseOperationContext getRootDseContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( getRootDseContext );
return interceptor.getRootDse( getRootDseContext );
}
/**
* {@inheritDoc}
*/
public boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException
{
// Return false in any case
return false;
}
/**
* Calls the next interceptor for the hasEntry operation.
*
* @param hasEntryContext The context in which we are executing this operation
* @return a boolean indicating if the entry exists on the server
* @throws LdapException If something went wrong
*/
protected final boolean next( HasEntryOperationContext hasEntryContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( hasEntryContext );
return interceptor.hasEntry( hasEntryContext );
}
/**
* {@inheritDoc}
*/
public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
{
return next( lookupContext );
}
/**
* Calls the next interceptor for the lookup operation.
*
* @param lookupContext The context in which we are executing this operation
* @return the Entry containing the found entry
* @throws LdapException If something went wrong
*/
protected final Entry next( LookupOperationContext lookupContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( lookupContext );
return interceptor.lookup( lookupContext );
}
/**
* {@inheritDoc}
*/
public void modify( ModifyOperationContext modifyContext ) throws LdapException
{
// Nothing to do
}
/**
* Calls the next interceptor for the modify operation.
*
* @param modifyContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( ModifyOperationContext modifyContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( modifyContext );
interceptor.modify( modifyContext );
}
/**
* {@inheritDoc}
*/
public void move( MoveOperationContext moveContext ) throws LdapException
{
// Do nothing
}
/**
* Calls the next interceptor for the move operation.
*
* @param moveContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( MoveOperationContext moveContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( moveContext );
interceptor.move( moveContext );
}
public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
{
// Do nothing
}
/**
* Calls the next interceptor for the moveAndRename operation.
*
* @param moveAndRenameContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( moveAndRenameContext );
interceptor.moveAndRename( moveAndRenameContext );
}
/**
* {@inheritDoc}
*/
public void rename( RenameOperationContext renameContext ) throws LdapException
{
// Nothing to do
}
/**
* Calls the next interceptor for the rename operation.
*
* @param renameContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( RenameOperationContext renameContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( renameContext );
interceptor.rename( renameContext );
}
/**
* {@inheritDoc}
*/
public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
{
return null;
}
/**
* Calls the next interceptor for the search operation.
*
* @param searchContext The context in which we are executing this operation
* @return the cursor containing the found entries
* @throws LdapException If something went wrong
*/
protected final EntryFilteringCursor next( SearchOperationContext searchContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( searchContext );
return interceptor.search( searchContext );
}
/**
* {@inheritDoc}
*/
public void unbind( UnbindOperationContext unbindContext ) throws LdapException
{
// Nothing to do
}
/**
* Compute the next interceptor for the unbind operation.
*
* @param unbindContext The context in which we are executing this operation
* @throws LdapException If something went wrong
*/
protected final void next( UnbindOperationContext unbindContext ) throws LdapException
{
Interceptor interceptor = getNextInterceptor( unbindContext );
interceptor.unbind( unbindContext );
}
}