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/12/29 19:55:12 UTC
svn commit: r1053701 -
/directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
Author: elecharny
Date: Wed Dec 29 18:55:12 2010
New Revision: 1053701
URL: http://svn.apache.org/viewvc?rev=1053701&view=rev
Log:
o Added some helper methods for the search and lookup operations
o Implemented the lookup operation
Modified:
directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
Modified: directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java?rev=1053701&r1=1053700&r2=1053701&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java Wed Dec 29 18:55:12 2010
@@ -72,6 +72,7 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
import org.apache.directory.server.core.interceptor.context.ListOperationContext;
+import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
@@ -342,334 +343,7 @@ public class SubentryInterceptor extends
{
public boolean accept( SearchingOperationContext searchContext, ClonedServerEntry entry ) throws Exception
{
- DN entryDn = entry.getDn();
- EntryAttribute newAcSeqNumberAT = null;
- EntryAttribute newCaSeqNumberAT = null;
- EntryAttribute newSsSeqNumberAT = null;
- EntryAttribute newTeSeqNumberAT = null;
- boolean hasModifications = false;
- Modification modificationAc = null;
- Modification modificationCa = null;
- Modification modificationSs = null;
- Modification modificationTe = null;
-
- // process the AccessControl AP
- DnNode<AdministrativePoint> apNode = directoryService.getAccessControlAPCache().getParentWithElement( entryDn );
-
- if ( apNode != null )
- {
- AdministrativePoint adminPoint = apNode.getElement();
- EntryAttribute acSeqNumberAT = entry.get( ACCESS_CONTROL_SEQ_NUMBER_AT );
-
- if ( adminPoint.isSpecific() )
- {
- long apSeqNumber = adminPoint.getSeqNumber();
-
- if ( acSeqNumberAT != null )
- {
- if ( apSeqNumber != Long.parseLong( acSeqNumberAT.getString() ) )
- {
- // The seqNumber is not up to date, we have to update it
- hasModifications = true;
- newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationAc = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newAcSeqNumberAT );
- }
- }
- else
- {
- // We have to add a seqNumber in the entry
- hasModifications = true;
- newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationAc = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newAcSeqNumberAT );
- }
- }
- else
- {
- // We have to recurse : starting from the IAP, we go up the AP tree
- // until we find the SAP. For each AP we find, we compare the AP's seqNumber
- // and if it's above the current SeqNumber (initialized to the entry value),
- // we select this SeqNumber. When we are done, if the selected SeqNumber is
- // greater than the initial entry seqNumber, then we update the entry
-
- // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
- long entrySeqNumber = -1L;
-
- if ( acSeqNumberAT != null )
- {
- entrySeqNumber = Long.parseLong( acSeqNumberAT.getString() );
- }
-
- boolean sapFound = false;
- boolean seqNumberUpdated = false;
-
- do
- {
- if ( adminPoint.isSpecific() )
- {
- sapFound = true;
- }
-
- if ( entrySeqNumber < adminPoint.getSeqNumber() )
- {
- // Evaluate the current AP on the entry for each subentry
- for ( Subentry subentry : adminPoint.getSubentries() )
- {
- if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
- {
- entrySeqNumber = adminPoint.getSeqNumber();
- seqNumberUpdated = true;
-
- // No need to evaluate another subentry
- break;
- }
- }
- }
-
- // Go down one level
- apNode = apNode.getParentWithElement( apNode.getDn() );
- } while ( !sapFound );
-
- if ( seqNumberUpdated )
- {
- hasModifications = true;
- newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
- modificationAc = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newAcSeqNumberAT );
- }
- }
- }
-
- // Process the CollectiveAttribute AP
- apNode = directoryService.getCollectiveAttributeAPCache().getParentWithElement( entryDn );
-
- if ( apNode != null )
- {
- AdministrativePoint adminPoint = apNode.getElement();
- EntryAttribute caSeqNumberAT = entry.get( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT );
-
- if ( adminPoint.isSpecific() )
- {
- long apSeqNumber = adminPoint.getSeqNumber();
-
- if ( caSeqNumberAT != null )
- {
- if ( apSeqNumber != Long.parseLong( caSeqNumberAT.getString() ) )
- {
- // The seqNumber is not up to date, we have to update it
- hasModifications = true;
- newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationCa = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newCaSeqNumberAT );
- }
- }
- else
- {
- // We have to add a seqNumber in the entry
- hasModifications = true;
- newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationCa = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newCaSeqNumberAT );
- }
- }
- else
- {
- // We have to recurse : starting from the IAP, we go up the AP tree
- // until we find the SAP. For each AP we find, we compare the AP's seqNumber
- // and if it's above the current SeqNumber (initialized to the entry value),
- // we select this SeqNumber. When we are done, if the selected SeqNumber is
- // greater than the initial entry seqNumber, then we update the entry
-
- // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
- long entrySeqNumber = -1L;
-
- if ( caSeqNumberAT != null )
- {
- entrySeqNumber = Long.parseLong( caSeqNumberAT.getString() );
- }
-
- boolean sapFound = false;
- boolean seqNumberUpdated = false;
-
- do
- {
- if ( adminPoint.isSpecific() )
- {
- sapFound = true;
- }
-
- if ( entrySeqNumber < adminPoint.getSeqNumber() )
- {
- // Evaluate the current AP on the entry for each subentry
- for ( Subentry subentry : adminPoint.getSubentries() )
- {
- if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
- {
- entrySeqNumber = adminPoint.getSeqNumber();
- seqNumberUpdated = true;
-
- // No need to evaluate another subentry
- break;
- }
- }
- }
-
- // Go down one level
- apNode = apNode.getParentWithElement( apNode.getDn() );
- } while ( !sapFound );
-
- if ( seqNumberUpdated )
- {
- hasModifications = true;
- newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
- modificationCa = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newCaSeqNumberAT );
- }
- }
- }
-
- // process the SubSchema : no InnerArea
- apNode = directoryService.getSubschemaAPCache().getParentWithElement( entryDn );
-
- if ( apNode != null )
- {
- AdministrativePoint adminPoint = apNode.getElement();
- EntryAttribute ssSeqNumberAT = entry.get( SUB_SCHEMA_SEQ_NUMBER_AT );
-
- long apSeqNumber = adminPoint.getSeqNumber();
-
- if ( ssSeqNumberAT != null )
- {
- if ( apSeqNumber != Long.parseLong( ssSeqNumberAT.getString() ) )
- {
- // The seqNumber is not up to date, we have to update it
- hasModifications = true;
- newSsSeqNumberAT = new DefaultEntryAttribute( SUB_SCHEMA_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationSs = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newSsSeqNumberAT );
- }
- }
- else
- {
- // We have to add a seqNumber in the entry
- hasModifications = true;
- newSsSeqNumberAT = new DefaultEntryAttribute( SUB_SCHEMA_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationSs = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newSsSeqNumberAT );
- }
- }
-
- // process the TriggerExecution
- apNode = directoryService.getTriggerExecutionAPCache().getParentWithElement( entryDn );
-
- if ( apNode != null )
- {
- AdministrativePoint adminPoint = apNode.getElement();
- EntryAttribute teSeqNumberAT = entry.get( TRIGGER_EXECUTION_SEQ_NUMBER_AT );
-
- if ( adminPoint.isSpecific() )
- {
- long apSeqNumber = adminPoint.getSeqNumber();
-
- if ( teSeqNumberAT != null )
- {
- if ( apSeqNumber != Long.parseLong( teSeqNumberAT.getString() ) )
- {
- // The seqNumber is not up to date, we have to update it
- hasModifications = true;
- newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationTe = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newTeSeqNumberAT );
- }
- }
- else
- {
- // We have to add a seqNumber in the entry
- hasModifications = true;
- newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
- modificationTe = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newTeSeqNumberAT );
- }
- }
- else
- {
- // We have to recurse : starting from the IAP, we go up the AP tree
- // until we find the SAP. For each AP we find, we compare the AP's seqNumber
- // and if it's above the current SeqNumber (initialized to the entry value),
- // we select this SeqNumber. When we are done, if the selected SeqNumber is
- // greater than the initial entry seqNumber, then we update the entry
-
- // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
- long entrySeqNumber = -1L;
-
- if ( teSeqNumberAT != null )
- {
- entrySeqNumber = Long.parseLong( teSeqNumberAT.getString() );
- }
-
- boolean sapFound = false;
- boolean seqNumberUpdated = false;
-
- do
- {
- if ( adminPoint.isSpecific() )
- {
- sapFound = true;
- }
-
- if ( entrySeqNumber < adminPoint.getSeqNumber() )
- {
- // Evaluate the current AP on the entry for each subentry
- for ( Subentry subentry : adminPoint.getSubentries() )
- {
- if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
- {
- entrySeqNumber = adminPoint.getSeqNumber();
- seqNumberUpdated = true;
-
- // No need to evaluate another subentry
- break;
- }
- }
- }
-
- // Go down one level
- apNode = apNode.getParentWithElement( apNode.getDn() );
- } while ( !sapFound );
-
- if ( seqNumberUpdated )
- {
- hasModifications = true;
- newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
- modificationTe = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newTeSeqNumberAT );
- }
- }
- }
-
- // Now apply the modifications to the entry
- if ( hasModifications )
- {
- List<Modification> modifications = new ArrayList<Modification>();
-
- if ( modificationAc != null )
- {
- modifications.add( modificationAc );
- }
-
- if ( modificationCa != null )
- {
- modifications.add( modificationCa );
- }
-
- if ( modificationSs != null )
- {
- modifications.add( modificationSs );
- }
-
- if ( modificationTe != null )
- {
- modifications.add( modificationTe );
- }
-
- ModifyOperationContext modCtx = new ModifyOperationContext( directoryService.getAdminSession() );
- modCtx.setByPassed( BYPASS_INTERCEPTORS );
- modCtx.setDn( entryDn );
- modCtx.setModItems( modifications );
-
- directoryService.getOperationManager().modify( modCtx );
- }
-
+ updateSeqNumber( entry );
return true;
}
@@ -842,6 +516,381 @@ public class SubentryInterceptor extends
return false;
}
+
+ /**
+ * Update the seqNumber for each kind of role. The entry will be updated in the backend only
+ * if its seqNumbers are not up to date.
+ */
+ private boolean updateSeqNumber( Entry entry ) throws LdapException
+ {
+ Modification modificationAc = updateACSeqNumber( entry );
+ Modification modificationCa = updateCASeqNumber( entry );
+ Modification modificationSs = updateSSSeqNumber( entry );
+ Modification modificationTe = updateTESeqNumber( entry );
+
+ if ( ( modificationAc != null ) || ( modificationCa != null ) || ( modificationSs != null ) || (modificationTe != null ) )
+ {
+ List<Modification> modifications = new ArrayList<Modification>();
+
+ if ( modificationAc != null )
+ {
+ modifications.add( modificationAc );
+ }
+
+ if ( modificationCa != null )
+ {
+ modifications.add( modificationCa );
+ }
+
+ if ( modificationSs != null )
+ {
+ modifications.add( modificationSs );
+ }
+
+ if ( modificationTe != null )
+ {
+ modifications.add( modificationTe );
+ }
+
+ ModifyOperationContext modCtx = new ModifyOperationContext( directoryService.getAdminSession() );
+ modCtx.setByPassed( BYPASS_INTERCEPTORS );
+ modCtx.setDn( entry.getDn() );
+ modCtx.setModItems( modifications );
+ modCtx.setEntry( (ClonedServerEntry)entry );
+
+ directoryService.getOperationManager().modify( modCtx );
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Update the AccessControl seqNumber for each kind of role. The entry will be updated in the backend only
+ * if its seqNumbers are not up to date.
+ */
+ private Modification updateACSeqNumber( Entry entry ) throws LdapException
+ {
+ DN entryDn = entry.getDn();
+ EntryAttribute newAcSeqNumberAT = null;
+ Modification modificationAc = null;
+
+ DnNode<AdministrativePoint> apNode = directoryService.getAccessControlAPCache().getParentWithElement( entryDn );
+
+ if ( apNode != null )
+ {
+ AdministrativePoint adminPoint = apNode.getElement();
+ EntryAttribute acSeqNumberAT = entry.get( ACCESS_CONTROL_SEQ_NUMBER_AT );
+
+ if ( adminPoint.isSpecific() )
+ {
+ long apSeqNumber = adminPoint.getSeqNumber();
+
+ if ( acSeqNumberAT != null )
+ {
+ if ( apSeqNumber != Long.parseLong( acSeqNumberAT.getString() ) )
+ {
+ // The seqNumber is not up to date, we have to update it
+ newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationAc = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newAcSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to add a seqNumber in the entry
+ newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationAc = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newAcSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to recurse : starting from the IAP, we go up the AP tree
+ // until we find the SAP. For each AP we find, we compare the AP's seqNumber
+ // and if it's above the current SeqNumber (initialized to the entry value),
+ // we select this SeqNumber. When we are done, if the selected SeqNumber is
+ // greater than the initial entry seqNumber, then we update the entry
+
+ // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
+ long entrySeqNumber = -1L;
+
+ if ( acSeqNumberAT != null )
+ {
+ entrySeqNumber = Long.parseLong( acSeqNumberAT.getString() );
+ }
+
+ boolean sapFound = false;
+ boolean seqNumberUpdated = false;
+
+ do
+ {
+ if ( adminPoint.isSpecific() )
+ {
+ sapFound = true;
+ }
+
+ if ( entrySeqNumber < adminPoint.getSeqNumber() )
+ {
+ // Evaluate the current AP on the entry for each subentry
+ for ( Subentry subentry : adminPoint.getSubentries() )
+ {
+ if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
+ {
+ entrySeqNumber = adminPoint.getSeqNumber();
+ seqNumberUpdated = true;
+
+ // No need to evaluate another subentry
+ break;
+ }
+ }
+ }
+
+ // Go down one level
+ apNode = apNode.getParentWithElement( apNode.getDn() );
+ } while ( !sapFound );
+
+ if ( seqNumberUpdated )
+ {
+ newAcSeqNumberAT = new DefaultEntryAttribute( ACCESS_CONTROL_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
+ modificationAc = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newAcSeqNumberAT );
+ }
+ }
+ }
+
+ return modificationAc;
+ }
+
+
+
+ /**
+ * Update the CollectiveAttribute seqNumber for each kind of role. The entry will be updated in the backend only
+ * if its seqNumbers are not up to date.
+ */
+ private Modification updateCASeqNumber( Entry entry ) throws LdapException
+ {
+ DN entryDn = entry.getDn();
+ EntryAttribute newCaSeqNumberAT = null;
+ Modification modificationCa = null;
+
+ DnNode<AdministrativePoint> apNode = directoryService.getCollectiveAttributeAPCache().getParentWithElement( entryDn );
+
+ if ( apNode != null )
+ {
+ AdministrativePoint adminPoint = apNode.getElement();
+ EntryAttribute caSeqNumberAT = entry.get( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT );
+
+ if ( adminPoint.isSpecific() )
+ {
+ long apSeqNumber = adminPoint.getSeqNumber();
+
+ if ( caSeqNumberAT != null )
+ {
+ if ( apSeqNumber != Long.parseLong( caSeqNumberAT.getString() ) )
+ {
+ // The seqNumber is not up to date, we have to update it
+ newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationCa = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newCaSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to add a seqNumber in the entry
+ newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationCa = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newCaSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to recurse : starting from the IAP, we go up the AP tree
+ // until we find the SAP. For each AP we find, we compare the AP's seqNumber
+ // and if it's above the current SeqNumber (initialized to the entry value),
+ // we select this SeqNumber. When we are done, if the selected SeqNumber is
+ // greater than the initial entry seqNumber, then we update the entry
+
+ // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
+ long entrySeqNumber = -1L;
+
+ if ( caSeqNumberAT != null )
+ {
+ entrySeqNumber = Long.parseLong( caSeqNumberAT.getString() );
+ }
+
+ boolean sapFound = false;
+ boolean seqNumberUpdated = false;
+
+ do
+ {
+ if ( adminPoint.isSpecific() )
+ {
+ sapFound = true;
+ }
+
+ if ( entrySeqNumber < adminPoint.getSeqNumber() )
+ {
+ // Evaluate the current AP on the entry for each subentry
+ for ( Subentry subentry : adminPoint.getSubentries() )
+ {
+ if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
+ {
+ entrySeqNumber = adminPoint.getSeqNumber();
+ seqNumberUpdated = true;
+
+ // No need to evaluate another subentry
+ break;
+ }
+ }
+ }
+
+ // Go down one level
+ apNode = apNode.getParentWithElement( apNode.getDn() );
+ } while ( !sapFound );
+
+ if ( seqNumberUpdated )
+ {
+ newCaSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
+ modificationCa = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newCaSeqNumberAT );
+ }
+ }
+ }
+
+ return modificationCa;
+ }
+
+
+ /**
+ * Update the SubSchema seqNumber for each kind of role. The entry will be updated in the backend only
+ * if its seqNumbers are not up to date.
+ */
+ private Modification updateSSSeqNumber( Entry entry ) throws LdapException
+ {
+ DN entryDn = entry.getDn();
+ EntryAttribute newSsSeqNumberAT = null;
+ Modification modificationSs = null;
+
+ DnNode<AdministrativePoint> apNode = directoryService.getSubschemaAPCache().getParentWithElement( entryDn );
+
+ if ( apNode != null )
+ {
+ AdministrativePoint adminPoint = apNode.getElement();
+ EntryAttribute ssSeqNumberAT = entry.get( SUB_SCHEMA_SEQ_NUMBER_AT );
+
+ long apSeqNumber = adminPoint.getSeqNumber();
+
+ if ( ssSeqNumberAT != null )
+ {
+ if ( apSeqNumber != Long.parseLong( ssSeqNumberAT.getString() ) )
+ {
+ // The seqNumber is not up to date, we have to update it
+ newSsSeqNumberAT = new DefaultEntryAttribute( SUB_SCHEMA_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationSs = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newSsSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to add a seqNumber in the entry
+ newSsSeqNumberAT = new DefaultEntryAttribute( SUB_SCHEMA_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationSs = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newSsSeqNumberAT );
+ }
+ }
+
+ return modificationSs;
+ }
+
+
+ /**
+ * Update the TriggerExecution seqNumber for each kind of role. The entry will be updated in the backend only
+ * if its seqNumbers are not up to date.
+ */
+ private Modification updateTESeqNumber( Entry entry ) throws LdapException
+ {
+ DN entryDn = entry.getDn();
+ EntryAttribute newTeSeqNumberAT = null;
+ Modification modificationTe = null;
+
+ DnNode<AdministrativePoint> apNode = directoryService.getTriggerExecutionAPCache().getParentWithElement( entryDn );
+
+ if ( apNode != null )
+ {
+ AdministrativePoint adminPoint = apNode.getElement();
+ EntryAttribute teSeqNumberAT = entry.get( TRIGGER_EXECUTION_SEQ_NUMBER_AT );
+
+ if ( adminPoint.isSpecific() )
+ {
+ long apSeqNumber = adminPoint.getSeqNumber();
+
+ if ( teSeqNumberAT != null )
+ {
+ if ( apSeqNumber != Long.parseLong( teSeqNumberAT.getString() ) )
+ {
+ // The seqNumber is not up to date, we have to update it
+ newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationTe = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newTeSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to add a seqNumber in the entry
+ newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( apSeqNumber ) );
+ modificationTe = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newTeSeqNumberAT );
+ }
+ }
+ else
+ {
+ // We have to recurse : starting from the IAP, we go up the AP tree
+ // until we find the SAP. For each AP we find, we compare the AP's seqNumber
+ // and if it's above the current SeqNumber (initialized to the entry value),
+ // we select this SeqNumber. When we are done, if the selected SeqNumber is
+ // greater than the initial entry seqNumber, then we update the entry
+
+ // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
+ long entrySeqNumber = -1L;
+
+ if ( teSeqNumberAT != null )
+ {
+ entrySeqNumber = Long.parseLong( teSeqNumberAT.getString() );
+ }
+
+ boolean sapFound = false;
+ boolean seqNumberUpdated = false;
+
+ do
+ {
+ if ( adminPoint.isSpecific() )
+ {
+ sapFound = true;
+ }
+
+ if ( entrySeqNumber < adminPoint.getSeqNumber() )
+ {
+ // Evaluate the current AP on the entry for each subentry
+ for ( Subentry subentry : adminPoint.getSubentries() )
+ {
+ if ( evaluator.evaluate( subentry.getSubtreeSpecification(), apNode.getDn(), entryDn, entry ) )
+ {
+ entrySeqNumber = adminPoint.getSeqNumber();
+ seqNumberUpdated = true;
+
+ // No need to evaluate another subentry
+ break;
+ }
+ }
+ }
+
+ // Go down one level
+ apNode = apNode.getParentWithElement( apNode.getDn() );
+ } while ( !sapFound );
+
+ if ( seqNumberUpdated )
+ {
+ newTeSeqNumberAT = new DefaultEntryAttribute( TRIGGER_EXECUTION_SEQ_NUMBER_AT, Long.toString( entrySeqNumber ) );
+ modificationTe = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, newTeSeqNumberAT );
+ }
+ }
+ }
+
+ return modificationTe;
+ }
/**
* Update all the entries under an AP adding the
@@ -2535,6 +2584,37 @@ public class SubentryInterceptor extends
next.delete( deleteContext );
}
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Entry lookup( NextInterceptor nextInterceptor, LookupOperationContext lookupContext )
+ throws LdapException
+ {
+ Entry entry = nextInterceptor.lookup( lookupContext );
+
+ // We have to update the entry now. At this point, we have no idea if the
+ // returned entry is an AP or a subentry. Check that now
+ Entry originalEntry = ((ClonedServerEntry)entry).getOriginalEntry();
+
+ if ( originalEntry.containsAttribute( ADMINISTRATIVE_ROLE_AT ) ||
+ originalEntry.contains( OBJECT_CLASS_AT, SchemaConstants.SUBENTRY_OC ) )
+ {
+ // No need to update anything
+ return entry;
+ }
+
+ // This is a normal entry, update its seqNumbers if neede
+ if ( updateSeqNumber( entry ) )
+ {
+ // Get the entry back again
+ entry = nextInterceptor.lookup( lookupContext );
+ }
+
+ return entry;
+ }
+
/**