/* | |
* Copyright 2004 The Apache Software Foundation | |
* | |
* Licensed 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.ldap.server.interceptor; | |
import java.util.*; | |
import javax.naming.ConfigurationException; | |
import javax.naming.Name; | |
import javax.naming.NamingEnumeration; | |
import javax.naming.NamingException; | |
import javax.naming.directory.Attributes; | |
import javax.naming.directory.ModificationItem; | |
import javax.naming.directory.SearchControls; | |
import org.apache.ldap.common.filter.ExprNode; | |
import org.apache.ldap.server.DirectoryServiceConfiguration; | |
import org.apache.ldap.server.invocation.Invocation; | |
import org.apache.ldap.server.invocation.InvocationStack; | |
import org.apache.ldap.server.configuration.DirectoryPartitionConfiguration; | |
import org.apache.ldap.server.configuration.InterceptorConfiguration; | |
import org.apache.ldap.server.configuration.MutableInterceptorConfiguration; | |
import org.apache.ldap.server.partition.DirectoryPartitionNexus; | |
import org.apache.ldap.server.partition.DirectoryPartitionNexusProxy; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* Manages the chain of {@link Interceptor}s. | |
* | |
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> | |
* @version $Rev$, $Date$ | |
*/ | |
public class InterceptorChain | |
{ | |
private static final Logger log = LoggerFactory.getLogger( InterceptorChain.class ); | |
private final Interceptor FINAL_INTERCEPTOR = new Interceptor() | |
{ | |
private DirectoryPartitionNexus nexus; | |
public void init( DirectoryServiceConfiguration factoryCfg, InterceptorConfiguration cfg ) | |
{ | |
this.nexus = factoryCfg.getPartitionNexus(); | |
} | |
public void destroy() | |
{ | |
// unused | |
} | |
public boolean compare( NextInterceptor next, Name name, String oid, Object value ) throws NamingException | |
{ | |
return nexus.compare( name, oid, value ); | |
} | |
public Attributes getRootDSE( NextInterceptor next ) throws NamingException | |
{ | |
return nexus.getRootDSE(); | |
} | |
public Name getMatchedName( NextInterceptor next, Name dn, boolean normalized ) throws NamingException | |
{ | |
return ( Name ) nexus.getMatchedName( dn, normalized ).clone(); | |
} | |
public Name getSuffix( NextInterceptor next, Name dn, boolean normalized ) throws NamingException | |
{ | |
return ( Name ) nexus.getSuffix( dn, normalized ).clone(); | |
} | |
public Iterator listSuffixes( NextInterceptor next, boolean normalized ) throws NamingException | |
{ | |
return nexus.listSuffixes( normalized ); | |
} | |
public void delete( NextInterceptor next, Name name ) throws NamingException | |
{ | |
nexus.delete( name ); | |
} | |
public void add( NextInterceptor next, String upName, Name normName, Attributes entry ) throws NamingException | |
{ | |
nexus.add( upName, normName, entry ); | |
} | |
public void modify( NextInterceptor next, Name name, int modOp, Attributes mods ) throws NamingException | |
{ | |
nexus.modify( name, modOp, mods ); | |
} | |
public void modify( NextInterceptor next, Name name, ModificationItem[] mods ) throws NamingException | |
{ | |
nexus.modify( name, mods ); | |
} | |
public NamingEnumeration list( NextInterceptor next, Name base ) throws NamingException | |
{ | |
return nexus.list( base ); | |
} | |
public NamingEnumeration search( NextInterceptor next, Name base, Map env, ExprNode filter, SearchControls searchCtls ) throws NamingException | |
{ | |
return nexus.search( base, env, filter, searchCtls ); | |
} | |
public Attributes lookup( NextInterceptor next, Name name ) throws NamingException | |
{ | |
return ( Attributes ) nexus.lookup( name ).clone(); | |
} | |
public Attributes lookup( NextInterceptor next, Name dn, String[] attrIds ) throws NamingException | |
{ | |
return ( Attributes ) nexus.lookup( dn, attrIds ).clone(); | |
} | |
public boolean hasEntry( NextInterceptor next, Name name ) throws NamingException | |
{ | |
return nexus.hasEntry( name ); | |
} | |
public boolean isSuffix( NextInterceptor next, Name name ) throws NamingException | |
{ | |
return nexus.isSuffix( name ); | |
} | |
public void modifyRn( NextInterceptor next, Name name, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
nexus.modifyRn( name, newRn, deleteOldRn ); | |
} | |
public void move( NextInterceptor next, Name oriChildName, Name newParentName ) throws NamingException | |
{ | |
nexus.move( oriChildName, newParentName ); | |
} | |
public void move( NextInterceptor next, Name oriChildName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
nexus.move( oriChildName, newParentName, newRn, deleteOldRn ); | |
} | |
public void addContextPartition( NextInterceptor next, DirectoryPartitionConfiguration cfg ) throws NamingException | |
{ | |
nexus.addContextPartition( cfg ); | |
} | |
public void removeContextPartition( NextInterceptor next, Name suffix ) throws NamingException | |
{ | |
nexus.removeContextPartition( suffix ); | |
} | |
}; | |
private final Map name2entry = new HashMap(); | |
private final Entry tail; | |
private Entry head; | |
private DirectoryServiceConfiguration factoryCfg; | |
/** | |
* Create a new interceptor chain. | |
*/ | |
public InterceptorChain() | |
{ | |
MutableInterceptorConfiguration tailCfg = new MutableInterceptorConfiguration(); | |
tailCfg.setName( "tail" ); | |
tailCfg.setInterceptor( FINAL_INTERCEPTOR ); | |
tail = new Entry( null, null, tailCfg ); | |
head = tail; | |
} | |
/** | |
* Initializes and registers all interceptors according to the specified | |
* {@link DirectoryServiceConfiguration}. | |
*/ | |
public synchronized void init( DirectoryServiceConfiguration factoryCfg ) throws NamingException | |
{ | |
this.factoryCfg = factoryCfg; | |
// Initialize tail first. | |
FINAL_INTERCEPTOR.init( factoryCfg, null ); | |
// And register and initialize all interceptors | |
ListIterator i = factoryCfg.getStartupConfiguration().getInterceptorConfigurations().listIterator(); | |
Interceptor interceptor = null; | |
try | |
{ | |
while( i.hasNext() ) | |
{ | |
InterceptorConfiguration cfg = ( InterceptorConfiguration ) i.next(); | |
register( cfg ); | |
} | |
} | |
catch ( Throwable t ) | |
{ | |
// destroy if failed to initialize all interceptors. | |
destroy(); | |
if ( t instanceof NamingException ) | |
{ | |
throw ( NamingException ) t; | |
} | |
else | |
{ | |
throw new InterceptorException( interceptor, "Failed to initialize interceptor chain.", t ); | |
} | |
} | |
} | |
/** | |
* Deinitializes and deregisters all interceptors this chain contains. | |
*/ | |
public synchronized void destroy() | |
{ | |
List entries = new ArrayList(); | |
Entry e = tail; | |
do | |
{ | |
entries.add( e ); | |
e = e.prevEntry; | |
} | |
while ( e != null ); | |
Iterator i = entries.iterator(); | |
while ( i.hasNext() ) | |
{ | |
e = ( Entry ) i.next(); | |
if( e != tail ) | |
{ | |
try | |
{ | |
deregister( e.configuration.getName() ); | |
} | |
catch ( Throwable t ) | |
{ | |
log.warn( "Failed to deregister an interceptor: " + | |
e.configuration.getName(), t ); | |
} | |
} | |
} | |
} | |
/** | |
* Returns the registered interceptor with the specified name. | |
* @return <tt>null</tt> if the specified name doesn't exist. | |
*/ | |
public Interceptor get( String interceptorName ) | |
{ | |
Entry e = (Entry) name2entry.get( interceptorName ); | |
if( e == null ) | |
{ | |
return null; | |
} | |
return e.configuration.getInterceptor(); | |
} | |
/** | |
* Returns the list of all registered interceptors. | |
*/ | |
public synchronized List getAll() | |
{ | |
List result = new ArrayList(); | |
Entry e = head; | |
do | |
{ | |
result.add( e.configuration.getInterceptor() ); | |
e = e.nextEntry; | |
} | |
while ( e != tail ); | |
return result; | |
} | |
public synchronized void addFirst( InterceptorConfiguration cfg ) throws NamingException | |
{ | |
register0( cfg, head ); | |
} | |
public synchronized void addLast( InterceptorConfiguration cfg ) throws NamingException | |
{ | |
register0( cfg, tail ); | |
} | |
public synchronized void addBefore( String nextInterceptorName, InterceptorConfiguration cfg ) throws NamingException | |
{ | |
Entry e = (Entry) name2entry.get( nextInterceptorName ); | |
if( e == null ) | |
{ | |
throw new ConfigurationException( "Interceptor not found: " + nextInterceptorName ); | |
} | |
register0( cfg, e ); | |
} | |
public synchronized InterceptorConfiguration remove( String interceptorName ) throws NamingException | |
{ | |
return deregister( interceptorName ); | |
} | |
public synchronized void addAfter( String prevInterceptorName, InterceptorConfiguration cfg ) throws NamingException | |
{ | |
Entry e = (Entry) name2entry.get( prevInterceptorName ); | |
if( e == null ) | |
{ | |
throw new ConfigurationException( "Interceptor not found: " + prevInterceptorName ); | |
} | |
register0( cfg, e.nextEntry ); | |
} | |
/** | |
* Adds and initializes an interceptor with the specified configuration. | |
*/ | |
private void register( InterceptorConfiguration cfg ) throws NamingException | |
{ | |
checkAddable( cfg ); | |
register0( cfg, tail ); | |
} | |
/** | |
* Removes and deinitializes the interceptor with the specified name. | |
*/ | |
private InterceptorConfiguration deregister( String name ) throws ConfigurationException | |
{ | |
Entry entry = checkOldName( name ); | |
Entry prevEntry = entry.prevEntry; | |
Entry nextEntry = entry.nextEntry; | |
if( nextEntry == null ) | |
{ | |
// Don't deregister tail | |
return null; | |
} | |
if ( prevEntry == null ) | |
{ | |
nextEntry.prevEntry = null; | |
head = nextEntry; | |
} | |
else | |
{ | |
prevEntry.nextEntry = nextEntry; | |
nextEntry.prevEntry = prevEntry; | |
} | |
name2entry.remove( name ); | |
entry.configuration.getInterceptor().destroy(); | |
return entry.configuration; | |
} | |
private void register0( InterceptorConfiguration cfg, Entry nextEntry ) throws NamingException | |
{ | |
String name = cfg.getName(); | |
Interceptor interceptor = cfg.getInterceptor(); | |
interceptor.init( factoryCfg, cfg ); | |
Entry newEntry; | |
if( nextEntry == head ) | |
{ | |
newEntry = new Entry( null, head, cfg ); | |
head.prevEntry = newEntry; | |
head = newEntry; | |
} | |
else if( head == tail ) | |
{ | |
newEntry = new Entry( null, tail, cfg ); | |
tail.prevEntry = newEntry; | |
head = newEntry; | |
} | |
else | |
{ | |
newEntry = new Entry( nextEntry.prevEntry, nextEntry, cfg ); | |
nextEntry.prevEntry.nextEntry = newEntry; | |
nextEntry.prevEntry = newEntry; | |
} | |
name2entry.put( name, newEntry ); | |
} | |
/** | |
* Throws an exception when the specified interceptor name is not registered in this chain. | |
* | |
* @return An interceptor entry with the specified name. | |
*/ | |
private Entry checkOldName( String baseName ) throws ConfigurationException | |
{ | |
Entry e = ( Entry ) name2entry.get( baseName ); | |
if ( e == null ) | |
{ | |
throw new ConfigurationException( "Unknown interceptor name:" + baseName ); | |
} | |
return e; | |
} | |
/** | |
* Checks the specified interceptor name is already taken and throws an exception if already taken. | |
*/ | |
private void checkAddable( InterceptorConfiguration cfg ) throws ConfigurationException | |
{ | |
if ( name2entry.containsKey( cfg.getName() ) ) | |
{ | |
throw new ConfigurationException( "Other interceptor is using name '" + cfg.getName() + "'" ); | |
} | |
} | |
/** | |
* Gets the InterceptorEntry to use first with bypass information considered. | |
* | |
* @return the first entry to use. | |
*/ | |
private Entry getStartingEntry() | |
{ | |
if ( InvocationStack.getInstance().isEmpty() ) | |
{ | |
return head; | |
} | |
Invocation invocation = InvocationStack.getInstance().peek(); | |
if ( ! invocation.hasBypass() ) | |
{ | |
return head; | |
} | |
if ( invocation.isBypassed( DirectoryPartitionNexusProxy.BYPASS_ALL ) ) | |
{ | |
return tail; | |
} | |
Entry next = head; | |
while ( next != tail ) | |
{ | |
if ( invocation.isBypassed( next.configuration.getName() ) ) | |
{ | |
next = next.nextEntry; | |
} | |
else | |
{ | |
return next; | |
} | |
} | |
return tail; | |
} | |
public Attributes getRootDSE() throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.getRootDSE( next ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Name getMatchedName( Name name, boolean normalized ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.getMatchedName( next, name, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Name getSuffix( Name name, boolean normalized ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.getSuffix( next, name, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public boolean compare( Name name, String oid, Object value ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.compare( next, name, oid, value ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Iterator listSuffixes( boolean normalized ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.listSuffixes( next, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void addContextPartition( DirectoryPartitionConfiguration cfg ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.addContextPartition( next, cfg ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void removeContextPartition( Name suffix ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.removeContextPartition( next, suffix ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void delete( Name name ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.delete( next, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public void add( String upName, Name normName, Attributes entry ) throws NamingException | |
{ | |
Entry node = getStartingEntry(); | |
Interceptor head = node.configuration.getInterceptor(); | |
NextInterceptor next = node.nextInterceptor; | |
try | |
{ | |
head.add( next, upName, normName, entry ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public void modify( Name name, int modOp, Attributes mods ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.modify( next, name, modOp, mods ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public void modify( Name name, ModificationItem[] mods ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.modify( next, name, mods ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public NamingEnumeration list( Name base ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.list( next, base ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public NamingEnumeration search( Name base, Map env, ExprNode filter, SearchControls searchCtls ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.search( next, base, env, filter, searchCtls ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Attributes lookup( Name name ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.lookup( next, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Attributes lookup( Name dn, String[] attrIds ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.lookup( next, dn, attrIds ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public boolean hasEntry( Name name ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.hasEntry( next, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public boolean isSuffix( Name name ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
return head.isSuffix( next, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void modifyRn( Name name, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.modifyRn( next, name, newRn, deleteOldRn ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public void move( Name oriChildName, Name newParentName ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.move( next, oriChildName, newParentName ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
public void move( Name oriChildName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
Entry entry = getStartingEntry(); | |
Interceptor head = entry.configuration.getInterceptor(); | |
NextInterceptor next = entry.nextInterceptor; | |
try | |
{ | |
head.move( next, oriChildName, newParentName, newRn, deleteOldRn ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( head, e ); | |
} | |
} | |
/** | |
* Represents an internal entry of this chain. | |
*/ | |
private class Entry | |
{ | |
private Entry prevEntry; | |
private Entry nextEntry; | |
private final InterceptorConfiguration configuration; | |
private final NextInterceptor nextInterceptor; | |
private Entry( Entry prevEntry, Entry nextEntry, | |
InterceptorConfiguration configuration ) | |
{ | |
if( configuration == null ) | |
{ | |
throw new NullPointerException( "configuration" ); | |
} | |
this.prevEntry = prevEntry; | |
this.nextEntry = nextEntry; | |
this.configuration = configuration; | |
this.nextInterceptor = new NextInterceptor() | |
{ | |
private Entry getNextEntry() | |
{ | |
if ( InvocationStack.getInstance().isEmpty() ) | |
{ | |
return Entry.this.nextEntry; | |
} | |
Invocation invocation = InvocationStack.getInstance().peek(); | |
if ( ! invocation.hasBypass() ) | |
{ | |
return Entry.this.nextEntry; | |
} | |
// I don't think we really need this since this check is performed by the chain when | |
// getting the interceptor head to use. | |
// | |
// if ( invocation.isBypassed( DirectoryPartitionNexusProxy.BYPASS_ALL ) ) | |
// { | |
// return tail; | |
// } | |
Entry next = Entry.this.nextEntry; | |
while ( next != tail ) | |
{ | |
if ( invocation.isBypassed( next.configuration.getName() ) ) | |
{ | |
next = next.nextEntry; | |
} | |
else | |
{ | |
return next; | |
} | |
} | |
return next; | |
} | |
public boolean compare( Name name, String oid, Object value ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.compare( next.nextInterceptor, name, oid, value ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Attributes getRootDSE() throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.getRootDSE( next.nextInterceptor ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Name getMatchedName( Name dn, boolean normalized ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.getMatchedName( next.nextInterceptor, dn, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Name getSuffix( Name dn, boolean normalized ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.getSuffix( next.nextInterceptor, dn, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Iterator listSuffixes( boolean normalized ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.listSuffixes( next.nextInterceptor, normalized ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void delete( Name name ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.delete( next.nextInterceptor, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void add( String upName, Name normName, Attributes entry ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.add( next.nextInterceptor, upName, normName, entry ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void modify( Name name, int modOp, Attributes mods ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.modify( next.nextInterceptor, name, modOp, mods ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void modify( Name name, ModificationItem[] mods ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.modify( next.nextInterceptor, name, mods ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public NamingEnumeration list( Name base ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.list( next.nextInterceptor, base ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public NamingEnumeration search( Name base, Map env, ExprNode filter, SearchControls searchCtls ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.search( next.nextInterceptor, base, env, filter, searchCtls ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Attributes lookup( Name name ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.lookup( next.nextInterceptor, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public Attributes lookup( Name dn, String[] attrIds ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.lookup( next.nextInterceptor, dn, attrIds ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public boolean hasEntry( Name name ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.hasEntry( next.nextInterceptor, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public boolean isSuffix( Name name ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
return interceptor.isSuffix( next.nextInterceptor, name ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void modifyRn( Name name, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.modifyRn( next.nextInterceptor, name, newRn, deleteOldRn ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void move( Name oriChildName, Name newParentName ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.move( next.nextInterceptor, oriChildName, newParentName ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void move( Name oriChildName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.move( next.nextInterceptor, oriChildName, newParentName, newRn, deleteOldRn ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
} | |
} | |
public void addContextPartition( DirectoryPartitionConfiguration cfg ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.addContextPartition( next.nextInterceptor, cfg ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
public void removeContextPartition( Name suffix ) throws NamingException | |
{ | |
Entry next = getNextEntry(); | |
Interceptor interceptor = next.configuration.getInterceptor(); | |
try | |
{ | |
interceptor.removeContextPartition( next.nextInterceptor, suffix ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw ne; | |
} | |
catch ( Throwable e ) | |
{ | |
throwInterceptorException( interceptor, e ); | |
throw new InternalError(); // Should be unreachable | |
} | |
} | |
}; | |
} | |
} | |
private static void throwInterceptorException( Interceptor interceptor, Throwable e ) throws InterceptorException | |
{ | |
throw new InterceptorException( interceptor, "Unexpected exception.", e ); | |
} | |
} |