private void rename()

in xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java [2505:2661]


    private void rename( PartitionTxn partitionTxn, String oldId, Rdn newRdn, boolean deleteOldRdn, Entry entry ) 
        throws LdapException, IndexNotFoundException
    {
        if ( entry == null )
        {
            entry = master.get( partitionTxn, oldId );
        }

        Dn updn = entry.getDn();

        if ( !newRdn.isSchemaAware() )
        {
            newRdn = new Rdn( schemaManager, newRdn );
        }

        /*
         * H A N D L E   N E W   R D N
         * ====================================================================
         * Add the new Rdn attribute to the entry.  If an index exists on the
         * new Rdn attribute we add the index for this attribute value pair.
         * Also we make sure that the presence index shows the existence of the
         * new Rdn attribute within this entry.
         * Last, not least, if the AttributeType is single value, take care
         * of removing the old value.
         */
        for ( Ava newAtav : newRdn )
        {
            String newNormType = newAtav.getNormType();
            Object newNormValue = newAtav.getValue().getString();

            AttributeType newRdnAttrType = schemaManager.lookupAttributeTypeRegistry( newNormType );

            if ( newRdnAttrType.isSingleValued() && entry.containsAttribute( newRdnAttrType ) )
            {
                Attribute oldAttribute = entry.get( newRdnAttrType );
                AttributeType oldAttributeType = oldAttribute.getAttributeType();
                
                // We have to remove the old attribute value, if we have some
                entry.removeAttributes( newRdnAttrType );
                
                // Deal with the index
                if ( hasUserIndexOn( newRdnAttrType ) )
                {
                    Index<?, String> userIndex = getUserIndex( newRdnAttrType );

                    String normalized = oldAttributeType.getEquality().getNormalizer().normalize( oldAttribute.get().getString() );
                    ( ( Index ) userIndex ).drop( partitionTxn, normalized, id );

                    /*
                     * If there is no value for id in this index due to our
                     * drop above we remove the oldRdnAttr from the presence idx
                     */
                    if ( null == userIndex.reverseLookup( partitionTxn, oldId ) )
                    {
                        presenceIdx.drop( partitionTxn, newRdnAttrType.getOid(), oldId );
                    }
                }
            }

            if ( newRdnAttrType.getSyntax().isHumanReadable() )
            {
                entry.add( newRdnAttrType, newAtav.getValue().getString() );
            }
            else
            {
                entry.add( newRdnAttrType, newAtav.getValue().getBytes() );
            }

            if ( hasUserIndexOn( newRdnAttrType ) )
            {
                Index<?, String> userIndex = getUserIndex( newRdnAttrType );
                
                String normalized = newRdnAttrType.getEquality().getNormalizer().normalize( ( String ) newNormValue );
                ( ( Index ) userIndex ).add( partitionTxn, normalized, oldId );

                // Make sure the altered entry shows the existence of the new attrib
                String normTypeOid = presenceNormalizer.normalize( newNormType );
                
                if ( !presenceIdx.forward( partitionTxn, normTypeOid, oldId ) )
                {
                    presenceIdx.add( partitionTxn, normTypeOid, oldId );
                }
            }
        }

        /*
         * H A N D L E   O L D   R D N
         * ====================================================================
         * If the old Rdn is to be removed we need to get the attribute and
         * value for it.  Keep in mind the old Rdn need not be based on the
         * same attr as the new one.  We remove the Rdn value from the entry
         * and remove the value/id tuple from the index on the old Rdn attr
         * if any.  We also test if the delete of the old Rdn index tuple
         * removed all the attribute values of the old Rdn using a reverse
         * lookup.  If so that means we blew away the last value of the old
         * Rdn attribute.  In this case we need to remove the attrName/id
         * tuple from the presence index.
         *
         * We only remove an ATAV of the old Rdn if it is not included in the
         * new Rdn.
         */

        if ( deleteOldRdn )
        {
            Rdn oldRdn = updn.getRdn();

            for ( Ava oldAtav : oldRdn )
            {
                // check if the new ATAV is part of the old Rdn
                // if that is the case we do not remove the ATAV
                boolean mustRemove = true;

                for ( Ava newAtav : newRdn )
                {
                    if ( oldAtav.equals( newAtav ) )
                    {
                        mustRemove = false;
                        break;
                    }
                }

                if ( mustRemove )
                {
                    String oldNormType = oldAtav.getNormType();
                    String oldNormValue = oldAtav.getValue().getString();
                    AttributeType oldRdnAttrType = schemaManager.lookupAttributeTypeRegistry( oldNormType );
                    entry.remove( oldRdnAttrType, oldNormValue );

                    if ( hasUserIndexOn( oldRdnAttrType ) )
                    {
                        Index<?, String> userIndex = getUserIndex( oldRdnAttrType );
                        
                        String normalized = oldRdnAttrType.getEquality().getNormalizer().normalize( oldNormValue );
                        ( ( Index ) userIndex ).drop( partitionTxn, normalized, id );

                        /*
                         * If there is no value for id in this index due to our
                         * drop above we remove the oldRdnAttr from the presence idx
                         */
                        if ( null == userIndex.reverseLookup( partitionTxn, oldId ) )
                        {
                            String oldNormTypeOid = presenceNormalizer.normalize( oldNormType );
                            presenceIdx.drop( partitionTxn, oldNormTypeOid, oldId );
                        }
                    }
                }
            }
        }

        // Remove the EntryDN
        entry.removeAttributes( entryDnAT );

        setContextCsn( entry.get( entryCsnAT ).getString() );

        // And save the modified entry
        master.put( partitionTxn, oldId, entry );
    }