in interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java [1088:1265]
public void modify( ModifyOperationContext modifyContext ) throws LdapException
{
Dn dn = modifyContext.getDn();
List<Modification> modifications = modifyContext.getModItems();
Entry entry = modifyContext.getEntry();
// We have three types of modifications :
// 1) A modification applied on a normal entry
// 2) A modification done on a subentry (the entry will have a 'subentry' ObjectClass)
// 3) A modification on a normal entry on whch we add a 'subentry' ObjectClass
// The third case is a transformation of a normal entry to a subentry. Not sure if it's
// legal ...
boolean isSubtreeSpecificationModification = false;
Modification subtreeMod = null;
// Find the subtreeSpecification
for ( Modification mod : modifications )
{
if ( mod.getAttribute().getAttributeType()
.equals( directoryService.getAtProvider().getSubtreeSpecification() ) )
{
isSubtreeSpecificationModification = true;
subtreeMod = mod;
break;
}
}
boolean containsSubentryOC = entry.contains( directoryService.getAtProvider().getObjectClass(),
SchemaConstants.SUBENTRY_OC );
// Check if we have a modified subentry attribute in a Subentry entry
if ( containsSubentryOC && isSubtreeSpecificationModification )
{
Subentry subentry = directoryService.getSubentryCache().removeSubentry( dn );
SubtreeSpecification ssOld = subentry.getSubtreeSpecification();
SubtreeSpecification ssNew;
try
{
ssNew = ssParser.parse( subtreeMod.getAttribute().getString() );
}
catch ( Exception e )
{
String msg = I18n.err( I18n.ERR_29000_CANNOT_PARSE_SUBTREE_SPECIFICATION );
LOG.error( msg, e );
throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
}
subentry.setSubtreeSpecification( ssNew );
subentry.setAdministrativeRoles( getSubentryTypes( entry, modifications ) );
directoryService.getSubentryCache().addSubentry( dn, subentry );
next( modifyContext );
// search for all entries selected by the old SS and remove references to subentry
Dn apName = dn.getParent();
Dn oldBaseDn = apName;
oldBaseDn = oldBaseDn.add( ssOld.getBase() );
ExprNode filter = new PresenceNode( directoryService.getAtProvider().getObjectClass() );
SearchControls controls = new SearchControls();
controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
controls.setReturningAttributes( new String[]
{ SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES, SchemaConstants.ALL_USER_ATTRIBUTES } );
SearchOperationContext searchOperationContext = new SearchOperationContext( modifyContext.getSession(),
oldBaseDn, filter, controls );
searchOperationContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES );
searchOperationContext.setPartition( modifyContext.getPartition() );
searchOperationContext.setTransaction( modifyContext.getTransaction() );
EntryFilteringCursor subentries = nexus.search( searchOperationContext );
try
{
while ( subentries.next() )
{
Entry candidate = subentries.get();
Dn candidateDn = candidate.getDn();
if ( directoryService.getEvaluator().evaluate( ssOld, apName, candidateDn, candidate ) )
{
ModifyOperationContext newModifyContext = new ModifyOperationContext( modifyContext.getSession(), candidateDn,
getOperationalModsForRemove( dn, candidate ) );
newModifyContext.setPartition( modifyContext.getPartition() );
newModifyContext.setTransaction( modifyContext.getTransaction() );
nexus.modify( newModifyContext );
}
}
subentries.close();
}
catch ( Exception e )
{
throw new LdapOperationErrorException( e.getMessage(), e );
}
finally
{
try
{
subentries.close();
}
catch ( Exception e )
{
LOG.error( I18n.err( I18n.ERR_38007_FAILED_ON_LIST_CLOSE ), e );
}
}
// search for all selected entries by the new SS and add references to subentry
subentry = directoryService.getSubentryCache().getSubentry( dn );
List<Attribute> operationalAttributes = getSubentryOperationalAttributes( dn, subentry );
Dn newBaseDn = apName;
newBaseDn = newBaseDn.add( ssNew.getBase() );
searchOperationContext = new SearchOperationContext( modifyContext.getSession(), newBaseDn, filter,
controls );
searchOperationContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES );
searchOperationContext.setPartition( modifyContext.getPartition() );
searchOperationContext.setTransaction( modifyContext.getTransaction() );
subentries = nexus.search( searchOperationContext );
try
{
while ( subentries.next() )
{
Entry candidate = subentries.get();
Dn candidateDn = candidate.getDn();
if ( directoryService.getEvaluator().evaluate( ssNew, apName, candidateDn, candidate ) )
{
ModifyOperationContext newModifyContext = new ModifyOperationContext( modifyContext.getSession(), candidateDn,
getOperationalModsForAdd( candidate, operationalAttributes ) );
newModifyContext.setTransaction( modifyContext.getTransaction() );
nexus.modify( newModifyContext );
}
}
subentries.close();
}
catch ( Exception e )
{
throw new LdapOperationErrorException( e.getMessage(), e );
}
finally
{
try
{
subentries.close();
}
catch ( Exception e )
{
LOG.error( I18n.err( I18n.ERR_38007_FAILED_ON_LIST_CLOSE ), e );
}
}
}
else
{
next( modifyContext );
if ( !containsSubentryOC )
{
Entry newEntry = modifyContext.getAlteredEntry();
List<Modification> subentriesOpAttrMods = getModsOnEntryModification( dn, entry, newEntry );
if ( !subentriesOpAttrMods.isEmpty() )
{
ModifyOperationContext newModifyContext = new ModifyOperationContext( modifyContext.getSession(), dn, subentriesOpAttrMods );
newModifyContext.setPartition( modifyContext.getPartition() );
newModifyContext.setTransaction( modifyContext.getTransaction() );
nexus.modify( newModifyContext );
}
}
}
}