diff --git a/changelog.txt b/changelog.txt
index 9362714b..0c2d4edd 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -12,7 +12,7 @@ http://www.ietf.org/rfc/rfc2256.txt
http://www.ietf.org/rfc/rfc2696.txt
http://www.ietf.org/rfc/rfc2829.txt
-Changes in version 1.3.1 (October 2010)
+Changes in version 1.3.1 (November 2010)
-------------------------------------------
* Added an object-directory mapping framework (ODM). Contributed by Paul
Harvey.
@@ -47,12 +47,17 @@ Changes in version 1.3.1 (October 2010)
* Authentication methods now log problems at level INFO rather than ERROR.
(LDAP-170)
+* It's now possible to control the case folding of attribute keys in
+ DistinguishedName by setting the system property
+ DistinguishedName.KEY_CASE_FOLD_PROPERTY to one of "lower", "upper", or
+ "none". (LDAP-188)
+
* DIGEST-MD5 SASL authentication mechanism is now supported, as specified by
RFC 2829 (see http://www.ietf.org/rfc/rfc2829.txt, section 4). (LDAP-173)
Contributed by Marvin S. Addison.
* DefaultDirObjectFactory calls a Java5 version of the IllegalArgumentException
- constructor. (LDAP 196).
+ constructor. (LDAP 196)
* DirContextAdapter JavaDoc now states clearly that several methods are not
implemented on purpose. (LDAP-208)
diff --git a/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java b/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java
index 5e959c19..1a6fd4da 100644
--- a/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java
+++ b/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java
@@ -95,24 +95,49 @@ import org.springframework.util.Assert;
*/
public class DistinguishedName implements Name {
/**
- * System property that will be inspected to determine whether toString will
- * format the DN with spaces after each comma or use a more compact
- * representation, i.e.:
+ * System property that will be inspected to determine whether
+ * {@link #toString()} will format the DN with spaces after each comma or
+ * use a more compact representation, i.e.:
* uid=adam.skogman, ou=People, dc=jayway, dc=se rather than
- * uid=adam.skogman,ou=People,dc=jayway,dc=se. Default is
- * compact representation.
+ * uid=adam.skogman,ou=People,dc=jayway,dc=se. A value other
+ * than null or blank will trigger the spaced format. Default is the compact
+ * representation.
+ *
+ * Valid values are: + *
+ * Valid values are: + *
- * If the System property
- * org.springframework.ldap.core.preserveKeyCase is set to
- * "true", the keys will preserve their original case. Default is to convert
- * them to lowercase.
+ * Depending on the value of the "key case fold" System property, the keys
+ * will be lowercased, uppercased, or preserve their original case. Default
+ * is to convert them to lowercase.
*
* @param key the Attribute name.
* @param value the Attribute value.
* @param decodeValue if true the value is decoded (typically
* used when a DN is parsed from a String), otherwise the value is used as
* specified.
- * @see DistinguishedName#PRESERVE_KEY_CASE_PROPERTY
+ * @see DistinguishedName#KEY_CASE_FOLD_PROPERTY
*/
public LdapRdnComponent(String key, String value, boolean decodeValue) {
Validate.notEmpty(key, "Key must not be empty");
Validate.notEmpty(value, "Value must not be empty");
- String preserveKeyCase = System.getProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY);
- if (StringUtils.isBlank(preserveKeyCase)) {
+ String caseFold = System.getProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
+ if (StringUtils.isBlank(caseFold) || caseFold.equals(DistinguishedName.KEY_CASE_FOLD_LOWER)) {
this.key = StringUtils.lowerCase(key);
- } else {
+ } else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_UPPER)) {
+ this.key = StringUtils.upperCase(key);
+ } else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_NONE)) {
this.key = key;
+ } else {
+ log
+ .warn("\"" + caseFold + "\" invalid property value for " + DistinguishedName.KEY_CASE_FOLD_PROPERTY
+ + "; expected \"" + DistinguishedName.KEY_CASE_FOLD_LOWER + "\", \""
+ + DistinguishedName.KEY_CASE_FOLD_UPPER + "\", or \""
+ + DistinguishedName.KEY_CASE_FOLD_NONE + "\"");
+ this.key = StringUtils.lowerCase(key);
}
if (decodeValue) {
this.value = LdapEncoder.nameDecode(value);
diff --git a/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java b/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java
index 34c5fc06..5714596f 100644
--- a/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java
+++ b/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java
@@ -582,18 +582,79 @@ public class DistinguishedNameTest extends TestCase {
}
}
- public void testPreserveKeyCasePropertyTrueShouldNotEqualLowerCasedKeys() throws Exception {
+ public void testKeyCaseFoldNoneShouldEqualOriginalCasedKeys() throws Exception {
try {
- DistinguishedName name = new DistinguishedName("ou=foo,Ou=bar,oU=baz,OU=bim");
+ String dnString = "ou=foo,Ou=bar,oU=baz,OU=bim";
+ DistinguishedName name = new DistinguishedName(dnString);
+
// First check the default
assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
- System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, "true");
- name = new DistinguishedName("ou=foo,Ou=bar,oU=baz,OU=bim");
- assertEquals("ou=foo,Ou=bar,oU=baz,OU=bim", name.toString());
+
+ System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, DistinguishedName.KEY_CASE_FOLD_NONE);
+ name = new DistinguishedName(dnString);
+ System.out.println(dnString + " folded as \"" + DistinguishedName.KEY_CASE_FOLD_NONE + "\": " + name);
+ assertEquals(dnString, name.toString());
}
finally {
// Always restore the system setting
- System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, "");
+ System.clearProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
+ }
+ }
+
+ public void testKeyCaseFoldUpperShouldEqualUpperCasedKeys() throws Exception {
+ try {
+ String dnString = "ou=foo,Ou=bar,oU=baz,OU=bim";
+ DistinguishedName name = new DistinguishedName(dnString);
+
+ // First check the default
+ assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
+
+ System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, DistinguishedName.KEY_CASE_FOLD_UPPER);
+ name = new DistinguishedName(dnString);
+ System.out.println(dnString + " folded as \"" + DistinguishedName.KEY_CASE_FOLD_UPPER + "\": " + name);
+ assertEquals("OU=foo,OU=bar,OU=baz,OU=bim", name.toString());
+ }
+ finally {
+ // Always restore the system setting
+ System.clearProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
+ }
+ }
+
+ public void testKeyCaseFoldLowerShouldEqualLowerCasedKeys() throws Exception {
+ try {
+ String dnString = "ou=foo,Ou=bar,oU=baz,OU=bim";
+ DistinguishedName name = new DistinguishedName(dnString);
+
+ // First check the default
+ assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
+
+ System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, DistinguishedName.KEY_CASE_FOLD_LOWER);
+ name = new DistinguishedName(dnString);
+ System.out.println(dnString + " folded as \"" + DistinguishedName.KEY_CASE_FOLD_LOWER + "\": " + name);
+ assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
+ }
+ finally {
+ // Always restore the system setting
+ System.clearProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
+ }
+ }
+
+ public void testKeyCaseFoldNonsenseShoulddefaultToLowerCasedKeysAndLogWarning() throws Exception {
+ try {
+ String dnString = "ou=foo,Ou=bar,oU=baz,OU=bim";
+ DistinguishedName name = new DistinguishedName(dnString);
+
+ // First check the default
+ assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
+
+ System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, "whatever");
+ name = new DistinguishedName(dnString);
+ System.out.println(dnString + " folded as \"whatever\": " + name);
+ assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString());
+ }
+ finally {
+ // Always restore the system setting
+ System.clearProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
}
}
}
diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java
index 5aa4af33..5dbc6a2c 100644
--- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java
+++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java
@@ -173,7 +173,7 @@ public class LdapTemplateModifyITest extends AbstractLdapTemplateIntegrationTest
tested.modifyAttributes(ctx);
// without this, the member added above will not be removed and the test fails
- System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, Boolean.TRUE.toString());
+ System.setProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY, DistinguishedName.KEY_CASE_FOLD_NONE);
ctx = tested.lookupContext(dn);
ctx.removeAttributeValue("uniqueMember", new DistinguishedName(upperCasedName).toCompactString());
@@ -189,7 +189,7 @@ public class LdapTemplateModifyITest extends AbstractLdapTemplateIntegrationTest
assertEquals("3", "cn=Some Person3,ou=company1,c=Sweden,dc=jayway,dc=se", attributes[3]);
}
finally {
- System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, "");
+ System.clearProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
}
}