You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/01/26 23:43:29 UTC
svn commit: r903465 [4/5] - in /directory/shared/trunk/ldap-ldif: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/directory/
src/main/java/org/apache/directory/shared/ src/main/java/org/apache/dire...
Added: directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java (added)
+++ directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java Tue Jan 26 22:43:27 2010
@@ -0,0 +1,1728 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.shared.ldap.ldif;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.ModificationOperation;
+import org.apache.directory.shared.ldap.message.control.Control;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 379008 $
+ */
+public class LdifReaderTest
+{
+ private static byte[] data;
+
+ private static File HJENSEN_JPEG_FILE = null;
+ private static File FIONA_JPEG_FILE = null;
+
+ private static File createFile( String name, byte[] data ) throws IOException
+ {
+ File jpeg = File.createTempFile( name, "jpg" );
+
+ jpeg.createNewFile();
+
+ DataOutputStream os = new DataOutputStream( new FileOutputStream( jpeg ) );
+
+ os.write( data );
+ os.close();
+
+ // This file will be deleted when the JVM
+ // will exit.
+ jpeg.deleteOnExit();
+
+ return jpeg;
+ }
+
+ /**
+ * Create a file to be used by ":<" values
+ */
+ @BeforeClass
+ public static void setUp() throws Exception
+ {
+ data = new byte[256];
+
+ for ( int i = 0; i < 256; i++ )
+ {
+ data[i] = (byte) i;
+ }
+
+ HJENSEN_JPEG_FILE = createFile( "hjensen", data );
+ FIONA_JPEG_FILE = createFile( "fiona", data );
+ }
+
+ @Test
+ public void testLdifNull() throws Exception
+ {
+ String ldif = null;
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+
+ assertEquals( 0, entries.size() );
+ }
+
+
+ @Test
+ public void testLdifEmpty() throws Exception
+ {
+ String ldif = "";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 0, entries.size() );
+ }
+
+
+ @Test
+ public void testLdifEmptyLines() throws Exception
+ {
+ String ldif = "\n\n\r\r\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 0, entries.size() );
+ }
+
+ @Test
+ public void testLdifComments() throws Exception
+ {
+ String ldif =
+ "#Comment 1\r" +
+ "#\r" +
+ " th\n" +
+ " is is still a comment\n" +
+ "\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 0, entries.size() );
+ }
+
+
+ @Test
+ public void testLdifVersion() throws Exception
+ {
+ String ldif =
+ "#Comment 1\r" +
+ "#\r" +
+ " th\n" +
+ " is is still a comment\n" +
+ "\n" +
+ "version:\n" +
+ " 1\n" +
+ "# end";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 0, entries.size() );
+ assertEquals( 1, reader.getVersion() );
+ }
+
+
+ @Test
+ public void testLdifVersionStart() throws Exception
+ {
+ String ldif =
+ "version:\n" +
+ " 1\n" +
+ "\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:";
+
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 1, reader.getVersion() );
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+ }
+
+
+ /**
+ * Test the ldif parser with a file without a version. It should default to 1
+ * @throws Exception
+ */
+ @Test
+ public void testLdifWithoutVersion() throws Exception
+ {
+ String ldif =
+ "#Comment 1\r" +
+ "#\r" +
+ " th\n" +
+ " is is still a comment\n" +
+ "\n" +
+ "# end";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 0, entries.size() );
+ assertEquals( 1, reader.getVersion() );
+ }
+
+
+ /**
+ * Spaces at the end of values should not be included into values.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLdifParserEndSpaces() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ }
+
+
+ @Test
+ public void testLdifParserAddAttrCaseInsensitiveAttrId() throws Exception
+ {
+ // test that mixed case attr ids work at all
+ String ldif =
+ "version: 1\n" +
+ "dn: dc=example,dc=com\n" +
+ "changetype: modify\n" +
+ "add: administrativeRole\n" +
+ "administrativeRole: accessControlSpecificArea\n" +
+ "-";
+
+ testReaderAttrIdCaseInsensitive( ldif );
+ // test that attr id comparisons are case insensitive and that the version in the add: line is used.
+ // See DIRSERVER-1029 for some discussion.
+ ldif =
+ "version: 1\n" +
+ "dn: dc=example,dc=com\n" +
+ "changetype: modify\n" +
+ "add: administrativeRole\n" +
+ "administrativerole: accessControlSpecificArea\n" +
+ "-";
+
+ testReaderAttrIdCaseInsensitive( ldif );
+ }
+
+
+ private void testReaderAttrIdCaseInsensitive( String ldif )
+ throws Exception
+ {
+ LdifReader reader = new LdifReader();
+
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ assertNotNull( entries );
+ reader.close();
+
+ LdifEntry entry = ( LdifEntry ) entries.get( 0 );
+
+ assertTrue( entry.isChangeModify() );
+
+ assertEquals( "dc=example,dc=com", entry.getDn().getName() );
+
+ List<Modification> mods = entry.getModificationItems( );
+ assertTrue( mods.size() == 1 );
+ EntryAttribute attr = mods.get(0).getAttribute();
+ assertTrue( attr.getId().equals( "administrativerole"));
+ assertEquals( attr.getString(), "accessControlSpecificArea" );
+ }
+
+
+ /**
+ * Changes and entries should not be mixed
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLdifParserCombinedEntriesChanges() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:\n" +
+ "\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.11A556.1.4.805 true\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ /**
+ * Changes and entries should not be mixed
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLdifParserCombinedEntriesChanges2() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:\n" +
+ "\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ /**
+ * Changes and entries should not be mixed
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLdifParserCombinedChangesEntries() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.11A556.1.4.805 true\n" +
+ "changetype: delete\n" +
+ "\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ /**
+ * Changes and entries should not be mixed
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLdifParserCombinedChangesEntries2() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "changetype: delete\n" +
+ "\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ @Test
+ public void testLdifParser() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1 \n" +
+ "dependencies:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "cn" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "apApplication" ) );
+
+ attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "dependencies" );
+ assertNull( attr.get().get() );
+
+ attr = entry.get( "envvars" );
+ assertNull( attr.get().get() );
+ }
+
+
+ @Test
+ public void testLdifParserMuiltiLineComments() throws Exception
+ {
+ String ldif =
+ "#comment\n" +
+ " still a comment\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1#another comment\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1\n" +
+ "serviceType: http\n" +
+ "dependencies:\n" +
+ "httpHeaders:\n" +
+ "startupOptions:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "cn" );
+ assertTrue( attr.contains( "app1#another comment" ) );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "apApplication" ) );
+
+ attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "dependencies" );
+ assertNull( attr.get().get() );
+
+ attr = entry.get( "envvars" );
+ assertNull( attr.get().get() );
+ }
+
+
+ @Test
+ public void testLdifParserMultiLineEntries() throws Exception
+ {
+ String ldif =
+ "#comment\n" +
+ "dn: cn=app1,ou=appli\n" +
+ " cations,ou=conf,dc=apache,dc=org\n" +
+ "cn: app1#another comment\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1\n" +
+ "serviceType: http\n" +
+ "dependencies:\n" +
+ "httpHeaders:\n" +
+ "startupOptions:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "cn" );
+ assertTrue( attr.contains( "app1#another comment" ) );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "apApplication" ) );
+
+ attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "dependencies" );
+ assertNull( attr.get().get() );
+
+ attr = entry.get( "envvars" );
+ assertNull( attr.get().get() );
+ }
+
+
+ @Test
+ public void testLdifParserBase64() throws Exception, UnsupportedEncodingException
+ {
+ String ldif =
+ "#comment\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn:: RW1tYW51ZWwgTMOpY2hhcm55\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1\n" +
+ "serviceType: http\n" +
+ "dependencies:\n" +
+ "httpHeaders:\n" +
+ "startupOptions:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Emmanuel L\u00e9charny".getBytes( "UTF-8" ) ) );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "apApplication" ) );
+
+ attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "dependencies" );
+ assertNull( attr.get().get() );
+
+ attr = entry.get( "envvars" );
+ assertNull( attr.get().get() );
+ }
+
+
+ @Test
+ public void testLdifParserBase64MultiLine() throws Exception, UnsupportedEncodingException
+ {
+ String ldif =
+ "#comment\n" +
+ "dn: cn=app1,ou=applications,ou=conf,dc=apache,dc=org\n" +
+ "cn:: RW1tYW51ZWwg\n" +
+ " TMOpY2hhcm55ICA=\n" +
+ "objectClass: top\n" +
+ "objectClass: apApplication\n" +
+ "displayName: app1\n" +
+ "serviceType: http\n" +
+ "dependencies:\n" +
+ "httpHeaders:\n" +
+ "startupOptions:\n" +
+ "envVars:";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertNotNull( entries );
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Emmanuel L\u00e9charny ".getBytes( "UTF-8" ) ) );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "apApplication" ) );
+
+ attr = entry.get( "displayname" );
+ assertTrue( attr.contains( "app1" ) );
+
+ attr = entry.get( "dependencies" );
+ assertNull( attr.get().get() );
+
+ attr = entry.get( "envvars" );
+ assertNull( attr.get().get() );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample1() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Barbara Jensen\n" +
+ "cn: Barbara J Jensen\n" +
+ "cn: Babs Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: bjensen\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "description: A big sailing fan.\n" +
+ "\n" +
+ "dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Bjorn Jensen\n" +
+ "sn: Jensen\n" +
+ "telephonenumber: +1 408 555 1212";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 2, entries.size() );
+
+ // Entry 1
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+
+ attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Barbara Jensen" ) );
+ assertTrue( attr.contains( "Barbara J Jensen" ) );
+ assertTrue( attr.contains( "Babs Jensen" ) );
+
+ attr = entry.get( "sn" );
+ assertTrue( attr.contains( "Jensen" ) );
+
+ attr = entry.get( "uid" );
+ assertTrue( attr.contains( "bjensen" ) );
+
+ attr = entry.get( "telephonenumber" );
+ assertTrue( attr.contains( "+1 408 555 1212" ) );
+
+ attr = entry.get( "description" );
+ assertTrue( attr.contains( "A big sailing fan." ) );
+
+ // Entry 2
+ entry = (LdifEntry) entries.get( 1 );
+ assertTrue( entry.isChangeAdd() );
+
+ attr = entry.get( "dn" );
+ assertEquals( "cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com", entry.getDn().getName() );
+
+ attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+
+ attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Bjorn Jensen" ) );
+
+ attr = entry.get( "sn" );
+ assertTrue( attr.contains( "Jensen" ) );
+
+ attr = entry.get( "telephonenumber" );
+ assertTrue( attr.contains( "+1 408 555 1212" ) );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample2() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Barbara Jensen\n" +
+ "cn: Barbara J Jensen\n" +
+ "cn: Babs Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: bjensen\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "description:Babs is a big sailing fan, and travels extensively in sea\n" +
+ " rch of perfect sailing conditions.\n" +
+ "title:Product Manager, Rod and Reel Division";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 1, entries.size() );
+
+ // Entry 1
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+
+ attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Barbara Jensen" ) );
+ assertTrue( attr.contains( "Barbara J Jensen" ) );
+ assertTrue( attr.contains( "Babs Jensen" ) );
+
+ attr = entry.get( "sn" );
+ assertTrue( attr.contains( "Jensen" ) );
+
+ attr = entry.get( "uid" );
+ assertTrue( attr.contains( "bjensen" ) );
+
+ attr = entry.get( "telephonenumber" );
+ assertTrue( attr.contains( "+1 408 555 1212" ) );
+
+ attr = entry.get( "description" );
+ assertTrue( attr
+ .contains( "Babs is a big sailing fan, and travels extensively in search of perfect sailing conditions." ) );
+
+ attr = entry.get( "title" );
+ assertTrue( attr.contains( "Product Manager, Rod and Reel Division" ) );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample3() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Gern Jensen\n" +
+ "cn: Gern O Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: gernj\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl\n" +
+ " IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG\n" +
+ " VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg\n" +
+ " b3V0IG1vcmUu";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 1, entries.size() );
+
+ // Entry 1
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+
+ attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Gern Jensen" ) );
+ assertTrue( attr.contains( "Gern O Jensen" ) );
+
+ attr = entry.get( "sn" );
+ assertTrue( attr.contains( "Jensen" ) );
+
+ attr = entry.get( "uid" );
+ assertTrue( attr.contains( "gernj" ) );
+
+ attr = entry.get( "telephonenumber" );
+ assertTrue( attr.contains( "+1 408 555 1212" ) );
+
+ attr = entry.get( "description" );
+ assertTrue( attr
+ .contains( "What a careful reader you are! This value is base-64-encoded because it has a control character in it (a CR).\r By the way, you should really get out more."
+ .getBytes( "UTF-8" ) ) );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample3VariousSpacing() throws Exception, Exception
+ {
+ String ldif =
+ "version:1\n" +
+ "dn:cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com \n" +
+ "objectclass:top\n" +
+ "objectclass: person \n" +
+ "objectclass:organizationalPerson\n" +
+ "cn:Gern Jensen\n" +
+ "cn:Gern O Jensen\n" +
+ "sn:Jensen\n" +
+ "uid:gernj\n" +
+ "telephonenumber:+1 408 555 1212 \n" +
+ "description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl\n" +
+ " IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG\n" +
+ " VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg\n" +
+ " b3V0IG1vcmUu ";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ assertEquals( 1, entries.size() );
+
+ // Entry 1
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ assertEquals( "cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+
+ attr = entry.get( "cn" );
+ assertTrue( attr.contains( "Gern Jensen" ) );
+ assertTrue( attr.contains( "Gern O Jensen" ) );
+
+ attr = entry.get( "sn" );
+ assertTrue( attr.contains( "Jensen" ) );
+
+ attr = entry.get( "uid" );
+ assertTrue( attr.contains( "gernj" ) );
+
+ attr = entry.get( "telephonenumber" );
+ assertTrue( attr.contains( "+1 408 555 1212" ) );
+
+ attr = entry.get( "description" );
+ assertTrue( attr
+ .contains( "What a careful reader you are! This value is base-64-encoded because it has a control character in it (a CR).\r By the way, you should really get out more."
+ .getBytes( "UTF-8" ) ) );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample4() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn:: b3U95Za25qWt6YOoLG89QWlyaXVz\n" +
+ "# dn:: ou=å¶æ¥é¨,o=Airius\n" +
+ "objectclass: top\n" +
+ "objectclass: organizationalUnit\n" +
+ "ou:: 5Za25qWt6YOo\n" +
+ "# ou:: å¶æ¥é¨\n" +
+ "ou;lang-ja:: 5Za25qWt6YOo\n" +
+ "# ou;lang-ja:: å¶æ¥é¨\n" +
+ "ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2\n" +
+ "# ou;lang-ja:: ãããããã¶\n" +
+ "ou;lang-en: Sales\n" +
+ "description: Japanese office\n" +
+ "\n" +
+ "dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz\n" +
+ "# dn:: uid=rogasawara,ou=å¶æ¥é¨,o=Airius\n" +
+ "userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "objectclass: inetOrgPerson\n" +
+ "uid: rogasawara\n" +
+ "mail: rogasawara@airius.co.jp\n" +
+ "givenname;lang-ja:: 44Ot44OJ44OL44O8\n" +
+ "# givenname;lang-ja:: ãããã¼\n" +
+ "sn;lang-ja:: 5bCP56yg5Y6f\n" +
+ "# sn;lang-ja:: å°ç¬ å\n" +
+ "cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==\n" +
+ "# cn;lang-ja:: å°ç¬ å ãããã¼\n" +
+ "title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==\n" +
+ "# title;lang-ja:: å¶æ¥é¨ é¨é·\n" +
+ "preferredlanguage: ja\n" +
+ "givenname:: 44Ot44OJ44OL44O8\n" +
+ "# givenname:: ãããã¼\n" +
+ "sn:: 5bCP56yg5Y6f\n" +
+ "# sn:: å°ç¬ å\n" +
+ "cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==\n" +
+ "# cn:: å°ç¬ å ãããã¼\n" +
+ "title:: 5Za25qWt6YOoIOmDqOmVtw==\n" +
+ "# title:: å¶æ¥é¨ é¨é·\n" +
+ "givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8\n" +
+ "# givenname;lang-ja;phonetic:: ãã©ã«ã¼\n" +
+ "sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ\n" +
+ "# sn;lang-ja;phonetic:: ããããã\n" +
+ "cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==\n" +
+ "# cn;lang-ja;phonetic:: ããããã ãã©ã«ã¼\n" +
+ "title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==\n" +
+ "# title;lang-ja;phonetic::\n" +
+ "# ããããã㶠ã¶ã¡ãã\n" +
+ "givenname;lang-en: Rodney\n" +
+ "sn;lang-en: Ogasawara\n" +
+ "cn;lang-en: Rodney Ogasawara\n" +
+ "title;lang-en: Sales, Director\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ String[][][] values =
+ {
+ {
+ { "dn", "ou=\u55b6\u696d\u90e8,o=Airius" }, // 55b6 = å¶, 696d = æ¥, 90e8 = é¨
+ { "objectclass", "top" },
+ { "objectclass", "organizationalUnit" },
+ { "ou", "\u55b6\u696d\u90e8" },
+ { "ou;lang-ja", "\u55b6\u696d\u90e8" },
+ { "ou;lang-ja;phonetic", "\u3048\u3044\u304e\u3087\u3046\u3076" }, // 3048 = ã, 3044 = ã, 304e = ã
+ // 3087 = ã, 3046 = ã, 3076 = ã¶
+ { "ou;lang-en", "Sales" },
+ { "description", "Japanese office" } },
+ {
+ { "dn", "uid=rogasawara,ou=\u55b6\u696d\u90e8,o=Airius" },
+ { "userpassword", "{SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=" },
+ { "objectclass", "top" },
+ { "objectclass", "person" },
+ { "objectclass", "organizationalPerson" },
+ { "objectclass", "inetOrgPerson" },
+ { "uid", "rogasawara" },
+ { "mail", "rogasawara@airius.co.jp" },
+ { "givenname;lang-ja", "\u30ed\u30c9\u30cb\u30fc" }, // 30ed = ã, 30c9 = ã, 30cb = ã, 30fc = ã¼
+ { "sn;lang-ja", "\u5c0f\u7b20\u539f" }, // 5c0f = å°, 7b20 = ç¬ , 539f = å
+ { "cn;lang-ja", "\u5c0f\u7b20\u539f \u30ed\u30c9\u30cb\u30fc" },
+ { "title;lang-ja", "\u55b6\u696d\u90e8 \u90e8\u9577" }, // 9577 = é·
+ { "preferredlanguage", "ja" },
+ { "givenname", "\u30ed\u30c9\u30cb\u30fc" },
+ { "sn", "\u5c0f\u7b20\u539f" },
+ { "cn", "\u5c0f\u7b20\u539f \u30ed\u30c9\u30cb\u30fc" },
+ { "title", "\u55b6\u696d\u90e8 \u90e8\u9577" },
+ { "givenname;lang-ja;phonetic", "\u308d\u3069\u306b\u30fc" }, // 308d = ã,3069 = ã©, 306b = ã«
+ { "sn;lang-ja;phonetic", "\u304a\u304c\u3055\u308f\u3089" }, // 304a = ã, 304c = ã,3055 = ã,308f = ã, 3089 = ã
+ { "cn;lang-ja;phonetic", "\u304a\u304c\u3055\u308f\u3089 \u308d\u3069\u306b\u30fc" },
+ { "title;lang-ja;phonetic", "\u3048\u3044\u304e\u3087\u3046\u3076 \u3076\u3061\u3087\u3046" }, // 304E = ã, 3061 = ã¡
+ { "givenname;lang-en", "Rodney" },
+ { "sn;lang-en", "Ogasawara" },
+ { "cn;lang-en", "Rodney Ogasawara" },
+ { "title;lang-en", "Sales, Director" }
+ }
+ };
+
+ assertEquals( 2, entries.size() );
+
+ // Entry 1
+ for ( int i = 0; i < entries.size(); i++ )
+ {
+ LdifEntry entry = (LdifEntry) entries.get( i );
+ assertTrue( entry.isChangeAdd() );
+
+ for ( int j = 0; j < values[i].length; j++ )
+ {
+ if ( "dn".equalsIgnoreCase( values[i][j][0] ) )
+ {
+ assertEquals( values[i][j][1], entry.getDn().getName() );
+ }
+ else
+ {
+ EntryAttribute attr = entry.get( values[i][j][0] );
+
+ if ( attr.contains( values[i][j][1] ) )
+ {
+ assertTrue( true );
+ }
+ else
+ {
+ assertTrue( attr.contains( values[i][j][1].getBytes( "UTF-8" ) ) );
+ }
+ }
+ }
+ }
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample5() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Horatio Jensen\n" +
+ "cn: Horatio N Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: hjensen\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "jpegphoto:< file:" + HJENSEN_JPEG_FILE.getAbsolutePath() + "\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ String[][] values =
+ {
+ { "dn", "cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com" },
+ { "objectclass", "top" },
+ { "objectclass", "person" },
+ { "objectclass", "organizationalPerson" },
+ { "cn", "Horatio Jensen" },
+ { "cn", "Horatio N Jensen" },
+ { "sn", "Jensen" },
+ { "uid", "hjensen" },
+ { "telephonenumber", "+1 408 555 1212" },
+ { "jpegphoto", null }
+ };
+
+ assertEquals( 1, entries.size() );
+
+ // Entry 1
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ for ( int i = 0; i < values.length; i++ )
+ {
+ if ( "dn".equalsIgnoreCase( values[i][0] ) )
+ {
+ assertEquals( values[i][1], entry.getDn().getName() );
+ }
+ else if ( "jpegphoto".equalsIgnoreCase( values[i][0] ) )
+ {
+ EntryAttribute attr = entry.get( values[i][0] );
+ assertEquals( StringTools.dumpBytes( data ), StringTools.dumpBytes( attr.getBytes() ) );
+ }
+ else
+ {
+ EntryAttribute attr = entry.get( values[i][0] );
+
+ if ( attr.contains( values[i][1] ) )
+ {
+ assertTrue( true );
+ }
+ else
+ {
+ assertTrue( attr.contains( values[i][1].getBytes( "UTF-8" ) ) );
+ }
+ }
+ }
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample5WithSizeLimit() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Horatio Jensen\n" +
+ "cn: Horatio N Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: hjensen\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "jpegphoto:< file:" + HJENSEN_JPEG_FILE.getAbsolutePath() + "\n";
+
+ LdifReader reader = new LdifReader();
+ reader.setSizeLimit( 128 );
+ reader.close();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertEquals( "Error while parsing the ldif buffer", ne.getMessage() );
+ }
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample6() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ // First entry modification : ADD
+ "# Add a new entry\n" +
+ "dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com\n" +
+ "changetype: add\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Fiona Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: fiona\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "jpegphoto:< file:" + FIONA_JPEG_FILE.getAbsolutePath() + "\n" +
+ "\n" +
+ // Second entry modification : DELETE
+ "# Delete an existing entry\n" +
+ "dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com\n" +
+ "changetype: delete\n" +
+ "\n" +
+ // Third entry modification : MODRDN
+ "# Modify an entry's relative distinguished name\n" +
+ "dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com\n" +
+ "changetype: modrdn\n" +
+ "newrdn: cn=Paula Jensen\n" +
+ "deleteoldrdn: 1\n" +
+ "\n" +
+ // Forth entry modification : MODRDN
+ "# Rename an entry and move all of its children to a new location in\n" +
+ "# the directory tree (only implemented by LDAPv3 servers).\n" +
+ "dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com\n" +
+ "changetype: moddn\n" +
+ "newrdn: ou=Product Development Accountants\n" +
+ "deleteoldrdn: 0\n" +
+ "newsuperior: ou=Accounting, dc=airius, dc=com\n" +
+ "# Modify an entry: add an additional value to the postaladdress\n" +
+ "# attribute, completely delete the description attribute, replace\n" +
+ "# the telephonenumber attribute with two values, and delete a specific\n" +
+ "# value from the facsimiletelephonenumber attribute\n" +
+ "\n" +
+ // Fitfh entry modification : MODIFY
+ "dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com\n" +
+ "changetype: modify\n" +
+ "add: postaladdress\n" +
+ "postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086\n" +
+ "-\n" +
+ "delete: description\n" +
+ "-\n" +
+ "replace: telephonenumber\n" +
+ "telephonenumber: +1 408 555 1234\n" +
+ "telephonenumber: +1 408 555 5678\n" +
+ "-\n" +
+ "delete: facsimiletelephonenumber\n" +
+ "facsimiletelephonenumber: +1 408 555 9876\n" +
+ "-\n" +
+ "\n" +
+ // Sixth entry modification : MODIFY
+ "# Modify an entry: replace the postaladdress attribute with an empty\n" +
+ "# set of values (which will cause the attribute to be removed), and\n" +
+ "# delete the entire description attribute. Note that the first will\n" +
+ "# always succeed, while the second will only succeed if at least\n" +
+ "# one value for the description attribute is present.\n" +
+ "dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com\n" +
+ "changetype: modify\n" +
+ "replace: postaladdress\n" +
+ "-\n" +
+ "delete: description\n" +
+ "-\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ String[][][] values =
+ {
+ // First entry modification : ADD
+ {
+ { "dn", "cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com" },
+ { "objectclass", "top" },
+ { "objectclass", "person" },
+ { "objectclass", "organizationalPerson" },
+ { "cn", "Fiona Jensen" },
+ { "sn", "Jensen" },
+ { "uid", "fiona" },
+ { "telephonenumber", "+1 408 555 1212" },
+ { "jpegphoto", "" }
+ },
+ // Second entry modification : DELETE
+ {
+ { "dn", "cn=Robert Jensen, ou=Marketing, dc=airius, dc=com" }
+ },
+ // Third entry modification : MODRDN
+ {
+ { "dn", "cn=Paul Jensen, ou=Product Development, dc=airius, dc=com" },
+ { "cn=Paula Jensen" }
+ },
+ // Forth entry modification : MODRDN
+ {
+ { "dn", "ou=PD Accountants, ou=Product Development, dc=airius, dc=com" },
+ { "ou=Product Development Accountants" },
+ { "ou=Accounting, dc=airius, dc=com" }
+ },
+ // Fitfh entry modification : MODIFY
+ {
+ { "dn", "cn=Paula Jensen, ou=Product Development, dc=airius, dc=com" },
+ // add
+ { "postaladdress", "123 Anystreet $ Sunnyvale, CA $ 94086" },
+ // delete
+ { "description" },
+ // replace
+ { "telephonenumber", "+1 408 555 1234", "+1 408 555 5678" },
+ // delete
+ { "facsimiletelephonenumber", "+1 408 555 9876" },
+ },
+ // Sixth entry modification : MODIFY
+ {
+ { "dn", "cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com" },
+ // replace
+ { "postaladdress" },
+ // delete
+ { "description" }
+ }
+ };
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+ assertTrue( entry.isChangeAdd() );
+
+ for ( int i = 0; i < values.length; i++ )
+ {
+ if ( "dn".equalsIgnoreCase( values[0][i][0] ) )
+ {
+ assertEquals( values[0][i][1], entry.getDn().getName() );
+ }
+ else if ( "jpegphoto".equalsIgnoreCase( values[0][i][0] ) )
+ {
+ EntryAttribute attr = entry.get( values[0][i][0] );
+ assertEquals( StringTools.dumpBytes( data ), StringTools.dumpBytes( attr.getBytes() ) );
+ }
+ else
+ {
+ EntryAttribute attr = entry.get( values[0][i][0] );
+
+ if ( attr.contains( values[0][i][1] ) )
+ {
+ assertTrue( true );
+ }
+ else
+ {
+ assertTrue( attr.contains( values[0][i][1].getBytes( "UTF-8" ) ) );
+ }
+ }
+ }
+
+ // Second entry
+ entry = (LdifEntry) entries.get( 1 );
+ assertTrue( entry.isChangeDelete() );
+ assertEquals( values[1][0][1], entry.getDn().getName() );
+
+ // Third entry
+ entry = (LdifEntry) entries.get( 2 );
+ assertTrue( entry.isChangeModRdn() );
+ assertEquals( values[2][0][1], entry.getDn().getName() );
+ assertEquals( values[2][1][0], entry.getNewRdn() );
+ assertTrue( entry.isDeleteOldRdn() );
+
+ // Forth entry
+ entry = (LdifEntry) entries.get( 3 );
+ assertTrue( entry.isChangeModDn() );
+ assertEquals( values[3][0][1], entry.getDn().getName() );
+ assertEquals( values[3][1][0], entry.getNewRdn() );
+ assertFalse( entry.isDeleteOldRdn() );
+ assertEquals( values[3][2][0], entry.getNewSuperior() );
+
+ // Fifth entry
+ entry = (LdifEntry) entries.get( 4 );
+ List<Modification> modifs = entry.getModificationItems();
+
+ assertTrue( entry.isChangeModify() );
+ assertEquals( values[4][0][1], entry.getDn().getName() );
+
+ // "add: postaladdress"
+ // "postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086"
+ Modification item = (Modification) modifs.get( 0 );
+ assertEquals( ModificationOperation.ADD_ATTRIBUTE, item.getOperation() );
+ assertEquals( values[4][1][0], item.getAttribute().getId() );
+ assertTrue( item.getAttribute().contains( values[4][1][1] ) );
+
+ // "delete: description\n" +
+ item = (Modification) modifs.get( 1 );
+ assertEquals( ModificationOperation.REMOVE_ATTRIBUTE, item.getOperation() );
+ assertEquals( values[4][2][0], item.getAttribute().getId() );
+
+ // "replace: telephonenumber"
+ // "telephonenumber: +1 408 555 1234"
+ // "telephonenumber: +1 408 555 5678"
+ item = (Modification) modifs.get( 2 );
+ assertEquals( ModificationOperation.REPLACE_ATTRIBUTE, item.getOperation() );
+
+ assertEquals( values[4][3][0], item.getAttribute().getId() );
+ assertTrue( item.getAttribute().contains( values[4][3][1], values[4][3][2] ) );
+
+ // "delete: facsimiletelephonenumber"
+ // "facsimiletelephonenumber: +1 408 555 9876"
+ item = (Modification) modifs.get( 3 );
+
+ assertEquals( ModificationOperation.REMOVE_ATTRIBUTE, item.getOperation() );
+
+ assertEquals( values[4][4][0], item.getAttribute().getId() );
+ assertTrue( item.getAttribute().contains( values[4][4][1] ) );
+
+ // Sixth entry
+ entry = (LdifEntry) entries.get( 5 );
+ modifs = entry.getModificationItems();
+
+ assertTrue( entry.isChangeModify() );
+ assertEquals( values[5][0][1], entry.getDn().getName() );
+
+ // "replace: postaladdress"
+ item = (Modification) modifs.get( 0 );
+ assertEquals( ModificationOperation.REPLACE_ATTRIBUTE, item.getOperation() );
+ assertEquals( values[5][1][0], item.getAttribute().getId() );
+
+ // "delete: description"
+ item = (Modification) modifs.get( 1 );
+ assertEquals( ModificationOperation.REMOVE_ATTRIBUTE, item.getOperation() );
+ assertEquals( values[5][2][0], item.getAttribute().getId() );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample7() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.113556.1.4.805 true\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertEquals( "ou=Product Development, dc=airius, dc=com", entry.getDn().getName() );
+ assertTrue( entry.isChangeDelete() );
+
+ // Check the control
+ Control control = entry.getControl();
+
+ assertEquals( "1.2.840.113556.1.4.805", control.getOid() );
+ assertTrue( control.isCritical() );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample7NoValueNoCritical() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.11556.1.4.805\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertEquals( "ou=Product Development, dc=airius, dc=com", entry.getDn().getName() );
+ assertTrue( entry.isChangeDelete() );
+
+ // Check the control
+ Control control = entry.getControl();
+
+ assertEquals( "1.2.840.11556.1.4.805", control.getOid() );
+ assertFalse( control.isCritical() );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample7NoCritical() throws Exception, Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.11556.1.4.805:control-value\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertEquals( "ou=Product Development, dc=airius, dc=com", entry.getDn().getName() );
+ assertTrue( entry.isChangeDelete() );
+
+ // Check the control
+ Control control = entry.getControl();
+
+ assertEquals( "1.2.840.11556.1.4.805", control.getOid() );
+ assertFalse( control.isCritical() );
+ assertEquals( "control-value", StringTools.utf8ToString( control.getValue() ) );
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample7NoOid() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: true\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ @Test
+ public void testLdifParserRFC2849Sample7BadOid() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "# Delete an entry. The operation will attach the LDAPv3\n" +
+ "# Tree Delete Control defined in [9]. The criticality\n" +
+ "# field is \"true\" and the controlValue field is\n" +
+ "# absent, as required by [9].\n" +
+ "dn: ou=Product Development, dc=airius, dc=com\n" +
+ "control: 1.2.840.11A556.1.4.805 true\n" +
+ "changetype: delete\n";
+
+ LdifReader reader = new LdifReader();
+
+ try
+ {
+ reader.parseLdif( ldif );
+ fail();
+ }
+ catch (Exception ne)
+ {
+ assertTrue( true );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+
+ @Test
+ public void testLdifReaderDirServer() throws Exception, Exception
+ {
+ String ldif =
+ "# -------------------------------------------------------------------\n" +
+ "#\n" +
+ "# Licensed to the Apache Software Foundation (ASF) under one\n" +
+ "# or more contributor license agreements. See the NOTICE file\n" +
+ "# distributed with this work for additional information\n" +
+ "# regarding copyright ownership. The ASF licenses this file\n" +
+ "# to you under the Apache License, Version 2.0 (the\n" +
+ "# \"License\"); you may not use this file except in compliance\n" +
+ "# with the License. You may obtain a copy of the License at\n" +
+ "# \n" +
+ "# http://www.apache.org/licenses/LICENSE-2.0\n" +
+ "# \n" +
+ "# Unless required by applicable law or agreed to in writing,\n" +
+ "# software distributed under the License is distributed on an\n" +
+ "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n" +
+ "# KIND, either express or implied. See the License for the\n" +
+ "# specific language governing permissions and limitations\n" +
+ "# under the License. \n" +
+ "# \n" +
+ "#\n" +
+ "# EXAMPLE.COM is freely and reserved for testing according to this RFC:\n" +
+ "#\n" +
+ "# http://www.rfc-editor.org/rfc/rfc2606.txt\n" +
+ "#\n" +
+ "# -------------------------------------------------------------------\n" +
+ "\n" +
+ "dn: ou=Users, dc=example, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: organizationalunit\n" +
+ "ou: Users";
+
+ LdifReader reader = new LdifReader();
+
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertEquals( "ou=Users, dc=example, dc=com", entry.getDn().getName() );
+
+ EntryAttribute attr = entry.get( "objectclass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( "organizationalunit" ) );
+
+ attr = entry.get( "ou" );
+ assertTrue( attr.contains( "Users" ) );
+ }
+
+
+ @Test
+ public void testLdifParserCommentsEmptyLines() throws Exception, Exception
+ {
+ String ldif =
+ "#\n" +
+ "# Licensed to the Apache Software Foundation (ASF) under one\n" +
+ "# or more contributor license agreements. See the NOTICE file\n" +
+ "# distributed with this work for additional information\n" +
+ "# regarding copyright ownership. The ASF licenses this file\n" +
+ "# to you under the Apache License, Version 2.0 (the\n" +
+ "# \"License\"); you may not use this file except in compliance\n" +
+ "# with the License. You may obtain a copy of the License at\n" +
+ "# \n" +
+ "# http://www.apache.org/licenses/LICENSE-2.0\n" +
+ "# \n" +
+ "# Unless required by applicable law or agreed to in writing,\n" +
+ "# software distributed under the License is distributed on an\n" +
+ "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n" +
+ "# KIND, either express or implied. See the License for the\n" +
+ "# specific language governing permissions and limitations\n" +
+ "# under the License. \n" +
+ "# \n" +
+ "#\n" +
+ "#\n" +
+ "# EXAMPLE.COM is freely and reserved for testing according to this RFC:\n" +
+ "#\n" +
+ "# http://www.rfc-editor.org/rfc/rfc2606.txt\n" +
+ "#\n" +
+ "#\n" +
+ "\n" +
+ "#\n" +
+ "# This ACI allows brouse access to the root suffix and one level below that to anyone.\n" +
+ "# At this level there is nothing critical exposed. Everything that matters is one or\n" +
+ "# more levels below this.\n" +
+ "#\n" +
+ "\n" +
+ "dn: cn=browseRootAci,dc=example,dc=com\n" +
+ "objectClass: top\n" +
+ "objectClass: subentry\n" +
+ "objectClass: accessControlSubentry\n" +
+ "subtreeSpecification: { maximum 1 }\n" +
+ "prescriptiveACI: { identificationTag \"browseRoot\", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } }\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = (LdifEntry) entries.get( 0 );
+
+ assertEquals( "cn=browseRootAci,dc=example,dc=com", entry.getDn().getName() );
+ EntryAttribute attr = entry.get( "objectClass" );
+ assertTrue( attr.contains( "top" ) );
+ assertTrue( attr.contains( SchemaConstants.SUBENTRY_OC ) );
+ assertTrue( attr.contains( "accessControlSubentry" ) );
+
+ attr = entry.get( "subtreeSpecification" );
+ assertTrue( attr.contains( "{ maximum 1 }" ) );
+
+ attr = entry.get( "prescriptiveACI" );
+ assertTrue( attr.contains( "{ identificationTag \"browseRoot\", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } }" ) );
+ }
+
+
+ @Test
+ public void testRemoveAttribute() throws Exception
+ {
+ String ldif =
+ "version: 1\n" +
+ "dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com\n" +
+ "objectclass: top\n" +
+ "objectclass: person\n" +
+ "objectclass: organizationalPerson\n" +
+ "cn: Horatio Jensen\n" +
+ "cn: Horatio N Jensen\n" +
+ "sn: Jensen\n" +
+ "uid: hjensen\n" +
+ "telephonenumber: +1 408 555 1212\n" +
+ "jpegphoto:< file:" + HJENSEN_JPEG_FILE.getAbsolutePath() + "\n";
+
+ LdifReader reader = new LdifReader();
+ List<LdifEntry> entries = reader.parseLdif( ldif );
+ reader.close();
+
+ LdifEntry entry = entries.get( 0 );
+
+ assertNotNull( entry.get( "uid" ) );
+ assertNotNull( entry.removeAttribute( "uid" ) );
+ assertNull( entry.get( "uid" ) );
+ }
+}