Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 63AD410326 for ; Wed, 26 Jun 2013 15:57:13 +0000 (UTC) Received: (qmail 75703 invoked by uid 500); 26 Jun 2013 15:57:13 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 75616 invoked by uid 500); 26 Jun 2013 15:57:09 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 75609 invoked by uid 99); 26 Jun 2013 15:57:09 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Jun 2013 15:57:09 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Jun 2013 15:57:06 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id EA72C2388A29; Wed, 26 Jun 2013 15:56:46 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1496979 - in /directory/apacheds/trunk: server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Date: Wed, 26 Jun 2013 15:56:46 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130626155646.EA72C2388A29@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Wed Jun 26 15:56:46 2013 New Revision: 1496979 URL: http://svn.apache.org/r1496979 Log: Fixed the modification of null values when doing a modification Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java?rev=1496979&r1=1496978&r2=1496979&view=diff ============================================================================== --- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java (original) +++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/modify/ModifyAddIT.java Wed Jun 26 15:56:46 2013 @@ -27,6 +27,7 @@ import static org.junit.Assert.assertNot import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.IOException; import java.util.Arrays; import javax.naming.NamingEnumeration; @@ -45,9 +46,18 @@ import javax.naming.directory.NoSuchAttr import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; +import org.apache.directory.api.ldap.model.entry.DefaultEntry; +import org.apache.directory.api.ldap.model.entry.DefaultModification; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.entry.ModificationOperation; import org.apache.directory.api.ldap.model.exception.LdapException; +import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; import org.apache.directory.api.ldap.model.ldif.LdifUtils; +import org.apache.directory.api.ldap.model.name.Dn; +import org.apache.directory.api.util.Strings; import org.apache.directory.junit.tools.MultiThreadedMultiInvoker; +import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; import org.apache.directory.server.annotations.CreateLdapServer; import org.apache.directory.server.annotations.CreateTransport; import org.apache.directory.server.core.annotations.ApplyLdifs; @@ -94,530 +104,569 @@ transports = }) public class ModifyAddIT extends AbstractLdapTestUnit { - @Rule - public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE ); - private static final String BASE = "ou=system"; - private static final String RDN_TORI_AMOS = "cn=Tori Amos"; - private static final String PERSON_DESCRIPTION = "an American singer-songwriter"; - private static final String RDN_DEBBIE_HARRY = "cn=Debbie Harry"; - - - /** - * Creation of required attributes of a person entry. - */ - protected Attributes getPersonAttributes( String sn, String cn ) throws LdapException - { - Attributes attributes = LdifUtils.createJndiAttributes( - "objectClass: top", - "objectClass: person", - "objectClass: organizationalperson", - "objectClass: inetorgperson", - "cn", cn, - "sn", sn ); - - return attributes; - } - - - /** - * Add a new attribute to a person entry. - */ - @Test - public void testAddNewAttributeValue() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add telephoneNumber attribute - String newValue = "1234567890"; - Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, true ); +@Rule +public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.NOT_THREADSAFE ); +private static final String BASE = "ou=system"; +private static final String RDN_TORI_AMOS = "cn=Tori Amos"; +private static final String PERSON_DESCRIPTION = "an American singer-songwriter"; +private static final String RDN_DEBBIE_HARRY = "cn=Debbie Harry"; + + +/** + * Creation of required attributes of a person entry. + */ +protected Attributes getPersonAttributes( String sn, String cn ) throws LdapException +{ + Attributes attributes = LdifUtils.createJndiAttributes( + "objectClass: top", + "objectClass: person", + "objectClass: organizationalperson", + "objectClass: inetorgperson", + "cn", cn, + "sn", sn ); + + return attributes; +} + + +/** + * Add a new attribute to a person entry. + */ +@Test +public void testAddNewAttributeValue() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add telephoneNumber attribute + String newValue = "1234567890"; + Attributes attrs = new BasicAttributes( "telephoneNumber", newValue, true ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that + // - case of attribute description is correct + // - attribute value is added + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "telephoneNumber" ); + assertNotNull( attr ); + assertEquals( "telephoneNumber", attr.getID() ); + assertTrue( attr.contains( newValue ) ); + assertEquals( 1, attr.size() ); +} + + +/** + * Add a new attribute with two values. + */ +@Test +public void testAddNewAttributeValues() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add telephoneNumber attribute + String[] newValues = + { "1234567890", "999999999" }; + Attribute attr = new BasicAttribute( "telephoneNumber" ); + attr.add( newValues[0] ); + attr.add( newValues[1] ); + Attributes attrs = new BasicAttributes( true ); + attrs.put( attr ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that + // - case of attribute description is correct + // - attribute values are present + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + attr = attrs.get( "telephoneNumber" ); + assertNotNull( attr ); + assertEquals( "telephoneNumber", attr.getID() ); + assertTrue( attr.contains( newValues[0] ) ); + assertTrue( attr.contains( newValues[1] ) ); + assertEquals( newValues.length, attr.size() ); +} + + +/** + * Add an additional value. + */ +@Test +public void testAddAdditionalAttributeValue() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // A new description attribute value + String newValue = "A new description for this person"; + assertFalse( newValue.equals( PERSON_DESCRIPTION ) ); + Attributes attrs = new BasicAttributes( "description", newValue, true ); + + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that attribute value is added + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "description" ); + assertNotNull( attr ); + assertTrue( attr.contains( newValue ) ); + assertTrue( attr.contains( PERSON_DESCRIPTION ) ); + assertEquals( 2, attr.size() ); +} + + +/** + * Try to add an already existing attribute value. + * + * Expected behaviour: Modify operation fails with an + * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the + * attribute value specified in a modify or add operation already exists as + * a value for that attribute). + */ +@Test +public void testAddExistingAttributeValue() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Change description attribute + Attributes attrs = new BasicAttributes( "description", PERSON_DESCRIPTION, true ); + + try + { ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that - // - case of attribute description is correct - // - attribute value is added - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - Attribute attr = attrs.get( "telephoneNumber" ); - assertNotNull( attr ); - assertEquals( "telephoneNumber", attr.getID() ); - assertTrue( attr.contains( newValue ) ); - assertEquals( 1, attr.size() ); + fail( "Adding an already existing atribute value should fail." ); } - - - /** - * Add a new attribute with two values. - */ - @Test - public void testAddNewAttributeValues() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add telephoneNumber attribute - String[] newValues = - { "1234567890", "999999999" }; - Attribute attr = new BasicAttribute( "telephoneNumber" ); - attr.add( newValues[0] ); - attr.add( newValues[1] ); - Attributes attrs = new BasicAttributes( true ); - attrs.put( attr ); - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that - // - case of attribute description is correct - // - attribute values are present - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - attr = attrs.get( "telephoneNumber" ); - assertNotNull( attr ); - assertEquals( "telephoneNumber", attr.getID() ); - assertTrue( attr.contains( newValues[0] ) ); - assertTrue( attr.contains( newValues[1] ) ); - assertEquals( newValues.length, attr.size() ); - } - - - /** - * Add an additional value. - */ - @Test - public void testAddAdditionalAttributeValue() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // A new description attribute value - String newValue = "A new description for this person"; - assertFalse( newValue.equals( PERSON_DESCRIPTION ) ); - Attributes attrs = new BasicAttributes( "description", newValue, true ); - + catch ( AttributeInUseException e ) + { + // expected behaviour + } + + // Verify, that attribute is still there, and is the only one + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "description" ); + assertNotNull( attr ); + assertTrue( attr.contains( PERSON_DESCRIPTION ) ); + assertEquals( 1, attr.size() ); +} + + +/** + * Try to add an already existing attribute value. + * + * Expected behaviour: Modify operation fails with an + * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the + * attribute value specified in a modify or add operation already exists as + * a value for that attribute). + * + * Check for bug DIR_SERVER664 + */ +@Test +public void testAddExistingNthAttributesDirServer664() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Change description attribute + Attributes attrs = new BasicAttributes( true ); + attrs.put( new BasicAttribute( "telephoneNumber", "1" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "2" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "3" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "4" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "5" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "6" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "7" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "8" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "9" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "10" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "11" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "12" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "13" ) ); + attrs.put( new BasicAttribute( "telephoneNumber", "14" ) ); + + Attribute attr = new BasicAttribute( "description", PERSON_DESCRIPTION ); + + attrs.put( attr ); + + try + { ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that attribute value is added - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - Attribute attr = attrs.get( "description" ); - assertNotNull( attr ); - assertTrue( attr.contains( newValue ) ); - assertTrue( attr.contains( PERSON_DESCRIPTION ) ); - assertEquals( 2, attr.size() ); + fail( "Adding an already existing atribute value should fail." ); } - - - /** - * Try to add an already existing attribute value. - * - * Expected behaviour: Modify operation fails with an - * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the - * attribute value specified in a modify or add operation already exists as - * a value for that attribute). - */ - @Test - public void testAddExistingAttributeValue() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Change description attribute - Attributes attrs = new BasicAttributes( "description", PERSON_DESCRIPTION, true ); - - try - { - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - fail( "Adding an already existing atribute value should fail." ); - } - catch ( AttributeInUseException e ) - { - // expected behaviour - } - - // Verify, that attribute is still there, and is the only one - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - Attribute attr = attrs.get( "description" ); - assertNotNull( attr ); - assertTrue( attr.contains( PERSON_DESCRIPTION ) ); - assertEquals( 1, attr.size() ); + catch ( AttributeInUseException e ) + { + // expected behaviour } - - - /** - * Try to add an already existing attribute value. - * - * Expected behaviour: Modify operation fails with an - * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the - * attribute value specified in a modify or add operation already exists as - * a value for that attribute). - * - * Check for bug DIR_SERVER664 - */ - @Test - public void testAddExistingNthAttributesDirServer664() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Change description attribute - Attributes attrs = new BasicAttributes( true ); - attrs.put( new BasicAttribute( "telephoneNumber", "1" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "2" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "3" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "4" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "5" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "6" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "7" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "8" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "9" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "10" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "11" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "12" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "13" ) ); - attrs.put( new BasicAttribute( "telephoneNumber", "14" ) ); - - Attribute attr = new BasicAttribute( "description", PERSON_DESCRIPTION ); - - attrs.put( attr ); - - try - { - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - fail( "Adding an already existing atribute value should fail." ); - } - catch ( AttributeInUseException e ) - { - // expected behaviour - } - - // Verify, that attribute is still there, and is the only one - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - attr = attrs.get( "description" ); - assertNotNull( attr ); - assertTrue( attr.contains( PERSON_DESCRIPTION ) ); - assertEquals( 1, attr.size() ); + + // Verify, that attribute is still there, and is the only one + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + attr = attrs.get( "description" ); + assertNotNull( attr ); + assertTrue( attr.contains( PERSON_DESCRIPTION ) ); + assertEquals( 1, attr.size() ); +} + + +/** + * Check for DIR_SERVER_643 + */ +@Test +public void testTwoDescriptionDirServer643() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Change description attribute + Attributes attrs = new BasicAttributes( true ); + Attribute attr = new BasicAttribute( "description", + "a British singer-songwriter with an expressive four-octave voice" ); + attr.add( "one of the most influential female artists of the twentieth century" ); + attrs.put( attr ); + + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that attribute is still there, and is the only one + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + attr = attrs.get( "description" ); + assertNotNull( attr ); + assertEquals( 3, attr.size() ); + assertTrue( attr.contains( "a British singer-songwriter with an expressive four-octave voice" ) ); + assertTrue( attr.contains( "one of the most influential female artists of the twentieth century" ) ); + assertTrue( attr.contains( PERSON_DESCRIPTION ) ); +} + + +/** + * Try to add a duplicate attribute value to an entry, where this attribute + * is already present (objectclass in this case). Expected behaviour is that + * the modify operation causes an error (error code 20, "Attribute or value + * exists"). + */ +@Test +public void testAddDuplicateValueToExistingAttribute() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // modify object classes, add a new value twice + Attribute ocls = new BasicAttribute( "objectClass", "organizationalPerson" ); + ModificationItem[] modItems = new ModificationItem[2]; + modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls ); + modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls ); + try + { + ctx.modifyAttributes( RDN_TORI_AMOS, modItems ); + fail( "Adding a duplicate attribute value should cause an error." ); + } + catch ( AttributeInUseException ex ) + { } - - - /** - * Check for DIR_SERVER_643 - */ - @Test - public void testTwoDescriptionDirServer643() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Change description attribute - Attributes attrs = new BasicAttributes( true ); - Attribute attr = new BasicAttribute( "description", - "a British singer-songwriter with an expressive four-octave voice" ); - attr.add( "one of the most influential female artists of the twentieth century" ); - attrs.put( attr ); - + + // Check, whether attribute objectClass is unchanged + Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS ); + ocls = attrs.get( "objectClass" ); + assertEquals( ocls.size(), 4 ); + assertTrue( ocls.contains( "top" ) ); + assertTrue( ocls.contains( "person" ) ); +} + + +/** + * Try to add a duplicate attribute value to an entry, where this attribute + * is not present. Expected behaviour is that the modify operation causes an + * error (error code 20, "Attribute or value exists"). + */ +@Test +public void testAddDuplicateValueToNewAttribute() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // add the same description value twice + Attribute desc = new BasicAttribute( "description", "another description value besides songwriter" ); + ModificationItem[] modItems = new ModificationItem[2]; + modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc ); + modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc ); + try + { + ctx.modifyAttributes( RDN_TORI_AMOS, modItems ); + fail( "Adding a duplicate attribute value should cause an error." ); + } + catch ( AttributeInUseException ex ) + { + } + + // Check, whether attribute description is still not present + Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS ); + assertEquals( 1, attrs.get( "description" ).size() ); +} + + +/** + * Modify the entry with a bad attribute : this should fail + */ +@Test +public void testSearchBadAttribute() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add a not existing attribute + String newValue = "unbelievable"; + Attributes attrs = new BasicAttributes( "voice", newValue, true ); + + try + { ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that attribute is still there, and is the only one - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - attr = attrs.get( "description" ); - assertNotNull( attr ); - assertEquals( 3, attr.size() ); - assertTrue( attr.contains( "a British singer-songwriter with an expressive four-octave voice" ) ); - assertTrue( attr.contains( "one of the most influential female artists of the twentieth century" ) ); - assertTrue( attr.contains( PERSON_DESCRIPTION ) ); - } - - - /** - * Try to add a duplicate attribute value to an entry, where this attribute - * is already present (objectclass in this case). Expected behaviour is that - * the modify operation causes an error (error code 20, "Attribute or value - * exists"). - */ - @Test - public void testAddDuplicateValueToExistingAttribute() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // modify object classes, add a new value twice - Attribute ocls = new BasicAttribute( "objectClass", "organizationalPerson" ); - ModificationItem[] modItems = new ModificationItem[2]; - modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls ); - modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, ocls ); - try - { - ctx.modifyAttributes( RDN_TORI_AMOS, modItems ); - fail( "Adding a duplicate attribute value should cause an error." ); - } - catch ( AttributeInUseException ex ) - { - } - - // Check, whether attribute objectClass is unchanged - Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS ); - ocls = attrs.get( "objectClass" ); - assertEquals( ocls.size(), 4 ); - assertTrue( ocls.contains( "top" ) ); - assertTrue( ocls.contains( "person" ) ); - } - - - /** - * Try to add a duplicate attribute value to an entry, where this attribute - * is not present. Expected behaviour is that the modify operation causes an - * error (error code 20, "Attribute or value exists"). - */ - @Test - public void testAddDuplicateValueToNewAttribute() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // add the same description value twice - Attribute desc = new BasicAttribute( "description", "another description value besides songwriter" ); - ModificationItem[] modItems = new ModificationItem[2]; - modItems[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc ); - modItems[1] = new ModificationItem( DirContext.ADD_ATTRIBUTE, desc ); - try - { - ctx.modifyAttributes( RDN_TORI_AMOS, modItems ); - fail( "Adding a duplicate attribute value should cause an error." ); - } - catch ( AttributeInUseException ex ) - { - } - - // Check, whether attribute description is still not present - Attributes attrs = ctx.getAttributes( RDN_TORI_AMOS ); - assertEquals( 1, attrs.get( "description" ).size() ); - } - - - /** - * Modify the entry with a bad attribute : this should fail - */ - @Test - public void testSearchBadAttribute() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add a not existing attribute - String newValue = "unbelievable"; - Attributes attrs = new BasicAttributes( "voice", newValue, true ); - - try - { - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - } - catch ( NoSuchAttributeException nsae ) + } + catch ( NoSuchAttributeException nsae ) + { + // We have a failure : the attribute is unknown in the schema + assertTrue( true ); + return; + } + + fail( "Cannot reach this point" ); +} + + +/** + * Create a person entry and perform a modify op, in which + * we modify an attribute two times. + */ +@Test +public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Create a person entry + Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" ); + String rdn = "cn=Kate Bush"; + ctx.createSubcontext( rdn, attrs ); + + // Add a description with two values + String[] descriptions = { - // We have a failure : the attribute is unknown in the schema - assertTrue( true ); - return; - } - - fail( "Cannot reach this point" ); - } - - - /** - * Create a person entry and perform a modify op, in which - * we modify an attribute two times. - */ - @Test - public void testAttributeValueMultiMofificationDIRSERVER_636() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Create a person entry - Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" ); - String rdn = "cn=Kate Bush"; - ctx.createSubcontext( rdn, attrs ); - - // Add a description with two values - String[] descriptions = - { - "Kate Bush is a British singer-songwriter.", - "She has become one of the most influential female artists of the twentieth century." }; - Attribute desc1 = new BasicAttribute( "description" ); - desc1.add( descriptions[0] ); - desc1.add( descriptions[1] ); - - ModificationItem addModOp = new ModificationItem( - DirContext.ADD_ATTRIBUTE, desc1 ); - - Attribute desc2 = new BasicAttribute( "description" ); - desc2.add( descriptions[1] ); - ModificationItem delModOp = new ModificationItem( - DirContext.REMOVE_ATTRIBUTE, desc2 ); - + "Kate Bush is a British singer-songwriter.", + "She has become one of the most influential female artists of the twentieth century." }; + Attribute desc1 = new BasicAttribute( "description" ); + desc1.add( descriptions[0] ); + desc1.add( descriptions[1] ); + + ModificationItem addModOp = new ModificationItem( + DirContext.ADD_ATTRIBUTE, desc1 ); + + Attribute desc2 = new BasicAttribute( "description" ); + desc2.add( descriptions[1] ); + ModificationItem delModOp = new ModificationItem( + DirContext.REMOVE_ATTRIBUTE, desc2 ); + + ctx.modifyAttributes( rdn, new ModificationItem[] + { addModOp, + delModOp } ); + + SearchControls sctls = new SearchControls(); + sctls.setSearchScope( SearchControls.SUBTREE_SCOPE ); + String filter = "(cn=*Bush)"; + String base = ""; + + // Check entry + NamingEnumeration enm = ctx.search( base, filter, sctls ); + assertTrue( enm.hasMore() ); + + while ( enm.hasMore() ) + { + SearchResult sr = enm.next(); + attrs = sr.getAttributes(); + Attribute desc = sr.getAttributes().get( "description" ); + assertEquals( 1, desc.size() ); + assertTrue( desc.contains( descriptions[0] ) ); + } + + // Remove the person entry + ctx.destroySubcontext( rdn ); +} + + +/** + * Try to add subschemaSubentry attribute to an entry + */ +@Test +public void testModifyOperationalAttributeAdd() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + ModificationItem modifyOp = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( + "subschemaSubentry", "cn=anotherSchema" ) ); + + try + { + ctx.modifyAttributes( RDN_DEBBIE_HARRY, new ModificationItem[] + { modifyOp } ); + + fail( "modification of entry should fail" ); + } + catch ( InvalidAttributeValueException e ) + { + // Expected result + } + catch ( NoPermissionException e ) + { + // Expected result + } +} + + +/** + * Create a person entry and perform a modify op on an + * attribute which is part of the Dn. This is not allowed. + * + * A JIRA has been created for this bug : DIRSERVER_687 + */ +@Test +public void testDNAttributeMemberModificationDIRSERVER_687() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Create a person entry + Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" ); + String rdn = "cn=Kate Bush"; + ctx.createSubcontext( rdn, attrs ); + + // Try to modify the cn attribute + Attribute desc1 = new BasicAttribute( "cn", "Georges Bush" ); + + ModificationItem addModOp = new ModificationItem( + DirContext.REPLACE_ATTRIBUTE, desc1 ); + + try + { ctx.modifyAttributes( rdn, new ModificationItem[] - { addModOp, - delModOp } ); - - SearchControls sctls = new SearchControls(); - sctls.setSearchScope( SearchControls.SUBTREE_SCOPE ); - String filter = "(cn=*Bush)"; - String base = ""; - - // Check entry - NamingEnumeration enm = ctx.search( base, filter, sctls ); - assertTrue( enm.hasMore() ); - - while ( enm.hasMore() ) - { - SearchResult sr = enm.next(); - attrs = sr.getAttributes(); - Attribute desc = sr.getAttributes().get( "description" ); - assertEquals( 1, desc.size() ); - assertTrue( desc.contains( descriptions[0] ) ); - } - + { addModOp } ); + fail(); + } + catch ( AttributeModificationException ame ) + { + assertTrue( true ); // Remove the person entry ctx.destroySubcontext( rdn ); } - - - /** - * Try to add subschemaSubentry attribute to an entry - */ - @Test - public void testModifyOperationalAttributeAdd() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - ModificationItem modifyOp = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( - "subschemaSubentry", "cn=anotherSchema" ) ); - - try - { - ctx.modifyAttributes( RDN_DEBBIE_HARRY, new ModificationItem[] - { modifyOp } ); - - fail( "modification of entry should fail" ); - } - catch ( InvalidAttributeValueException e ) - { - // Expected result - } - catch ( NoPermissionException e ) - { - // Expected result - } + catch ( NamingException ne ) + { + assertTrue( true ); + // Remove the person entry + ctx.destroySubcontext( rdn ); } - - - /** - * Create a person entry and perform a modify op on an - * attribute which is part of the Dn. This is not allowed. - * - * A JIRA has been created for this bug : DIRSERVER_687 - */ - @Test - public void testDNAttributeMemberModificationDIRSERVER_687() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Create a person entry - Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" ); - String rdn = "cn=Kate Bush"; - ctx.createSubcontext( rdn, attrs ); - - // Try to modify the cn attribute - Attribute desc1 = new BasicAttribute( "cn", "Georges Bush" ); - - ModificationItem addModOp = new ModificationItem( - DirContext.REPLACE_ATTRIBUTE, desc1 ); - - try - { - ctx.modifyAttributes( rdn, new ModificationItem[] - { addModOp } ); - fail(); - } - catch ( AttributeModificationException ame ) - { - assertTrue( true ); - // Remove the person entry - ctx.destroySubcontext( rdn ); - } - catch ( NamingException ne ) - { - assertTrue( true ); - // Remove the person entry - ctx.destroySubcontext( rdn ); - } - } - - - /** - * Try to modify an entry adding invalid number of values for a single-valued atribute - * - * @see DIRSERVER-614 - */ - @Test - public void testModifyAddWithInvalidNumberOfAttributeValues() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - Attributes attrs = new BasicAttributes( true ); - Attribute ocls = new BasicAttribute( "objectClass" ); - ocls.add( "top" ); - ocls.add( "inetOrgPerson" ); - attrs.put( ocls ); - attrs.put( "cn", "Fiona Apple" ); - attrs.put( "sn", "Apple" ); - ctx.createSubcontext( "cn=Fiona Apple", attrs ); - - // add two displayNames to an inetOrgPerson - attrs = new BasicAttributes( true ); - Attribute displayName = new BasicAttribute( "displayName" ); - displayName.add( "Fiona" ); - displayName.add( "Fiona A." ); - attrs.put( displayName ); - - try - { - ctx.modifyAttributes( "cn=Fiona Apple", DirContext.ADD_ATTRIBUTE, attrs ); - fail( "modification of entry should fail" ); - } - catch ( InvalidAttributeValueException e ) - { - - } +} + + +/** + * Try to modify an entry adding invalid number of values for a single-valued atribute + * + * @see DIRSERVER-614 + */ +@Test +public void testModifyAddWithInvalidNumberOfAttributeValues() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + Attributes attrs = new BasicAttributes( true ); + Attribute ocls = new BasicAttribute( "objectClass" ); + ocls.add( "top" ); + ocls.add( "inetOrgPerson" ); + attrs.put( ocls ); + attrs.put( "cn", "Fiona Apple" ); + attrs.put( "sn", "Apple" ); + ctx.createSubcontext( "cn=Fiona Apple", attrs ); + + // add two displayNames to an inetOrgPerson + attrs = new BasicAttributes( true ); + Attribute displayName = new BasicAttribute( "displayName" ); + displayName.add( "Fiona" ); + displayName.add( "Fiona A." ); + attrs.put( displayName ); + + try + { + ctx.modifyAttributes( "cn=Fiona Apple", DirContext.ADD_ATTRIBUTE, attrs ); + fail( "modification of entry should fail" ); } - - - /** - * Add a new binary attribute to a person entry. - */ - @Test - public void testAddNewBinaryAttributeValue() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add a binary attribute - byte[] newValue = new byte[] - { 0x00, 0x01, 0x02, 0x03 }; - Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true ); - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that attribute value is added - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - Attribute attr = attrs.get( "userCertificate" ); - assertNotNull( attr ); - assertTrue( attr.contains( newValue ) ); - byte[] certificate = ( byte[] ) attr.get(); - assertTrue( Arrays.equals( newValue, certificate ) ); - assertEquals( 1, attr.size() ); + catch ( InvalidAttributeValueException e ) + { + } - - - /** - * Add a new attribute to a person entry. - */ - @Test - public void testAddNewBinaryAttributeValueAbove0x80() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add a binary attribute - byte[] newValue = new byte[] - { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 }; - Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true ); - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that attribute value is added - attrs = ctx.getAttributes( RDN_TORI_AMOS ); +} + + +/** + * Add a new binary attribute to a person entry. + */ +@Test +public void testAddNewBinaryAttributeValue() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add a binary attribute + byte[] newValue = new byte[] + { 0x00, 0x01, 0x02, 0x03 }; + Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that attribute value is added + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "userCertificate" ); + assertNotNull( attr ); + assertTrue( attr.contains( newValue ) ); + byte[] certificate = ( byte[] ) attr.get(); + assertTrue( Arrays.equals( newValue, certificate ) ); + assertEquals( 1, attr.size() ); +} + + +/** + * Add a new attribute to a person entry. + */ +@Test +public void testAddNewBinaryAttributeValueAbove0x80() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add a binary attribute + byte[] newValue = new byte[] + { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 }; + Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue, true ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that attribute value is added + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "userCertificate" ); + assertNotNull( attr ); + assertTrue( attr.contains( newValue ) ); + byte[] certificate = ( byte[] ) attr.get(); + assertTrue( Arrays.equals( newValue, certificate ) ); + assertEquals( 1, attr.size() ); +} + + +/** + * Add a new binary attribute to a person entry. + */ +@Test +public void testRetrieveEntryWithBinaryAttributeValue() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add a ;binary attribute + byte[] newValue = new byte[] + { 0x00, 0x01, 0x02, 0x03 }; + Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Search entry an request ;binary attribute + SearchControls sctls = new SearchControls(); + sctls.setSearchScope( SearchControls.OBJECT_SCOPE ); + sctls.setReturningAttributes( new String[] + { "userCertificate;binary" } ); + String filter = "(objectClass=*)"; + String base = RDN_TORI_AMOS; + + // Test that ;binary attribute is present + NamingEnumeration enm = ctx.search( base, filter, sctls ); + assertTrue( enm.hasMore() ); + + while ( enm.hasMore() ) + { + SearchResult sr = enm.next(); + attrs = sr.getAttributes(); Attribute attr = attrs.get( "userCertificate" ); assertNotNull( attr ); assertTrue( attr.contains( newValue ) ); @@ -625,73 +674,113 @@ public class ModifyAddIT extends Abstrac assertTrue( Arrays.equals( newValue, certificate ) ); assertEquals( 1, attr.size() ); } - - - /** - * Add a new binary attribute to a person entry. - */ - @Test - public void testRetrieveEntryWithBinaryAttributeValue() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add a ;binary attribute - byte[] newValue = new byte[] - { 0x00, 0x01, 0x02, 0x03 }; - Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue ); - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Search entry an request ;binary attribute - SearchControls sctls = new SearchControls(); - sctls.setSearchScope( SearchControls.OBJECT_SCOPE ); - sctls.setReturningAttributes( new String[] - { "userCertificate;binary" } ); - String filter = "(objectClass=*)"; - String base = RDN_TORI_AMOS; - - // Test that ;binary attribute is present - NamingEnumeration enm = ctx.search( base, filter, sctls ); - assertTrue( enm.hasMore() ); - - while ( enm.hasMore() ) - { - SearchResult sr = enm.next(); - attrs = sr.getAttributes(); - Attribute attr = attrs.get( "userCertificate" ); - assertNotNull( attr ); - assertTrue( attr.contains( newValue ) ); - byte[] certificate = ( byte[] ) attr.get(); - assertTrue( Arrays.equals( newValue, certificate ) ); - assertEquals( 1, attr.size() ); - } - - } - - - /** - * Add a new ;binary attribute with bytes greater than 0x80 - * to a person entry. - * Test for DIRSERVER-1146 - * - * @throws NamingException - */ - public void testAddNewBinaryAttributeValue0x80() throws Exception - { - DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); - - // Add a ;binary attribute with high-bytes - byte[] newValue = new byte[] - { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 }; - Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue ); - ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); - - // Verify, that attribute value is added - attrs = ctx.getAttributes( RDN_TORI_AMOS ); - Attribute attr = attrs.get( "userCertificate" ); - assertNotNull( attr ); - assertTrue( attr.contains( newValue ) ); - byte[] certificate = ( byte[] ) attr.get(); - assertTrue( Arrays.equals( newValue, certificate ) ); - assertEquals( 1, attr.size() ); + +} + + +/** + * Add a new ;binary attribute with bytes greater than 0x80 + * to a person entry. + * Test for DIRSERVER-1146 + * + * @throws NamingException + */ +public void testAddNewBinaryAttributeValue0x80() throws Exception +{ + DirContext ctx = ( DirContext ) getWiredContext( getLdapServer() ).lookup( BASE ); + + // Add a ;binary attribute with high-bytes + byte[] newValue = new byte[] + { ( byte ) 0x80, ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83 }; + Attributes attrs = new BasicAttributes( "userCertificate;binary", newValue ); + ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); + + // Verify, that attribute value is added + attrs = ctx.getAttributes( RDN_TORI_AMOS ); + Attribute attr = attrs.get( "userCertificate" ); + assertNotNull( attr ); + assertTrue( attr.contains( newValue ) ); + byte[] certificate = ( byte[] ) attr.get(); + assertTrue( Arrays.equals( newValue, certificate ) ); + assertEquals( 1, attr.size() ); +} + + +@Test +public void testModifyMultipleValues() throws LdapException, IOException +{ + LdapConnection connection = new LdapNetworkConnection( "localhost", getLdapServer().getPort() ); + connection.setTimeOut( 0L ); + + // Use the client API + connection.bind( "uid=admin,ou=system", "secret" ); + + // Add a new entry with some null values + Entry entry = new DefaultEntry( "uid=12345,ou=system", + "ObjectClass: top", + "ObjectClass: person", + "ObjectClass: person", + "ObjectClass: OrganizationalPerson", + "ObjectClass: inetOrgPerson", + "uid: 12345", + "cn: test", + "sn: Test", + "userPassword: null" ); + + connection.add( entry ); + + // Now modify the entry + connection.modify( new Dn( "uid=12345,ou=system" ), + new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, "sn", "foo" ), + new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, "cn", "Foo" ), + new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, "userPassword", "123456" ), + new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, "givenname", "foo" ), + new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, "displayName", "foo" ), + new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, "employeeNumber", "foo" ), + new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, "mail" ) + ); + + // Get back the entry + Entry found = connection.lookup( "uid=12345,ou=system" ); + + assertNotNull( found ); + assertNotNull( found.get( "userPassword" ) ); + assertTrue( found.contains( "mail", Strings.EMPTY_BYTES ) ); + + connection.close(); +} + + +@Test +public void testAddNullValueDirectoryString() throws LdapException, IOException +{ + LdapConnection connection = new LdapNetworkConnection( "localhost", getLdapServer().getPort() ); + connection.setTimeOut( 0L ); + + // Use the client API + connection.bind( "uid=admin,ou=system", "secret" ); + + // Add a new entry with some null values + Entry entry = new DefaultEntry( "cn=test,ou=system", + "ObjectClass: top", + "ObjectClass: person", + "ObjectClass: person", + "ObjectClass: OrganizationalPerson", + "ObjectClass: inetOrgPerson", + "cn: test", + "sn: Test", + "displayName:" ); // The DisplayName must contain a value + + try + { + connection.add( entry ); + fail(); } + catch ( LdapInvalidAttributeValueException liave ) + { + // Expected + } + + connection.close(); +} } Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java?rev=1496979&r1=1496978&r2=1496979&view=diff ============================================================================== --- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java (original) +++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Wed Jun 26 15:56:46 2013 @@ -36,8 +36,10 @@ import java.util.concurrent.locks.Reentr import org.apache.directory.api.ldap.model.constants.SchemaConstants; import org.apache.directory.api.ldap.model.cursor.Cursor; import org.apache.directory.api.ldap.model.entry.Attribute; +import org.apache.directory.api.ldap.model.entry.BinaryValue; import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Modification; +import org.apache.directory.api.ldap.model.entry.StringValue; import org.apache.directory.api.ldap.model.entry.Value; import org.apache.directory.api.ldap.model.exception.LdapAliasDereferencingException; import org.apache.directory.api.ldap.model.exception.LdapAliasException; @@ -1257,9 +1259,17 @@ public abstract class AbstractBTreeParti { Index index = getUserIndex( attributeType ); - for ( Value value : mods ) + if ( mods.size() > 0 ) + { + for ( Value value : mods ) + { + ( ( Index ) index ).add( value.getNormValue(), id ); + } + } + else { - ( ( Index ) index ).add( value.getNormValue(), id ); + // Special case when we have null values + ( ( Index ) index ).add( null, id ); } // If the attr didn't exist for this id add it to presence index @@ -1285,9 +1295,24 @@ public abstract class AbstractBTreeParti } // add all the values in mods to the same attribute in the entry - for ( Value value : mods ) + if ( mods.size() > 0 ) { - entry.add( mods.getAttributeType(), value ); + for ( Value value : mods ) + { + entry.add( mods.getAttributeType(), value ); + } + } + else + { + // Special cases for null values + if ( mods.getAttributeType().getSyntax().isHumanReadable() ) + { + entry.add( mods.getAttributeType(), new StringValue( null ) ); + } + else + { + entry.add( mods.getAttributeType(), new BinaryValue( null ) ); + } } if ( modsOid.equals( SchemaConstants.ALIASED_OBJECT_NAME_AT_OID ) )