@SuppressWarnings("unchecked")
public void rename( DN dn, RDN newRdn, boolean deleteOldRdn ) throws Exception
{
Long id = getEntryId( dn.getNormName() );
ServerEntry entry = lookup( id );
DN updn = entry.getDn();
/*
* 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 existance index shows the existance of the
* new RDN attribute within this entry.
*/
for ( AVA newAtav : newRdn )
{
String newNormType = newAtav.getNormType();
Object newNormValue = newAtav.getNormValue().get();
AttributeType newRdnAttrType = schemaManager.lookupAttributeTypeRegistry( newNormType );
entry.add( newRdnAttrType, newAtav.getUpValue() );
if ( hasUserIndexOn( newNormType ) )
{
Index<?, E, Long> index = getUserIndex( newNormType );
( ( Index ) index ).add( newNormValue, id );
// Make sure the altered entry shows the existence of the new attrib
if ( !existenceIdx.forward( newNormType, id ) )
{
existenceIdx.add( newNormType, id );
}
}
}
/*
* 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 existance 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.getNormValue().getString();
AttributeType oldRdnAttrType = schemaManager.lookupAttributeTypeRegistry( oldNormType );
entry.remove( oldRdnAttrType, oldNormValue );
if ( hasUserIndexOn( oldNormType ) )
{
Index<?, E, Long> index = getUserIndex( oldNormType );
( ( AvlIndex ) index ).drop( oldNormValue, id );
/*
* If there is no value for id in this index due to our
* drop above we remove the oldRdnAttr from the existance idx
*/
if ( null == index.reverseLookup( id ) )
{
existenceIdx.drop( oldNormType, id );
}
}
}
}
}
/*
* H A N D L E D N C H A N G E
* ====================================================================
* 1) Build the new user defined distinguished name
* - clone / copy old updn
* - remove old upRdn from copy
* - add the new upRdn to the copy
* 2) Make call to recursive modifyDn method to change the names of the
* entry and its descendants
*/
DN newUpdn = ( DN ) updn.clone(); // copy da old updn
newUpdn.remove( newUpdn.size() - 1 ); // remove old upRdn
newUpdn.add( newRdn.getUpName() ); // add da new upRdn
// gotta normalize cuz this thang is cloned and not normalized by default
newUpdn.normalize( schemaManager.getNormalizerMapping() );
modifyDn( id, newUpdn, false ); // propagate dn changes
// Update the current entry
entry.setDn( newUpdn );