/*
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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 scriptella.driver.ldap.ldif;
import junit.framework.TestCase;
import scriptella.expression.LineIterator;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.ldap.Control;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
/**
* Tests for {@link LdifReader}.
* Based on LdifReaderTest from Apache Driectory Project.
*
* @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
* @author Fyodor Kupolov
* @version $Rev: 379008 $
*/
public class LdifReaderTest extends TestCase {
private byte[] data;
private static File HJENSEN_JPEG_FILE = null;
private static File FIONA_JPEG_FILE = null;
private 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
*/
public void setUp() throws Exception {
super.setUp();
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);
}
public void testLdifEmpty() throws NamingException {
String ldif = "";
List entries = new LdifReader(ldif).asList();
assertEquals(0, entries.size());
}
public void testLdifEmptyLines() throws NamingException {
String ldif = "\n\n\r\r\n";
List entries = new LdifReader(ldif).asList();
assertEquals(0, entries.size());
}
public void testLdifComments() throws NamingException {
String ldif =
"#Comment 1\r" +
"#\r" +
" th\n" +
" is is still a comment\n" +
"\n";
List entries = new LdifReader(ldif).asList();
assertEquals(0, entries.size());
}
public void testLdifVersion() throws NamingException {
String ldif =
"#Comment 1\r" +
"#\r" +
" th\n" +
" is is still a comment\n" +
"\n" +
"version:\n" +
" 2\n" +
"# end";
LdifReader reader = new LdifReader(ldif);
reader.asList();
List entries = reader.asList();
assertEquals(0, entries.size());
assertEquals(2, reader.getVersion());
}
/**
* Spaces at the end of values should not be included into values.
*
* @throws NamingException
*/
public void testLdifParserEndSpaces() throws NamingException {
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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute attr = entry.get("displayname");
assertTrue(attr.contains("app1"));
}
/**
* Changes and entries should not be mixed
*
* @throws NamingException
*/
public void testLdifParserCombinedEntriesChanges() throws NamingException {
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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
/**
* Changes and entries should not be mixed
*
* @throws NamingException
*/
public void testLdifParserCombinedEntriesChanges2() throws NamingException {
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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
/**
* Changes and entries should not be mixed
*
* @throws NamingException
*/
public void testLdifParserCombinedChangesEntries() throws NamingException {
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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
/**
* Changes and entries should not be mixed
*
* @throws NamingException
*/
public void testLdifParserCombinedChangesEntries2() throws NamingException {
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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
public void testLdifParser() throws NamingException {
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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute 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());
attr = entry.get("envvars");
assertNull(attr.get());
}
public void testLdifParserMuiltiLineComments() throws NamingException {
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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute 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());
attr = entry.get("envvars");
assertNull(attr.get());
}
public void testLdifParserMultiLineEntries() throws NamingException {
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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute 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());
attr = entry.get("envvars");
assertNull(attr.get());
}
public void testLdifParserBase64() throws NamingException, 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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute 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());
attr = entry.get("envvars");
assertNull(attr.get());
}
public void testLdifParserBase64MultiLine() throws NamingException, 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:";
List entries = new LdifReader(ldif).asList();
assertNotNull(entries);
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=app1,ou=applications,ou=conf,dc=apache,dc=org", entry.getDn());
Attribute 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());
attr = entry.get("envvars");
assertNull(attr.get());
}
public void testLdifParserRFC2849Sample1() throws NamingException {
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";
List entries = new LdifReader(ldif).asList();
assertEquals(2, entries.size());
// Entry 1
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com", entry.getDn());
Attribute 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 = (Entry) entries.get(1);
assertTrue(entry.isChangeAdd());
assertEquals("cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com", entry.getDn());
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"));
}
public void testLdifParserRFC2849Sample2() throws NamingException {
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";
List entries = new LdifReader(ldif).asList();
assertEquals(1, entries.size());
// Entry 1
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com", entry.getDn());
Attribute 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"));
}
public void testLdifParserRFC2849Sample3() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
assertEquals(1, entries.size());
// Entry 1
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com", entry.getDn());
Attribute 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")));
}
public void testLdifParserRFC2849Sample3VariousSpacing() throws NamingException, 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 ";
List entries = new LdifReader(ldif).asList();
assertEquals(1, entries.size());
// Entry 1
Entry entry = (Entry) entries.get(0);
assertTrue(entry.isChangeAdd());
assertEquals("cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com", entry.getDn());
Attribute 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")));
}
public void testLdifParserRFC2849Sample4() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
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++) {
Entry entry = (Entry) 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());
} else {
Attribute 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")));
}
}
}
}
}
public void testLdifParserRFC2849Sample5() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
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
Entry entry = (Entry) 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());
} else if ("jpegphoto".equalsIgnoreCase(values[i][0])) {
Attribute attr = entry.get(values[i][0]);
assertTrue(Arrays.equals(data, (byte[]) attr.get()));
} else {
Attribute attr = entry.get(values[i][0]);
if (attr.contains(values[i][1])) {
assertTrue(true);
} else {
assertTrue(attr.contains(values[i][1].getBytes("UTF-8")));
}
}
}
}
public void testLdifParserRFC2849Sample5WithSizeLimit() throws NamingException, 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";
try {
new LdifReader(new LineIterator(new StringReader(ldif)), 128);
fail();
}
catch (LdifParseException e) {
final Throwable cause = e.getCause();
assertTrue("Content too long exception must be thrown",
cause !=null && cause.getMessage().indexOf("too long")>0);
}
}
public void testLdifParserRFC2849Sample6() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
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"}
}
};
Entry entry = (Entry) 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());
} else if ("jpegphoto".equalsIgnoreCase(values[0][i][0])) {
Attribute attr = entry.get(values[0][i][0]);
assertTrue(Arrays.equals(data, (byte[]) attr.get()));
} else {
Attribute 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 = (Entry) entries.get(1);
assertTrue(entry.isChangeDelete());
assertEquals(values[1][0][1], entry.getDn());
// Third entry
entry = (Entry) entries.get(2);
assertTrue(entry.isChangeModRdn());
assertEquals(values[2][0][1], entry.getDn());
assertEquals(values[2][1][0], entry.getNewRdn());
assertTrue(entry.isDeleteOldRdn());
// Forth entry
entry = (Entry) entries.get(3);
assertTrue(entry.isChangeModDn());
assertEquals(values[3][0][1], entry.getDn());
assertEquals(values[3][1][0], entry.getNewRdn());
assertFalse(entry.isDeleteOldRdn());
assertEquals(values[3][2][0], entry.getNewSuperior());
// Fifth entry
entry = (Entry) entries.get(4);
List modifs = entry.getModificationItems();
assertTrue(entry.isChangeModify());
assertEquals(values[4][0][1], entry.getDn());
// "add: postaladdress"
// "postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086"
ModificationItem item = (ModificationItem) modifs.get(0);
assertEquals(DirContext.ADD_ATTRIBUTE, item.getModificationOp());
assertEquals(values[4][1][0], item.getAttribute().getID());
assertEquals(values[4][1][1], item.getAttribute().get(0));
// "delete: description\n" +
item = (ModificationItem) modifs.get(1);
assertEquals(DirContext.REMOVE_ATTRIBUTE, item.getModificationOp());
assertEquals(values[4][2][0], item.getAttribute().getID());
// "replace: telephonenumber"
// "telephonenumber: +1 408 555 1234"
// "telephonenumber: +1 408 555 5678"
item = (ModificationItem) modifs.get(2);
assertEquals(DirContext.REPLACE_ATTRIBUTE, item.getModificationOp());
assertEquals(values[4][3][0], item.getAttribute().getID());
assertEquals(values[4][3][1], item.getAttribute().get(0));
assertEquals(values[4][3][2], item.getAttribute().get(1));
// "delete: facsimiletelephonenumber"
// "facsimiletelephonenumber: +1 408 555 9876"
item = (ModificationItem) modifs.get(3);
assertEquals(DirContext.REMOVE_ATTRIBUTE, item.getModificationOp());
assertEquals(values[4][4][0], item.getAttribute().getID());
assertEquals(values[4][4][1], item.getAttribute().get(0));
// Sixth entry
entry = (Entry) entries.get(5);
modifs = entry.getModificationItems();
assertTrue(entry.isChangeModify());
assertEquals(values[5][0][1], entry.getDn());
// "replace: postaladdress"
item = (ModificationItem) modifs.get(0);
assertEquals(DirContext.REPLACE_ATTRIBUTE, item.getModificationOp());
assertEquals(values[5][1][0], item.getAttribute().getID());
// "delete: description"
item = (ModificationItem) modifs.get(1);
assertEquals(DirContext.REMOVE_ATTRIBUTE, item.getModificationOp());
assertEquals(values[5][2][0], item.getAttribute().getID());
}
public void testLdifParserRFC2849Sample7() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
Entry entry = (Entry) entries.get(0);
assertEquals("ou=Product Development, dc=airius, dc=com", entry.getDn());
assertTrue(entry.isChangeDelete());
// Check the control
Control control = entry.getControl();
assertEquals("1.2.840.113556.1.4.805", control.getID());
assertTrue(control.isCritical());
}
public void testLdifParserRFC2849Sample7NoValueNoCritical() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
Entry entry = (Entry) entries.get(0);
assertEquals("ou=Product Development, dc=airius, dc=com", entry.getDn());
assertTrue(entry.isChangeDelete());
// Check the control
Control control = entry.getControl();
assertEquals("1.2.840.11556.1.4.805", control.getID());
assertFalse(control.isCritical());
}
public void testLdifParserRFC2849Sample7NoCritical() throws NamingException, 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";
List entries = new LdifReader(ldif).asList();
Entry entry = (Entry) entries.get(0);
assertEquals("ou=Product Development, dc=airius, dc=com", entry.getDn());
assertTrue(entry.isChangeDelete());
// Check the control
Control control = entry.getControl();
assertEquals("1.2.840.11556.1.4.805", control.getID());
assertFalse(control.isCritical());
assertEquals("control-value", new String(control.getEncodedValue()));
}
public void testLdifParserRFC2849Sample7NoOid() throws NamingException, 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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
public void testLdifParserRFC2849Sample7BadOid() throws NamingException, 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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
public void testLdifParserChangeModifyMultiAttrs() throws NamingException, Exception {
String ldif =
"version: 1\n" +
"dn: ou=Product Development, dc=airius, dc=com\n" +
"changetype: modify\n" +
"add: postaladdress\n" +
"postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086\n" +
"-\n" +
"delete: postaladdress\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";
try {
new LdifReader(ldif).asList();
fail();
}
catch (LdifParseException e) {
//OK
}
}
}