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