in interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java [664:876]
private void checkModifyEntry( ModifyOperationContext modifyContext ) throws LdapException
{
Dn dn = modifyContext.getDn();
Entry currentEntry = modifyContext.getEntry();
List<Modification> mods = modifyContext.getModItems();
// The first step is to check that the modifications are valid :
// - the ATs are present in the schema
// - The value is syntaxically correct
//
// While doing that, we will apply the modification to a copy of the current entry
Entry tempEntry = currentEntry.clone();
// Now, apply each mod one by one
for ( Modification mod : mods )
{
Attribute attribute = mod.getAttribute();
AttributeType attributeType = attribute.getAttributeType();
assertAttributeIsModifyable( modifyContext, attributeType );
switch ( mod.getOperation() )
{
case ADD_ATTRIBUTE:
// Check the syntax here
Attribute currentAttribute = tempEntry.get( attributeType );
// First check if the added Attribute is already present in the entry
// If not, we have to create the entry
if ( currentAttribute != null )
{
for ( Value value : attribute )
{
// At this point, we know that the attribute's syntax is correct
// We just have to check that the current attribute does not
// contains the value already
if ( currentAttribute.contains( value ) )
{
// This is an error.
String msg = I18n.err( I18n.ERR_28003_CANNOT_ADD_ALREADY_PRESENT_VALUE, value );
LOG.error( msg );
throw new LdapAttributeInUseException( msg );
}
currentAttribute.add( value );
}
}
else
{
// We don't check if the attribute is not in the MUST or MAY at this
// point, as one of the following modification can change the
// ObjectClasses.
Attribute newAttribute = attribute.clone();
// Check that the attribute allows null values if we don'y have any value
if ( ( newAttribute.size() == 0 ) && !newAttribute.isValid( attributeType ) )
{
// This is an error.
String msg = I18n.err( I18n.ERR_28003_CANNOT_ADD_ALREADY_PRESENT_VALUE, ( Object[] ) null );
LOG.error( msg );
throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
}
tempEntry.put( newAttribute );
}
break;
case REMOVE_ATTRIBUTE:
// First check that the removed attribute exists
if ( !tempEntry.containsAttribute( attributeType ) )
{
String msg = I18n.err( I18n.ERR_28004_CANNOT_REMOVE_ABSENT_ATTRIBUTE, attributeType );
LOG.error( msg );
throw new LdapNoSuchAttributeException( msg );
}
// We may have to remove the attribute or only some values
if ( attribute.size() == 0 )
{
// No value : we have to remove the entire attribute
tempEntry.removeAttributes( attributeType );
}
else
{
currentAttribute = tempEntry.get( attributeType );
// Now remove all the values
for ( Value value : attribute )
{
// We can only remove existing values.
if ( currentAttribute.contains( value ) )
{
currentAttribute.remove( value );
}
else
{
String msg = I18n.err( I18n.ERR_28005_CANNOT_REMOVE_ABSENT_VALUE, attributeType );
LOG.error( msg );
throw new LdapNoSuchAttributeException( msg );
}
}
// If the current attribute is empty, we have to remove
// it from the entry
if ( currentAttribute.size() == 0 )
{
tempEntry.removeAttributes( attributeType );
}
}
break;
case REPLACE_ATTRIBUTE:
// The replaced attribute might not exist, it will then be a Add
// If there is no value, then the attribute will be removed
if ( !tempEntry.containsAttribute( attributeType ) )
{
if ( attribute.size() == 0 )
{
// Ignore the modification, as the attributeType does not
// exists in the entry
break;
}
else
{
// Create the new Attribute
Attribute newAttribute = createNewAttribute( attribute );
tempEntry.put( newAttribute );
}
}
else
{
if ( attribute.size() == 0 )
{
// Remove the attribute from the entry
tempEntry.removeAttributes( attributeType );
}
else
{
// Replace the existing values with the new values
// This is done by removing the Attribute
tempEntry.removeAttributes( attributeType );
// Create the new Attribute
Attribute newAttribute = createNewAttribute( attribute );
tempEntry.put( newAttribute );
}
}
break;
case INCREMENT_ATTRIBUTE:
// The incremented attribute might not exist
if ( !tempEntry.containsAttribute( attributeType ) )
{
throw new IllegalArgumentException( "Increment operation on a non existing attribute"
+ attributeType );
}
else if ( !SchemaConstants.INTEGER_SYNTAX.equals( attributeType.getSyntax().getOid() ) )
{
throw new IllegalArgumentException( "Increment operation on a non integer attribute"
+ attributeType );
}
else
{
Attribute modified = tempEntry.get( attributeType );
Value[] newValues = new Value[ modified.size() ];
int increment = 1;
int i = 0;
if ( mod.getAttribute().size() != 0 )
{
increment = Integer.parseInt( mod.getAttribute().getString() );
}
for ( Value value : modified )
{
int intValue = Integer.parseInt( value.getNormalized() );
if ( intValue >= Integer.MAX_VALUE - increment )
{
throw new IllegalArgumentException( "Increment operation overflow for attribute"
+ attributeType );
}
newValues[i++] = new Value( Integer.toString( intValue + increment ) );
modified.remove( value );
}
modified.add( newValues );
}
break;
default:
throw new IllegalArgumentException( "Unexpected modify operation " + mod.getOperation() );
}
}
// Ok, we have created the modified entry. We now have to check that it's a valid
// entry wrt the schema.
// We have to check that :
// - the rdn values are present in the entry
// - the objectClasses inheritence is correct
// - all the MUST are present
// - all the attribute are in MUST and MAY, except fo the extensibleObeject OC
// is present
// - We haven't removed a part of the Rdn
check( dn, tempEntry );
}