private void addCollectiveAttributes( FilteringOperationContext opContext, Entry entry )
throws LdapException
{
CoreSession session = opContext.getSession();
Attribute collectiveAttributeSubentries = ( ( ClonedServerEntry ) entry ).getOriginalEntry().get(
COLLECTIVE_ATTRIBUTE_SUBENTRIES_AT );
/*
* If there are no collective attribute subentries referenced then we
* have no collective attributes to inject to this entry.
*/
if ( collectiveAttributeSubentries == null )
{
return;
}
LOG.debug( "Filtering entry " + entry.getDn() );
/*
* Before we proceed we need to lookup the exclusions within the entry
* and build a set of exclusions for rapid lookup. We use OID values
* in the exclusions set instead of regular names that may have case
* variance.
*/
Attribute collectiveExclusions = ( ( ClonedServerEntry ) entry ).getOriginalEntry().get(
COLLECTIVE_EXCLUSIONS_AT );
Set<AttributeType> exclusions = new HashSet<AttributeType>();
if ( collectiveExclusions != null )
{
LOG.debug( "The entry has some exclusions : {}", collectiveExclusions );
if ( collectiveExclusions.contains( SchemaConstants.EXCLUDE_ALL_COLLECTIVE_ATTRIBUTES_AT_OID )
|| collectiveExclusions.contains( SchemaConstants.EXCLUDE_ALL_COLLECTIVE_ATTRIBUTES_AT ) )
{
/*
* This entry does not allow any collective attributes
* to be injected into itself.
*/
LOG.debug( "The entry excludes all the collectiveAttributes" );
return;
}
for ( Value<?> value : collectiveExclusions )
{
AttributeType attrType = schemaManager.lookupAttributeTypeRegistry( value.getString() );
exclusions.add( attrType );
LOG.debug( "Adding {} in the list of excluded collectiveAttributes", attrType.getName() );
}
}
/*
* For each collective subentry referenced by the entry we lookup the
* attributes of the subentry and copy collective attributes from the
* subentry into the entry.
*/
for ( Value<?> value : collectiveAttributeSubentries )
{
String subentryDnStr = value.getString();
Dn subentryDn = dnFactory.create( subentryDnStr );
LOG.debug( "Applying subentries {}", subentryDn.getName() );
/*
* TODO - Instead of hitting disk here can't we leverage the
* SubentryService to get us cached sub-entries so we're not
* wasting time with a lookup here? It is ridiculous to waste
* time looking up this sub-entry.
*/
LookupOperationContext lookupContext = new LookupOperationContext( session, subentryDn,
SchemaConstants.ALL_ATTRIBUTES_ARRAY );
Entry subentry = directoryService.getPartitionNexus().lookup( lookupContext );
//LOG.debug( "Fetched the subentry : {}", subentry.getDn().getName() );
for ( Attribute attribute : subentry.getAttributes() )
{
AttributeType attributeType = attribute.getAttributeType();
// Skip the attributes which are not collective
if ( !attributeType.isCollective() )
{
//LOG.debug( "The {} subentry attribute is not collective", attributeType.getName() );
continue;
}
/*
* Skip the addition of this collective attribute if it is excluded
* in the 'collectiveAttributes' attribute.
*/
if ( exclusions.contains( attributeType ) )
{
LOG.debug( "The {} subentry attribute has been removed, it's in the exclusion list",
attributeType.getName() );
continue;
}
/*
* If not all attributes or this collective attribute requested specifically
* then bypass the inclusion process.
*/
if ( !opContext.isAllUserAttributes() && !opContext.contains( schemaManager, attributeType ) )
{
LOG.debug( "The {} subentry attribute is not in the list of attributes to return",
attributeType.getName() );
continue;
}
Attribute subentryColAttr = subentry.get( attributeType );
Attribute entryColAttr = entry.get( attributeType );
/*
* If entry does not have attribute for collective attribute then create it.
*/
if ( entryColAttr == null )
{
entryColAttr = new DefaultAttribute( attributeType );
entry.put( entryColAttr );
}
/*
* Add all the collective attribute values in the subentry
* to the currently processed collective attribute in the entry.
*/
for ( Value<?> subentryColVal : subentryColAttr )
{
LOG.debug( "Adding the {} collective attribute into the entry", subentryColAttr );
entryColAttr.add( subentryColVal.getString() );
}
}
}
}