diff --git a/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java b/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java index 393f92ad..d1eb6fd3 100644 --- a/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java +++ b/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java @@ -23,6 +23,7 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import javax.naming.Context; +import javax.naming.InvalidNameException; import javax.naming.Name; import javax.naming.NameNotFoundException; import javax.naming.NameParser; @@ -35,7 +36,10 @@ import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import java.util.ArrayList; +import java.util.Collections; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; @@ -87,9 +91,9 @@ public class DirContextAdapter implements DirContextOperations { private final Attributes originalAttrs; - private DistinguishedName dn; + private LdapName dn; - private DistinguishedName base; + private LdapName base = LdapUtils.emptyLdapName(); private boolean updateMode = false; @@ -110,7 +114,7 @@ public class DirContextAdapter implements DirContextOperations { * exception will be thrown. */ public DirContextAdapter(String dnString) { - this(new DistinguishedName(dnString)); + this(LdapUtils.newLdapName(dnString)); } /** @@ -160,19 +164,21 @@ public class DirContextAdapter implements DirContextOperations { else { this.originalAttrs = new BasicAttributes(true); } - if (dn != null) { - this.dn = new DistinguishedName(dn); - } - else { - this.dn = new DistinguishedName(); - } - if (base != null) { - this.base = new DistinguishedName(base); - } - else { - this.base = new DistinguishedName(); - } - if (referralUrl != null) { + + if (dn != null) { + this.dn = LdapUtils.newLdapName(dn); + } + else { + this.dn = LdapUtils.emptyLdapName(); + } + if (base != null) { + this.base = LdapUtils.newLdapName(base); + } + else { + this.base = LdapUtils.emptyLdapName(); + } + + if (referralUrl != null) { this.referralUrl = referralUrl; } else { @@ -1265,9 +1271,17 @@ public class DirContextAdapter implements DirContextOperations { * @see javax.naming.Context#getNameInNamespace() */ public String getNameInNamespace() { - DistinguishedName result = new DistinguishedName(dn); - result.prepend(base); - return result.toString(); + if(base.size() == 0) { + return dn.toString(); + } + + try { + LdapName result = (LdapName) dn.clone(); + result.addAll(0, base); + return result.toString(); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } } /* @@ -1276,7 +1290,7 @@ public class DirContextAdapter implements DirContextOperations { * @see org.springframework.ldap.support.DirContextOperations#getDn() */ public Name getDn() { - return new DistinguishedName(dn); + return LdapUtils.newLdapName(dn); } /* @@ -1288,8 +1302,13 @@ public class DirContextAdapter implements DirContextOperations { */ public final void setDn(Name dn) { if (!updateMode) { - this.dn = new DistinguishedName(dn.toString()); - } + this.dn = new LdapName(Collections.emptyList()); + try { + this.dn.addAll(0, dn); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } + } else { throw new IllegalStateException( "Not possible to call setDn() on a DirContextAdapter in update mode"); 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 5745a363..63ebfc1b 100644 --- a/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java +++ b/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java @@ -91,6 +91,13 @@ import java.util.ListIterator; * true. * @author Adam Skogman * @author Mattias Hellborg Arthursson + * + * @deprecated As of 2.0 it is recommended to use {@link javax.naming.ldap.LdapName} along with + * utility methods in {@link LdapUtils} instead. + * @see javax.naming.ldap.LdapName + * @see LdapUtils#newLdapName(javax.naming.Name) + * @see LdapUtils#newLdapName(String) + * @see org.springframework.ldap.support.LdapUtils#emptyLdapName() */ public class DistinguishedName implements Name { /** diff --git a/core/src/main/java/org/springframework/ldap/core/DistinguishedNameEditor.java b/core/src/main/java/org/springframework/ldap/core/DistinguishedNameEditor.java index 32eaec78..1e0b1ca5 100644 --- a/core/src/main/java/org/springframework/ldap/core/DistinguishedNameEditor.java +++ b/core/src/main/java/org/springframework/ldap/core/DistinguishedNameEditor.java @@ -24,6 +24,7 @@ import java.beans.PropertyEditorSupport; * * @author Mattias Hellborg Arthursson * @since 1.2 + * @deprecated {@link DistinguishedName and associated classes are deprecated as of 2.0}. */ public class DistinguishedNameEditor extends PropertyEditorSupport { diff --git a/core/src/main/java/org/springframework/ldap/core/DnParser.java b/core/src/main/java/org/springframework/ldap/core/DnParser.java index 84e29e45..6e720557 100644 --- a/core/src/main/java/org/springframework/ldap/core/DnParser.java +++ b/core/src/main/java/org/springframework/ldap/core/DnParser.java @@ -19,7 +19,7 @@ package org.springframework.ldap.core; * A parser for RFC2253-compliant Distinguished Names. * * @author Mattias Hellborg Arthursson - * + * @deprecated {@link DistinguishedName and associated classes are deprecated as of 2.0}. */ public interface DnParser { /** diff --git a/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java index 3a257a1a..089aa665 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java @@ -15,10 +15,12 @@ */ package org.springframework.ldap.core; -import javax.naming.directory.DirContext; - +import org.springframework.ldap.support.LdapUtils; import org.springframework.util.Assert; +import javax.naming.directory.DirContext; +import javax.naming.ldap.LdapName; + /** * Wrapper class to handle the full identification of an LDAP entry. An LDAP * entry is identified by its Distinguished Name, in Spring LDAP represented by @@ -36,9 +38,9 @@ import org.springframework.util.Assert; * @author Mattias Hellborg Arthursson */ public class LdapEntryIdentification { - private final DistinguishedName relativeDn; + private final LdapName relativeDn; - private final DistinguishedName absoluteDn; + private final LdapName absoluteDn; /** * Construct an LdapEntryIdentification instance. @@ -46,30 +48,71 @@ public class LdapEntryIdentification { * returned by {@link DirContext#getNameInNamespace()}. * @param relativeDn the DN of the identified entry relative to the base * LDAP path, e.g. as returned by {@link DirContextOperations#getDn()}. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + * use {@link #LdapEntryIdentification(javax.naming.ldap.LdapName, javax.naming.ldap.LdapName)} instead. */ public LdapEntryIdentification(DistinguishedName absoluteDn, DistinguishedName relativeDn) { Assert.notNull(absoluteDn, "Absolute DN must not be null"); Assert.notNull(relativeDn, "Relative DN must not be null"); - this.absoluteDn = absoluteDn.immutableDistinguishedName(); - this.relativeDn = relativeDn.immutableDistinguishedName(); + this.absoluteDn = LdapUtils.newLdapName(absoluteDn); + this.relativeDn = LdapUtils.newLdapName(relativeDn); } - /** + /** + * Construct an LdapEntryIdentification instance. + * @param absoluteDn the absolute DN of the identified entry, e.g. as + * returned by {@link DirContext#getNameInNamespace()}. + * @param relativeDn the DN of the identified entry relative to the base + * LDAP path, e.g. as returned by {@link DirContextOperations#getDn()}. + * @since 2.0 + */ + public LdapEntryIdentification(LdapName absoluteDn, LdapName relativeDn) { + Assert.notNull(absoluteDn, "Absolute DN must not be null"); + Assert.notNull(relativeDn, "Relative DN must not be null"); + this.absoluteDn = LdapUtils.newLdapName(absoluteDn); + this.relativeDn = LdapUtils.newLdapName(relativeDn); + } + + /** + * Get the DN of the identified entry relative to the base LDAP path, e.g. + * as returned by {@link DirContextOperations#getDn()}. + * @return the relative DN. + * @since 2.0 + */ + public LdapName getAbsoluteName() { + return LdapUtils.newLdapName(absoluteDn); + } + + /** + * Get the absolute DN of the identified entry, e.g. as returned by + * {@link DirContext#getNameInNamespace()}. + * @return the absolute DN. + * @since 2.0 + */ + public LdapName getRelativeName() { + return LdapUtils.newLdapName(relativeDn); + } + + /** * Get the DN of the identified entry relative to the base LDAP path, e.g. * as returned by {@link DirContextOperations#getDn()}. * @return the relative DN. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + * use {@link #getRelativeName()} instead. */ public DistinguishedName getRelativeDn() { - return relativeDn; + return new DistinguishedName(relativeDn); } /** * Get the absolute DN of the identified entry, e.g. as returned by * {@link DirContext#getNameInNamespace()}. * @return the absolute DN. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + * use {@link #getAbsoluteName()} instead. */ public DistinguishedName getAbsoluteDn() { - return absoluteDn; + return new DistinguishedName(absoluteDn); } public boolean equals(Object obj) { diff --git a/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentificationContextMapper.java b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentificationContextMapper.java index 9c649e87..22d1072b 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentificationContextMapper.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentificationContextMapper.java @@ -15,6 +15,8 @@ */ package org.springframework.ldap.core; +import org.springframework.ldap.support.LdapUtils; + /** * ContextMapper implementation that maps the found entries to the * {@link LdapEntryIdentification} of each respective entry. @@ -26,7 +28,8 @@ public class LdapEntryIdentificationContextMapper implements ContextMapper { public Object mapFromContext(Object ctx) { DirContextOperations adapter = (DirContextOperations) ctx; - return new LdapEntryIdentification(new DistinguishedName(adapter.getNameInNamespace()), new DistinguishedName( - adapter.getDn())); + return new LdapEntryIdentification( + LdapUtils.newLdapName(adapter.getNameInNamespace()), + LdapUtils.newLdapName(adapter.getDn())); } } diff --git a/core/src/main/java/org/springframework/ldap/core/LdapOperations.java b/core/src/main/java/org/springframework/ldap/core/LdapOperations.java index 63532226..69dd26c5 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapOperations.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapOperations.java @@ -16,7 +16,11 @@ package org.springframework.ldap.core; -import java.util.List; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.ldap.ContextNotEmptyException; +import org.springframework.ldap.NamingException; +import org.springframework.ldap.core.support.AbstractContextSource; +import org.springframework.ldap.support.LdapUtils; import javax.naming.Binding; import javax.naming.Name; @@ -24,12 +28,7 @@ import javax.naming.NameClassPair; import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; - -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.ldap.ContextNotEmptyException; -import org.springframework.ldap.NamingException; -import org.springframework.ldap.core.support.AbstractContextSource; -import org.springframework.ldap.support.LdapUtils; +import java.util.List; /** * Interface that specifies a basic set of LDAP operations. Implemented by @@ -1314,7 +1313,7 @@ public interface LdapOperations { *
 	 * AndFilter filter = new AndFilter();
 	 * filter.and("objectclass", "person").and("uid", userId);
-	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * boolean authenticated = ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.toString(), password);
 	 * 
* * @param base the DN to use as the base of the search. @@ -1338,7 +1337,7 @@ public interface LdapOperations { *
 	 * AndFilter filter = new AndFilter();
 	 * filter.and("objectclass", "person").and("uid", userId);
-	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * boolean authenticated = ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.toString(), password);
 	 * 
* * @param base the DN to use as the base of the search. diff --git a/core/src/main/java/org/springframework/ldap/core/LdapRdn.java b/core/src/main/java/org/springframework/ldap/core/LdapRdn.java index a0a63403..e83baadd 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapRdn.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapRdn.java @@ -36,6 +36,7 @@ import java.util.Set; * * @author Adam Skogman * @author Mattias Hellborg Arthursson + * @deprecated {@link DistinguishedName and associated classes are deprecated as of 2.0}. */ public class LdapRdn implements Serializable, Comparable { private static final long serialVersionUID = 5681397547245228750L; diff --git a/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java b/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java index 5e3c7b63..2055cbcb 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java @@ -30,7 +30,7 @@ import java.net.URISyntaxException; * LdapRdnComponent represents one of these attributes. * * @author Mattias Hellborg Arthursson - * + * @deprecated {@link DistinguishedName and associated classes are deprecated as of 2.0}. */ public class LdapRdnComponent implements Comparable, Serializable { private static final long serialVersionUID = -3296747972616243038L; diff --git a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java index 0f99bbcb..559757c1 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -34,6 +34,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; +import javax.naming.ldap.LdapName; import java.util.List; /** @@ -950,7 +951,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { return executeReadOnly(new ContextExecutor() { public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { Attributes filteredAttributes = ctx.getAttributes(dn, attributes); - DistinguishedName name = new DistinguishedName(dn); + LdapName name = LdapUtils.newLdapName(dn); DirContextAdapter contextAdapter = new DirContextAdapter(filteredAttributes, name); return mapper.mapFromContext(contextAdapter); } @@ -1079,7 +1080,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { private void doUnbindRecursively(final Name dn) { executeReadWrite(new ContextExecutor() { public Object executeWithContext(DirContext ctx) { - deleteRecursively(ctx, new DistinguishedName(dn)); + deleteRecursively(ctx, LdapUtils.newLdapName(dn)); return null; } }); @@ -1088,7 +1089,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { private void doUnbindRecursively(final String dn) { executeReadWrite(new ContextExecutor() { public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { - deleteRecursively(ctx, new DistinguishedName(dn)); + deleteRecursively(ctx, LdapUtils.newLdapName(dn)); return null; } }); @@ -1101,15 +1102,15 @@ public class LdapTemplate implements LdapOperations, InitializingBean { * @param name The starting point to delete recursively. * @throws NamingException if any error occurs */ - protected void deleteRecursively(DirContext ctx, DistinguishedName name) { + protected void deleteRecursively(DirContext ctx, Name name) { NamingEnumeration enumeration = null; try { enumeration = ctx.listBindings(name); while (enumeration.hasMore()) { Binding binding = (Binding) enumeration.next(); - DistinguishedName childName = new DistinguishedName(binding.getName()); - childName.prepend((DistinguishedName) name); + LdapName childName = LdapUtils.newLdapName(binding.getName()); + childName.addAll(0, name); deleteRecursively(ctx, childName); } ctx.unbind(name); @@ -1395,7 +1396,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { * , java.lang.String, java.lang.String) */ public boolean authenticate(String base, String filter, String password) { - return authenticate(new DistinguishedName(base), filter, password, + return authenticate(LdapUtils.newLdapName(base), filter, password, new NullAuthenticatedLdapEntryContextCallback(), new NullAuthenticationErrorCallback()); } @@ -1410,7 +1411,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public boolean authenticate(String base, String filter, String password, AuthenticatedLdapEntryContextCallback callback) { - return authenticate(new DistinguishedName(base), filter, password, callback, new NullAuthenticationErrorCallback()); + return authenticate(LdapUtils.newLdapName(base), filter, password, callback, new NullAuthenticationErrorCallback()); } /* @@ -1436,7 +1437,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public boolean authenticate(String base, String filter, String password, AuthenticationErrorCallback errorCallback) { - return authenticate(new DistinguishedName(base), filter, password, new NullAuthenticatedLdapEntryContextCallback(), errorCallback); + return authenticate(LdapUtils.newLdapName(base), filter, password, new NullAuthenticatedLdapEntryContextCallback(), errorCallback); } /* @@ -1463,7 +1464,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public boolean authenticate(String base, String filter, String password, final AuthenticatedLdapEntryContextCallback callback, final AuthenticationErrorCallback errorCallback) { - return authenticate(new DistinguishedName(base), filter, password, callback, errorCallback); + return authenticate(LdapUtils.newLdapName(base), filter, password, callback, errorCallback); } /* @@ -1534,7 +1535,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { * .String, java.lang.String, org.springframework.ldap.core.ContextMapper) */ public Object searchForObject(String base, String filter, ContextMapper mapper) { - return searchForObject(new DistinguishedName(base), filter, mapper); + return searchForObject(LdapUtils.newLdapName(base), filter, mapper); } private static final class NullAuthenticatedLdapEntryContextCallback diff --git a/core/src/main/java/org/springframework/ldap/core/support/AbstractContextSource.java b/core/src/main/java/org/springframework/ldap/core/support/AbstractContextSource.java index f86b731f..5b74b37f 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/AbstractContextSource.java +++ b/core/src/main/java/org/springframework/ldap/core/support/AbstractContextSource.java @@ -16,21 +16,31 @@ package org.springframework.ldap.core.support; -import org.springframework.util.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.JdkVersion; +import org.springframework.ldap.UncategorizedLdapException; import org.springframework.ldap.core.AuthenticationSource; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapEncoder; import org.springframework.ldap.support.LdapUtils; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; import javax.naming.Context; +import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Hashtable; +import java.util.ListIterator; import java.util.Map; /** @@ -74,7 +84,7 @@ public abstract class AbstractContextSource implements BaseLdapPathContextSource private Class contextFactory = DEFAULT_CONTEXT_FACTORY; - private DistinguishedName base = DistinguishedName.EMPTY_PATH; + private LdapName base = LdapUtils.emptyLdapName(); protected String userDn = ""; @@ -204,17 +214,76 @@ public abstract class AbstractContextSource implements BaseLdapPathContextSource StringBuffer providerUrlBuffer = new StringBuffer(1024); for (int i = 0; i < ldapUrls.length; i++) { providerUrlBuffer.append(ldapUrls[i]); - if (!DistinguishedName.EMPTY_PATH.equals(base)) { + if (!base.isEmpty()) { if (!ldapUrls[i].endsWith("/")) { providerUrlBuffer.append("/"); } } - providerUrlBuffer.append(base.toUrl()); + providerUrlBuffer.append(formatForUrl(base)); providerUrlBuffer.append(' '); } return providerUrlBuffer.toString().trim(); } + static String formatForUrl(LdapName ldapName) { + StringBuilder sb = new StringBuilder(); + ListIterator it = ldapName.getRdns().listIterator(ldapName.size()); + while (it.hasPrevious()) { + Rdn component = it.previous(); + + Attributes attributes = component.toAttributes(); + + // Loop through all attribute of the rdn (usually just one, but more are supported by RFC) + NamingEnumeration allAttributes = attributes.getAll(); + while(allAttributes.hasMoreElements()) { + Attribute oneAttribute = allAttributes.nextElement(); + String encodedAttributeName = nameEncodeForUrl(oneAttribute.getID()); + + // Loop through all values of the attribute (usually just one, but more are supported by RFC) + NamingEnumeration allValues; + try { + allValues = oneAttribute.getAll(); + } catch (NamingException e) { + throw new UncategorizedLdapException("Unexpected error occurred formatting base URL", e); + } + + while(allValues.hasMoreElements()) { + sb.append(encodedAttributeName).append('='); + + Object oneValue = allValues.nextElement(); + if (oneValue instanceof String) { + String oneString = (String) oneValue; + sb.append(nameEncodeForUrl(oneString)); + } else { + throw new IllegalArgumentException("Binary attributes not supported for base URL"); + } + + if(allValues.hasMoreElements()) { + sb.append('+'); + } + } + if(allAttributes.hasMoreElements()) { + sb.append('+'); + } + } + + if(it.hasPrevious()) { + sb.append(','); + } + } + return sb.toString(); + } + + static String nameEncodeForUrl(String value) { + try { + String ldapEncoded = LdapEncoder.nameEncode(value); + URI valueUri = new URI(null, null, ldapEncoded, null); + return valueUri.toString(); + } catch (URISyntaxException e) { + throw new UncategorizedLdapException("This really shouldn't happen - report this", e); + } + } + /** * Set the base suffix from which all operations should origin. If a base * suffix is set, you will not have to (and, indeed, must not) specify the @@ -223,39 +292,35 @@ public abstract class AbstractContextSource implements BaseLdapPathContextSource * @param base the base suffix. */ public void setBase(String base) { - this.base = new DistinguishedName(base); - } + if (base != null) { + this.base = LdapUtils.newLdapName(base); + } else { + this.base = LdapUtils.emptyLdapName(); + } + } - /** - * Get the base suffix from which all operations should originate. If a base - * suffix is set, you will not have to (and, indeed, must not) specify the - * full distinguished names in any operations performed. - * - * @return the base suffix - */ - protected DistinguishedName getBase() { + /** + * @return + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + */ + @Override + public DistinguishedName getBaseLdapPath() { return new DistinguishedName(base); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.ldap.core.support.BaseLdapPathSource#getBaseLdapPath - * () - */ - public DistinguishedName getBaseLdapPath() { - return getBase().immutableDistinguishedName(); - } + @Override + public LdapName getBaseLdapName() { + return (LdapName) base.clone(); + } - /* - * (non-Javadoc) - * - * @seeorg.springframework.ldap.core.support.BaseLdapPathSource# - * getBaseLdapPathAsString() - */ + /* + * (non-Javadoc) + * + * @seeorg.springframework.ldap.core.support.BaseLdapPathSource# + * getBaseLdapPathAsString() + */ public String getBaseLdapPathAsString() { - return getBaseLdapPath().toString(); + return getBaseLdapName().toString(); } /** @@ -339,7 +404,7 @@ public abstract class AbstractContextSource implements BaseLdapPathContextSource throw new IllegalArgumentException("At least one server url must be set"); } - if (!DistinguishedName.EMPTY_PATH.equals(base) && getJdkVersion().compareTo(JDK_142) < 0) { + if (!base.isEmpty() && getJdkVersion().compareTo(JDK_142) < 0) { throw new IllegalArgumentException("Base path is not supported for JDK versions < 1.4.2"); } @@ -382,7 +447,7 @@ public abstract class AbstractContextSource implements BaseLdapPathContextSource env.put(Context.REFERRAL, referral); } - if (!DistinguishedName.EMPTY_PATH.equals(base)) { + if (!base.isEmpty()) { // Save the base path for use in the DefaultDirObjectFactory. env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base); } diff --git a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapNameAware.java b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapNameAware.java new file mode 100644 index 00000000..787d71c9 --- /dev/null +++ b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapNameAware.java @@ -0,0 +1,49 @@ +/* + * Copyright 2005-2013 the original author or authors. + * + * 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 org.springframework.ldap.core.support; + +import javax.naming.ldap.LdapName; + +/** + * Interface to be implemented by classes that want to have access to the base + * context used in the active ContextSource. There are several + * cases in which services may want to have access to the base context, e.g. + * when working with groups (groupOfNames objectclass), in which + * case the full DN of each group member needs to be specified in the attribute + * value. + *

+ * If a class implements this interface and a + * {@link BaseLdapPathBeanPostProcessor} is defined in the + * ApplicationContext, the default base path will automatically + * passed to the {@link #setBaseLdapPath(javax.naming.ldap.LdapName)} method on + * initialization. + *

+ * NB:The ContextSource needs to be a subclass of + * {@link AbstractContextSource} for this mechanism to work. + * + * + * @author Mattias Hellborg Arthursson + * @since 2.0 + */ +public interface BaseLdapNameAware { + /** + * Set the base LDAP path specified in the current + * ApplicationContext. + * @param baseLdapPath the base path used in the ContextSource + */ + void setBaseLdapPath(LdapName baseLdapPath); +} diff --git a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathAware.java b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathAware.java index 84aa720a..4ab07747 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathAware.java +++ b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathAware.java @@ -37,6 +37,8 @@ import org.springframework.ldap.core.DistinguishedName; * * @author Mattias Hellborg Arthursson * @since 1.2 + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + * Use {@link BaseLdapNameAware} instead. */ public interface BaseLdapPathAware { diff --git a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java index dff8cead..1a97b920 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java +++ b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java @@ -23,13 +23,17 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.Ordered; import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.support.LdapUtils; import org.springframework.util.StringUtils; +import javax.naming.ldap.LdapName; + /** * This BeanPostProcessor checks each bean if it implements - * {@link BaseLdapPathAware}. If it does, the default context base LDAP path - * will be determined, and that value will be injected to the - * {@link BaseLdapPathAware#setBaseLdapPath(DistinguishedName)} method of the + * {@link BaseLdapNameAware} or {@link BaseLdapPathAware}. + * If it does, the default context base LDAP path will be determined, + * and that value will be injected to the {@link BaseLdapNameAware#setBaseLdapPath(javax.naming.ldap.LdapName)} + * or {@link BaseLdapPathAware#setBaseLdapPath(DistinguishedName)} method of the * processed bean. *

* If the baseLdapPath property of this @@ -52,18 +56,28 @@ public class BaseLdapPathBeanPostProcessor implements BeanPostProcessor, Applica private ApplicationContext applicationContext; - private DistinguishedName basePath; + private LdapName basePath; private String baseLdapPathSourceName; private int order = Ordered.LOWEST_PRECEDENCE; public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof BaseLdapPathAware) { + if(bean instanceof BaseLdapNameAware) { + BaseLdapNameAware baseLdapNameAware = (BaseLdapNameAware) bean; + + if (basePath != null) { + baseLdapNameAware.setBaseLdapPath(LdapUtils.newLdapName(basePath)); + } + else { + BaseLdapPathSource ldapPathSource = getBaseLdapPathSourceFromApplicationContext(); + baseLdapNameAware.setBaseLdapPath(LdapUtils.newLdapName(ldapPathSource.getBaseLdapName())); + } + } else if (bean instanceof BaseLdapPathAware) { BaseLdapPathAware baseLdapPathAware = (BaseLdapPathAware) bean; if (basePath != null) { - baseLdapPathAware.setBaseLdapPath(basePath); + baseLdapPathAware.setBaseLdapPath(new DistinguishedName(basePath)); } else { BaseLdapPathSource ldapPathSource = getBaseLdapPathSourceFromApplicationContext(); @@ -110,11 +124,16 @@ public class BaseLdapPathBeanPostProcessor implements BeanPostProcessor, Applica * ApplicationContext. * * @param basePath the base path. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. */ public void setBasePath(DistinguishedName basePath) { - this.basePath = basePath.immutableDistinguishedName(); + this.basePath = LdapUtils.newLdapName(basePath); } + public void setBasePath(String basePath) { + this.basePath = LdapUtils.newLdapName(basePath); + } + /** * Set the name of the ContextSource bean to use for getting * the base path. This method is typically useful if several ContextSource diff --git a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathSource.java b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathSource.java index 89539846..f3a23e4e 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathSource.java +++ b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathSource.java @@ -18,6 +18,8 @@ package org.springframework.ldap.core.support; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.DistinguishedName; +import javax.naming.ldap.LdapName; + /** * Implementations of this interface are capable of providing a base LDAP path. * The base LDAP path is the root path to which all LDAP operations performed on @@ -33,9 +35,20 @@ public interface BaseLdapPathSource { * * @return the base LDAP path as a {@link DistinguishedName}. The path will * be empty if no base path is specified. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + * Use {@link #getBaseLdapName()} instead. */ DistinguishedName getBaseLdapPath(); + /** + * Get the base LDAP path as a {@link LdapName}. + * + * @return the base LDAP path as a {@link LdapName}. The path will + * be empty if no base path is specified. + * @since 2.0 + */ + LdapName getBaseLdapName(); + /** * Get the base LDAP path as a String. * diff --git a/core/src/main/java/org/springframework/ldap/core/support/DefaultDirObjectFactory.java b/core/src/main/java/org/springframework/ldap/core/support/DefaultDirObjectFactory.java index f7a9cb58..c70f3400 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/DefaultDirObjectFactory.java +++ b/core/src/main/java/org/springframework/ldap/core/support/DefaultDirObjectFactory.java @@ -16,23 +16,21 @@ package org.springframework.ldap.core.support; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Hashtable; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.JdkVersion; +import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.support.LdapUtils; +import org.springframework.util.StringUtils; import javax.naming.CompositeName; import javax.naming.Context; import javax.naming.Name; import javax.naming.directory.Attributes; import javax.naming.spi.DirObjectFactory; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.core.JdkVersion; -import org.springframework.ldap.core.DirContextAdapter; -import org.springframework.ldap.core.DistinguishedName; -import org.springframework.ldap.support.LdapUtils; -import org.springframework.util.StringUtils; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Hashtable; /** * Default implementation of the DirObjectFactory interface. Creates a @@ -138,7 +136,7 @@ public class DefaultDirObjectFactory implements DirObjectFactory { if (nameString.startsWith(LDAP_PROTOCOL_PREFIX) || nameString.startsWith(LDAPS_PROTOCOL_PREFIX)) { if (log.isDebugEnabled()) { log.debug("Received name '" + nameString + "' contains protocol delimiter; indicating a referral." - + "Stripping protocol and address info to enable construction of a proper DistinguishedName"); + + "Stripping protocol and address info to enable construction of a proper LdapName"); } try { URI url = new URI(nameString); @@ -171,12 +169,11 @@ public class DefaultDirObjectFactory implements DirObjectFactory { } } - DirContextAdapter dirContextAdapter = new DirContextAdapter(attrs, new DistinguishedName(nameString), - new DistinguishedName(nameInNamespace), referralUrl); - dirContextAdapter.setUpdateMode(true); - - return dirContextAdapter; - } + DirContextAdapter dirContextAdapter = new DirContextAdapter(attrs, LdapUtils.newLdapName(nameString), + LdapUtils.newLdapName(nameInNamespace), referralUrl); + dirContextAdapter.setUpdateMode(true); + return dirContextAdapter; + } /* * (non-Javadoc) diff --git a/core/src/main/java/org/springframework/ldap/core/support/DefaultIncrementalAttributesMapper.java b/core/src/main/java/org/springframework/ldap/core/support/DefaultIncrementalAttributesMapper.java index 9ff85438..09652313 100644 --- a/core/src/main/java/org/springframework/ldap/core/support/DefaultIncrementalAttributesMapper.java +++ b/core/src/main/java/org/springframework/ldap/core/support/DefaultIncrementalAttributesMapper.java @@ -19,9 +19,9 @@ package org.springframework.ldap.core.support; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.ldap.core.AttributesMapper; -import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.IncrementalAttributesMapper; import org.springframework.ldap.core.LdapOperations; +import org.springframework.ldap.support.LdapUtils; import javax.naming.Name; import javax.naming.NamingEnumeration; @@ -261,7 +261,7 @@ public class DefaultIncrementalAttributesMapper implements AttributesMapper, Inc * set on the requested object. */ public static Attributes lookupAttributes(LdapOperations ldapOperations, String dn, String attribute) { - return lookupAttributes(ldapOperations, new DistinguishedName(dn), attribute); + return lookupAttributes(ldapOperations, LdapUtils.newLdapName(dn), attribute); } /** @@ -275,7 +275,7 @@ public class DefaultIncrementalAttributesMapper implements AttributesMapper, Inc * set on the requested object. */ public static Attributes lookupAttributes(LdapOperations ldapOperations, String dn, String[] attributes) { - return lookupAttributes(ldapOperations, new DistinguishedName(dn), attributes); + return lookupAttributes(ldapOperations, LdapUtils.newLdapName(dn), attributes); } /** @@ -316,7 +316,7 @@ public class DefaultIncrementalAttributesMapper implements AttributesMapper, Inc * Never null, an empty list indicates that the attribute was not set or empty. */ public static List lookupAttributeValues(LdapOperations ldapOperations, String dn, String attribute) { - return lookupAttributeValues(ldapOperations, new DistinguishedName(dn), attribute); + return lookupAttributeValues(ldapOperations, LdapUtils.newLdapName(dn), attribute); } /** diff --git a/core/src/main/java/org/springframework/ldap/support/LdapUtils.java b/core/src/main/java/org/springframework/ldap/support/LdapUtils.java index b99ebcf8..7e3aeca2 100644 --- a/core/src/main/java/org/springframework/ldap/support/LdapUtils.java +++ b/core/src/main/java/org/springframework/ldap/support/LdapUtils.java @@ -23,13 +23,19 @@ import org.springframework.ldap.NoSuchAttributeException; import org.springframework.util.Assert; import javax.naming.CompositeName; +import javax.naming.InvalidNameException; +import javax.naming.Name; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.ldap.LdapContext; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import java.math.BigInteger; import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.NoSuchElementException; /** * Generic utility methods for working with LDAP. Mainly for internal use within @@ -274,7 +280,7 @@ public final class LdapUtils { } } - /** + /** * An {@link AttributeValueCallbackHandler} to collect values in a supplied * collection. * @@ -312,6 +318,124 @@ public final class LdapUtils { } } + /** + * Construct a new LdapName instance from the supplied Name instance. + * LdapName instances will be cloned, CompositeName tweaks will be managed using + * {@link #convertCompositeNameToString(javax.naming.CompositeName)}; for all other Name + * implementations, new LdapName instances are constructed using {@link LdapName#addAll(int, javax.naming.Name)}. + * + * @param name the Name instance to convert to LdapName, not null. + * @return a new LdapName representing the same Distinguished Name as the supplied instance. + * @throws org.springframework.ldap.InvalidNameException to wrap any InvalidNameExceptions thrown by LdapName. + * @since 2.0 + */ + public static LdapName newLdapName(Name name) { + Assert.notNull(name, "name must not be null"); + if(name instanceof LdapName) { + return (LdapName) name.clone(); + } else if (name instanceof CompositeName) { + CompositeName compositeName = (CompositeName) name; + + try { + return new LdapName(convertCompositeNameToString(compositeName)); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } + } else { + LdapName result = emptyLdapName(); + try { + result.addAll(0, name); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } + + return result; + } + } + + /** + * Construct a new LdapName instance from the supplied distinguished name string. + * + * @param distinguishedName the string to parse for constructing an LdapName instance. + * @return a new LdapName instance. + * @throws org.springframework.ldap.InvalidNameException to wrap any InvalidNameExceptions thrown by LdapName. + * @since 2.0 + */ + public static LdapName newLdapName(String distinguishedName) { + Assert.notNull(distinguishedName, "distinguishedName must not be null"); + + try { + return new LdapName(distinguishedName); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } + } + + + /** + * Remove the supplied path from the beginning of this + * LdapName if this instance starts with + * path. Useful for stripping base path suffix from a + * LdapName. The original LdapName will not be affected. + * + * @param dn the dn to strip from. + * @param path the path to remove from the beginning of this instance. + * @return a copy of the original LdapName with the specified path stripped from its beginning. + * @since 2.0 + */ + public static LdapName removeFirst(LdapName dn, LdapName path) { + Assert.notNull(dn, "dn must not be null"); + Assert.notNull(path, "path must not be null"); + + LdapName result = newLdapName(dn); + + if(path.size() == 0 || !dn.startsWith(path)) { + return result; + } + + for(int i = 0; i < path.size(); i++) { + try { + result.remove(0); + } catch (InvalidNameException e) { + throw new org.springframework.ldap.InvalidNameException(e); + } + } + + return result; + } + + /** + * Construct a new, empty LdapName instance. + * @return a new LdapName instance representing the empty path (""). + * @since 2.0 + */ + public static LdapName emptyLdapName() { + return newLdapName(""); + } + + /** + * Find the Rdn with the requested key in the supplied LdapName. + * + * @param name the LdapName in which to search for the key. + * @param key the attribute key to search for. + * @return the rdn corresponding to the first occurrence of the requested key. + * @throws NoSuchElementException if no corresponding entry is found. + * @since 2.0 + */ + public static Rdn getRdn(LdapName name, String key) { + Assert.notNull(name, "name must not be null"); + Assert.hasText(key, "key must not be blank"); + + List rdns = name.getRdns(); + for (Rdn rdn : rdns) { + if(rdn.getType().equalsIgnoreCase(key)) { + return rdn; + } + } + + throw new NoSuchElementException("No Rdn with the requested key: '" + key + "'"); + } + /** * Converts a binary SID to its String representation, according to the * algorithm described * While DNs appear to be and can be treated as attributes, they have a special * meaning in that they define the address to which the object is bound. DNs must - * conform to special formating rules and are typically required to be handled + * conform to special formatting rules and are typically required to be handled * separately from other attributes. *

* This class makes this distinction between the DN and other @@ -56,7 +56,7 @@ public class LdapAttributes extends BasicAttributes { /** * Distinguished name to which the object is bound. */ - protected DistinguishedName dn = new DistinguishedName(); + protected LdapName dn = LdapUtils.emptyLdapName(); /** * Default constructor. @@ -65,99 +65,47 @@ public class LdapAttributes extends BasicAttributes { } - /** - * Creates an LdapAttributes object with the specified DN. - * - * @param dn The {@link org.springframework.ldap.core.DistinguishedName} to which this object is bound. - */ - public LdapAttributes(DistinguishedName dn) { - super(); - this.dn = dn; - } - /** * Constructor for specifying whether or not the object is case sensitive. - * + * * @param ignoreCase boolean indicator. */ public LdapAttributes(boolean ignoreCase) { super(ignoreCase); } - /** - * Creates an LdapAttributes object with the specified DN and case sensitivity setting. - * - * @param dn The {@link org.springframework.ldap.core.DistinguishedName} to which this object is bound. - * @param ignoreCase boolean indicator. - */ - public LdapAttributes(DistinguishedName dn, boolean ignoreCase) { - super(ignoreCase); - this.dn = dn; - } - - /** - * Creates an LdapAttributes object with the specified attribute. - * - * @param attrID {@link java.lang.String} ID of the attribute. - * @param val Value of the attribute. - */ - public LdapAttributes(String attrID, Object val) { - put(new LdapAttribute(attrID, val)); - } - - /** - * Creates an LdapAttributes object with the specifying attribute and value and case sensitivity setting. - * - * @param dn The {@link org.springframework.ldap.core.DistinguishedName} to which this object is bound. - * @param attrID {@link java.lang.String} ID of the attribute. - * @param val Value of the attribute. - */ - public LdapAttributes(DistinguishedName dn, String attrID, Object val) { - this.dn = dn; - put(new LdapAttribute(attrID, val)); - } - - /** - * Creates an LdapAttributes object with the specifying attribute and value and case sensitivity setting. - * - * @param attrID {@link java.lang.String} ID of the attribute. - * @param val Value of the attribute. - * @param ignoreCase boolean indicator. - */ - public LdapAttributes(String attrID, Object val, boolean ignoreCase) { - put(new LdapAttribute(attrID, val, ignoreCase)); - } - - /** - * Creates an LdapAttributes object for the supplied DN with the attribute specified. - * - * @param dn The {@link org.springframework.ldap.core.DistinguishedName} to which this object is bound. - * @param attrID {@link java.lang.String} ID of the attribute. - * @param val Value of the attribute. - * @param ignoreCase boolean indicator. - */ - public LdapAttributes(DistinguishedName dn, String attrID, Object val, boolean ignoreCase) { - this.dn = dn; - put(new LdapAttribute(attrID, val, ignoreCase)); - } - /** * Returns the distinguished name to which the object is bound. * * @return {@link org.springframework.ldap.core.DistinguishedName} specifying the name to which the object is bound. + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. */ public DistinguishedName getDN() { - return dn; + return new DistinguishedName(dn); } - + + /** + * Returns the distinguished name to which the object is bound. + * + * @return {@link LdapName} specifying the name to which the object is bound. + */ + public LdapName getName() { + return LdapUtils.newLdapName(dn); + } + /** * Sets the distinguished name of the object. * * @param dn {@link org.springframework.ldap.core.DistinguishedName} specifying the name to which the object is bound. - */ + * @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}. + */ public void setDN(DistinguishedName dn) { - this.dn = dn; + this.dn = LdapUtils.newLdapName(dn); } + + public void setName(Name name) { + this.dn = LdapUtils.newLdapName(name); + } /** * Returns a string representation of the object in LDIF format. diff --git a/ldif/ldif-core/src/main/java/org/springframework/ldap/ldif/parser/LdifParser.java b/ldif/ldif-core/src/main/java/org/springframework/ldap/ldif/parser/LdifParser.java index 33d9c32f..4bbc57e4 100644 --- a/ldif/ldif-core/src/main/java/org/springframework/ldap/ldif/parser/LdifParser.java +++ b/ldif/ldif-core/src/main/java/org/springframework/ldap/ldif/parser/LdifParser.java @@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; -import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapAttributes; import org.springframework.ldap.ldif.InvalidRecordFormatException; import org.springframework.ldap.ldif.support.AttributeValidationPolicy; @@ -30,6 +29,7 @@ import org.springframework.ldap.ldif.support.LineIdentifier; import org.springframework.ldap.ldif.support.SeparatorPolicy; import org.springframework.ldap.schema.DefaultSchemaSpecification; import org.springframework.ldap.schema.Specification; +import org.springframework.ldap.support.LdapUtils; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -338,7 +338,7 @@ public class LdifParser implements Parser, InitializingBean { dn = (String) attribute.get(); } - record.setDN(new DistinguishedName(dn)); + record.setName(LdapUtils.newLdapName(dn)); } else { log.trace("...adding attribute to record."); diff --git a/odm/src/test/java/org/springframework/ldap/odm/test/TestLdap.java b/odm/src/test/java/org/springframework/ldap/odm/test/TestLdap.java index 0244d246..4dd4802d 100755 --- a/odm/src/test/java/org/springframework/ldap/odm/test/TestLdap.java +++ b/odm/src/test/java/org/springframework/ldap/odm/test/TestLdap.java @@ -51,6 +51,7 @@ import org.springframework.ldap.odm.typeconversion.impl.Converter; import org.springframework.ldap.odm.typeconversion.impl.ConverterManagerImpl; import org.springframework.ldap.odm.typeconversion.impl.converters.FromStringConverter; import org.springframework.ldap.odm.typeconversion.impl.converters.ToStringConverter; +import org.springframework.ldap.support.LdapUtils; import org.springframework.ldap.test.LdapTestUtils; import org.springframework.util.CollectionUtils; @@ -222,21 +223,21 @@ public final class TestLdap { } private Person[] personTestData=new Person[] { - new Person(new DistinguishedName("cn=William Hartnell,ou=Doctors,o=Whoniverse"), "Hartnell", Arrays + new Person(LdapUtils.newLdapName("cn=William Hartnell,ou=Doctors,o=Whoniverse"), "Hartnell", Arrays .asList(new String[] { "First Doctor", "Grumpy" }), 1, null), - new Person(new DistinguishedName("cn=Patrick Troughton,ou=Doctors,o=Whoniverse"), "Troughton", Arrays + new Person(LdapUtils.newLdapName("cn=Patrick Troughton,ou=Doctors,o=Whoniverse"), "Troughton", Arrays .asList(new String[] { "Second Doctor", "Clown" }), 2, null), - new Person(new DistinguishedName("cn=Jon Pertwee,ou=Doctors,o=Whoniverse"), "Pertwee", Arrays + new Person(LdapUtils.newLdapName("cn=Jon Pertwee,ou=Doctors,o=Whoniverse"), "Pertwee", Arrays .asList(new String[] { "Third Doctor", "Dandy" }), 3, null), - new Person(new DistinguishedName("cn=Tom Baker,ou=Doctors,o=Whoniverse"), "Baker", Arrays + new Person(LdapUtils.newLdapName("cn=Tom Baker,ou=Doctors,o=Whoniverse"), "Baker", Arrays .asList(new String[] { "Fourth Doctor", "The one and only!" }), 4, null), - new Person(new DistinguishedName("cn=Peter Davison,ou=Doctors,o=Whoniverse"), "Davison", Arrays + new Person(LdapUtils.newLdapName("cn=Peter Davison,ou=Doctors,o=Whoniverse"), "Davison", Arrays .asList(new String[] { "Fifth Doctor" }), 5, null), - new Person(new DistinguishedName("cn=Davros,ou=Enemies,o=Whoniverse"), "Unknown", Arrays + new Person(LdapUtils.newLdapName("cn=Davros,ou=Enemies,o=Whoniverse"), "Unknown", Arrays .asList(new String[] { "Creator of the Daleks", "Kaled head scientist" }), 0, null), - new Person(new DistinguishedName("cn=Daleks,ou=Enemies,o=Whoniverse"), "NA", Arrays + new Person(LdapUtils.newLdapName("cn=Daleks,ou=Enemies,o=Whoniverse"), "NA", Arrays .asList(new String[] { "The Doctor's greatest foe" }), 0, null), - new Person(new DistinguishedName("cn=Master,ou=Enemies,o=Whoniverse"), "Unknown", Arrays + new Person(LdapUtils.newLdapName("cn=Master,ou=Enemies,o=Whoniverse"), "Unknown", Arrays .asList(new String[] { "An evil Time Lord" }), 0, photo), }; @@ -313,9 +314,9 @@ public final class TestLdap { } private static OrganizationalUnit ouTestData[]=new OrganizationalUnit[] { - new OrganizationalUnit(new DistinguishedName("ou=Enemies,o=Whoniverse"), "Acacia Avenue", "The bad guys"), - new OrganizationalUnit(new DistinguishedName("ou=Assistants,o=Whoniverse"), "Somewhere in space", "The plucky helpers"), - new OrganizationalUnit(new DistinguishedName("ou=Doctors,o=Whoniverse"), "Somewhere in time", "Our hero"), + new OrganizationalUnit(LdapUtils.newLdapName("ou=Enemies,o=Whoniverse"), "Acacia Avenue", "The bad guys"), + new OrganizationalUnit(LdapUtils.newLdapName("ou=Assistants,o=Whoniverse"), "Somewhere in space", "The plucky helpers"), + new OrganizationalUnit(LdapUtils.newLdapName("ou=Doctors,o=Whoniverse"), "Somewhere in time", "Our hero"), }; // Check everything works OK with a second managed class @@ -375,11 +376,11 @@ public final class TestLdap { } private Person[] createTestData = { - new Person(new DistinguishedName("cn=Colin Baker,ou=Doctors,o=Whoniverse"), "Baker", Arrays + new Person(LdapUtils.newLdapName("cn=Colin Baker,ou=Doctors,o=Whoniverse"), "Baker", Arrays .asList(new String[] { "Sixth Doctor" }), 6, null), - new Person(new DistinguishedName("cn=Sylvester McCoy,ou=Doctors,o=Whoniverse"), "McCoy", Arrays + new Person(LdapUtils.newLdapName("cn=Sylvester McCoy,ou=Doctors,o=Whoniverse"), "McCoy", Arrays .asList(new String[] { "Seventh Doctor" }), 7, null), - new Person(new DistinguishedName("cn=Paul McGann,ou=Doctors,o=Whoniverse"), "McGann", Arrays + new Person(LdapUtils.newLdapName("cn=Paul McGann,ou=Doctors,o=Whoniverse"), "McGann", Arrays .asList(new String[] { "Eigth Doctor" }), 8, photo), }; // Create some entries, read them back and check they are what we'd expect. diff --git a/odm/src/test/java/org/springframework/ldap/odm/test/TestSchemaToJava.java b/odm/src/test/java/org/springframework/ldap/odm/test/TestSchemaToJava.java index 12fcbfb6..c4d513b8 100755 --- a/odm/src/test/java/org/springframework/ldap/odm/test/TestSchemaToJava.java +++ b/odm/src/test/java/org/springframework/ldap/odm/test/TestSchemaToJava.java @@ -35,8 +35,10 @@ import org.springframework.ldap.odm.typeconversion.impl.Converter; import org.springframework.ldap.odm.typeconversion.impl.ConverterManagerImpl; import org.springframework.ldap.odm.typeconversion.impl.converters.FromStringConverter; import org.springframework.ldap.odm.typeconversion.impl.converters.ToStringConverter; +import org.springframework.ldap.support.LdapUtils; import org.springframework.ldap.test.LdapTestUtils; +import javax.naming.ldap.LdapName; import java.io.File; import java.lang.reflect.Method; import java.net.URL; @@ -185,8 +187,8 @@ public final class TestSchemaToJava { odmManager.addManagedClass(clazz); // And try reading from the directory using it - DistinguishedName testDn=new DistinguishedName(baseName); - testDn.addAll(new DistinguishedName("cn=William Hartnell,ou=Doctors")); + LdapName testDn= LdapUtils.newLdapName(baseName); + testDn.addAll(LdapUtils.newLdapName("cn=William Hartnell,ou=Doctors")); Object fromDirectory=odmManager.read(clazz, testDn); LOG.debug(String.format("Read - %1$s", fromDirectory)); diff --git a/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java b/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java index 040dec03..5f192ad0 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java +++ b/test-support/src/main/java/org/springframework/ldap/test/LdapTestUtils.java @@ -25,6 +25,7 @@ import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapAttributes; import org.springframework.ldap.core.support.DefaultDirObjectFactory; import org.springframework.ldap.ldif.parser.LdifParser; +import org.springframework.ldap.support.LdapUtils; import javax.naming.Binding; import javax.naming.Context; @@ -36,6 +37,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; +import javax.naming.ldap.LdapName; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -235,7 +237,7 @@ public class LdapTestUtils { private static void loadLdif(DirContext context, Resource ldifFile) throws IOException { try { - DistinguishedName baseDn = (DistinguishedName) + LdapName baseDn = (LdapName) context.getEnvironment().get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY); LdifParser parser = new LdifParser(ldifFile); @@ -243,28 +245,16 @@ public class LdapTestUtils { while (parser.hasMoreRecords()) { LdapAttributes record = parser.getRecord(); - DistinguishedName dn = record.getDN(); + LdapName dn = record.getName(); + if(baseDn != null) { - dn.removeFirst(baseDn); + dn = LdapUtils.removeFirst(dn, baseDn); } context.bind(dn, null, record); } } catch (NamingException e) { throw new RuntimeException("Failed to populate LDIF", e); } - - -// -// try { -// DefaultDirectoryService directoryService = -// (DefaultDirectoryService) context.getEnvironment().get(DIRECTORY_SERVICE_KEY); -// if(directoryService == null) { -// throw new IllegalStateException("The specified context does not appear to have been created by LdapTestUtils"); -// } -// loadLdif(directoryService, ldifFile); -// } catch (NamingException e) { -// throw new RuntimeException("Failed to get environment", e); -// } } public static void loadLdif(DefaultDirectoryService directoryService, Resource ldifFile) throws IOException { diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/InvalidBackslashITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/InvalidBackslashITest.java index f00740fe..23018ebe 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/InvalidBackslashITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/InvalidBackslashITest.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,24 @@ package org.springframework.ldap; -import static junit.framework.Assert.assertEquals; - -import java.util.List; - -import javax.naming.InvalidNameException; - import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextOperations; -import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.AbstractContextMapper; +import org.springframework.ldap.support.LdapUtils; import org.springframework.test.context.ContextConfiguration; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; +import java.util.List; + +import static junit.framework.Assert.assertEquals; + /** * Integration tests for verifying that issues LDAP-50 and LDAP-109 are solved. * @@ -44,7 +45,7 @@ public class InvalidBackslashITest extends AbstractLdapTemplateIntegrationTest { @Autowired private LdapTemplate tested; - private static DistinguishedName DN = new DistinguishedName("cn=Some\\\\Person6,ou=company1,c=Sweden"); + private static LdapName DN = LdapUtils.newLdapName("cn=Some\\\\Person6,ou=company1,c=Sweden"); @Before public void prepareTestedInstance() throws Exception { @@ -94,9 +95,10 @@ public class InvalidBackslashITest extends AbstractLdapTemplateIntegrationTest { List result = tested.search("", "(sn=Person6)", new AbstractContextMapper() { @Override protected Object doMapFromContext(DirContextOperations ctx) { - DistinguishedName dn = (DistinguishedName) ctx.getDn(); - assertEquals("cn=Some\\\\Person6,ou=company1,c=Sweden", dn.toString()); - assertEquals("Some\\Person6", dn.getLdapRdn("cn").getValue()); + LdapName dn = (LdapName) ctx.getDn(); + Rdn rdn = LdapUtils.getRdn(dn, "cn"); + assertEquals("cn=Some\\\\Person6,ou=company1,c=Sweden", dn.toString()); + assertEquals("Some\\Person6", rdn.getValue()); return new Object(); } }); diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateLookupITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateLookupITest.java index 20e252dc..f8bc3c04 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateLookupITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateLookupITest.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,6 @@ package org.springframework.ldap; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNull; - -import javax.naming.NamingException; -import javax.naming.directory.Attributes; - -import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.core.AttributesMapper; @@ -34,8 +27,16 @@ import org.springframework.ldap.core.support.AbstractContextSource; import org.springframework.ldap.itest.Person; import org.springframework.ldap.itest.PersonAttributesMapper; import org.springframework.ldap.itest.PersonContextMapper; +import org.springframework.ldap.support.LdapUtils; import org.springframework.test.context.ContextConfiguration; +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.ldap.LdapName; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNull; + /** * Tests the lookup methods of LdapTemplate. * @@ -184,14 +185,13 @@ public class LdapTemplateLookupITest extends AbstractLdapTemplateIntegrationTest * means more than one attribute is part of the relative DN for the entry. */ @Test - @Ignore("Enable test when ApacheDS supports multi-valued rdns") public void DISABLED_testLookup_MultiValuedRdn() { AttributesMapper mapper = new PersonAttributesMapper(); Person person = (Person) tested.lookup("cn=Some Person+sn=Person, ou=company1,c=Norway", mapper); assertEquals("Some Person", person.getFullname()); assertEquals("Person", person.getLastname()); - assertEquals("Norway, Company1, Some Person2", person.getDescription()); + assertEquals("Norway, Company1, Some Person+Person", person.getDescription()); } /** @@ -200,26 +200,27 @@ public class LdapTemplateLookupITest extends AbstractLdapTemplateIntegrationTest * */ @Test - @Ignore("Enable test when ApacheDS supports multi-valued rdns") public void DISABLED_testLookup_MultiValuedRdn_DirContextAdapter() { DirContextAdapter result = (DirContextAdapter) tested.lookup("cn=Some Person+sn=Person, ou=company1,c=Norway"); assertEquals("Some Person", result.getStringAttribute("cn")); assertEquals("Person", result.getStringAttribute("sn")); - assertEquals("Norway, Company1, Some Person", result.getStringAttribute("description")); + assertEquals("Norway, Company1, Some Person+Person", result.getStringAttribute("description")); } @Test public void testLookup_GetNameInNamespace_Plain() { - DirContextAdapter result = (DirContextAdapter) tested.lookup("cn=Some Person2, ou=company1,c=Sweden"); + String expectedDn = "cn=Some Person2, ou=company1,c=Sweden"; + DirContextAdapter result = (DirContextAdapter) tested.lookup(expectedDn); - assertEquals("cn=Some Person2,ou=company1,c=Sweden", result.getDn().toString()); + LdapName expectedName = LdapUtils.newLdapName(expectedDn); + assertEquals(expectedName, result.getDn()); assertEquals("cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se", result.getNameInNamespace()); } @Test public void testLookup_GetNameInNamespace_MultiRdn() { - DirContextAdapter result = (DirContextAdapter) tested.lookup("cn=Some Person+sn=Person, ou=company1,c=Norway"); + DirContextAdapter result = (DirContextAdapter) tested.lookup("cn=Some Person+sn=Person,ou=company1,c=Norway"); assertEquals("cn=Some Person+sn=Person,ou=company1,c=Norway", result.getDn().toString()); assertEquals("cn=Some Person+sn=Person,ou=company1,c=Norway,dc=jayway,dc=se", result.getNameInNamespace()); diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java index 5ed5f78b..cebfbdc7 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,21 @@ package org.springframework.ldap; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; - import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler; +import org.springframework.ldap.support.LdapUtils; import org.springframework.test.context.ContextConfiguration; +import javax.naming.ldap.LdapName; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + /** * Tests to verify that not setting a base suffix on the ContextSource (as * defined in ldapTemplateNoBaseSuffixTestContext.xml) works as expected. @@ -53,14 +56,16 @@ public class LdapTemplateNoBaseSuffixITest extends AbstractLdapTemplateIntegrati */ @Test public void testLookup_Plain() { - DirContextAdapter result = (DirContextAdapter) tested - .lookup("cn=Some Person2, ou=company1, c=Sweden, dc=jayway, dc=se"); + String expectedDn = "cn=Some Person2, ou=company1, c=Sweden, dc=jayway, dc=se"; + DirContextAdapter result = (DirContextAdapter) tested.lookup(expectedDn); assertEquals("Some Person2", result.getStringAttribute("cn")); assertEquals("Person2", result.getStringAttribute("sn")); assertEquals("Sweden, Company1, Some Person2", result.getStringAttribute("description")); - assertEquals("cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se", result.getDn().toString()); - assertEquals("cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se", result.getNameInNamespace()); + + LdapName expectedName = LdapUtils.newLdapName(expectedDn); + assertEquals(expectedName, result.getDn()); + assertEquals(expectedDn, result.getNameInNamespace()); } @Test @@ -84,7 +89,7 @@ public class LdapTemplateNoBaseSuffixITest extends AbstractLdapTemplateIntegrati assertEquals("Some Person4", result.getStringAttribute("cn")); assertEquals("Person4", result.getStringAttribute("sn")); - assertEquals("cn=Some Person4,ou=company1,c=Sweden,dc=jayway,dc=se", result.getDn().toString()); + assertEquals(LdapUtils.newLdapName("cn=Some Person4,ou=company1,c=Sweden,dc=jayway,dc=se"), result.getDn()); tested.unbind("cn=Some Person4,ou=company1,c=Sweden,dc=jayway,dc=se"); try {