You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/01/13 06:32:08 UTC
svn commit: r368602 - in /directory/trunks:
apacheds/src/main/java/org/apache/ldap/server/configuration/
apacheds/src/main/java/org/apache/ldap/server/jndi/
apacheds/src/main/java/org/apache/ldap/server/partition/
apacheds/src/main/java/org/apache/ldap...
Author: akarasulu
Date: Thu Jan 12 21:31:56 2006
New Revision: 368602
URL: http://svn.apache.org/viewcvs?rev=368602&view=rev
Log:
partial commit of referral stuff ... in the works
Added:
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java (with props)
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java (with props)
directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/
directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java (with props)
directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java (with props)
Modified:
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerContext.java
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerDirContext.java
directory/trunks/apacheds/src/main/java/org/apache/ldap/server/partition/DirectoryPartitionNexusProxy.java
directory/trunks/apacheds/src/test/java/org/apache/ldap/server/jndi/RootDSETest.java
Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java?rev=368602&r1=368601&r2=368602&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java Thu Jan 12 21:31:56 2006
@@ -36,6 +36,7 @@
import org.apache.ldap.server.exception.ExceptionService;
import org.apache.ldap.server.normalization.NormalizationService;
import org.apache.ldap.server.operational.OperationalAttributeService;
+import org.apache.ldap.server.referral.ReferralService;
import org.apache.ldap.server.schema.SchemaService;
import org.apache.ldap.server.schema.bootstrap.*;
import org.apache.ldap.server.subtree.SubentryService;
@@ -159,6 +160,11 @@
interceptorCfg = new MutableInterceptorConfiguration();
interceptorCfg.setName( "schemaService" );
interceptorCfg.setInterceptor( new SchemaService() );
+ list.add( interceptorCfg );
+
+ interceptorCfg = new MutableInterceptorConfiguration();
+ interceptorCfg.setName( "referralService" );
+ interceptorCfg.setInterceptor( new ReferralService() );
list.add( interceptorCfg );
interceptorCfg = new MutableInterceptorConfiguration();
Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerContext.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerContext.java?rev=368602&r1=368601&r2=368602&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerContext.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerContext.java Thu Jan 12 21:31:56 2006
@@ -298,19 +298,9 @@
attributes.put( rdnAttribute, rdnValue );
attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.JCONTAINER_ATTR );
attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.TOP_ATTR );
-
- /*
- * Add the new context to the server which as a side effect adds
- * operational attributes to the attributes refering instance which
- * can them be used to initialize a new ServerLdapContext. Remember
- * we need to copy over the controls as well to propagate the complete
- * environment besides whats in the hashtable for env.
- */
+
nexusProxy.add( target.toString(), target, attributes );
- ServerLdapContext ctx = new ServerLdapContext( principal, nexusProxy, env, target );
- Control [] controls = ( Control [] ) ( ( ServerLdapContext ) this ).getRequestControls().clone();
- ctx.setRequestControls( controls );
- return ctx;
+ return new ServerLdapContext( principal, nexusProxy, env, target );
}
Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerDirContext.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerDirContext.java?rev=368602&r1=368601&r2=368602&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerDirContext.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/jndi/ServerDirContext.java Thu Jan 12 21:31:56 2006
@@ -35,7 +35,6 @@
import javax.naming.directory.SearchControls;
import javax.naming.event.EventDirContext;
import javax.naming.event.NamingListener;
-import javax.naming.ldap.Control;
import javax.naming.spi.DirStateFactory;
import javax.naming.spi.DirectoryManager;
@@ -350,24 +349,9 @@
attributes.put( rdnAttribute, rdnValue );
}
- // Add the new context to the server which as a side effect adds
+ // Add the new entry to the server and return the new context
getNexusProxy().add( target.toString(), target, attributes );
-
- // Initialize the new context
- ServerLdapContext ctx = new ServerLdapContext( getPrincipal(), getNexusProxy(), getEnvironment(), target );
- Control [] controls = ( ( ServerLdapContext ) this ).getRequestControls();
-
- if ( controls != null )
- {
- controls = ( Control[] ) controls.clone();
- }
- else
- {
- controls = new Control[0];
- }
-
- ctx.setRequestControls( controls );
- return ctx;
+ return new ServerLdapContext( getPrincipal(), getNexusProxy(), getEnvironment(), target );
}
Modified: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/partition/DirectoryPartitionNexusProxy.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/partition/DirectoryPartitionNexusProxy.java?rev=368602&r1=368601&r2=368602&view=diff
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/partition/DirectoryPartitionNexusProxy.java (original)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/partition/DirectoryPartitionNexusProxy.java Thu Jan 12 21:31:56 2006
@@ -91,6 +91,7 @@
c.add( "schemaService" );
c.add( "subentryService" );
c.add( "operationalAttributeService" );
+ c.add( "referralService" );
c.add( "eventService" );
LOOKUP_BYPASS = Collections.unmodifiableCollection( c );
@@ -101,6 +102,7 @@
c.add( "schemaService" );
c.add( "subentryService" );
c.add( "operationalAttributeService" );
+ c.add( "referralService" );
c.add( "eventService" );
GETMATCHEDDN_BYPASS = Collections.unmodifiableCollection( c );
}
Added: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java?rev=368602&view=auto
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java (added)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java Thu Jan 12 21:31:56 2006
@@ -0,0 +1,296 @@
+/*
+ * 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.referral;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+
+import org.apache.ldap.common.name.LdapName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A simple lookup table of normalized referral distinguished names.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ReferralLut
+{
+ /** the logger for this class */
+ private static final Logger log = LoggerFactory.getLogger( ReferralLut.class );
+ /** the set of names in the LUT */
+ private Set names = new HashSet();
+
+
+ // -----------------------------------------------------------------------
+ // Methods to access the LUT: all names are expected to be normalized
+ // -----------------------------------------------------------------------
+
+
+ /**
+ * Checks if a the entry at a name is a referral.
+ *
+ * @param dn the normalized name of the referral
+ */
+ public boolean isReferral( Name dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ return names.contains( dn.toString() );
+ }
+
+
+ /**
+ * Checks if a the entry at a name is a referral.
+ *
+ * @param dn the normalized name of the referral
+ */
+ public boolean isReferral( String dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ return names.contains( dn );
+ }
+
+
+ /**
+ * Gets the normalized name of the farthest ancestor that is a referral. If the argument
+ * is a referral it will not be returned. Only ancestor's (includes parent) are considered.
+ *
+ * @param dn the name to get the farthest ancestor referral name for
+ * @return the farthest referral ancestor
+ */
+ public Name getFarthestReferralAncestor( Name dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ Name farthest = new LdapName();
+ for ( int ii = 0; ii < dn.size(); ii++ )
+ {
+ try
+ {
+ farthest.add( dn.get( ii ) );
+ }
+ catch ( InvalidNameException e )
+ {
+ log.error( "Should never get this when moving names from a proper normalized name!", e );
+ }
+ // do not return dn if it is the farthest referral
+ if ( isReferral( farthest ) && farthest.size() != dn.size() )
+ {
+ return farthest;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Gets the normalized name of the nearest ancestor that is a referral. If the argument
+ * is a referral it will not be returned. Only ancestor's (includes parent) are considered.
+ *
+ * @param dn the name to get the nearest ancestor referral name for
+ * @return the nearest referral ancestor or null if one does not exist
+ */
+ public Name getNearestReferralAncestor( Name dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ Name cloned = ( Name ) dn.clone();
+
+ // do not return the argument dn if it is a referral (skip it)
+ if ( cloned.size() > 0 )
+ {
+ try
+ {
+ cloned.remove( cloned.size() - 1 );
+ }
+ catch ( InvalidNameException e )
+ {
+ log.error( "Should never get this when removing from a cloned normalized name!", e );
+ }
+ }
+ else
+ {
+ return null;
+ }
+
+ while ( ! isReferral( cloned ) && cloned.size() > 0 )
+ {
+ try
+ {
+ cloned.remove( cloned.size() - 1 );
+ }
+ catch ( InvalidNameException e )
+ {
+ log.error( "Should never get this when removing from a cloned normalized name!", e );
+ }
+ }
+ return cloned.isEmpty() ? null : cloned;
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Methods that notify this lookup table of changes to referrals
+ // -----------------------------------------------------------------------
+
+
+ /**
+ * Called to add an entry to the LUT when a referral is added.
+ *
+ * @param dn the normalized name of the added referral
+ */
+ public void referralAdded( Name dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ if ( ! names.add( dn.toString() ) && log.isWarnEnabled() )
+ {
+ log.warn( "found " + dn + " in refname lut while adding it" );
+ }
+ }
+
+
+ /**
+ * Called to add an entry to the LUT when a referral is added.
+ *
+ * @param dn the normalized name of the added referral
+ */
+ public void referralAdded( String dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ if ( ! names.add( dn ) && log.isWarnEnabled() )
+ {
+ log.warn( "found " + dn + " in refname lut while adding it" );
+ }
+ }
+
+
+ /**
+ * Called delete an entry from the LUT when a referral is deleted.
+ *
+ * @param dn the normalized name of the deleted referral
+ */
+ public void referralDeleted( Name dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ if ( ! names.remove( dn.toString() ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find " + dn + " in refname lut while deleting it" );
+ }
+ }
+
+
+ /**
+ * Called delete an entry from the LUT when a referral is deleted.
+ *
+ * @param dn the normalized name of the deleted referral
+ */
+ public void referralDeleted( String dn )
+ {
+ if ( dn == null ) throw new IllegalArgumentException( "dn cannot be null" );
+ if ( ! names.remove( dn ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find " + dn + " in refname lut while deleting it" );
+ }
+ }
+
+
+ /**
+ * Called to update the LUT when the name of the referral changes due to
+ * a rename or move in the DIT.
+ *
+ * @param oldDn the normalized old name for the referral
+ * @param newDn the normalized new name for the referral
+ */
+ public void referralChanged( Name oldDn, Name newDn )
+ {
+ if ( oldDn == null || newDn == null ) throw new IllegalArgumentException( "old or new dn cannot be null" );
+ if ( ! names.remove( oldDn.toString() ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find old name (" + oldDn + ") in refname lut while moving or renaming it" );
+ }
+ if ( ! names.add( newDn.toString() ) && log.isWarnEnabled() )
+ {
+ log.warn( "found new name (" + newDn + ") in refname lut while moving or renaming " + oldDn );
+ }
+ }
+
+
+ /**
+ * Called to update the LUT when the name of the referral changes due to
+ * a rename or move in the DIT.
+ *
+ * @param oldDn the normalized old name for the referral
+ * @param newDn the normalized new name for the referral
+ */
+ public void referralChanged( String oldDn, String newDn )
+ {
+ if ( oldDn == null || newDn == null ) throw new IllegalArgumentException( "old or new dn cannot be null" );
+ if ( ! names.remove( oldDn ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find old name (" + oldDn + ") in refname lut while moving or renaming it" );
+ }
+ if ( ! names.add( newDn ) && log.isWarnEnabled() )
+ {
+ log.warn( "found new name (" + newDn + ") in refname lut while moving or renaming " + oldDn );
+ }
+ }
+
+
+ /**
+ * Called to update the LUT when the name of the referral changes due to
+ * a rename or move in the DIT.
+ *
+ * @param oldDn the normalized old name for the referral
+ * @param newDn the normalized new name for the referral
+ */
+ public void referralChanged( Name oldDn, String newDn )
+ {
+ if ( oldDn == null || newDn == null ) throw new IllegalArgumentException( "old or new dn cannot be null" );
+ if ( ! names.remove( oldDn.toString() ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find old name (" + oldDn + ") in refname lut while moving or renaming it" );
+ }
+ if ( ! names.add( newDn ) && log.isWarnEnabled() )
+ {
+ log.warn( "found new name (" + newDn + ") in refname lut while moving or renaming " + oldDn );
+ }
+ }
+
+
+ /**
+ * Called to update the LUT when the name of the referral changes due to
+ * a rename or move in the DIT.
+ *
+ * @param oldDn the normalized old name for the referral
+ * @param newDn the normalized new name for the referral
+ */
+ public void referralChanged( String oldDn, Name newDn )
+ {
+ if ( oldDn == null || newDn == null ) throw new IllegalArgumentException( "old or new dn cannot be null" );
+ if ( ! names.remove( oldDn ) && log.isWarnEnabled() )
+ {
+ log.warn( "cound not find old name (" + oldDn + ") in refname lut while moving or renaming it" );
+ }
+ if ( ! names.add( newDn ) && log.isWarnEnabled() )
+ {
+ log.warn( "found new name (" + newDn + ") in refname lut while moving or renaming " + oldDn );
+ }
+ }
+}
Propchange: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralLut.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java?rev=368602&view=auto
==============================================================================
--- directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java (added)
+++ directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java Thu Jan 12 21:31:56 2006
@@ -0,0 +1,559 @@
+/*
+ * 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.referral;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.commons.lang.NotImplementedException;
+
+import org.apache.ldap.common.codec.util.LdapURL;
+import org.apache.ldap.common.codec.util.LdapURLEncodingException;
+import org.apache.ldap.common.exception.LdapNamingException;
+import org.apache.ldap.common.exception.LdapReferralException;
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.LeafNode;
+import org.apache.ldap.common.filter.SimpleNode;
+import org.apache.ldap.common.message.ResultCodeEnum;
+import org.apache.ldap.common.name.DnParser;
+import org.apache.ldap.common.name.LdapName;
+import org.apache.ldap.server.DirectoryServiceConfiguration;
+import org.apache.ldap.server.configuration.DirectoryPartitionConfiguration;
+import org.apache.ldap.server.configuration.InterceptorConfiguration;
+import org.apache.ldap.server.interceptor.BaseInterceptor;
+import org.apache.ldap.server.interceptor.NextInterceptor;
+import org.apache.ldap.server.invocation.Invocation;
+import org.apache.ldap.server.invocation.InvocationStack;
+import org.apache.ldap.server.jndi.ServerLdapContext;
+import org.apache.ldap.server.partition.DirectoryPartition;
+import org.apache.ldap.server.partition.DirectoryPartitionNexus;
+import org.apache.ldap.server.partition.DirectoryPartitionNexusProxy;
+import org.apache.ldap.server.schema.AttributeTypeRegistry;
+import org.apache.ldap.server.schema.ConcreteNameComponentNormalizer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An service which is responsible referral handling behavoirs. It manages
+ * referral handling behavoir when the {@link Context.REFERRAL} is implicitly
+ * or explicitly set to "ignore", when set to "throw" and when set to "follow".
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ReferralService extends BaseInterceptor
+{
+ private static final Logger log = LoggerFactory.getLogger( ReferralService.class );
+ private static final String IGNORE = "ignore";
+ private static final String THROW = "throw";
+ private static final String FOLLOW = "follow";
+ private static final String REFERRAL_OC = "referral";
+ private static final String OBJCLASS_ATTR = "objectClass";
+ private static final Collection SEARCH_BYPASS;
+ private static final String REF_ATTR = "ref";
+
+ private ReferralLut lut = new ReferralLut();
+ private DnParser parser;
+ private Hashtable env;
+
+ static
+ {
+ /*
+ * These are the services that we will bypass while searching for referrals in
+ * partitions of the system during startup and during add/remove partition ops
+ */
+ Collection c = new HashSet();
+ c.add( "normalizationService" );
+ c.add( "authenticationService" );
+ c.add( "authorizationService" );
+ c.add( "oldAuthorizationService" );
+ c.add( "schemaService" );
+ c.add( "subentryService" );
+ c.add( "operationalAttributeService" );
+ c.add( "referralService" );
+ c.add( "eventService" );
+ SEARCH_BYPASS = Collections.unmodifiableCollection( c );
+ }
+
+
+ static boolean hasValue( Attribute attr, String value ) throws NamingException
+ {
+ if ( attr == null )
+ {
+ return false;
+ }
+ for ( int ii = 0; ii < attr.size(); ii++ )
+ {
+ if ( ! ( attr.get( ii ) instanceof String ) )
+ {
+ continue;
+ }
+ if ( value.equalsIgnoreCase( ( String ) attr.get( ii ) ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ static boolean isReferral( Attributes entry ) throws NamingException
+ {
+ Attribute oc = entry.get( OBJCLASS_ATTR );
+ if ( oc == null )
+ {
+ log.warn( "could not find objectClass attribute in entry: " + entry );
+ return false;
+ }
+ for ( int ii = 0; ii < oc.size(); ii++ )
+ {
+ if ( REFERRAL_OC.equalsIgnoreCase( ( String ) oc.get( ii ) ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public void init( DirectoryServiceConfiguration dsConfig, InterceptorConfiguration cfg ) throws NamingException
+ {
+ DirectoryPartitionNexus nexus = dsConfig.getPartitionNexus();
+ AttributeTypeRegistry atr = dsConfig.getGlobalRegistries().getAttributeTypeRegistry();
+ parser = new DnParser( new ConcreteNameComponentNormalizer( atr ) );
+ env = dsConfig.getEnvironment();
+
+ Iterator suffixes = nexus.listSuffixes( true );
+ while ( suffixes.hasNext() )
+ {
+ Name suffix = new LdapName( ( String ) suffixes.next() );
+ addReferrals( nexus.search( suffix, env, getReferralFilter(), getControls() ), suffix );
+ }
+ }
+
+
+ public void add( NextInterceptor next, String upName, Name normName, Attributes entry ) throws NamingException
+ {
+ Invocation invocation = InvocationStack.getInstance().peek();
+ ServerLdapContext caller = ( ServerLdapContext ) invocation.getCaller();
+ String refval = ( String ) caller.getEnvironment().get( Context.REFERRAL );
+
+ // handle updating the lut
+ if ( isReferral( entry ) )
+ {
+ lut.referralAdded( normName );
+ }
+
+ // handle a normal add without following referrals
+ if ( refval == null || refval.equals( IGNORE ) )
+ {
+ next.add( upName, normName, entry );
+ return;
+ }
+
+ if ( refval.equals( THROW ) )
+ {
+ Name farthest = lut.getFarthestReferralAncestor( normName );
+ if ( farthest == null )
+ {
+ next.add( upName, normName, entry );
+ return;
+ }
+
+ // handle referral here
+ Attributes referral = invocation.getProxy().lookup( farthest, DirectoryPartitionNexusProxy.LOOKUP_BYPASS );
+ Attribute refs = referral.get( REF_ATTR );
+ List list = new ArrayList( refs.size() );
+ for ( int ii = 0; ii < refs.size(); ii++ )
+ {
+ String val = ( String ) refs.get( ii );
+
+ // need to add non-ldap URLs as-is
+ if ( ! val.startsWith( "ldap" ) )
+ {
+ list.add( val );
+ continue;
+ }
+
+ // parse the ref value and normalize the DN according to schema
+ LdapURL ldapUrl = new LdapURL();
+ try
+ {
+ ldapUrl.parse( val.toCharArray() );
+ }
+ catch ( LdapURLEncodingException e )
+ {
+ log.error( "Bad URL ("+ val +") for ref in " + farthest + ". Reference will be ignored." );
+ }
+
+ Name urlDn = parser.parse( ldapUrl.getDn().toString() );
+ if ( urlDn.equals( farthest ) )
+ {
+ // according to the protocol there is no need for the dn since it is the same as this request
+ list.add( ldapUrl.getScheme() + "://" + ldapUrl.getHost() );
+ continue;
+ }
+
+ /*
+ * If we get here then the DN of the referral was not the same as the
+ * DN of the ref LDAP URL. We must calculate the remaining (difference)
+ * name past the farthest referral DN which the target name extends.
+ */
+ Name upNameAsName = new LdapName( upName );
+ int diff = normName.size() - farthest.size();
+ Name extra = new LdapName();
+ for ( int jj = 0; jj < diff; jj++ )
+ {
+ extra.add( upNameAsName.get( farthest.size() + jj ) );
+ }
+
+ urlDn.addAll( extra );
+ list.add( ldapUrl.getScheme() + "://" + ldapUrl.getHost() + "/" + urlDn );
+ }
+ LdapReferralException lre = new LdapReferralException( getRefs( referral ) );
+ throw lre;
+ }
+ else if ( refval.equals( FOLLOW ) )
+ {
+ throw new NotImplementedException( FOLLOW + " referral handling mode not implemented" );
+ }
+ else
+ {
+ throw new LdapNamingException( "Undefined value for " + Context.REFERRAL + " key: "
+ + refval, ResultCodeEnum.OTHER );
+ }
+ }
+
+
+ static List getRefs( Attributes referral ) throws NamingException
+ {
+ Attribute ref = referral.get( REF_ATTR );
+ List list = new ArrayList( ref.size() );
+ for ( int ii = 0; ii < ref.size(); ii++ )
+ {
+ list.add( ref.get( ii ) );
+ }
+ return list;
+ }
+
+
+ public void delete( NextInterceptor next, Name normName ) throws NamingException
+ {
+ Invocation invocation = InvocationStack.getInstance().peek();
+ ServerLdapContext caller = ( ServerLdapContext ) invocation.getCaller();
+ String refval = ( String ) caller.getEnvironment().get( Context.REFERRAL );
+
+ // handle updating the lut
+ if ( lut.isReferral( normName ) )
+ {
+ lut.referralDeleted( normName );
+ }
+
+ // handle a normal delete without following referrals
+ if ( refval == null || refval.equals( IGNORE ) )
+ {
+ next.delete( normName );
+ return;
+ }
+
+ if ( refval.equals( THROW ) )
+ {
+ Name farthest = lut.getFarthestReferralAncestor( normName );
+ if ( farthest == null )
+ {
+ next.delete( normName );
+ return;
+ }
+
+ // handle referral here
+ }
+ else if ( refval.equals( FOLLOW ) )
+ {
+ throw new NotImplementedException( FOLLOW + " referral handling mode not implemented" );
+ }
+ else
+ {
+ throw new LdapNamingException( "Undefined value for " + Context.REFERRAL + " key: "
+ + refval, ResultCodeEnum.OTHER );
+ }
+ }
+
+
+ public void move( NextInterceptor next, Name oldName, Name newParent ) throws NamingException
+ {
+ next.move( oldName, newParent );
+
+ // update the lut of a referral is being moved
+ if ( lut.isReferral( oldName ) )
+ {
+ Name newName = ( Name ) newParent.clone();
+ newName.add( oldName.get( oldName.size() - 1 ) );
+ lut.referralChanged( oldName, newName );
+ }
+ }
+
+
+ public void move( NextInterceptor next, Name oldName, Name newParent, String newRdn, boolean deleteOldRdn )
+ throws NamingException
+ {
+ next.move( oldName, newParent, newRdn, deleteOldRdn );
+
+ // update the lut of a referral is being moved
+ if ( lut.isReferral( oldName ) )
+ {
+ Name newName = ( Name ) newParent.clone();
+ newName.add( newRdn );
+ lut.referralChanged( oldName, newName );
+ }
+ }
+
+
+ public void modifyRdn( NextInterceptor next, Name oldName, Name newParent, String newRdn, boolean deleteOldRdn )
+ throws NamingException
+ {
+ next.modifyRn( oldName, newRdn, deleteOldRdn );
+
+ // update the lut of a referral is being renamed
+ if ( lut.isReferral( oldName ) )
+ {
+ Name newName = ( Name ) newParent.clone();
+ newName.add( newRdn );
+ lut.referralChanged( oldName, newName );
+ }
+ }
+
+
+ public void modify( NextInterceptor next, Name name, int modOp, Attributes mods ) throws NamingException
+ {
+ next.modify( name, modOp, mods );
+
+ // -------------------------------------------------------------------
+ // Check and update lut if we change the objectClass
+ // -------------------------------------------------------------------
+
+ boolean isTargetReferral = lut.isReferral( name );
+ boolean isOcChange = mods.get( OBJCLASS_ATTR ) != null;
+ boolean modsOcHasReferral = hasValue( mods.get( OBJCLASS_ATTR ), REFERRAL_OC );
+ if ( isOcChange )
+ {
+ switch ( modOp )
+ {
+ /*
+ * if ADD op where refferal is added to objectClass of a
+ * non-referral entry then we add a new referral to lut
+ */
+ case( DirContext.ADD_ATTRIBUTE ):
+ if ( modsOcHasReferral && !isTargetReferral )
+ {
+ lut.referralAdded( name );
+ }
+ break;
+ /*
+ * if REMOVE op where refferal is removed from objectClass of a
+ * referral entry then we remove the referral from lut
+ */
+ case( DirContext.REMOVE_ATTRIBUTE ):
+ if ( modsOcHasReferral && isTargetReferral )
+ {
+ lut.referralDeleted( name );
+ }
+ break;
+ /*
+ * if REPLACE op on referral has new set of OC values which does
+ * not contain a referral value then we remove the referral from
+ * the lut
+ *
+ * if REPLACE op on non-referral has new set of OC values with
+ * referral value then we add the new referral to the lut
+ */
+ case( DirContext.REPLACE_ATTRIBUTE ):
+ if ( isTargetReferral && ! modsOcHasReferral )
+ {
+ lut.referralDeleted( name );
+ }
+ else if ( ! isTargetReferral && modsOcHasReferral )
+ {
+ lut.referralAdded( name );
+ }
+ break;
+ default:
+ throw new IllegalStateException( "undefined modification operation" );
+ }
+ }
+ }
+
+
+ public void modify( NextInterceptor next, Name name, ModificationItem[] mods ) throws NamingException
+ {
+ boolean isTargetReferral = lut.isReferral( name );
+ next.modify( name, mods );
+
+ // -------------------------------------------------------------------
+ // Check and update lut if we change the objectClass
+ // -------------------------------------------------------------------
+
+ for ( int ii = 0; ii < mods.length; ii++ )
+ {
+ if ( mods[ii].getAttribute().getID().equalsIgnoreCase( OBJCLASS_ATTR ) )
+ {
+ boolean modsOcHasReferral = hasValue( mods[ii].getAttribute(), REFERRAL_OC );
+
+ switch ( mods[ii].getModificationOp() )
+ {
+ /*
+ * if ADD op where refferal is added to objectClass of a
+ * non-referral entry then we add a new referral to lut
+ */
+ case( DirContext.ADD_ATTRIBUTE ):
+ if ( modsOcHasReferral && !isTargetReferral )
+ {
+ lut.referralAdded( name );
+ }
+ break;
+ /*
+ * if REMOVE op where refferal is removed from objectClass of a
+ * referral entry then we remove the referral from lut
+ */
+ case( DirContext.REMOVE_ATTRIBUTE ):
+ if ( modsOcHasReferral && isTargetReferral )
+ {
+ lut.referralDeleted( name );
+ }
+ break;
+ /*
+ * if REPLACE op on referral has new set of OC values which does
+ * not contain a referral value then we remove the referral from
+ * the lut
+ *
+ * if REPLACE op on non-referral has new set of OC values with
+ * referral value then we add the new referral to the lut
+ */
+ case( DirContext.REPLACE_ATTRIBUTE ):
+ if ( isTargetReferral && ! modsOcHasReferral )
+ {
+ lut.referralDeleted( name );
+ }
+ else if ( ! isTargetReferral && modsOcHasReferral )
+ {
+ lut.referralAdded( name );
+ }
+ break;
+ default:
+ throw new IllegalStateException( "undefined modification operation" );
+ }
+
+ break;
+ }
+ }
+ }
+
+
+ static ExprNode getReferralFilter()
+ {
+ return new SimpleNode( OBJCLASS_ATTR, REFERRAL_OC, LeafNode.EQUALITY );
+ }
+
+
+ static SearchControls getControls()
+ {
+ SearchControls controls = new SearchControls();
+ controls.setReturningObjFlag( false );
+ controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+ return controls;
+ }
+
+
+ public void addContextPartition( NextInterceptor next, DirectoryPartitionConfiguration cfg ) throws NamingException
+ {
+ next.addContextPartition( cfg );
+
+ // add referrals immediately after adding the new partition
+ DirectoryPartition partition = cfg.getContextPartition();
+ Name suffix = partition.getSuffix( true );
+ Invocation invocation = InvocationStack.getInstance().peek();
+ NamingEnumeration list = invocation.getProxy().search( suffix, env, getReferralFilter(), getControls(), SEARCH_BYPASS );
+ addReferrals( list, suffix );
+ }
+
+
+ public void removeContextPartition( NextInterceptor next, Name suffix ) throws NamingException
+ {
+ // remove referrals immediately before removing the partition
+ Invocation invocation = InvocationStack.getInstance().peek();
+ NamingEnumeration list = invocation.getProxy().search( suffix, env, getReferralFilter(), getControls(), SEARCH_BYPASS );
+ deleteReferrals( list, suffix );
+
+ next.removeContextPartition( suffix );
+ }
+
+
+ private void addReferrals( NamingEnumeration referrals, Name base ) throws NamingException
+ {
+ while ( referrals.hasMore() )
+ {
+ SearchResult r = ( SearchResult ) referrals.next();
+ Name referral = null;
+ if ( r.isRelative() )
+ {
+ referral = ( Name ) base.clone();
+ referral.addAll( parser.parse( r.getName() ) );
+ }
+ else
+ {
+ referral = parser.parse( r.getName() );
+ }
+ }
+ }
+
+
+ private void deleteReferrals( NamingEnumeration referrals, Name base ) throws NamingException
+ {
+ while ( referrals.hasMore() )
+ {
+ SearchResult r = ( SearchResult ) referrals.next();
+ Name referral = null;
+ if ( r.isRelative() )
+ {
+ referral = ( Name ) base.clone();
+ referral.addAll( parser.parse( r.getName() ) );
+ }
+ else
+ {
+ referral = parser.parse( r.getName() );
+ }
+ }
+ }
+}
Propchange: directory/trunks/apacheds/src/main/java/org/apache/ldap/server/referral/ReferralService.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: directory/trunks/apacheds/src/test/java/org/apache/ldap/server/jndi/RootDSETest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/test/java/org/apache/ldap/server/jndi/RootDSETest.java?rev=368602&r1=368601&r2=368602&view=diff
==============================================================================
--- directory/trunks/apacheds/src/test/java/org/apache/ldap/server/jndi/RootDSETest.java (original)
+++ directory/trunks/apacheds/src/test/java/org/apache/ldap/server/jndi/RootDSETest.java Thu Jan 12 21:31:56 2006
@@ -154,7 +154,6 @@
Attributes attributes = ctx.getAttributes( "" );
// Added some objectClass attributes to the rootDSE
-
assertEquals( 2, attributes.size() );
}
Added: directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java?rev=368602&view=auto
==============================================================================
--- directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java (added)
+++ directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java Thu Jan 12 21:31:56 2006
@@ -0,0 +1,161 @@
+/*
+ * 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.referral;
+
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+
+import org.apache.ldap.common.name.LdapName;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Unit tests for ReferralLut.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ReferralLutTest extends TestCase
+{
+ public void testNullLimits()
+ {
+ ReferralLut lut = new ReferralLut();
+ try { lut.isReferral( ( String ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.isReferral( ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.getFarthestReferralAncestor( ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.getNearestReferralAncestor( ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralAdded( ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralAdded( ( String ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralDeleted( ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralDeleted( ( String ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralChanged( ( Name ) null, ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralChanged( ( String ) null, ( String ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralChanged( ( Name ) null, ( String ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ try { lut.referralChanged( ( String ) null, ( Name ) null ); fail( "can't get here" ); } catch( IllegalArgumentException e ) {}
+ }
+
+
+ public void testUpdateOperations() throws NamingException
+ {
+ String dn = "ou=users,ou=system";
+ Name name = new LdapName( dn );
+ ReferralLut lut = new ReferralLut();
+
+ // some add delete tests
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralDeleted( dn );
+ assertFalse( lut.isReferral( dn ) );
+
+ assertFalse( lut.isReferral( name ) );
+ lut.referralAdded( name );
+ assertTrue( lut.isReferral( name ) );
+ lut.referralDeleted( name );
+ assertFalse( lut.isReferral( name ) );
+
+ assertFalse( lut.isReferral( name ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( name ) );
+ lut.referralDeleted( name );
+ assertFalse( lut.isReferral( name ) );
+
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( name );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralDeleted( dn );
+ assertFalse( lut.isReferral( dn ) );
+
+ assertFalse( lut.isReferral( name ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( name ) );
+ lut.referralDeleted( dn );
+ assertFalse( lut.isReferral( name ) );
+
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( name );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralDeleted( name );
+ assertFalse( lut.isReferral( dn ) );
+
+ // change (rename and move) tests
+ String newDn = "ou=people,ou=system";
+ Name newName = new LdapName( newDn );
+
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralChanged( dn, newDn );
+ assertFalse( lut.isReferral( dn ) );
+ assertTrue( lut.isReferral( newDn ) );
+ lut.referralDeleted( dn );
+
+ assertFalse( lut.isReferral( name ) );
+ lut.referralAdded( name );
+ assertTrue( lut.isReferral( name ) );
+ lut.referralChanged( name, newName );
+ assertFalse( lut.isReferral( name ) );
+ assertTrue( lut.isReferral( newName ) );
+ lut.referralDeleted( name );
+
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralChanged( dn, newName );
+ assertFalse( lut.isReferral( dn ) );
+ assertTrue( lut.isReferral( newDn ) );
+ lut.referralDeleted( dn );
+
+ assertFalse( lut.isReferral( dn ) );
+ lut.referralAdded( dn );
+ assertTrue( lut.isReferral( dn ) );
+ lut.referralChanged( name, newDn );
+ assertFalse( lut.isReferral( dn ) );
+ assertTrue( lut.isReferral( newDn ) );
+ lut.referralDeleted( dn );
+ }
+
+
+ public void testReferralAncestors() throws NamingException
+ {
+ Name ancestor = new LdapName( "ou=users,ou=system" );
+ Name farthest = new LdapName( "ou=system" );
+ Name nearest = new LdapName( "ou=apache,ou=users,ou=system" );
+ Name testDn = new LdapName( "cn=Alex Karasulu,ou=apache,ou=users,ou=system" );
+ ReferralLut lut = new ReferralLut();
+ assertNull( lut.getNearestReferralAncestor( testDn ) );
+ assertNull( lut.getFarthestReferralAncestor( testDn ) );
+ lut.referralAdded( testDn );
+ assertNull( lut.getNearestReferralAncestor( testDn ) );
+ assertNull( lut.getFarthestReferralAncestor( testDn ) );
+ lut.referralDeleted( testDn );
+ lut.referralAdded( ancestor );
+ assertEquals( ancestor, lut.getNearestReferralAncestor( testDn ) );
+ assertEquals( ancestor, lut.getFarthestReferralAncestor( testDn ) );
+ lut.referralAdded( testDn );
+ assertEquals( ancestor, lut.getNearestReferralAncestor( testDn ) );
+ assertEquals( ancestor, lut.getFarthestReferralAncestor( testDn ) );
+ lut.referralAdded( nearest );
+ assertEquals( nearest, lut.getNearestReferralAncestor( testDn ) );
+ assertEquals( ancestor, lut.getFarthestReferralAncestor( testDn ) );
+ lut.referralAdded( farthest );
+ assertEquals( nearest, lut.getNearestReferralAncestor( testDn ) );
+ assertEquals( farthest, lut.getFarthestReferralAncestor( testDn ) );
+ }
+}
Propchange: directory/trunks/apacheds/src/test/java/org/apache/ldap/server/referral/ReferralLutTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java
URL: http://svn.apache.org/viewcvs/directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java?rev=368602&view=auto
==============================================================================
--- directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java (added)
+++ directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java Thu Jan 12 21:31:56 2006
@@ -0,0 +1,110 @@
+/*
+ * 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.common.exception;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.ReferralException;
+
+import org.apache.ldap.common.NotImplementedException;
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * A ReferralException which associates a resultCode namely the
+ * {@link ResultCodeEnum#REFERRAL} resultCode with the exception.
+ *
+ * @see LdapException
+ * @see ReferralException
+ * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jndi/jndi-ldap-gl.html#EXCEPT">
+ * LDAP ResultCode to JNDI Exception Mappings</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class LdapReferralException extends ReferralException implements LdapException
+{
+ static final long serialVersionUID = -8611970137960601723L;
+ private final List refs;
+ private int index = 0;
+
+
+ /**
+ * @see ReferralException#ReferralException()
+ */
+ public LdapReferralException( Collection refs )
+ {
+ this.refs = new ArrayList( refs );
+ }
+
+
+ /**
+ * @see ReferralException#ReferralException(java.lang.String)
+ */
+ public LdapReferralException( Collection refs, String explanation )
+ {
+ super( explanation );
+ this.refs = new ArrayList( refs );
+ }
+
+
+ /**
+ * Always returns {@link ResultCodeEnum#REFERRAL}
+ *
+ * @see LdapException#getResultCode()
+ */
+ public ResultCodeEnum getResultCode()
+ {
+ return ResultCodeEnum.REFERRAL;
+ }
+
+
+ public Object getReferralInfo()
+ {
+ return refs.get( index );
+ }
+
+
+ public Context getReferralContext() throws NamingException
+ {
+ throw new NotImplementedException();
+ }
+
+
+ public Context getReferralContext( Hashtable arg ) throws NamingException
+ {
+ throw new NotImplementedException();
+ }
+
+
+ public boolean skipReferral()
+ {
+ index++;
+ return index < refs.size();
+ }
+
+
+ public void retryReferral()
+ {
+ throw new NotImplementedException();
+ }
+}
Propchange: directory/trunks/ldap-common/src/main/java/org/apache/ldap/common/exception/LdapReferralException.java
------------------------------------------------------------------------------
svn:eol-style = native