You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/08/04 16:53:23 UTC
svn commit: r982272 [1/2] - in /directory:
apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/
apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/
apacheds/trunk/core/src/main/java/org/apache/direc...
Author: elecharny
Date: Wed Aug 4 14:53:22 2010
New Revision: 982272
URL: http://svn.apache.org/viewvc?rev=982272&view=rev
Log:
o Refactored the DnNode code : there is now only one class instead of three plus an interface
o Modified the DnNode class to allow branches to store an element (we need this for overlapping partitions and APs)
o Changed the api to be more consistent and more explicit
o Added extensive tests for the api
o Removed a test in the PartitionTreeTest class, as overlapping partition will be accepted in the partition tree
o Added code in the AdministrativePointInterceptor to create the list of APs for an entry
Removed:
directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnBranchNode.java
directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnLeafNode.java
Modified:
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ReferralManager.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AbstractAdministrativePoint.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AdministrativePoint.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AutonomousAdministrativePoint.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/InnerAdministrativePoint.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/SpecificAdministrativePoint.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/ReferralManagerImpl.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/tree/PartitionTreeTest.java
directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/AdministrativeRole.java
directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnNode.java
directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/DNTest.java
directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/tree/TestDnNode.java
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ReferralManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ReferralManager.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ReferralManager.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ReferralManager.java Wed Aug 4 14:53:22 2010
@@ -6,20 +6,21 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.directory.server.core;
import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.name.DN;
/**
@@ -30,40 +31,40 @@ import org.apache.directory.shared.ldap.
public interface ReferralManager
{
/**
- * Get a read-lock on the referralManager.
+ * Get a read-lock on the referralManager.
* No read operation can be done on the referralManager if this
* method is not called before.
*/
void lockRead();
-
-
+
+
/**
- * Get a write-lock on the referralManager.
+ * Get a write-lock on the referralManager.
* No write operation can be done on the referralManager if this
* method is not called before.
*/
void lockWrite();
-
-
+
+
/**
- * Release the read-write lock on the referralManager.
+ * Release the read-write lock on the referralManager.
* This method must be called after having read or modified the
* ReferralManager
*/
void unlock();
-
-
+
+
/**
* Tells if a DN is a referral (its associated entry contains the Referral ObjectClass).
- *
+ *
* It does not check that the associated entry inherits from a referral.
*
* @param dn The entry's DN we want to check
* @return <code>true</code> if the DN is associated with a referral
*/
boolean isReferral( DN dn );
-
-
+
+
/**
* Tells if this DN has a parent which is a referral.
* <br>
@@ -74,8 +75,8 @@ public interface ReferralManager
* @return <code>true</code> if there is a parent referral
*/
boolean hasParentReferral( DN dn );
-
-
+
+
/**
* Get the DN of the parent referral for a specific DN
*
@@ -83,24 +84,24 @@ public interface ReferralManager
* @return The parent referral of null if none is found
*/
Entry getParentReferral( DN dn );
-
-
+
+
/**
* Add a referral to the manager.
*
* @param dn The referral to add
*/
void addReferral( Entry entry );
-
-
+
+
/**
* Remove a referral from the manager.
- *
+ *
* @param dn The referral to remove
*/
- void removeReferral( Entry entry );
-
-
+ void removeReferral( Entry entry ) throws LdapException;
+
+
/**
* Initialize the manager, reading all the referrals from the base.
* The manager will search for every entries having a Referral ObjectClass.
@@ -111,7 +112,7 @@ public interface ReferralManager
*/
void init( DirectoryService directoryService, String... suffixes ) throws Exception;
-
+
/**
* Remove a partition from the manager, reading all the referrals from the base.
* The manager will search for every entries having a Referral ObjectClass, and
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AbstractAdministrativePoint.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AbstractAdministrativePoint.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AbstractAdministrativePoint.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AbstractAdministrativePoint.java Wed Aug 4 14:53:22 2010
@@ -55,9 +55,12 @@ public abstract class AbstractAdministra
}
/**
- * @return The administrativeRole
+ * {@inheritDoc}
*/
- public abstract AdministrativeRole getRole();
+ public AdministrativeRole getRole()
+ {
+ return role;
+ }
/**
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AdministrativePoint.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AdministrativePoint.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AdministrativePoint.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AdministrativePoint.java Wed Aug 4 14:53:22 2010
@@ -22,6 +22,7 @@ package org.apache.directory.server.core
import java.util.Map;
import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.subtree.AdministrativeRole;
/**
*
@@ -93,4 +94,10 @@ public interface AdministrativePoint
* @param children the AdministrativePoint children
*/
void setChildren( Map<String, AdministrativePoint> children );
+
+
+ /**
+ * @return The administrativeRole
+ */
+ AdministrativeRole getRole();
}
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AutonomousAdministrativePoint.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AutonomousAdministrativePoint.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AutonomousAdministrativePoint.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/AutonomousAdministrativePoint.java Wed Aug 4 14:53:22 2010
@@ -34,7 +34,7 @@ public class AutonomousAdministrativePoi
* @param dn The AdministrativePoint DN
* @param uuid The AdministrativePoint UUID
*/
- protected AutonomousAdministrativePoint( DN dn, String uuid )
+ public AutonomousAdministrativePoint( DN dn, String uuid )
{
super( dn, uuid, AdministrativeRole.AutonomousArea );
}
@@ -47,13 +47,4 @@ public class AutonomousAdministrativePoi
{
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
- public AdministrativeRole getRole()
- {
- return AdministrativeRole.AutonomousArea;
- }
}
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/InnerAdministrativePoint.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/InnerAdministrativePoint.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/InnerAdministrativePoint.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/InnerAdministrativePoint.java Wed Aug 4 14:53:22 2010
@@ -35,7 +35,7 @@ public class InnerAdministrativePoint ex
* @param uuid The AdministrativePoint UUID
* @param role The AdministrativePoint role
*/
- protected InnerAdministrativePoint( DN dn, String uuid, AdministrativeRole role )
+ public InnerAdministrativePoint( DN dn, String uuid, AdministrativeRole role )
{
super( dn, uuid, role );
}
@@ -53,15 +53,6 @@ public class InnerAdministrativePoint ex
/**
* {@inheritDoc}
*/
- public AdministrativeRole getRole()
- {
- return role;
- }
-
-
- /**
- * {@inheritDoc}
- */
public AdministrativePoint getParent()
{
return parent;
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/SpecificAdministrativePoint.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/SpecificAdministrativePoint.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/SpecificAdministrativePoint.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/administrative/SpecificAdministrativePoint.java Wed Aug 4 14:53:22 2010
@@ -35,7 +35,7 @@ public class SpecificAdministrativePoint
* @param uuid The AdministrativePoint UUID
* @param role The AdministrativePoint role
*/
- protected SpecificAdministrativePoint( DN dn, String uuid, AdministrativeRole role )
+ public SpecificAdministrativePoint( DN dn, String uuid, AdministrativeRole role )
{
super( dn, uuid, role );
}
@@ -53,15 +53,6 @@ public class SpecificAdministrativePoint
/**
* {@inheritDoc}
*/
- public AdministrativeRole getRole()
- {
- return role;
- }
-
-
- /**
- * {@inheritDoc}
- */
public AdministrativePoint getParent()
{
return parent;
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java Wed Aug 4 14:53:22 2010
@@ -100,18 +100,18 @@ public class DefaultOperationManager imp
{
// we have to replace the parent by the referral
LdapURL ldapUrl = new LdapURL( url.getString() );
-
+
// We have a problem with the DN : we can't use the UpName,
// as we may have some spaces around the ',' and '+'.
- // So we have to take the RDN one by one, and create a
+ // So we have to take the RDN one by one, and create a
// new DN with the type and value UP form
-
+
DN urlDn = ldapUrl.getDn().addAll( childDn );
-
+
ldapUrl.setDn( urlDn );
urls.add( ldapUrl.toString() );
}
- }
+ }
catch ( LdapInvalidDnException lide )
{
throw new LdapOperationErrorException( lide.getMessage() );
@@ -157,7 +157,7 @@ public class DefaultOperationManager imp
{
// We have a problem with the DN : we can't use the UpName,
// as we may have some spaces around the ',' and '+'.
- // So we have to take the RDN one by one, and create a
+ // So we have to take the RDN one by one, and create a
// new DN with the type and value UP form
DN urlDn = ldapUrl.getDn().addAll( childDn );
@@ -235,7 +235,7 @@ public class DefaultOperationManager imp
if ( directoryService.getReferralManager().hasParentReferral( dn ) )
{
Entry parentEntry = directoryService.getReferralManager().getParentReferral( dn );
- DN childDn = ( DN ) dn.getSuffix( parentEntry.getDn().size() );
+ DN childDn = dn.getSuffix( parentEntry.getDn().size() );
// Depending on the Context.REFERRAL property value, we will throw
// a different exception.
@@ -322,7 +322,7 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
+ // We have found a parent referral for the current DN
DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
@@ -401,7 +401,7 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
+ // We have found a parent referral for the current DN
DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
@@ -590,7 +590,7 @@ public class DefaultOperationManager imp
// Unlock the referral manager
referralManager.unlock();
- // We have found a parent referral for the current DN
+ // We have found a parent referral for the current DN
DN childDn = dn.getSuffix( parentEntry.getDn().size() );
LdapReferralException exception = buildReferralException( parentEntry, childDn );
@@ -607,7 +607,7 @@ public class DefaultOperationManager imp
{
referralManager.unlock();
- // We have found a parent referral for the current DN
+ // We have found a parent referral for the current DN
DN childDn = dn.getSuffix( parentEntry.getDn().size() );
LdapPartialResultException exception = buildLdapPartialResultException( childDn );
@@ -618,7 +618,7 @@ public class DefaultOperationManager imp
// Unlock the referral manager
referralManager.unlock();
- // We have found a parent referral for the current DN
+ // We have found a parent referral for the current DN
DN childDn = dn.getSuffix( parentEntry.getDn().size() );
LdapReferralException exception = buildReferralException( parentEntry, childDn );
@@ -673,8 +673,8 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
- DN childDn = ( DN ) dn.getSuffix( parentEntry.getDn().size() );
+ // We have found a parent referral for the current DN
+ DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
{
@@ -771,8 +771,8 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
- DN childDn = ( DN ) dn.getSuffix( parentEntry.getDn().size() );
+ // We have found a parent referral for the current DN
+ DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
{
@@ -851,7 +851,7 @@ public class DefaultOperationManager imp
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
public void rename( RenameOperationContext renameContext ) throws LdapException
{
@@ -885,8 +885,8 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
- DN childDn = ( DN ) dn.getSuffix( parentEntry.getDn().size() );
+ // We have found a parent referral for the current DN
+ DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
{
@@ -967,8 +967,8 @@ public class DefaultOperationManager imp
if ( parentEntry != null )
{
- // We have found a parent referral for the current DN
- DN childDn = ( DN ) dn.getSuffix( parentEntry.getDn().size() );
+ // We have found a parent referral for the current DN
+ DN childDn = dn.getSuffix( parentEntry.getDn().size() );
if ( directoryService.getReferralManager().isReferral( dn ) )
{
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/ReferralManagerImpl.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/ReferralManagerImpl.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/ReferralManagerImpl.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/ReferralManagerImpl.java Wed Aug 4 14:53:22 2010
@@ -6,16 +6,16 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.directory.server.core;
@@ -38,13 +38,13 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.message.AliasDerefMode;
import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.schema.AttributeType;
-import org.apache.directory.shared.ldap.util.tree.DnBranchNode;
+import org.apache.directory.shared.ldap.util.tree.DnNode;
/**
* Implement a referral Manager, handling the requests from the LDAP protocol.
* <br>
- * Referrals are stored in a tree, where leaves are the referrals. We are using
+ * Referrals are stored in a tree, where leaves are the referrals. We are using
* the very same structure than for the partition manager.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
@@ -52,7 +52,7 @@ import org.apache.directory.shared.ldap.
public class ReferralManagerImpl implements ReferralManager
{
/** The referrals tree */
- private DnBranchNode<Entry> referrals;
+ private DnNode<Entry> referrals;
/** A lock to guarantee the manager consistency */
private ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
@@ -60,9 +60,9 @@ public class ReferralManagerImpl impleme
/** A storage for the ObjectClass attributeType */
private AttributeType OBJECT_CLASS_AT;
-
+
/**
- *
+ *
* Creates a new instance of ReferralManagerImpl.
*
* @param directoryService The directory service
@@ -71,8 +71,8 @@ public class ReferralManagerImpl impleme
public ReferralManagerImpl( DirectoryService directoryService ) throws LdapException
{
lockWrite();
-
- referrals = new DnBranchNode<Entry>();
+
+ referrals = new DnNode<Entry>();
PartitionNexus nexus = directoryService.getPartitionNexus();
Set<String> suffixes = nexus.listSuffixes();
@@ -82,10 +82,10 @@ public class ReferralManagerImpl impleme
unlock();
}
-
-
+
+
/**
- * Get a read-lock on the referralManager.
+ * Get a read-lock on the referralManager.
* No read operation can be done on the referralManager if this
* method is not called before.
*/
@@ -93,10 +93,10 @@ public class ReferralManagerImpl impleme
{
mutex.readLock().lock();
}
-
-
+
+
/**
- * Get a write-lock on the referralManager.
+ * Get a write-lock on the referralManager.
* No write operation can be done on the referralManager if this
* method is not called before.
*/
@@ -105,9 +105,9 @@ public class ReferralManagerImpl impleme
mutex.writeLock().lock();
}
-
+
/**
- * Release the read-write lock on the referralManager.
+ * Release the read-write lock on the referralManager.
* This method must be called after having read or modified the
* ReferralManager
*/
@@ -122,8 +122,8 @@ public class ReferralManagerImpl impleme
mutex.readLock().unlock();
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -133,7 +133,7 @@ public class ReferralManagerImpl impleme
{
try
{
- ((DnBranchNode<Entry>)referrals).add( entry.getDn(), entry );
+ referrals.add( entry.getDn(), entry );
}
catch ( LdapException ne )
{
@@ -147,14 +147,14 @@ public class ReferralManagerImpl impleme
*/
public void init( DirectoryService directoryService, String... suffixes ) throws LdapException
{
- ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
+ ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
new StringValue( SchemaConstants.REFERRAL_OC ) );
// Lookup for each entry with the ObjectClass = Referral value
SearchControls searchControl = new SearchControls();
searchControl.setReturningObjFlag( false );
searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );
-
+
CoreSession adminSession = directoryService.getAdminSession();
PartitionNexus nexus = directoryService.getPartitionNexus();
@@ -162,30 +162,30 @@ public class ReferralManagerImpl impleme
{
// We will store each entry's DN into the Referral tree
DN suffixDn = DNFactory.create( suffix, directoryService.getSchemaManager() );
-
+
SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, suffixDn, referralFilter, searchControl );
searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
EntryFilteringCursor cursor = nexus.search( searchOperationContext );
-
+
try
{
// Move to the first entry in the cursor
cursor.beforeFirst();
-
- while ( cursor.next() )
+
+ while ( cursor.next() )
{
Entry entry = cursor.get();
-
+
// Lock the referralManager
lockWrite();
-
+
// Add it at the right place
addReferral( entry );
-
+
// Unlock the referralManager
unlock();
}
-
+
cursor.close();
}
catch ( Exception e )
@@ -194,21 +194,21 @@ public class ReferralManagerImpl impleme
}
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
public void remove( DirectoryService directoryService, DN suffix ) throws Exception
{
- ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
+ ExprNode referralFilter = new EqualityNode<String>( OBJECT_CLASS_AT,
new StringValue( SchemaConstants.REFERRAL_OC ) );
// Lookup for each entry with the ObjectClass = Referral value
SearchControls searchControl = new SearchControls();
searchControl.setReturningObjFlag( false );
searchControl.setSearchScope( SearchControls.SUBTREE_SCOPE );
-
+
CoreSession adminSession = directoryService.getAdminSession();
PartitionNexus nexus = directoryService.getPartitionNexus();
@@ -217,26 +217,28 @@ public class ReferralManagerImpl impleme
referralFilter, searchControl );
searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
EntryFilteringCursor cursor = nexus.search( searchOperationContext );
-
+
// Move to the first entry in the cursor
cursor.beforeFirst();
-
- while ( cursor.next() )
+
+ while ( cursor.next() )
{
Entry entry = cursor.get();
-
+
// Add it at the right place
removeReferral( entry );
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
public boolean hasParentReferral( DN dn )
{
- return referrals.hasParentElement( dn );
+ DnNode<Entry> referral = referrals.getNode( dn );
+
+ return ( referral != null ) && referral.isLeaf();
}
@@ -249,18 +251,18 @@ public class ReferralManagerImpl impleme
{
return null;
}
-
- return referrals.getParentElement( dn );
+
+ return referrals.getElement( dn );
}
-
+
/**
* {@inheritDoc}
*/
public boolean isReferral( DN dn )
{
- Entry parent = referrals.getParentElement( dn );
-
+ Entry parent = referrals.getElement( dn );
+
if ( parent != null )
{
return dn.equals( parent.getDn() );
@@ -275,8 +277,8 @@ public class ReferralManagerImpl impleme
/**
* {@inheritDoc}
*/
- public void removeReferral( Entry entry )
+ public void removeReferral( Entry entry ) throws LdapException
{
- referrals.remove( entry );
+ referrals.remove( entry.getDn() );
}
}
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java Wed Aug 4 14:53:22 2010
@@ -31,6 +31,10 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.DefaultCoreSession;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.LdapPrincipal;
+import org.apache.directory.server.core.administrative.AdministrativePoint;
+import org.apache.directory.server.core.administrative.AutonomousAdministrativePoint;
+import org.apache.directory.server.core.administrative.InnerAdministrativePoint;
+import org.apache.directory.server.core.administrative.SpecificAdministrativePoint;
import org.apache.directory.server.core.authn.Authenticator;
import org.apache.directory.server.core.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.interceptor.BaseInterceptor;
@@ -67,6 +71,7 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.schema.SchemaManager;
import org.apache.directory.shared.ldap.subtree.AdministrativeRole;
import org.apache.directory.shared.ldap.util.StringTools;
+import org.apache.directory.shared.ldap.util.tree.DnNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -151,6 +156,8 @@ public class AdministrativePointIntercep
SPECIFIC_AREA_ROLES.add( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
}
+ private DnNode<List<AdministrativePoint>> adminPointCache;
+
/**
* Tells if the given role is a InnerArea role
@@ -202,6 +209,204 @@ public class AdministrativePointIntercep
return false;
}
+
+ /**
+ * Create the list of AP for a given entry
+ */
+ private List<AdministrativePoint> createAdministrativePoints( EntryAttribute adminPoint, DN dn, String uuid )
+ {
+ List<AdministrativePoint> adminPoints = new ArrayList<AdministrativePoint> ();
+
+ for ( Value<?> value : adminPoint )
+ {
+ String role = value.getString();
+
+ // Deal with Autonomous AP
+ if ( role.equalsIgnoreCase( SchemaConstants.AUTONOMOUS_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.AUTONOMOUS_AREA_OID ) )
+ {
+ AdministrativePoint aap = new AutonomousAdministrativePoint( dn, uuid );
+ adminPoints.add( aap );
+
+ // If it's an AAP, we can get out immediately
+ return adminPoints;
+ }
+
+ // Deal with AccessControl AP
+ if ( role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID ) )
+ {
+ AdministrativePoint sap = new SpecificAdministrativePoint( dn, uuid, AdministrativeRole.AccessControlSpecificArea );
+ adminPoints.add( sap );
+
+ continue;
+ }
+
+ if ( role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_INNER_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_INNER_AREA_OID ) )
+ {
+ AdministrativePoint iap = new InnerAdministrativePoint( dn, uuid, AdministrativeRole.AccessControlInnerArea );
+ adminPoints.add( iap );
+
+ continue;
+ }
+
+ // Deal with CollectveAttribute AP
+ if ( role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID ) )
+ {
+ AdministrativePoint sap = new SpecificAdministrativePoint( dn, uuid, AdministrativeRole.CollectiveAttributeSpecificArea );
+ adminPoints.add( sap );
+
+ continue;
+ }
+
+ if ( role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA_OID ) )
+ {
+ AdministrativePoint iap = new InnerAdministrativePoint( dn, uuid, AdministrativeRole.CollectiveAttributeInnerArea );
+ adminPoints.add( iap );
+
+ continue;
+ }
+
+ // Deal with SubSchema AP
+ if ( role.equalsIgnoreCase( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA_OID ) )
+ {
+ AdministrativePoint sap = new SpecificAdministrativePoint( dn, uuid, AdministrativeRole.SubSchemaSpecificArea );
+ adminPoints.add( sap );
+
+ continue;
+ }
+
+ // Deal with TriggerExecution AP
+ if ( role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID ) )
+ {
+ AdministrativePoint sap = new SpecificAdministrativePoint( dn, uuid, AdministrativeRole.TriggerExecutionSpecificArea );
+ adminPoints.add( sap );
+
+ continue;
+ }
+
+ if ( role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA ) ||
+ role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA_OID ) )
+ {
+ AdministrativePoint iap = new InnerAdministrativePoint( dn, uuid, AdministrativeRole.TriggerExecutionInnerArea );
+ adminPoints.add( iap );
+
+ continue;
+ }
+ }
+
+ return adminPoints;
+ }
+
+
+ private AdministrativePoint getParent( AdministrativePoint ap, List<AdministrativePoint> aps, AdministrativeRole role, DnNode<List<AdministrativePoint>> currentNode )
+ {
+ AdministrativePoint parent = null;
+
+ for ( AdministrativePoint adminPoint : aps )
+ {
+ if ( adminPoint.isAutonomous() || ( adminPoint.getRole() == ap.getRole() ) )
+ {
+ // Same role or AP : this is the parent
+ return adminPoint;
+ }
+ else if ( adminPoint.getRole() == role )
+ {
+ parent = adminPoint;
+ }
+ }
+
+ if ( parent != null )
+ {
+ return parent;
+ }
+
+ // We have to go down one level
+ if ( currentNode.hasParent() )
+ {
+ return findParent( ap, currentNode );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+
+ private AdministrativePoint findParent( AdministrativePoint ap, DnNode<List<AdministrativePoint>> currentNode )
+ {
+ List<AdministrativePoint> aps = currentNode.getElement();
+
+ if ( aps != null )
+ {
+ // Check if the current element is a valid parent
+ switch ( ap.getRole() )
+ {
+ case AutonomousArea :
+ AdministrativePoint currentAp = aps.get( 0 );
+
+ if ( currentAp.isAutonomous() )
+ {
+ return currentAp;
+ }
+ else
+ {
+ // We have to go down one level, as an AAP
+ // must have another AAP as a parent
+ if ( currentNode.hasParent() )
+ {
+ return findParent( ap, currentNode );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ case AccessControlInnerArea :
+ return getParent( ap, aps, AdministrativeRole.AccessControlSpecificArea, currentNode );
+
+ case CollectiveAttributeInnerArea :
+ return getParent( ap, aps, AdministrativeRole.CollectiveAttributeSpecificArea, currentNode );
+
+ case TriggerExecutionInnerArea :
+ return getParent( ap, aps, AdministrativeRole.TriggerExecutionSpecificArea, currentNode );
+
+ case AccessControlSpecificArea :
+ return getParent( ap, aps, AdministrativeRole.AccessControlSpecificArea, currentNode );
+
+ case CollectiveAttributeSpecificArea :
+ return getParent( ap, aps, AdministrativeRole.CollectiveAttributeSpecificArea, currentNode );
+
+ case SubSchemaSpecificArea :
+ return getParent( ap, aps, AdministrativeRole.SubSchemaSpecificArea, currentNode );
+
+ case TriggerExecutionSpecificArea :
+ return getParent( ap, aps, AdministrativeRole.TriggerExecutionSpecificArea, currentNode );
+
+ default :
+ return null;
+ }
+ }
+ else
+ {
+ if ( currentNode.hasParent() )
+ {
+ return findParent( ap, currentNode.getParent() );
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
/**
* Creates an Administrative service interceptor.
*/
@@ -312,6 +517,9 @@ public class AdministrativePointIntercep
List<Entry> accessControlIAPs = getAdministrativePoints( SchemaConstants.ACCESS_CONTROL_INNER_AREA );
List<Entry> collectiveAttributeIAPs = getAdministrativePoints( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA );
List<Entry> triggerExecutionIAPs = getAdministrativePoints( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA );
+
+ // Create the root AdministrativePoint cache. The first DN
+ adminPointCache = new DnNode<List<AdministrativePoint>>();
}
@@ -413,8 +621,29 @@ public class AdministrativePointIntercep
// Now, update the cache
String uuid = addContext.getEntry().get( ENTRY_UUID_AT ).getString();
- AdministrativeRole adminRole = null;
+ // Construct the AdministrativePoint objects
+ List<AdministrativePoint> administrativePoints = createAdministrativePoints( adminPoint, addContext.getDn(), uuid );
+
+ for ( AdministrativePoint ap : administrativePoints )
+ {
+ if ( ap.isAutonomous() )
+ {
+ // Find the parent
+ AdministrativePoint parent = findParent( ap, adminPointCache );
+ ap.setParent( parent );
+
+ // We won't have any children as the entry has just been added
+ }
+ else
+ {
+ // Find the parent
+ AdministrativePoint parent = findParent( ap, adminPointCache );
+ ap.setParent( parent );
+
+ // We won't have any children as the entry has just been added
+ }
+ }
LOG.debug( "Added an Autonomous Administrative Point at {}", entry.getDn() );
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java Wed Aug 4 14:53:22 2010
@@ -6,16 +6,16 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.directory.server.core.partition;
@@ -100,7 +100,7 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.schema.UsageEnum;
import org.apache.directory.shared.ldap.util.DateUtils;
import org.apache.directory.shared.ldap.util.NamespaceTools;
-import org.apache.directory.shared.ldap.util.tree.DnBranchNode;
+import org.apache.directory.shared.ldap.util.tree.DnNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -137,7 +137,7 @@ public class DefaultPartitionNexus exten
private Map<String, Partition> partitions = new HashMap<String, Partition>();
/** A structure to hold all the partitions */
- private DnBranchNode<Partition> partitionLookupTree = new DnBranchNode<Partition>();
+ private DnNode<Partition> partitionLookupTree = new DnNode<Partition>();
/** the system partition */
private Partition system;
@@ -689,10 +689,10 @@ public class DefaultPartitionNexus exten
{
// Get the current partition
Partition backend = getPartition( moveContext.getDn() );
-
+
// We also have to get the new partition as it can be different
//Partition newBackend = getPartition( opContext.getNewDn() );
-
+
backend.move( moveContext );
}
@@ -807,7 +807,7 @@ public class DefaultPartitionNexus exten
ExprNode filter = searchContext.getFilter();
// TODO since we're handling the *, and + in the EntryFilteringCursor
- // we may not need this code: we need see if this is actually the
+ // we may not need this code: we need see if this is actually the
// case and remove this code.
if ( base.size() == 0 )
{
@@ -844,7 +844,7 @@ public class DefaultPartitionNexus exten
else if ( isOnelevelScope )
{
List<EntryFilteringCursor> cursors = new ArrayList<EntryFilteringCursor>();
-
+
for ( Partition partition : partitions.values() )
{
searchContext.setDn( partition.getSuffix() );
@@ -857,12 +857,12 @@ public class DefaultPartitionNexus exten
else if ( isSublevelScope )
{
List<EntryFilteringCursor> cursors = new ArrayList<EntryFilteringCursor>();
-
+
for ( Partition partition : partitions.values() )
{
ClonedServerEntry entry = partition.lookup( new LookupOperationContext( directoryService.getAdminSession(),
partition.getSuffix() ) );
-
+
if ( entry != null )
{
Partition backend = getPartition( entry.getDn() );
@@ -871,7 +871,7 @@ public class DefaultPartitionNexus exten
}
}
- // don't feed the above Cursors' list to a BaseEntryFilteringCursor it is skipping the naming context entry of each partition
+ // don't feed the above Cursors' list to a BaseEntryFilteringCursor it is skipping the naming context entry of each partition
return new CursorList( cursors, searchContext );
}
@@ -885,7 +885,7 @@ public class DefaultPartitionNexus exten
}
Partition backend = getPartition( base );
-
+
return backend.search( searchContext );
}
@@ -995,9 +995,9 @@ public class DefaultPartitionNexus exten
}
// Update the partition tree
- partitionLookupTree.remove( partition );
+ partitionLookupTree.remove( partition.getSuffix() );
partitions.remove( key );
-
+
try
{
partition.destroy();
@@ -1023,7 +1023,7 @@ public class DefaultPartitionNexus exten
*/
public Partition getPartition( DN dn ) throws LdapException
{
- Partition parent = partitionLookupTree.getParentElement( dn );
+ Partition parent = partitionLookupTree.getElement( dn );
if ( parent == null )
{
@@ -1042,11 +1042,11 @@ public class DefaultPartitionNexus exten
public DN findSuffix( DN dn ) throws LdapException
{
Partition backend = getPartition( dn );
-
+
return backend.getSuffix();
}
-
-
+
+
public DN getSuffix()
{
return null;
Modified: directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/tree/PartitionTreeTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/tree/PartitionTreeTest.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/tree/PartitionTreeTest.java (original)
+++ directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/tree/PartitionTreeTest.java Wed Aug 4 14:53:22 2010
@@ -23,14 +23,12 @@ package org.apache.directory.server.core
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.name.DN;
-import org.apache.directory.shared.ldap.util.tree.DnBranchNode;
-import org.apache.directory.shared.ldap.util.tree.DnLeafNode;
+import org.apache.directory.shared.ldap.name.RDN;
import org.apache.directory.shared.ldap.util.tree.DnNode;
import org.junit.Test;
@@ -48,24 +46,24 @@ public class PartitionTreeTest
@Test public void testNewPartitionTree() throws LdapException
{
/** A structure to hold all the partitions */
- DnBranchNode<Partition> partitionLookupTree = new DnBranchNode<Partition>();
-
+ DnNode<Partition> partitionLookupTree = new DnNode<Partition>();
+
DN suffix = new DN( "dc=example, dc=com" );
Partition partition = new JdbmPartition();
partition.setSuffix( suffix );
-
+
partitionLookupTree.add( suffix, partition );
-
+
assertNotNull( partitionLookupTree );
- assertTrue( partitionLookupTree instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)partitionLookupTree).contains( "dc=com" ) );
-
- DnNode<Partition> child = ((DnBranchNode<Partition>)partitionLookupTree).getChild( "dc=com" );
- assertTrue( child instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)child).contains( "dc=example" ) );
+ assertTrue( partitionLookupTree.hasChildren() );
+ assertTrue( partitionLookupTree.contains( new RDN( "dc=com" ) ) );
+
+ DnNode<Partition> child = partitionLookupTree.getChild( new RDN( "dc=com" ) );
+ assertTrue( child.hasChildren() );
+ assertTrue( child.contains( new RDN( "dc=example" ) ) );
- child = ((DnBranchNode<Partition>)child).getChild( "dc=example" );
- assertEquals( "dc=example, dc=com", ((DnLeafNode<Partition>)child).getElement().getSuffix().getName() );
+ child = child.getChild( new RDN( "dc=example" ) );
+ assertEquals( "dc=example, dc=com", child.getElement().getSuffix().getName() );
}
@@ -75,66 +73,36 @@ public class PartitionTreeTest
@Test public void testNewPartitionTree2Nodes() throws LdapException
{
/** A structure to hold all the partitions */
- DnBranchNode<Partition> partitionLookupTree = new DnBranchNode<Partition>();
-
+ DnNode<Partition> partitionLookupTree = new DnNode<Partition>();
+
DN suffix1 = new DN( "dc=example, dc=com" );
Partition partition1 = new JdbmPartition();
partition1.setSuffix( suffix1 );
-
+
partitionLookupTree.add( suffix1, partition1 );
-
+
DN suffix2 = new DN( "ou=system" );
Partition partition2 = new JdbmPartition();
partition2.setSuffix( suffix2 );
-
+
partitionLookupTree.add( suffix2, partition2 );
assertNotNull( partitionLookupTree );
- assertTrue( partitionLookupTree instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)partitionLookupTree).contains( "ou=system" ) );
- assertTrue( ((DnBranchNode<Partition>)partitionLookupTree).contains( "dc=com" ) );
-
- DnNode<Partition> child = ((DnBranchNode<Partition>)partitionLookupTree).getChild( "ou=system" );
- assertTrue( child instanceof DnLeafNode );
- assertEquals( "ou=system", ((DnLeafNode<Partition>)child).getElement().getSuffix().getName() );
-
- child = ((DnBranchNode<Partition>)partitionLookupTree).getChild( "dc=com" );
- assertTrue( child instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)child).contains( "dc=example" ) );
-
- child = ((DnBranchNode<Partition>)child).getChild( "dc=example" );
- assertTrue( child instanceof DnLeafNode );
- assertEquals( "dc=example, dc=com", ((DnLeafNode<Partition>)child).getElement().getSuffix().getName() );
- }
-
-
- /**
- * Test the addition of a two overlapping partitions
- */
- @Test public void testNewPartitionTree2OverlapingNodes() throws LdapException
- {
- /** A structure to hold all the partitions */
- DnBranchNode<Partition> partitionLookupTree = new DnBranchNode<Partition>();
-
- DN suffix1 = new DN( "dc=com" );
- Partition partition1 = new JdbmPartition();
- partition1.setSuffix( suffix1 );
-
- partitionLookupTree.add( suffix1, partition1 );
-
- DN suffix2 = new DN( "dc=example, dc=com" );
- Partition partition2 = new JdbmPartition();
- partition2.setSuffix( suffix2 );
-
- try
- {
- partitionLookupTree.add( suffix2, partition2 );
- fail();
- }
- catch ( LdapException ne )
- {
- assertTrue( true );
- }
+ assertTrue( partitionLookupTree.hasChildren() );
+ assertTrue( partitionLookupTree.contains( new RDN( "ou=system" ) ) );
+ assertTrue( partitionLookupTree.contains( new RDN( "dc=com" ) ) );
+
+ DnNode<Partition> child = partitionLookupTree.getChild( new RDN( "ou=system" ) );
+ assertTrue( child.isLeaf() );
+ assertEquals( "ou=system", child.getElement().getSuffix().getName() );
+
+ child = partitionLookupTree.getChild( new RDN( "dc=com" ) );
+ assertTrue( child.hasChildren() );
+ assertTrue( child.contains( new RDN( "dc=example" ) ) );
+
+ child = child.getChild( new RDN( "dc=example" ) );
+ assertTrue( child.isLeaf() );
+ assertEquals( "dc=example, dc=com", child.getElement().getSuffix().getName() );
}
@@ -144,39 +112,39 @@ public class PartitionTreeTest
@Test public void testNewPartitionTree2NodesWithSameRoot() throws LdapException
{
/** A structure to hold all the partitions */
- DnBranchNode<Partition> partitionLookupTree = new DnBranchNode<Partition>();
-
+ DnNode<Partition> partitionLookupTree = new DnNode<Partition>();
+
DN suffix1 = new DN( "dc=example1, dc=com" );
Partition partition1 = new JdbmPartition();
partition1.setSuffix( suffix1 );
-
+
partitionLookupTree.add( suffix1, partition1 );
-
+
DN suffix2 = new DN( "dc=example2, dc=com" );
Partition partition2 = new JdbmPartition();
partition2.setSuffix( suffix2 );
-
+
partitionLookupTree.add( suffix2, partition2 );
assertNotNull( partitionLookupTree );
-
- assertTrue( partitionLookupTree instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)partitionLookupTree).contains( "dc=com" ) );
-
- DnNode<Partition> child = ((DnBranchNode<Partition>)partitionLookupTree).getChild( "dc=com" );
- assertTrue( child instanceof DnBranchNode );
-
- child = ((DnBranchNode<Partition>)partitionLookupTree).getChild( "dc=com" );
- assertTrue( child instanceof DnBranchNode );
- assertTrue( ((DnBranchNode<Partition>)child).contains( "dc=example1" ) );
- assertTrue( ((DnBranchNode<Partition>)child).contains( "dc=example2" ) );
-
- DnNode<Partition> child1 = ((DnBranchNode<Partition>)child).getChild( "dc=example1" );
- assertTrue( child1 instanceof DnLeafNode );
- assertEquals( "dc=example1, dc=com", ((DnLeafNode<Partition>)child1).getElement().getSuffix().getName() );
-
- DnNode<Partition> child2 = ((DnBranchNode<Partition>)child).getChild( "dc=example1" );
- assertTrue( child2 instanceof DnLeafNode );
- assertEquals( "dc=example1, dc=com", ((DnLeafNode<Partition>)child2).getElement().getSuffix().getName() );
+
+ assertTrue( partitionLookupTree.hasChildren() );
+ assertTrue( partitionLookupTree.contains( new RDN( "dc=com" ) ) );
+
+ DnNode<Partition> child = partitionLookupTree.getChild( new RDN( "dc=com" ) );
+ assertTrue( child.hasChildren() );
+
+ child = partitionLookupTree.getChild( new RDN( "dc=com" ) );
+ assertTrue( child.hasChildren() );
+ assertTrue( child.contains( new RDN( "dc=example1" ) ) );
+ assertTrue( child.contains( new RDN( "dc=example2" ) ) );
+
+ DnNode<Partition> child1 = child.getChild( new RDN( "dc=example1" ) );
+ assertTrue( child1.isLeaf() );
+ assertEquals( "dc=example1, dc=com", child1.getElement().getSuffix().getName() );
+
+ DnNode<Partition> child2 = child.getChild( new RDN( "dc=example1" ) );
+ assertTrue( child2.isLeaf() );
+ assertEquals( "dc=example1, dc=com", child2.getElement().getSuffix().getName() );
}
}
Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/AdministrativeRole.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/AdministrativeRole.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/AdministrativeRole.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/subtree/AdministrativeRole.java Wed Aug 4 14:53:22 2010
@@ -22,9 +22,10 @@ package org.apache.directory.shared.ldap
import org.apache.directory.shared.ldap.util.StringTools;
/**
-*
-* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
-*/
+ * The Administrative roles
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
public enum AdministrativeRole
{
/** The AutonomousArea role */
Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnNode.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnNode.java?rev=982272&r1=982271&r2=982272&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnNode.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/tree/DnNode.java Wed Aug 4 14:53:22 2010
@@ -6,44 +6,694 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.directory.shared.ldap.util.tree;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.name.RDN;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
- * An interface for nodes in a tree designed to quickly lookup hierarchical DN.
- * Branch nodes in this tree contain other nodes. Leaf nodes in the tree
- * contain a reference to an object whose suffix is the path through the
+ * An class for nodes in a tree designed to quickly lookup hierarchical DN.
+ * Branch nodes in this tree refers to child nodes. Leaf nodes in the tree
+ * don't have any children. <br/>
+ * A node may cotain a reference to an object whose suffix is the path through the
* nodes of the tree from the root.
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public interface DnNode<N>
+public class DnNode<N>
{
+ /** The logger for this class */
+ private static final Logger LOG = LoggerFactory.getLogger( DnNode.class );
+
+ /** The stored element */
+ private N element;
+
+ /** The node's key */
+ private RDN rdn;
+
+ /** The node's DN */
+ private DN dn;
+
+ /** The node's depth in the tree */
+ private int depth;
+
+ /** The parent, if any */
+ private DnNode<N> parent;
+
+ /** Stores the list of all the descendant */
+ private Map<RDN, DnNode<N>> children;
+
+ //-------------------------------------------------------------------------
+ // Helper methods
+ //-------------------------------------------------------------------------
+ /**
+ * Check that the DN is not null
+ */
+ private void checkDn( DN dn ) throws LdapException
+ {
+ if ( ( dn == null ) || dn.isEmpty() )
+ {
+ String message = "Cannot process an empty DN";
+ LOG.error( message );
+ throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, message );
+ }
+ }
+
+ /**
+ * Create a new DnNode, recursively creating all the intermediate nodes.
+ */
+ private DnNode<N> createNode( DN dn, N element, int nbRdns ) throws LdapException
+ {
+ checkDn( dn );
+
+ DnNode<N> rootNode = null;
+
+ // No parent : add from the current position
+ for ( RDN rdn : dn )
+ {
+ if ( nbRdns == 0 )
+ {
+ break;
+ }
+
+ if ( rootNode == null )
+ {
+ // Create the new top node
+ DnNode<N> node = new DnNode<N>( element );
+ node.rdn = rdn;
+ node.dn = dn;
+ node.depth = dn.size() + depth;
+
+ rootNode = node;
+ }
+ else
+ {
+ DnNode<N> node = new DnNode<N>();
+ node.rdn = rdn;
+ node.dn = rootNode.dn.getParent();
+ node.depth = node.dn.size() + depth;
+ rootNode.parent = node;
+ node.children.put( rootNode.rdn, rootNode );
+ rootNode = node;
+ }
+
+ nbRdns--;
+ }
+
+ return rootNode;
+ }
+
+
+ /**
+ * Creates a new instance of DnNode.
+ */
+ public DnNode()
+ {
+ children = new ConcurrentHashMap<RDN, DnNode<N>>();
+ dn = DN.EMPTY_DN;
+ rdn = RDN.EMPTY_RDN;
+ }
+
+
+ /**
+ * Creates a new instance of DnNode.
+ *
+ * @param element the element to store
+ */
+ public DnNode( N element )
+ {
+ this.element = element;
+ children = new ConcurrentHashMap<RDN, DnNode<N>>();
+ }
+
+
+ /**
+ * Creates a new instance of DnNode.
+ *
+ * @param element the element to store
+ */
+ public DnNode( DN dn, N element )
+ {
+ if ( ( dn == null ) || ( dn.isEmpty() ) )
+ {
+ children = new ConcurrentHashMap<RDN, DnNode<N>>();
+ this.dn = DN.EMPTY_DN;
+
+ return;
+ }
+
+ try
+ {
+ DnNode<N> rootNode = createNode( dn, element, dn.size() );
+
+ // Now copy back the created node into this
+ this.children = rootNode.children;
+ this.depth = rootNode.depth;
+ this.dn = rootNode.dn;
+ this.element = rootNode.element;
+ this.rdn = rootNode.rdn;
+ this.parent = null;
+ }
+ catch ( LdapException le )
+ {
+ // Special cas e: the DN is empty, this is not allowed
+ throw new IllegalArgumentException( le.getMessage() );
+ }
+ }
+
+
/**
* Tells if the implementation is a leaf node. If it's a branch node
* then false is returned.
*
* @return <code>true</code> if the class is a leaf node, false otherwise.
*/
- boolean isLeaf();
-
-
+ public boolean isLeaf()
+ {
+ return !hasChildren();
+ }
+
+
+ /**
+ * Tells if the implementation is a leaf node. If it's a branch node
+ * then false is returned.
+ *
+ * @param dn The DN we want to check
+ * @return <code>true</code> if this is a leaf node, false otherwise.
+ */
+ public boolean isLeaf( DN dn )
+ {
+ DnNode<N> node = getNode( dn );
+
+ if ( node == null )
+ {
+ return false;
+ }
+
+ return node.children.size() == 0;
+ }
+
+
/**
* Returns the number of entries under this node. It includes
- * the node itself, plus the sum of all it children and descendents.
+ * the node itself, plus the number of all it children and descendants.
*
* @return The number of descendents
*/
- int size();
+ public int size()
+ {
+ // The node itself
+ int size = 1;
+
+ // Iterate through the children if any
+ if ( children.size() !=0 )
+ {
+ for ( DnNode<N> node : children.values() )
+ {
+ size += node.size();
+ }
+ }
+
+ return size;
+ }
+
+
+ /**
+ * @return Return the stored element, if any
+ */
+ public N getElement()
+ {
+ return element;
+ }
+
+
+ /**
+ * @return Return the stored element, if any
+ * @param dn The DN we want to get the element for
+ */
+ public N getElement( DN dn )
+ {
+ DnNode<N> node = getNode( dn );
+
+ if ( node == null )
+ {
+ return null;
+ }
+
+ return node.element;
+ }
+
+
+ /**
+ * @return True if the Node stores an element. BranchNode may not hold any
+ * element.
+ */
+ public boolean hasElement()
+ {
+ return element != null;
+ }
+
+
+ /**
+ * @return True if the Node stores an element. BranchNode may not hold any
+ * element.
+ * @param dn The DN we want to get the element for
+ */
+ public boolean hasElement( DN dn )
+ {
+ DnNode<N> node = getNode( dn );
+
+ if ( node == null )
+ {
+ return false;
+ }
+
+ return node.element != null;
+ }
+
+
+ /**
+ * Tells if the current DnNode has some children or not
+ *
+ * @return <code>true</code> if the node has some children
+ */
+ public boolean hasChildren()
+ {
+ return ( children != null ) && children.size() != 0;
+ }
+
+
+ /**
+ * Tells if a node has some children or not
+ *
+ * @return <code>true</code> if the node has some children
+ */
+ public boolean hasChildren( DN dn ) throws LdapException
+ {
+ checkDn( dn );
+
+ DnNode<N> node = getNode( dn );
+
+ return ( node != null ) && node.hasChildren();
+ }
+
+
+ /**
+ * @return The list of DnNode
+ */
+ public Map<RDN, DnNode<N>> getChildren()
+ {
+ return children;
+ }
+
+
+ /**
+ * @return The parent DnNode, if any
+ */
+ public DnNode<N> getParent()
+ {
+ return parent;
+ }
+
+
+ /**
+ * @return True if the current DnNode has a parent
+ */
+ public boolean hasParent()
+ {
+ return parent != null;
+ }
+
+
+ /**
+ * Tells if there is a parent for a given DN,. This parent should be a
+ * subset of the given dn.<br>
+ * For instance, if we have stored dc=acme, dc=org into the tree,
+ * the DN: ou=example, dc=acme, dc=org will have a parent
+ * <br>For the DN ou=apache, dc=org, there is no parent, so false will be returned.
+ *
+ * @param dn the normalized distinguished name to resolve to a parent
+ * @return true if there is a parent associated with the normalized dn
+ */
+ public boolean hasParent( DN dn )
+ {
+ List<RDN> rdns = dn.getRdns();
+
+ DnNode<N> currentNode = this;
+ DnNode<N> parent = null;
+
+ // Iterate through all the RDN until we find the associated partition
+ for ( int i = rdns.size() - 1; i >= 0; i-- )
+ {
+ RDN rdn = rdns.get( i );
+
+ if ( rdn.equals( currentNode.rdn ) )
+ {
+ parent = currentNode;
+ }
+ else if ( currentNode.hasChildren() )
+ {
+ currentNode = currentNode.children.get( rdn );
+
+ if ( currentNode == null )
+ {
+ break;
+ }
+
+ parent = currentNode;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return( parent != null );
+ }
+
+
+ /**
+ * Add a new node in the tree. The added node won't have any element.
+ *
+ * @param dn The node's DN
+ * @throws NamingException
+ */
+ public void add( DN dn ) throws LdapException
+ {
+ add( dn, null );
+ }
+
+
+ /**
+ * Add a new node in the tree. We can't add a node if its DN is empty.
+ *
+ * @param dn The node's DN
+ * @param element The element to associate with this Node. Can be null.
+ * @throws NamingException
+ */
+ public void add( DN dn, N element ) throws LdapException
+ {
+ checkDn( dn );
+
+ // We first have to find the Node which will be the parent
+ DnNode<N> parent = getNode( dn );
+
+ if ( parent == null )
+ {
+ // No parent : add a new node to the root
+ DnNode<N> childNode = createNode( dn, element, dn.size() );
+ childNode.parent = this;
+ children.put( childNode.rdn, childNode );
+ }
+ else
+ {
+ // We have a parent. Add the new node to the found parent
+ int nbRdns = dn.size() - parent.depth;
+
+ if ( nbRdns == 0 )
+ {
+ // That means the added DN is already present.
+ String message = "Cannot add a node with a DN already existing in the tree";
+ LOG.error( message );
+ throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, message );
+ }
+
+ DnNode<N> rootNode = createNode( dn, element, nbRdns );
+
+ // done. now, add the newly created tree to the parent node
+ rootNode.parent = parent;
+ parent.children.put( rootNode.rdn, rootNode );
+ }
+ }
+
+
+ /**
+ * Removes an element from the tree.
+ *
+ * @param element The element to remove
+ */
+ public void remove( DN dn ) throws LdapException
+ {
+ checkDn( dn );
+
+ // Find the parent first : we won't be able to remove
+ // a node if it's not present in the tree !
+ DnNode<N> parent = getNode( dn );
+
+ if ( parent == null )
+ {
+ return;
+ }
+
+ // Now, check that this parent has the same DN than the one
+ // we gave and that there is no children
+ if ( ( dn.size() != parent.depth ) || parent.hasChildren() )
+ {
+ return;
+ }
+
+ // Ok, no children, same DN, let's remove what we can.
+ parent = parent.getParent();
+
+ for ( RDN rdn : dn )
+ {
+ parent.children.remove( rdn );
+
+ if ( parent.children.size() > 0 )
+ {
+ // We have to stop here, because the parent's node is shared with other Node.
+ break;
+ }
+
+ parent = parent.getParent();
+ }
+ }
+
+
+ /**
+ * Tells if the current DnBranchNode contains another node associated
+ * with an rdn.
+ *
+ * @param rdn The name we are looking for
+ * @return <code>true</code> if the tree instance contains this name
+ */
+ public boolean contains( RDN rdn )
+ {
+ return children.containsKey( rdn );
+ }
+
+
+ /**
+ * Get's a child using an rdn string.
+ *
+ * @param rdn the rdn to use as the node key
+ * @return the child node corresponding to the rdn.
+ */
+ public DnNode<N> getChild( RDN rdn )
+ {
+ if ( children.containsKey( rdn ) )
+ {
+ return children.get( rdn );
+ }
+
+ return null;
+ }
+
+
+ /**
+ * @return The Node's RDN
+ */
+ public RDN getRdn()
+ {
+ return rdn;
+ }
+
+
+ /**
+ * Get the parent element of a given DN, if present in the tree. This parent should be a
+ * subset of the given dn.<br>
+ * For instance, if we have stored dc=acme, dc=org into the tree,
+ * the DN: ou=example, dc=acme, dc=org will have a parent, and
+ * dc=acme, dc=org will be returned.
+ * <br>For the DN ou=apache, dc=org, there is no parent, so null will be returned.
+ *
+ * @param dn the normalized distinguished name to resolve to a parent
+ * @return the parent associated with the normalized dn
+ *
+ public N getParentElement( DN dn )
+ {
+ List<RDN> rdns = dn.getRdns();
+
+ DnNode<N> currentNode = this;
+ DnNode<N> parent = null;
+
+ // Iterate through all the RDN until we find the associated partition
+ for ( int i = rdns.size() - 1; i >= 0; i-- )
+ {
+ if ( currentNode == null )
+ {
+ // We can stop here : there is no more node in the tree
+ break;
+ }
+
+ RDN rdn = rdns.get( i );
+
+ if ( currentNode.rdn.equals( rdn ) )
+ {
+ parent = currentNode;
+ currentNode = children.get( rdn );
+ continue;
+ }
+
+ break;
+ }
+
+ if ( parent != null )
+ {
+ return parent.getElement();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the Node for a given DN, if present in the tree.<br>
+ * For instance, if we have stored dc=acme, dc=org into the tree,
+ * the DN: ou=example, dc=acme, dc=org will have a parent, and
+ * dc=acme, dc=org will be returned.
+ * <br>For the DN ou=apache, dc=org, there is no parent, so null will be returned.
+ *
+ * @param dn the normalized distinguished name to resolve to a parent
+ * @return the Node associated with the normalized dn
+ */
+ public DnNode<N> getNode( DN dn )
+ {
+ List<RDN> rdns = dn.getRdns();
+
+ DnNode<N> currentNode = this;
+ DnNode<N> parent = null;
+
+ // Iterate through all the RDN until we find the associated partition
+ for ( int i = rdns.size() - 1; i >= 0; i-- )
+ {
+ RDN rdn = rdns.get( i );
+
+ if ( rdn.equals( currentNode.rdn ) )
+ {
+ parent = currentNode;
+ }
+ else if ( currentNode.hasChildren() )
+ {
+ currentNode = currentNode.children.get( rdn );
+
+ if ( currentNode == null )
+ {
+ break;
+ }
+
+ parent = currentNode;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if ( parent != null )
+ {
+ return parent;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ private String toString( String tabs )
+ {
+ if ( rdn == null )
+ {
+ return tabs;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append( tabs );
+
+ boolean hasChildren = hasChildren();
+
+ if ( isLeaf() )
+ {
+ sb.append( "Leaf[" ).append( rdn ).append( "]: " ).append( "'" ).append( element ).append( "'" );
+ return sb.toString();
+ }
+
+ sb.append( "Branch[" ).append( rdn ).append( "]: " );
+
+ if ( element != null )
+ {
+ sb.append( "'" ).append( element ).append( "'" );
+ }
+
+ tabs += " ";
+
+ sb.append( '\n' );
+
+ boolean isFirst = true;
+
+ if ( hasChildren )
+ {
+ for ( RDN rdn : children.keySet() )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( "\n" );
+ }
+
+ DnNode<N> child = children.get( rdn );
+
+ sb.append( child.toString( tabs ) );
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
}