public void add()

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 );
        }
    }