in interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java [666:773]
private void processSubordinates( OperationContext operationContext, Set<AttributeTypeOptions> returningAttributes,
boolean allAttributes, Entry entry ) throws LdapException
{
// Bypass the rootDSE : we won't get the nbChildren and nbSubordiantes for this special entry
if ( Dn.isNullOrEmpty( entry.getDn() ) )
{
return;
}
// Add the Subordinates AttributeType if it's requested
AttributeType nbChildrenAt = directoryService.getAtProvider().getNbChildren();
AttributeTypeOptions nbChildrenAto = new AttributeTypeOptions( nbChildrenAt );
AttributeType nbSubordinatesAt = directoryService.getAtProvider().getNbSubordinates();
AttributeTypeOptions nbSubordinatesAto = new AttributeTypeOptions( nbSubordinatesAt );
AttributeType hasSubordinatesAt = directoryService.getAtProvider().getHasSubordinates();
AttributeTypeOptions hasSubordinatesAto = new AttributeTypeOptions( hasSubordinatesAt );
AttributeType structuralObjectClassAt = directoryService.getAtProvider().getStructuralObjectClass();
AttributeTypeOptions structuralObjectClassAto = new AttributeTypeOptions( structuralObjectClassAt );
if ( returningAttributes != null )
{
boolean nbChildrenRequested = returningAttributes.contains( nbChildrenAto ) || allAttributes;
boolean nbSubordinatesRequested = returningAttributes.contains( nbSubordinatesAto ) || allAttributes;
boolean hasSubordinatesRequested = returningAttributes.contains( hasSubordinatesAto ) || allAttributes;
boolean structuralObjectClassRequested = returningAttributes.contains( structuralObjectClassAto ) || allAttributes;
if ( nbChildrenRequested || nbSubordinatesRequested || hasSubordinatesRequested
|| structuralObjectClassRequested )
{
Partition partition = directoryService.getPartitionNexus().getPartition( entry.getDn() );
Subordinates subordinates = partition.getSubordinates( operationContext.getTransaction(), entry );
long nbChildren = subordinates.getNbChildren();
long nbSubordinates = subordinates.getNbSubordinates();
// Inject the nbChildren OpAttr if needed
if ( nbChildrenRequested )
{
entry.add( new DefaultAttribute( nbChildrenAt,
Long.toString( nbChildren ) ) );
}
// Inject the nbSubordinates OpAttr if needed
if ( nbSubordinatesRequested )
{
entry.add( new DefaultAttribute( nbSubordinatesAt,
Long.toString( nbSubordinates ) ) );
}
// Inject the hasSubordinates OpAttr if needed
if ( hasSubordinatesRequested )
{
if ( nbSubordinates > 0 )
{
entry.add( new DefaultAttribute( hasSubordinatesAt, "TRUE" ) );
}
else
{
entry.add( new DefaultAttribute( hasSubordinatesAt, "FALSE" ) );
}
}
// Inject the structuralObjectclass OpAttr if needed
if ( structuralObjectClassRequested )
{
Attribute objectClasses = entry.get( SchemaConstants.OBJECT_CLASS_AT );
Map<String, ObjectClass> superiors = new HashMap<>();
ObjectClass[] objectClassArray = new ObjectClass[objectClasses.size()];
int nbStructural = 0;
// First get all the structural objectClasses
for ( Value objectClassValue : objectClasses )
{
ObjectClass objectClass =
schemaManager.getObjectClassRegistry().get( objectClassValue.getNormalized() );
if ( objectClass.isStructural() )
{
objectClassArray[nbStructural++] = objectClass;
// We can only have one superior objectClass for Structural ObjectClass
superiors.put( objectClass.getSuperiors().get( 0 ).getOid(), objectClass );
}
}
// Then find the top of them
if ( nbStructural == 1 )
{
entry.add( new DefaultAttribute( structuralObjectClassAt,
objectClassArray[0].getName() ) );
}
else
{
for ( ObjectClass oc : objectClassArray )
{
if ( !superiors.containsKey( oc.getOid() ) )
{
// We are done : the current OC is not the superior of any other
// OC, this is necessarily the top level one
entry.add( new DefaultAttribute( structuralObjectClassAt, oc.getName() ) );
break;
}
}
}
}
}
}
}