in xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java [765:946]
public void add( AddOperationContext addContext ) throws LdapException
{
PartitionTxn partitionTxn = addContext.getTransaction();
assert ( partitionTxn != null );
assert ( partitionTxn instanceof PartitionWriteTxn );
try
{
setRWLock( addContext );
Entry entry = ( ( ClonedServerEntry ) addContext.getEntry() ).getClonedEntry();
Dn entryDn = entry.getDn();
// check if the entry already exists
ParentIdAndRdn parentIdAndRdn = getParentId( partitionTxn, entryDn );
// don't keep going if we cannot find the parent Id
if ( parentIdAndRdn == null )
{
throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_49008_ID_FOR_PARENT_NOT_FOUND,
parentIdAndRdn ) );
}
String parentId = parentIdAndRdn.getParentId();
lockRead();
try
{
if ( rdnIdx.forwardLookup( partitionTxn, parentIdAndRdn ) != null )
{
throw new LdapEntryAlreadyExistsException(
I18n.err( I18n.ERR_49014_ENTRY_ALREADY_EXISTS, entryDn.getName() ) );
}
}
finally
{
unlockRead();
}
// Get a new UUID for the added entry if it does not have any already
Attribute entryUUID = entry.get( entryUuidAT );
String id;
if ( entryUUID == null )
{
id = master.getNextId( entry );
}
else
{
id = entryUUID.getString();
}
if ( entryDn.getNormName().equals( suffixDn.getNormName() ) )
{
suffixId = id;
}
// Update the ObjectClass index
Attribute objectClass = entry.get( objectClassAT );
if ( objectClass == null )
{
String msg = I18n.err( I18n.ERR_49009_ENTRY_WITHOUT_OBJECT_CLASS, entryDn.getName(), entry );
ResultCodeEnum rc = ResultCodeEnum.OBJECT_CLASS_VIOLATION;
throw new LdapSchemaViolationException( rc, msg );
}
for ( Value value : objectClass )
{
if ( value.equals( topOCValue ) )
{
continue;
}
String normalizedOc = objectClassNormalizer.normalize( value.getString() );
objectClassIdx.add( partitionTxn, normalizedOc, id );
}
if ( objectClass.contains( SchemaConstants.ALIAS_OC ) )
{
Attribute aliasAttr = entry.get( aliasedObjectNameAT );
addAliasIndices( partitionTxn, id, entryDn, new Dn( schemaManager, aliasAttr.getString() ) );
}
// Update the EntryCsn index
Attribute entryCsn = entry.get( entryCsnAT );
if ( entryCsn == null )
{
String msg = I18n.err( I18n.ERR_49010_ENTRY_WITHOUT_ENTRY_CSN, entryDn.getName(), entry );
throw new LdapSchemaViolationException( ResultCodeEnum.OBJECT_CLASS_VIOLATION, msg );
}
entryCsnIdx.add( partitionTxn, entryCsn.getString(), id );
// Update the AdministrativeRole index, if needed
if ( entry.containsAttribute( administrativeRoleAT ) )
{
// We may have more than one role
Attribute adminRoles = entry.get( administrativeRoleAT );
for ( Value value : adminRoles )
{
adminRoleIdx.add( partitionTxn, value.getString(), id );
}
// Adds only those attributes that are indexed
presenceIdx.add( partitionTxn, administrativeRoleAT.getOid(), id );
}
// Now work on the user defined userIndices
for ( Attribute attribute : entry )
{
AttributeType attributeType = attribute.getAttributeType();
String attributeOid = attributeType.getOid();
if ( hasUserIndexOn( attributeType ) )
{
Index<Object, String> userIndex = ( Index<Object, String> ) getUserIndex( attributeType );
// here lookup by attributeId is OK since we got attributeId from
// the entry via the enumeration - it's in there as is for sure
for ( Value value : attribute )
{
String normalized = value.getNormalized();
userIndex.add( partitionTxn, normalized, id );
}
// Adds only those attributes that are indexed
presenceIdx.add( partitionTxn, attributeOid, id );
}
}
// Add the parentId in the entry
entry.put( ApacheSchemaConstants.ENTRY_PARENT_ID_AT, parentId );
lockWrite();
try
{
// Update the RDN index
rdnIdx.add( partitionTxn, parentIdAndRdn, id );
// Update the PIAR cache at the same time
updatePiarCache( parentIdAndRdn, id, ADD_CACHE );
// Update the parent's nbChildren and nbDescendants values
if ( parentId != Partition.ROOT_ID )
{
updateRdnIdx( partitionTxn, parentId, ADD_CHILD, 0 );
}
// Remove the EntryDN attribute
entry.removeAttributes( entryDnAT );
Attribute at = entry.get( SchemaConstants.ENTRY_CSN_AT );
setContextCsn( at.getString() );
// And finally add the entry into the master table
master.put( partitionTxn, id, entry );
}
finally
{
unlockWrite();
}
}
catch ( LdapException le )
{
throw le;
}
catch ( Exception e )
{
throw new LdapException( e );
}
}