From e910acfbbad69cd969f91500d878cf5c33751d96 Mon Sep 17 00:00:00 2001 From: Mattias Arthursson Date: Tue, 18 Nov 2008 14:10:27 +0000 Subject: [PATCH] Added methods for 'simple' bind authentication in LdapTemplate (LdapOperations, SimpleLdapOperations and SimpleLdapTemplate as well). Introduced new callback interface for use with certain authentication methods. Added LdapEntryIdentification to wrap the full identification of an LDAP entry (absolute and relative DNs) Added LdapEntryIdentificationContextMapper. --- .../core/simple/SimpleLdapOperations.java | 79 + .../ldap/core/simple/SimpleLdapTemplate.java | 48 + ...AuthenticatedLdapEntryContextCallback.java | 40 + .../ldap/core/LdapEntryIdentification.java | 87 + .../ldap/core/LdapOperations.java | 2882 ++++++++--------- .../ldap/core/LdapTemplate.java | 111 + .../LdapEntryIdentificationContextMapper.java | 37 + .../ldap/core/LdapTemplateTest.java | 2750 ++++++++-------- .../test/AttributeCheckContextMapper.java | 2 +- .../ldap/LdapTemplateAuthenticationITest.java | 81 + .../ldap/LdapTemplateSearchResultITest.java | 35 + .../core/simple/SimpleLdapTemplateITest.java | 15 + 12 files changed, 3300 insertions(+), 2867 deletions(-) create mode 100644 core/src/main/java/org/springframework/ldap/core/AuthenticatedLdapEntryContextCallback.java create mode 100644 core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java create mode 100644 core/src/main/java/org/springframework/ldap/support/LdapEntryIdentificationContextMapper.java create mode 100644 test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java diff --git a/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapOperations.java b/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapOperations.java index a24ad7f5..9f3e9c75 100644 --- a/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapOperations.java +++ b/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapOperations.java @@ -22,6 +22,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.SearchControls; import org.springframework.ldap.NamingException; +import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.DirContextOperations; import org.springframework.ldap.core.DirContextProcessor; import org.springframework.ldap.core.LdapOperations; @@ -131,6 +132,36 @@ public interface SimpleLdapOperations { */ T lookup(Name dn, ParameterizedContextMapper mapper); + /** + * Perform a search for a unique entry matching the specified search + * criteria and return the found object. If no entry is found or if there + * are more than one matching entry, an + * {@link IncorrectResultSizeDataAccessException} is thrown. + * @param base the DN to use as the base of the search. + * @param filter the search filter. + * @param mapper the mapper to use for the search. + * @return the single object returned by the mapper that matches the search + * criteria. + * @throws IncorrectResultSizeDataAccessException if the result is not one unique entry + * @since 1.3 + */ + T searchForObject(String base, String filter, ParameterizedContextMapper mapper); + + /** + * Perform a search for a unique entry matching the specified search + * criteria and return the found object. If no entry is found or if there + * are more than one matching entry, an + * {@link IncorrectResultSizeDataAccessException} is thrown. + * @param base the DN to use as the base of the search. + * @param filter the search filter. + * @param mapper the mapper to use for the search. + * @return the single object returned by the mapper that matches the search + * criteria. + * @throws IncorrectResultSizeDataAccessException if the result is not one unique entry + * @since 1.3 + */ + T searchForObject(Name base, String filter, ParameterizedContextMapper mapper); + /** * Look up the specified DN, and automatically cast it to a * {@link DirContextOperations} instance. @@ -232,4 +263,52 @@ public interface SimpleLdapOperations { * @throws NamingException if any error occurs. */ void modifyAttributes(DirContextOperations ctx); + + /** + * Utility method to perform a simple LDAP 'bind' authentication. Search for + * the LDAP entry to authenticate using the supplied base DN and filter; use + * the DN of the found entry together with the password as input to + * {@link ContextSource#getContext(String, String)}, thus authenticating the + * entry. + *

+ * Example:
+ * + *

+	 * AndFilter filter = new AndFilter();
+	 * filter.and("objectclass", "person").and("uid", userId);
+	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * 
+ * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @return true if the authentication was successful, + * false otherwise. + * @since 1.3 + */ + boolean authenticate(String base, String filter, String password); + + /** + * Utility method to perform a simple LDAP 'bind' authentication. Search for + * the LDAP entry to authenticate using the supplied base DN and filter; use + * the DN of the found entry together with the password as input to + * {@link ContextSource#getContext(String, String)}, thus authenticating the + * entry. + *

+ * Example:
+ * + *

+	 * AndFilter filter = new AndFilter();
+	 * filter.and("objectclass", "person").and("uid", userId);
+	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * 
+ * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @return true if the authentication was successful, + * false otherwise. + * @since 1.3 + */ + boolean authenticate(Name base, String filter, String password); } diff --git a/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapTemplate.java b/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapTemplate.java index 2546253e..7a62b5c0 100644 --- a/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapTemplate.java +++ b/core-tiger/src/main/java/org/springframework/ldap/core/simple/SimpleLdapTemplate.java @@ -239,4 +239,52 @@ public class SimpleLdapTemplate implements SimpleLdapOperations { public void bind(DirContextOperations ctx) { ldapOperations.bind(ctx); } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.simple.SimpleLdapOperations#searchForObject + * (java.lang.String, java.lang.String, + * org.springframework.ldap.core.simple.ParameterizedContextMapper) + */ + @SuppressWarnings("unchecked") + public T searchForObject(String base, String filter, ParameterizedContextMapper mapper) { + return (T) ldapOperations.searchForObject(base, filter, mapper); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.simple.SimpleLdapOperations#searchForObject + * (javax.naming.Name, java.lang.String, + * org.springframework.ldap.core.simple.ParameterizedContextMapper) + */ + @SuppressWarnings("unchecked") + public T searchForObject(Name base, String filter, ParameterizedContextMapper mapper) { + return (T) ldapOperations.searchForObject(base, filter, mapper); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.simple.SimpleLdapOperations#authenticate + * (java.lang.String, java.lang.String, java.lang.String) + */ + public boolean authenticate(String base, String filter, String password) { + return ldapOperations.authenticate(base, filter, password); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.simple.SimpleLdapOperations#authenticate + * (javax.naming.Name, java.lang.String, java.lang.String) + */ + public boolean authenticate(Name base, String filter, String password) { + return ldapOperations.authenticate(base, filter, password); + } } diff --git a/core/src/main/java/org/springframework/ldap/core/AuthenticatedLdapEntryContextCallback.java b/core/src/main/java/org/springframework/ldap/core/AuthenticatedLdapEntryContextCallback.java new file mode 100644 index 00000000..61275e6e --- /dev/null +++ b/core/src/main/java/org/springframework/ldap/core/AuthenticatedLdapEntryContextCallback.java @@ -0,0 +1,40 @@ +/* + * Copyright 2005-2008 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; + +import javax.naming.directory.DirContext; + +/** + * Callback interface to be used in the authentication methods in + * {@link LdapOperations} for performing operations on individually + * authenticated contexts. + * + * @author Mattias Hellborg Arthursson + * @since 1.3 + */ +public interface AuthenticatedLdapEntryContextCallback { + /** + * Perform some LDAP operation on the supplied authenticated + * DirContext instance. The target context will be + * automatically closed. + * + * @param ctx the DirContext instance to perform an operation + * on. + * @param ldapEntryIdentification the identification of the LDAP entry used + * to authenticate the supplied DirContext. + */ + void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification); +} diff --git a/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java new file mode 100644 index 00000000..7651340b --- /dev/null +++ b/core/src/main/java/org/springframework/ldap/core/LdapEntryIdentification.java @@ -0,0 +1,87 @@ +/* + * Copyright 2005-2008 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; + +import javax.naming.directory.DirContext; + +import org.springframework.util.Assert; + +/** + * 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 + * the {@link DistinguishedName} class. A Distinguished Name can be absolute - + * i.e. complete including the very root (base) of the LDAP tree - or relative - + * i.e relative to the base LDAP path of the current LDAP connection (specified + * as base to the {@link ContextSource}). + *

+ * The different representations are needed on different occasions, e.g. the + * relative DN is typically what is needed to perform lookups and searches in + * the LDAP tree, whereas the absolute DN is needed when authenticating and when + * an LDAP entry is referred to in e.g. a group. This wrapper class contains + * both of these representations. + * + * @author Mattias Hellborg Arthursson + */ +public class LdapEntryIdentification { + private final DistinguishedName relativeDn; + + private final DistinguishedName absoluteDn; + + /** + * 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()}. + */ + 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(); + } + + /** + * 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. + */ + public DistinguishedName getRelativeDn() { + return relativeDn; + } + + /** + * Get the absolute DN of the identified entry, e.g. as returned by + * {@link DirContext#getNameInNamespace()}. + * @return the absolute DN. + */ + public DistinguishedName getAbsoluteDn() { + return absoluteDn; + } + + public boolean equals(Object obj) { + if (obj != null && obj.getClass().equals(this.getClass())) { + LdapEntryIdentification that = (LdapEntryIdentification) obj; + return this.absoluteDn.equals(that.absoluteDn) && this.relativeDn.equals(that.relativeDn); + } + + return false; + } + + public int hashCode() { + return absoluteDn.hashCode() ^ relativeDn.hashCode(); + } +} 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 9a5e6062..43d993a5 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapOperations.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapOperations.java @@ -25,6 +25,8 @@ import javax.naming.directory.Attributes; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.ldap.AuthenticationException; import org.springframework.ldap.ContextNotEmptyException; import org.springframework.ldap.NamingException; import org.springframework.ldap.core.support.AbstractContextSource; @@ -39,1548 +41,1234 @@ import org.springframework.ldap.support.LdapUtils; * @author Ulrik Sandberg */ public interface LdapOperations { - /** - * Perform a search using a particular {@link SearchExecutor} and context - * processor. Use this method only if especially needed - for the most cases - * there is an overloaded convenience method which calls this one with - * suitable argments. This method handles all the plumbing; getting a - * readonly context; looping through the NamingEnumeration - * and closing the context and enumeration. The actual search is delegated - * to the SearchExecutor and each found NameClassPair is - * passed to the CallbackHandler. Any encountered - * NamingException will be translated using - * {@link LdapUtils#convertLdapException(javax.naming.NamingException)}. - * - * @param se - * The SearchExecutor to use for performing the - * actual search. - * @param handler - * The NameClassPairCallbackHandler to which each - * found entry will be passed. - * @param processor - * DirContextProcessor for custom pre- and - * post-processing. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted as no entries being found. - */ - void search(SearchExecutor se, NameClassPairCallbackHandler handler, - DirContextProcessor processor) throws NamingException; - - /** - * Perform a search using a particular {@link SearchExecutor}. Use this - * method only if especially needed - for the most cases there is an - * overloaded convenience method which calls this one with suitable - * argments. This method handles all the plumbing; getting a readonly - * context; looping through the NamingEnumeration and closing - * the context and enumeration. The actual search is delegated to the - * SearchExecutor and each found NameClassPair - * is passed to the CallbackHandler. Any encountered - * NamingException will be translated using the - * {@link LdapUtils#convertLdapException(javax.naming.NamingException)}. - * - * @param se - * The SearchExecutor to use for performing the - * actual search. - * @param handler - * The NameClassPairCallbackHandler to which each - * found entry will be passed. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted as no entries being found. - * @see #search(Name, String, AttributesMapper) - * @see #search(Name, String, ContextMapper) - */ - void search(SearchExecutor se, NameClassPairCallbackHandler handler) - throws NamingException; - - /** - * Perform an operation (or series of operations) on a read-only context. - * This method handles the plumbing - getting a DirContext, - * translating any Exceptions and closing the context afterwards. This - * method is not intended for searches; use - * {@link #search(SearchExecutor, NameClassPairCallbackHandler)} or any of - * the overloaded search methods for this. - * - * @param ce - * The ContextExecutor to which the actual - * operation on the DirContext will be delegated. - * @return the result from the ContextExecutor's operation. - * @throws NamingException - * if the operation resulted in a NamingException. - * - * @see #search(SearchExecutor, NameClassPairCallbackHandler) - * @see #search(Name, String, AttributesMapper) - * @see #search(Name, String, ContextMapper) - */ - Object executeReadOnly(ContextExecutor ce) throws NamingException; - - /** - * Perform an operation (or series of operations) on a read-write context. - * This method handles the plumbing - getting a DirContext, - * translating any exceptions and closing the context afterwards. This - * method is intended only for very particular cases, where there is no - * suitable method in this interface to use. - * - * @param ce - * The ContextExecutor to which the actual - * operation on the DirContext will be delegated. - * @return the result from the ContextExecutor's operation. - * @throws NamingException - * if the operation resulted in a NamingException. - * @see #bind(Name, Object, Attributes) - * @see #unbind(Name) - * @see #rebind(Name, Object, Attributes) - * @see #rename(Name, Name) - * @see #modifyAttributes(Name, ModificationItem[]) - */ - Object executeReadWrite(ContextExecutor ce) throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. The - * SearchScope specified in the supplied - * SearchControls will be used in the search. Note that if - * you are using a ContextMapper, the returningObjFlag needs - * to be set to true in the SearchControls. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResult to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(Name base, String filter, SearchControls controls, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Search for all objects matching the supplied filter. See - * {@link #search(Name, String, SearchControls, NameClassPairCallbackHandler)} - * for details. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResult to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(String base, String filter, SearchControls controls, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. The - * SearchScope specified in the supplied - * SearchControls will be used in the search. Note that if - * you are using a ContextMapper, the returningObjFlag needs - * to be set to true in the SearchControls. The given - * DirContextProcessor will be called before and after the - * search. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResult to. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(Name base, String filter, SearchControls controls, - NameClassPairCallbackHandler handler, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. The SearchScope - * specified in the supplied SearchControls will be used in - * the search. The given DirContextProcessor will be called - * before and after the search. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, SearchControls controls, - AttributesMapper mapper, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. The SearchScope - * specified in the supplied SearchControls will be used in - * the search. The given DirContextProcessor will be called - * before and after the search. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, SearchControls controls, - AttributesMapper mapper, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Object returned - * in each SearchResult is supplied to the specified - * ContextMapper. The SearchScope specified - * in the supplied SearchControls will be used in the search. - * The given DirContextProcessor will be called before and - * after the search. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. If the - * returnObjFlag is not set in the SearchControls, - * this method will set it automatically, as this is required for - * the ContextMapper to work. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, SearchControls controls, - ContextMapper mapper, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Object returned - * in each SearchResult is supplied to the specified - * ContextMapper. The SearchScope specified - * in the supplied SearchControls will be used in the search. - * The given DirContextProcessor will be called before and - * after the search. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. If the - * returnObjFlag is not set in the SearchControls, - * this method will set it automatically, as this is required for - * the ContextMapper to work. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, SearchControls controls, - ContextMapper mapper, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. See - * {@link #search(Name, String, SearchControls, NameClassPairCallbackHandler, DirContextProcessor)} - * for details. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResults to. - * @param processor - * The DirContextProcessor to use before and after - * the search. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(String base, String filter, SearchControls controls, - NameClassPairCallbackHandler handler, DirContextProcessor processor) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. Use the specified values - * for search scope and return objects flag. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param returningObjFlag - * Whether the bound object should be returned in search results. - * Must be set to true if a - * ContextMapper is used. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResults to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(Name base, String filter, int searchScope, - boolean returningObjFlag, NameClassPairCallbackHandler handler) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. Use the specified values - * for search scope and return objects flag. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param returningObjFlag - * Whether the bound object should be returned in search results. - * Must be set to true if a - * ContextMapper is used. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResults to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(String base, String filter, int searchScope, - boolean returningObjFlag, NameClassPairCallbackHandler handler) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. The default Search scope (SearchControls.SUBTREE_SCOPE) - * will be used and the returnObjects flag will be set to false. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResults to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(Name base, String filter, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Search for all objects matching the supplied filter. Each - * SearchResult is supplied to the specified - * NameClassPairCallbackHandler. The default Search scope (SearchControls.SUBTREE_SCOPE) - * will be used and the returnObjects flag will be set to false. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param handler - * The NameClassPairCallbackHandler to supply the - * SearchResults to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void search(String base, String filter, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Search for all objects matching the supplied filter. Only return any - * attributes mathing the specified attribute names. The Attributes in each - * SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param attrs - * The attributes to return, null means returning - * all attributes. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, int searchScope, - String[] attrs, AttributesMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. Only return any - * attributes mathing the specified attribute names. The Attributes in each - * SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param attrs - * The attributes to return, null means returning - * all attributes. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, int searchScope, - String[] attrs, AttributesMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, int searchScope, - AttributesMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, int searchScope, - AttributesMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. The default search scope will be used. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, AttributesMapper mapper) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes in - * each SearchResult is supplied to the specified - * AttributesMapper. The default search scope will be used. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * AttributesMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, AttributesMapper mapper) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. Only return the - * supplied attributes. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param attrs - * The attributes to return, null means all - * attributes. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, int searchScope, - String[] attrs, ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. Only return the - * supplied attributes. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param attrs - * The attributes to return, null means all - * attributes. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, int searchScope, - String[] attrs, ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, int searchScope, - ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param searchScope - * The search scope to set in SearchControls. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, int searchScope, - ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. The default - * search scope (SearchControls.SUBTREE_SCOPE) will be - * used. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, ContextMapper mapper) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. The default - * search scope (SearchControls.SUBTREE_SCOPE) will be - * used. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, ContextMapper mapper) - throws NamingException; - - /** - * Search for all objects matching the supplied filter. The - * Object returned in each SearchResult is - * supplied to the specified ContextMapper. The default - * search scope (SearchControls.SUBTREE_SCOPE) will be - * used. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, SearchControls controls, - ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Object returned - * in each SearchResult is supplied to the specified - * ContextMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. If the - * returnObjFlag is not set in the SearchControls, - * this method will set it automatically, as this is required for - * the ContextMapper to work. - * @param mapper - * The ContextMapper to use for translating each - * entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, SearchControls controls, - ContextMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes - * returned in each SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(String base, String filter, SearchControls controls, - AttributesMapper mapper) throws NamingException; - - /** - * Search for all objects matching the supplied filter. The Attributes - * returned in each SearchResult is supplied to the specified - * AttributesMapper. - * - * @param base - * The base DN where the search should begin. - * @param filter - * The filter to use in the search. - * @param controls - * The SearchControls to use in the search. - * @param mapper - * The AttributesMapper to use for translating - * each entry. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List search(Name base, String filter, SearchControls controls, - AttributesMapper mapper) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Each resulting NameClassPair is - * supplied to the specified NameClassPairCallbackHandler. - * - * @param base - * The base DN where the list should be performed. - * @param handler - * The NameClassPairCallbackHandler to supply each - * {@link NameClassPair} to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void list(String base, NameClassPairCallbackHandler handler) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Each resulting NameClassPair is - * supplied to the specified NameClassPairCallbackHandler. - * - * @param base - * The base DN where the list should be performed. - * @param handler - * The NameClassPairCallbackHandler to supply each - * {@link NameClassPair} to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void list(Name base, NameClassPairCallbackHandler handler) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Pass all the found NameClassPair - * objects to the supplied NameClassPairMapper and return all - * the returned values as a List. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The NameClassPairMapper to supply each - * {@link NameClassPair} to. - * @return a List containing the Objects returned from the - * Mapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List list(String base, NameClassPairMapper mapper) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Pass all the found NameClassPair - * objects to the supplied NameClassPairMapper and return all - * the returned values as a List. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The NameClassPairMapper to supply each - * {@link NameClassPair} to. - * @return a List containing the Objects returned from the - * Mapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List list(Name base, NameClassPairMapper mapper) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. - * - * @param base - * The base DN where the list should be performed. - * @return a List containing the names of all the contexts bound to - * base. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List list(String base) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. - * - * @param base - * The base DN where the list should be performed. - * @return a List containing the names of all the contexts bound to - * base. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List list(Name base) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Each resulting Binding is supplied - * to the specified NameClassPairCallbackHandler. - * - * @param base - * The base DN where the list should be performed. - * @param handler - * The NameClassPairCallbackHandler to supply each - * {@link Binding} to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void listBindings(final String base, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Each resulting Binding is supplied - * to the specified NameClassPairCallbackHandler. - * - * @param base - * The base DN where the list should be performed. - * @param handler - * The NameClassPairCallbackHandler to supply each - * {@link Binding} to. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - void listBindings(final Name base, - NameClassPairCallbackHandler handler) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Pass all the found Binding objects - * to the supplied NameClassPairMapper and return all the - * returned values as a List. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The NameClassPairMapper to supply each - * {@link Binding} to. - * @return a List containing the Objects returned from the - * Mapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(String base, NameClassPairMapper mapper) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. Pass all the found Binding objects - * to the supplied NameClassPairMapper and return all the - * returned values as a List. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The NameClassPairMapper to supply each - * {@link Binding} to. - * @return a List containing the Objects returned from the - * Mapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(Name base, NameClassPairMapper mapper) - throws NamingException; - - /** - * Perform a non-recursive listing of children of the given - * base. - * - * @param base - * The base DN where the list should be performed. - * @return a List containing the names of all the contexts - * bound to base. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(final String base) throws NamingException; - - /** - * Perform a non-recursive listing of children of the given - * base. - * - * @param base - * The base DN where the list should be performed. - * @return a List containing the names of all the contexts - * bound to base. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(final Name base) throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. The Object returned in each {@link Binding} is - * supplied to the specified ContextMapper. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(String base, ContextMapper mapper) - throws NamingException; - - /** - * Perform a non-recursive listing of the children of the given - * base. The Object returned in each {@link Binding} is - * supplied to the specified ContextMapper. - * - * @param base - * The base DN where the list should be performed. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return a List containing all entries received from the - * ContextMapper. - * @throws NamingException - * if any error occurs. Note that a - * NameNotFoundException will be ignored. Instead - * this is interpreted that no entries were found. - */ - List listBindings(Name base, ContextMapper mapper) - throws NamingException; - - /** - * Lookup the supplied DN and return the found object. This will typically - * be a {@link DirContextAdapter}, unless the DirObjectFactory - * has been modified in the ContextSource. - * - * @param dn - * The distinguished name of the object to find. - * @return the found object, typically a {@link DirContextAdapter} instance. - * @throws NamingException - * if any error occurs. - * @see #lookupContext(Name) - * @see AbstractContextSource#setDirObjectFactory(Class) - */ - Object lookup(Name dn) throws NamingException; - - /** - * Lookup the supplied DN and return the found object. This will typically - * be a {@link DirContextAdapter}, unless the DirObjectFactory - * has been modified in the ContextSource. - * - * @param dn - * The distinguished name of the object to find. - * @return the found object, typically a {@link DirContextAdapter} instance. - * @throws NamingException - * if any error occurs. - * @see #lookupContext(String) - * @see AbstractContextSource#setDirObjectFactory(Class) - */ - Object lookup(String dn) throws NamingException; - - /** - * Convenience method to get the attributes of a specified DN and - * automatically pass them to an AttributesMapper. - * - * @param dn - * The distinguished name to find. - * @param mapper - * The AttributesMapper to use for mapping the - * found object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(Name dn, AttributesMapper mapper) - throws NamingException; - - /** - * Convenience method to get the attributes of a specified DN and - * automatically pass them to an AttributesMapper. - * - * @param dn - * The distinguished name to find. - * @param mapper - * The AttributesMapper to use for mapping the - * found object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(String dn, AttributesMapper mapper) - throws NamingException; - - /** - * Convenience method to lookup a specified DN and automatically pass the - * found object to a ContextMapper. - * - * @param dn - * The distinguished name to find. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(Name dn, ContextMapper mapper) throws NamingException; - - /** - * Convenience method to lookup a specified DN and automatically pass the - * found object to a ContextMapper. - * - * @param dn - * The distinguished name to find. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(String dn, ContextMapper mapper) - throws NamingException; - - /** - * Convenience method to get the specified attributes of a specified DN and - * automatically pass them to an AttributesMapper. - * - * @param dn - * The distinguished name to find. - * @param attributes - * The names of the attributes to pass to the mapper. - * @param mapper - * The AttributesMapper to use for mapping the - * found object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(Name dn, String[] attributes, AttributesMapper mapper) - throws NamingException; - - /** - * Convenience method to get the specified attributes of a specified DN and - * automatically pass them to an AttributesMapper. - * - * @param dn - * The distinguished name to find. - * @param attributes - * The names of the attributes to pass to the mapper. - * @param mapper - * The AttributesMapper to use for mapping the - * found object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(String dn, String[] attributes, AttributesMapper mapper) - throws NamingException; - - /** - * Convenience method to get the specified attributes of a specified DN and - * automatically pass them to a ContextMapper. - * - * @param dn - * The distinguished name to find. - * @param attributes - * The names of the attributes to pass to the mapper. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(Name dn, String[] attributes, ContextMapper mapper) - throws NamingException; - - /** - * Convenience method to get the specified attributes of a specified DN and - * automatically pass them to a ContextMapper. - * - * @param dn - * The distinguished name to find. - * @param attributes - * The names of the attributes to pass to the mapper. - * @param mapper - * The ContextMapper to use for mapping the found - * object. - * @return the object returned from the mapper. - * @throws NamingException - * if any error occurs. - */ - Object lookup(String dn, String[] attributes, ContextMapper mapper) - throws NamingException; - - /** - * Modify an entry in the LDAP tree using the supplied - * ModificationItems. - * - * @param dn - * The distinguished name of the node to modify. - * @param mods - * The modifications to perform. - * @throws NamingException - * if any error occurs. - * @see #modifyAttributes(DirContextOperations) - */ - void modifyAttributes(Name dn, ModificationItem[] mods) - throws NamingException; - - /** - * Modify an entry in the LDAP tree using the supplied - * ModificationItems. - * - * @param dn - * The distinguished name of the node to modify. - * @param mods - * The modifications to perform. - * @throws NamingException - * if any error occurs. - * @see #modifyAttributes(DirContextOperations) - */ - void modifyAttributes(String dn, ModificationItem[] mods) - throws NamingException; - - /** - * Create an entry in the LDAP tree. The attributes used to create the entry - * are either retrieved from the obj parameter or the - * attributes parameter (or both). One of these parameters - * may be null but not both. - * - * @param dn - * The distinguished name to bind the object and attributes to. - * @param obj - * The object to bind, may be null. Typically a - * DirContext implementation. - * @param attributes - * The attributes to bind, may be null. - * @throws NamingException - * if any error occurs. - * @see DirContextAdapter - */ - void bind(Name dn, Object obj, Attributes attributes) - throws NamingException; - - /** - * Create an entry in the LDAP tree. The attributes used to create the entry - * are either retrieved from the obj parameter or the - * attributes parameter (or both). One of these parameters - * may be null but not both. - * - * @param dn - * The distinguished name to bind the object and attributes to. - * @param obj - * The object to bind, may be null. Typically a - * DirContext implementation. - * @param attributes - * The attributes to bind, may be null. - * @throws NamingException - * if any error occurs. - * @see DirContextAdapter - */ - void bind(String dn, Object obj, Attributes attributes) - throws NamingException; - - /** - * Remove an entry from the LDAP tree. The entry must not have any children - - * if you suspect that the entry might have descendants, use - * {@link #unbind(Name, boolean)} in stead. - * - * @param dn - * The distinguished name of the entry to remove. - * @throws NamingException - * if any error occurs. - */ - void unbind(Name dn) throws NamingException; - - /** - * Remove an entry from the LDAP tree. The entry must not have any children - - * if you suspect that the entry might have descendants, use - * {@link #unbind(Name, boolean)} in stead. - * - * @param dn - * The distinguished name to unbind. - * @throws NamingException - * if any error occurs. - */ - void unbind(String dn) throws NamingException; - - /** - * Remove an entry from the LDAP tree, optionally removing all descendants - * in the process. - * - * @param dn - * The distinguished name to unbind. - * @param recursive - * Whether to unbind all subcontexts as well. If this parameter - * is false and the entry has children, the - * operation will fail. - * @throws NamingException - * if any error occurs. - */ - void unbind(Name dn, boolean recursive) throws NamingException; - - /** - * Remove an entry from the LDAP tree, optionally removing all descendants - * in the process. - * - * @param dn - * The distinguished name to unbind. - * @param recursive - * Whether to unbind all subcontexts as well. If this parameter - * is false and the entry has children, the - * operation will fail. - * @throws NamingException - * if any error occurs. - */ - void unbind(String dn, boolean recursive) throws NamingException; - - /** - * Remove an entry and replace it with a new one. The attributes used to - * create the entry are either retrieved from the obj - * parameter or the attributes parameter (or both). One of - * these parameters may be null but not both. This method - * assumes that the specified context already exists - if not it will fail. - * - * @param dn - * The distinguished name to rebind. - * @param obj - * The object to bind to the DN, may be null. - * Typically a DirContext implementation. - * @param attributes - * The attributes to bind, may be null. - * @throws NamingException - * if any error occurs. - * @see DirContextAdapter - */ - void rebind(Name dn, Object obj, Attributes attributes) - throws NamingException; - - /** - * Remove an entry and replace it with a new one. The attributes used to - * create the entry are either retrieved from the obj - * parameter or the attributes parameter (or both). One of - * these parameters may be null but not both. This method - * assumes that the specified context already exists - if not it will fail. - * - * @param dn - * The distinguished name to rebind. - * @param obj - * The object to bind to the DN, may be null. - * Typically a DirContext implementation. - * @param attributes - * The attributes to bind, may be null. - * @throws NamingException - * if any error occurs. - * @see DirContextAdapter - */ - void rebind(String dn, Object obj, Attributes attributes) - throws NamingException; - - /** - * Move an entry in the LDAP tree to a new location. - * - * @param oldDn - * The distinguished name of the entry to move; may not be - * null or empty. - * @param newDn - * The distinguished name where the entry should be moved; may - * not be null or empty. - * @throws ContextNotEmptyException - * if newDn is already bound - * @throws NamingException - * if any other error occurs. - */ - void rename(final Name oldDn, final Name newDn) - throws NamingException; - - /** - * Move an entry in the LDAP tree to a new location. - * - * @param oldDn - * The distinguished name of the entry to move; may not be - * null or empty. - * @param newDn - * The distinguished name where the entry should be moved; may - * not be null or empty. - * @throws ContextNotEmptyException - * if newDn is already bound - * @throws NamingException - * if any other error occurs. - */ - void rename(final String oldDn, final String newDn) - throws NamingException; - - /** - * Convenience method to lookup the supplied DN and automatically cast it to - * {@link DirContextOperations}. - * - * @param dn - * The distinguished name of the object to find. - * @return The found object, cast to {@link DirContextOperations}. - * @throws ClassCastException - * if an alternative DirObjectFactory has been - * registered with the ContextSource, causing - * the actual class of the returned object to be something else - * than {@link DirContextOperations}. - * @throws NamingException - * if any other error occurs. - * @see #lookup(Name) - * @see #modifyAttributes(DirContextOperations) - * @since 1.2 - */ - DirContextOperations lookupContext(Name dn) throws NamingException, - ClassCastException; - - /** - * Convenience method to lookup the supplied DN and automatically cast it to - * {@link DirContextOperations}. - * - * @param dn - * The distinguished name of the object to find. - * @return The found object, cast to {@link DirContextOperations}. - * @throws ClassCastException - * if an alternative DirObjectFactory has been - * registered with the ContextSource, causing - * the actual class of the returned object to be something else - * than {@link DirContextOperations}. - * @throws NamingException - * if any other error occurs. - * @see #lookup(String) - * @see #modifyAttributes(DirContextOperations) - * @since 1.2 - */ - DirContextOperations lookupContext(String dn) - throws NamingException, ClassCastException; - - /** - * Modify the attributes of the entry referenced by the supplied - * {@link DirContextOperations} instance. The DN to update will be the DN of - * the DirContextOperationsinstance, and the - * ModificationItem array is retrieved from the - * DirContextOperations instance using a call to - * {@link AttributeModificationsAware#getModificationItems()}. NB: - * The supplied instance needs to have been properly initialized; this means - * that if it hasn't been received from a lookup operation, - * its DN needs to be initialized and it must have been put in update mode ({@link DirContextAdapter#setUpdateMode(boolean)}). - *

- * Typical use of this method would be as follows: - * - *

-     * public void update(Person person) {
-     *     DirContextOperations ctx = ldapOperations.lookupContext(person.getDn());
-     * 
-     *     ctx.setAttributeValue("description", person.getDescription());
-     *     ctx.setAttributeValue("telephoneNumber", person.getPhone());
-     *     // More modifications here
-     * 
-     *     ldapOperations.modifyAttributes(ctx);
-     * }
-     * 
- * - * @param ctx - * the DirContextOperations instance to use in the update. - * @throws IllegalStateException - * if the supplied instance is not in update mode or has not - * been properly initialized. - * @throws NamingException - * if any other error occurs. - * @since 1.2 - * @see #lookupContext(Name) - * @see DirContextAdapter - */ - void modifyAttributes(DirContextOperations ctx) - throws IllegalStateException, NamingException; - + /** + * Perform a search using a particular {@link SearchExecutor} and context + * processor. Use this method only if especially needed - for the most cases + * there is an overloaded convenience method which calls this one with + * suitable argments. This method handles all the plumbing; getting a + * readonly context; looping through the NamingEnumeration and + * closing the context and enumeration. The actual search is delegated to + * the SearchExecutor and each found NameClassPair is passed to + * the CallbackHandler. Any encountered + * NamingException will be translated using + * {@link LdapUtils#convertLdapException(javax.naming.NamingException)}. + * + * @param se The SearchExecutor to use for performing the + * actual search. + * @param handler The NameClassPairCallbackHandler to which + * each found entry will be passed. + * @param processor DirContextProcessor for custom pre- and + * post-processing. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted as no entries being found. + */ + void search(SearchExecutor se, NameClassPairCallbackHandler handler, DirContextProcessor processor) + throws NamingException; + + /** + * Perform a search using a particular {@link SearchExecutor}. Use this + * method only if especially needed - for the most cases there is an + * overloaded convenience method which calls this one with suitable + * argments. This method handles all the plumbing; getting a readonly + * context; looping through the NamingEnumeration and closing + * the context and enumeration. The actual search is delegated to the + * SearchExecutor and each found NameClassPair is + * passed to the CallbackHandler. Any encountered + * NamingException will be translated using the + * {@link LdapUtils#convertLdapException(javax.naming.NamingException)}. + * + * @param se The SearchExecutor to use for performing the + * actual search. + * @param handler The NameClassPairCallbackHandler to which + * each found entry will be passed. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted as no entries being found. + * @see #search(Name, String, AttributesMapper) + * @see #search(Name, String, ContextMapper) + */ + void search(SearchExecutor se, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Perform an operation (or series of operations) on a read-only context. + * This method handles the plumbing - getting a DirContext, + * translating any Exceptions and closing the context afterwards. This + * method is not intended for searches; use + * {@link #search(SearchExecutor, NameClassPairCallbackHandler)} or any of + * the overloaded search methods for this. + * + * @param ce The ContextExecutor to which the actual operation + * on the DirContext will be delegated. + * @return the result from the ContextExecutor's operation. + * @throws NamingException if the operation resulted in a + * NamingException. + * + * @see #search(SearchExecutor, NameClassPairCallbackHandler) + * @see #search(Name, String, AttributesMapper) + * @see #search(Name, String, ContextMapper) + */ + Object executeReadOnly(ContextExecutor ce) throws NamingException; + + /** + * Perform an operation (or series of operations) on a read-write context. + * This method handles the plumbing - getting a DirContext, + * translating any exceptions and closing the context afterwards. This + * method is intended only for very particular cases, where there is no + * suitable method in this interface to use. + * + * @param ce The ContextExecutor to which the actual operation + * on the DirContext will be delegated. + * @return the result from the ContextExecutor's operation. + * @throws NamingException if the operation resulted in a + * NamingException. + * @see #bind(Name, Object, Attributes) + * @see #unbind(Name) + * @see #rebind(Name, Object, Attributes) + * @see #rename(Name, Name) + * @see #modifyAttributes(Name, ModificationItem[]) + */ + Object executeReadWrite(ContextExecutor ce) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. The SearchScope + * specified in the supplied SearchControls will be used in the + * search. Note that if you are using a ContextMapper, the + * returningObjFlag needs to be set to true in the + * SearchControls. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResult to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(Name base, String filter, SearchControls controls, NameClassPairCallbackHandler handler) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. See + * {@link #search(Name, String, SearchControls, NameClassPairCallbackHandler)} + * for details. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResult to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(String base, String filter, SearchControls controls, NameClassPairCallbackHandler handler) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. The SearchScope + * specified in the supplied SearchControls will be used in the + * search. Note that if you are using a ContextMapper, the + * returningObjFlag needs to be set to true in the + * SearchControls. The given DirContextProcessor + * will be called before and after the search. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResult to. + * @param processor The DirContextProcessor to use before and + * after the search. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(Name base, String filter, SearchControls controls, NameClassPairCallbackHandler handler, + DirContextProcessor processor) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. The SearchScope specified in + * the supplied SearchControls will be used in the search. The + * given DirContextProcessor will be called before and after + * the search. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @param processor The DirContextProcessor to use before and + * after the search. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, SearchControls controls, AttributesMapper mapper, + DirContextProcessor processor) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. The SearchScope specified in + * the supplied SearchControls will be used in the search. The + * given DirContextProcessor will be called before and after + * the search. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @param processor The DirContextProcessor to use before and + * after the search. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, SearchControls controls, AttributesMapper mapper, + DirContextProcessor processor) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Object returned + * in each SearchResult is supplied to the specified + * ContextMapper. The SearchScope specified in the + * supplied SearchControls will be used in the search. The + * given DirContextProcessor will be called before and after + * the search. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. If + * the returnObjFlag is not set in the SearchControls, this + * method will set it automatically, as this is required for the + * ContextMapper to work. + * @param mapper The ContextMapper to use for translating each + * entry. + * @param processor The DirContextProcessor to use before and + * after the search. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, SearchControls controls, ContextMapper mapper, DirContextProcessor processor) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Object returned + * in each SearchResult is supplied to the specified + * ContextMapper. The SearchScope specified in the + * supplied SearchControls will be used in the search. The + * given DirContextProcessor will be called before and after + * the search. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. If + * the returnObjFlag is not set in the SearchControls, this + * method will set it automatically, as this is required for the + * ContextMapper to work. + * @param mapper The ContextMapper to use for translating each + * entry. + * @param processor The DirContextProcessor to use before and + * after the search. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, SearchControls controls, ContextMapper mapper, DirContextProcessor processor) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. See + * {@link #search(Name, String, SearchControls, NameClassPairCallbackHandler, DirContextProcessor)} + * for details. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResults to. + * @param processor The DirContextProcessor to use before and + * after the search. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(String base, String filter, SearchControls controls, NameClassPairCallbackHandler handler, + DirContextProcessor processor) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. Use the specified values for + * search scope and return objects flag. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param returningObjFlag Whether the bound object should be returned in + * search results. Must be set to true if a + * ContextMapper is used. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResults to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(Name base, String filter, int searchScope, boolean returningObjFlag, + NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. Use the specified values for + * search scope and return objects flag. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param returningObjFlag Whether the bound object should be returned in + * search results. Must be set to true if a + * ContextMapper is used. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResults to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(String base, String filter, int searchScope, boolean returningObjFlag, + NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. The default Search scope ( + * SearchControls.SUBTREE_SCOPE) will be used and the + * returnObjects flag will be set to false. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResults to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(Name base, String filter, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Each + * SearchResult is supplied to the specified + * NameClassPairCallbackHandler. The default Search scope ( + * SearchControls.SUBTREE_SCOPE) will be used and the + * returnObjects flag will be set to false. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param handler The NameClassPairCallbackHandler to supply + * the SearchResults to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void search(String base, String filter, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Search for all objects matching the supplied filter. Only return any + * attributes mathing the specified attribute names. The Attributes in each + * SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param attrs The attributes to return, null means returning + * all attributes. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, int searchScope, String[] attrs, AttributesMapper mapper) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. Only return any + * attributes mathing the specified attribute names. The Attributes in each + * SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param attrs The attributes to return, null means returning + * all attributes. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, int searchScope, String[] attrs, AttributesMapper mapper) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, int searchScope, AttributesMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, int searchScope, AttributesMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. The default search scope will be used. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, AttributesMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes in + * each SearchResult is supplied to the specified + * AttributesMapper. The default search scope will be used. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * AttributesMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, AttributesMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. Only return the + * supplied attributes. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param attrs The attributes to return, null means all + * attributes. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, int searchScope, String[] attrs, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. Only return the + * supplied attributes. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param attrs The attributes to return, null means all + * attributes. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, int searchScope, String[] attrs, ContextMapper mapper) + throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, int searchScope, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param searchScope The search scope to set in SearchControls + * . + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, int searchScope, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. The default search + * scope (SearchControls.SUBTREE_SCOPE) will be used. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. The default search + * scope (SearchControls.SUBTREE_SCOPE) will be used. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The + * Object returned in each SearchResult is + * supplied to the specified ContextMapper. The default search + * scope (SearchControls.SUBTREE_SCOPE) will be used. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, SearchControls controls, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Object returned + * in each SearchResult is supplied to the specified + * ContextMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. If + * the returnObjFlag is not set in the SearchControls, this + * method will set it automatically, as this is required for the + * ContextMapper to work. + * @param mapper The ContextMapper to use for translating each + * entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, SearchControls controls, ContextMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes + * returned in each SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(String base, String filter, SearchControls controls, AttributesMapper mapper) throws NamingException; + + /** + * Search for all objects matching the supplied filter. The Attributes + * returned in each SearchResult is supplied to the specified + * AttributesMapper. + * + * @param base The base DN where the search should begin. + * @param filter The filter to use in the search. + * @param controls The SearchControls to use in the search. + * @param mapper The AttributesMapper to use for translating + * each entry. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List search(Name base, String filter, SearchControls controls, AttributesMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Each resulting NameClassPair is supplied + * to the specified NameClassPairCallbackHandler. + * + * @param base The base DN where the list should be performed. + * @param handler The NameClassPairCallbackHandler to supply + * each {@link NameClassPair} to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void list(String base, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Each resulting NameClassPair is supplied + * to the specified NameClassPairCallbackHandler. + * + * @param base The base DN where the list should be performed. + * @param handler The NameClassPairCallbackHandler to supply + * each {@link NameClassPair} to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void list(Name base, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Pass all the found NameClassPair objects + * to the supplied NameClassPairMapper and return all the + * returned values as a List. + * + * @param base The base DN where the list should be performed. + * @param mapper The NameClassPairMapper to supply each + * {@link NameClassPair} to. + * @return a List containing the Objects returned from the + * Mapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List list(String base, NameClassPairMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Pass all the found NameClassPair objects + * to the supplied NameClassPairMapper and return all the + * returned values as a List. + * + * @param base The base DN where the list should be performed. + * @param mapper The NameClassPairMapper to supply each + * {@link NameClassPair} to. + * @return a List containing the Objects returned from the + * Mapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List list(Name base, NameClassPairMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. + * + * @param base The base DN where the list should be performed. + * @return a List containing the names of all the contexts bound to + * base. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List list(String base) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. + * + * @param base The base DN where the list should be performed. + * @return a List containing the names of all the contexts bound to + * base. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List list(Name base) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Each resulting Binding is supplied to the + * specified NameClassPairCallbackHandler. + * + * @param base The base DN where the list should be performed. + * @param handler The NameClassPairCallbackHandler to supply + * each {@link Binding} to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void listBindings(final String base, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Each resulting Binding is supplied to the + * specified NameClassPairCallbackHandler. + * + * @param base The base DN where the list should be performed. + * @param handler The NameClassPairCallbackHandler to supply + * each {@link Binding} to. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + void listBindings(final Name base, NameClassPairCallbackHandler handler) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Pass all the found Binding objects to the + * supplied NameClassPairMapper and return all the returned + * values as a List. + * + * @param base The base DN where the list should be performed. + * @param mapper The NameClassPairMapper to supply each + * {@link Binding} to. + * @return a List containing the Objects returned from the + * Mapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(String base, NameClassPairMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. Pass all the found Binding objects to the + * supplied NameClassPairMapper and return all the returned + * values as a List. + * + * @param base The base DN where the list should be performed. + * @param mapper The NameClassPairMapper to supply each + * {@link Binding} to. + * @return a List containing the Objects returned from the + * Mapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(Name base, NameClassPairMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of children of the given + * base. + * + * @param base The base DN where the list should be performed. + * @return a List containing the names of all the contexts + * bound to base. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(final String base) throws NamingException; + + /** + * Perform a non-recursive listing of children of the given + * base. + * + * @param base The base DN where the list should be performed. + * @return a List containing the names of all the contexts + * bound to base. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(final Name base) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. The Object returned in each {@link Binding} is + * supplied to the specified ContextMapper. + * + * @param base The base DN where the list should be performed. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(String base, ContextMapper mapper) throws NamingException; + + /** + * Perform a non-recursive listing of the children of the given + * base. The Object returned in each {@link Binding} is + * supplied to the specified ContextMapper. + * + * @param base The base DN where the list should be performed. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return a List containing all entries received from the + * ContextMapper. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is + * interpreted that no entries were found. + */ + List listBindings(Name base, ContextMapper mapper) throws NamingException; + + /** + * Lookup the supplied DN and return the found object. This will typically + * be a {@link DirContextAdapter}, unless the DirObjectFactory + * has been modified in the ContextSource. + * + * @param dn The distinguished name of the object to find. + * @return the found object, typically a {@link DirContextAdapter} instance. + * @throws NamingException if any error occurs. + * @see #lookupContext(Name) + * @see AbstractContextSource#setDirObjectFactory(Class) + */ + Object lookup(Name dn) throws NamingException; + + /** + * Lookup the supplied DN and return the found object. This will typically + * be a {@link DirContextAdapter}, unless the DirObjectFactory + * has been modified in the ContextSource. + * + * @param dn The distinguished name of the object to find. + * @return the found object, typically a {@link DirContextAdapter} instance. + * @throws NamingException if any error occurs. + * @see #lookupContext(String) + * @see AbstractContextSource#setDirObjectFactory(Class) + */ + Object lookup(String dn) throws NamingException; + + /** + * Convenience method to get the attributes of a specified DN and + * automatically pass them to an AttributesMapper. + * + * @param dn The distinguished name to find. + * @param mapper The AttributesMapper to use for mapping the + * found object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(Name dn, AttributesMapper mapper) throws NamingException; + + /** + * Convenience method to get the attributes of a specified DN and + * automatically pass them to an AttributesMapper. + * + * @param dn The distinguished name to find. + * @param mapper The AttributesMapper to use for mapping the + * found object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(String dn, AttributesMapper mapper) throws NamingException; + + /** + * Convenience method to lookup a specified DN and automatically pass the + * found object to a ContextMapper. + * + * @param dn The distinguished name to find. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(Name dn, ContextMapper mapper) throws NamingException; + + /** + * Convenience method to lookup a specified DN and automatically pass the + * found object to a ContextMapper. + * + * @param dn The distinguished name to find. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(String dn, ContextMapper mapper) throws NamingException; + + /** + * Convenience method to get the specified attributes of a specified DN and + * automatically pass them to an AttributesMapper. + * + * @param dn The distinguished name to find. + * @param attributes The names of the attributes to pass to the mapper. + * @param mapper The AttributesMapper to use for mapping the + * found object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(Name dn, String[] attributes, AttributesMapper mapper) throws NamingException; + + /** + * Convenience method to get the specified attributes of a specified DN and + * automatically pass them to an AttributesMapper. + * + * @param dn The distinguished name to find. + * @param attributes The names of the attributes to pass to the mapper. + * @param mapper The AttributesMapper to use for mapping the + * found object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(String dn, String[] attributes, AttributesMapper mapper) throws NamingException; + + /** + * Convenience method to get the specified attributes of a specified DN and + * automatically pass them to a ContextMapper. + * + * @param dn The distinguished name to find. + * @param attributes The names of the attributes to pass to the mapper. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(Name dn, String[] attributes, ContextMapper mapper) throws NamingException; + + /** + * Convenience method to get the specified attributes of a specified DN and + * automatically pass them to a ContextMapper. + * + * @param dn The distinguished name to find. + * @param attributes The names of the attributes to pass to the mapper. + * @param mapper The ContextMapper to use for mapping the found + * object. + * @return the object returned from the mapper. + * @throws NamingException if any error occurs. + */ + Object lookup(String dn, String[] attributes, ContextMapper mapper) throws NamingException; + + /** + * Modify an entry in the LDAP tree using the supplied + * ModificationItems. + * + * @param dn The distinguished name of the node to modify. + * @param mods The modifications to perform. + * @throws NamingException if any error occurs. + * @see #modifyAttributes(DirContextOperations) + */ + void modifyAttributes(Name dn, ModificationItem[] mods) throws NamingException; + + /** + * Modify an entry in the LDAP tree using the supplied + * ModificationItems. + * + * @param dn The distinguished name of the node to modify. + * @param mods The modifications to perform. + * @throws NamingException if any error occurs. + * @see #modifyAttributes(DirContextOperations) + */ + void modifyAttributes(String dn, ModificationItem[] mods) throws NamingException; + + /** + * Create an entry in the LDAP tree. The attributes used to create the entry + * are either retrieved from the obj parameter or the + * attributes parameter (or both). One of these parameters may + * be null but not both. + * + * @param dn The distinguished name to bind the object and attributes to. + * @param obj The object to bind, may be null. Typically a + * DirContext implementation. + * @param attributes The attributes to bind, may be null. + * @throws NamingException if any error occurs. + * @see DirContextAdapter + */ + void bind(Name dn, Object obj, Attributes attributes) throws NamingException; + + /** + * Create an entry in the LDAP tree. The attributes used to create the entry + * are either retrieved from the obj parameter or the + * attributes parameter (or both). One of these parameters may + * be null but not both. + * + * @param dn The distinguished name to bind the object and attributes to. + * @param obj The object to bind, may be null. Typically a + * DirContext implementation. + * @param attributes The attributes to bind, may be null. + * @throws NamingException if any error occurs. + * @see DirContextAdapter + */ + void bind(String dn, Object obj, Attributes attributes) throws NamingException; + + /** + * Remove an entry from the LDAP tree. The entry must not have any children + * - if you suspect that the entry might have descendants, use + * {@link #unbind(Name, boolean)} in stead. + * + * @param dn The distinguished name of the entry to remove. + * @throws NamingException if any error occurs. + */ + void unbind(Name dn) throws NamingException; + + /** + * Remove an entry from the LDAP tree. The entry must not have any children + * - if you suspect that the entry might have descendants, use + * {@link #unbind(Name, boolean)} in stead. + * + * @param dn The distinguished name to unbind. + * @throws NamingException if any error occurs. + */ + void unbind(String dn) throws NamingException; + + /** + * Remove an entry from the LDAP tree, optionally removing all descendants + * in the process. + * + * @param dn The distinguished name to unbind. + * @param recursive Whether to unbind all subcontexts as well. If this + * parameter is false and the entry has children, the operation + * will fail. + * @throws NamingException if any error occurs. + */ + void unbind(Name dn, boolean recursive) throws NamingException; + + /** + * Remove an entry from the LDAP tree, optionally removing all descendants + * in the process. + * + * @param dn The distinguished name to unbind. + * @param recursive Whether to unbind all subcontexts as well. If this + * parameter is false and the entry has children, the operation + * will fail. + * @throws NamingException if any error occurs. + */ + void unbind(String dn, boolean recursive) throws NamingException; + + /** + * Remove an entry and replace it with a new one. The attributes used to + * create the entry are either retrieved from the obj parameter + * or the attributes parameter (or both). One of these + * parameters may be null but not both. This method assumes + * that the specified context already exists - if not it will fail. + * + * @param dn The distinguished name to rebind. + * @param obj The object to bind to the DN, may be null. + * Typically a DirContext implementation. + * @param attributes The attributes to bind, may be null. + * @throws NamingException if any error occurs. + * @see DirContextAdapter + */ + void rebind(Name dn, Object obj, Attributes attributes) throws NamingException; + + /** + * Remove an entry and replace it with a new one. The attributes used to + * create the entry are either retrieved from the obj parameter + * or the attributes parameter (or both). One of these + * parameters may be null but not both. This method assumes + * that the specified context already exists - if not it will fail. + * + * @param dn The distinguished name to rebind. + * @param obj The object to bind to the DN, may be null. + * Typically a DirContext implementation. + * @param attributes The attributes to bind, may be null. + * @throws NamingException if any error occurs. + * @see DirContextAdapter + */ + void rebind(String dn, Object obj, Attributes attributes) throws NamingException; + + /** + * Move an entry in the LDAP tree to a new location. + * + * @param oldDn The distinguished name of the entry to move; may not be + * null or empty. + * @param newDn The distinguished name where the entry should be moved; may + * not be null or empty. + * @throws ContextNotEmptyException if newDn is already bound + * @throws NamingException if any other error occurs. + */ + void rename(final Name oldDn, final Name newDn) throws NamingException; + + /** + * Move an entry in the LDAP tree to a new location. + * + * @param oldDn The distinguished name of the entry to move; may not be + * null or empty. + * @param newDn The distinguished name where the entry should be moved; may + * not be null or empty. + * @throws ContextNotEmptyException if newDn is already bound + * @throws NamingException if any other error occurs. + */ + void rename(final String oldDn, final String newDn) throws NamingException; + + /** + * Convenience method to lookup the supplied DN and automatically cast it to + * {@link DirContextOperations}. + * + * @param dn The distinguished name of the object to find. + * @return The found object, cast to {@link DirContextOperations}. + * @throws ClassCastException if an alternative + * DirObjectFactory has been registered with the + * ContextSource, causing the actual class of the returned + * object to be something else than {@link DirContextOperations}. + * @throws NamingException if any other error occurs. + * @see #lookup(Name) + * @see #modifyAttributes(DirContextOperations) + * @since 1.2 + */ + DirContextOperations lookupContext(Name dn) throws NamingException, ClassCastException; + + /** + * Convenience method to lookup the supplied DN and automatically cast it to + * {@link DirContextOperations}. + * + * @param dn The distinguished name of the object to find. + * @return The found object, cast to {@link DirContextOperations}. + * @throws ClassCastException if an alternative + * DirObjectFactory has been registered with the + * ContextSource, causing the actual class of the returned + * object to be something else than {@link DirContextOperations}. + * @throws NamingException if any other error occurs. + * @see #lookup(String) + * @see #modifyAttributes(DirContextOperations) + * @since 1.2 + */ + DirContextOperations lookupContext(String dn) throws NamingException, ClassCastException; + + /** + * Modify the attributes of the entry referenced by the supplied + * {@link DirContextOperations} instance. The DN to update will be the DN of + * the DirContextOperationsinstance, and the + * ModificationItem array is retrieved from the + * DirContextOperations instance using a call to + * {@link AttributeModificationsAware#getModificationItems()}. NB: + * The supplied instance needs to have been properly initialized; this means + * that if it hasn't been received from a lookup operation, its + * DN needs to be initialized and it must have been put in update mode ( + * {@link DirContextAdapter#setUpdateMode(boolean)}). + *

+ * Typical use of this method would be as follows: + * + *

+	 * public void update(Person person) {
+	 * 	DirContextOperations ctx = ldapOperations.lookupContext(person.getDn());
+	 * 
+	 * 	ctx.setAttributeValue("description", person.getDescription());
+	 * 	ctx.setAttributeValue("telephoneNumber", person.getPhone());
+	 * 	// More modifications here
+	 * 
+	 * 	ldapOperations.modifyAttributes(ctx);
+	 * }
+	 * 
+ * + * @param ctx the DirContextOperations instance to use in the update. + * @throws IllegalStateException if the supplied instance is not in update + * mode or has not been properly initialized. + * @throws NamingException if any other error occurs. + * @since 1.2 + * @see #lookupContext(Name) + * @see DirContextAdapter + */ + void modifyAttributes(DirContextOperations ctx) throws IllegalStateException, NamingException; + /** * Bind the data in the supplied context in the tree. All specified * Attributes in will be bound to the DN set on the instance. - *

Example:
+ *

+ * Example:
+ * *

 	 * DirContextOperations ctx = new DirContextAdapter(dn);
-	 * ctx.setAttributeValue("cn", "john doe");
-	 * ctx.setAttributeValue("description", "some description");
+	 * ctx.setAttributeValue("cn", "john doe");
+	 * ctx.setAttributeValue("description", "some description");
 	 * //More initialization here.
 	 * 
 	 * ldapTemplate.bind(ctx);
@@ -1591,4 +1279,124 @@ public interface LdapOperations {
 	 * @since 1.3
 	 */
 	void bind(DirContextOperations ctx);
+
+	/**
+	 * Utility method to perform a simple LDAP 'bind' authentication. Search for
+	 * the LDAP entry to authenticate using the supplied base DN and filter; use
+	 * the DN of the found entry together with the password as input to
+	 * {@link ContextSource#getContext(String, String)}, thus authenticating the
+	 * entry.
+	 * 

+ * Example:
+ * + *

+	 * AndFilter filter = new AndFilter();
+	 * filter.and("objectclass", "person").and("uid", userId);
+	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * 
+ * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @return true if the authentication was successful, + * false otherwise. + * @since 1.3 + */ + boolean authenticate(Name base, String filter, String password); + + /** + * Utility method to perform a simple LDAP 'bind' authentication. Search for + * the LDAP entry to authenticate using the supplied base DN and filter; use + * the DN of the found entry together with the password as input to + * {@link ContextSource#getContext(String, String)}, thus authenticating the + * entry. + *

+ * Example:
+ * + *

+	 * AndFilter filter = new AndFilter();
+	 * filter.and("objectclass", "person").and("uid", userId);
+	 * boolean authenticated = ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
+	 * 
+ * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @return true if the authentication was successful, + * false otherwise. + * @since 1.3 + */ + boolean authenticate(String base, String filter, String password); + + /** + * Utility method to perform a simple LDAP 'bind' authentication. Search for + * the LDAP entry to authenticate using the supplied base DN and filter; use + * the DN of the found entry together with the password as input to + * {@link ContextSource#getContext(String, String)}, thus authenticating the + * entry. The resulting DirContext instance is then used as input to the + * supplied {@link AuthenticatedLdapEntryContextCallback} to perform any + * additional LDAP operations against the authenticated DirContext. + * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @param callback the callback to that will be called to perform operations + * on the DirContext authenticated with the found user. + * @return true if the authentication was successful, + * false otherwise. + * @see #authenticate(Name, String, String) + * @since 1.3 + */ + boolean authenticate(Name base, String filter, String password, AuthenticatedLdapEntryContextCallback callback); + + /** + * Utility method to perform a simple LDAP 'bind' authentication. Search for + * the LDAP entry to authenticate using the supplied base DN and filter; use + * the DN of the found entry together with the password as input to + * {@link ContextSource#getContext(String, String)}, thus authenticating the + * entry. The resulting DirContext instance is then used as input to the + * supplied {@link AuthenticatedLdapEntryContextCallback} to perform any + * additional LDAP operations against the authenticated DirContext. + * + * @param base the DN to use as the base of the search. + * @param filter the search filter - must result in a unique result. + * @param password the password to use for authentication. + * @param callback the callback to that will be called to perform operations + * on the DirContext authenticated with the found user. + * @return true if the authentication was successful, + * false otherwise. + * @see #authenticate(String, String, String) + * @since 1.3 + */ + boolean authenticate(String base, String filter, String password, AuthenticatedLdapEntryContextCallback callback); + + /** + * Perform a search for a unique entry matching the specified search + * criteria and return the found object. If no entry is found or if there + * are more than one matching entry, an + * {@link IncorrectResultSizeDataAccessException} is thrown. + * @param base the DN to use as the base of the search. + * @param filter the search filter. + * @param mapper the mapper to use for the search. + * @return the single object returned by the mapper that matches the search + * criteria. + * @throws IncorrectResultSizeDataAccessException if the result is not one unique entry + * @since 1.3 + */ + Object searchForObject(Name base, String filter, ContextMapper mapper); + + /** + * Perform a search for a unique entry matching the specified search + * criteria and return the found object. If no entry is found or if there + * are more than one matching entry, an + * {@link IncorrectResultSizeDataAccessException} is thrown. + * @param base the DN to use as the base of the search. + * @param filter the search filter. + * @param mapper the mapper to use for the search. + * @return the single object returned by the mapper that matches the search + * criteria. + * @throws IncorrectResultSizeDataAccessException if the result is not one unique entry + * @since 1.3 + */ + Object searchForObject(String base, String filter, ContextMapper mapper); } 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 6a206e77..35bf8ece 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -32,7 +32,10 @@ import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.ldap.NamingException; +import org.springframework.ldap.support.LdapEntryIdentificationContextMapper; import org.springframework.ldap.support.LdapUtils; /** @@ -1347,4 +1350,112 @@ public class LdapTemplate implements LdapOperations, InitializingBean { throw new IllegalStateException("The DirContextOperations instance needs to be properly initialized."); } } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#authenticate(javax.naming + * .Name, java.lang.String, java.lang.String) + */ + public boolean authenticate(Name base, String filter, String password) { + return authenticate(base, filter, password, new NullAuthenticatedLdapEntryContextCallback()); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#authenticate(java.lang.String + * , java.lang.String, java.lang.String) + */ + public boolean authenticate(String base, String filter, String password) { + return authenticate(base, filter, password, new NullAuthenticatedLdapEntryContextCallback()); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#authenticate(java.lang.String + * , java.lang.String, java.lang.String, + * org.springframework.ldap.core.AuthenticatedLdapEntryContextCallback) + */ + public boolean authenticate(String base, String filter, String password, + AuthenticatedLdapEntryContextCallback callback) { + return authenticate(new DistinguishedName(base), filter, password, callback); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#authenticate(javax.naming + * .Name, java.lang.String, java.lang.String, + * org.springframework.ldap.core.AuthenticatedLdapEntryContextCallback) + */ + public boolean authenticate(Name base, String filter, String password, + final AuthenticatedLdapEntryContextCallback callback) { + + List result = search(base, filter, new LdapEntryIdentificationContextMapper()); + if (result.size() != 1) { + log.error("Unable to find unique entry matching in authentication; base: '" + base + "'; filter: '" + + filter + "'. Found " + result.size() + " mathching entries"); + return false; + } + + final LdapEntryIdentification entryIdentification = (LdapEntryIdentification) result.get(0); + + try { + DirContext ctx = contextSource.getContext(entryIdentification.getAbsoluteDn().toString(), password); + executeWithContext(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + callback.executeWithContext(ctx, entryIdentification); + return null; + } + }, ctx); + return true; + } + catch (Exception e) { + log.error("Authentication failed for entry with DN '" + entryIdentification.getAbsoluteDn() + "'", e); + return false; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#searchForObject(javax.naming + * .Name, java.lang.String, org.springframework.ldap.core.ContextMapper) + */ + public Object searchForObject(Name base, String filter, ContextMapper mapper) { + List result = search(base, filter, mapper); + if (result.size() == 0) { + throw new EmptyResultDataAccessException(1); + } + else if (result.size() != 1) { + throw new IncorrectResultSizeDataAccessException(1, result.size()); + } + + return result.get(0); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.ldap.core.LdapOperations#searchForObject(java.lang + * .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); + } + + private static final class NullAuthenticatedLdapEntryContextCallback implements + AuthenticatedLdapEntryContextCallback { + public void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) { + // Do nothing + } + } } diff --git a/core/src/main/java/org/springframework/ldap/support/LdapEntryIdentificationContextMapper.java b/core/src/main/java/org/springframework/ldap/support/LdapEntryIdentificationContextMapper.java new file mode 100644 index 00000000..0efe3169 --- /dev/null +++ b/core/src/main/java/org/springframework/ldap/support/LdapEntryIdentificationContextMapper.java @@ -0,0 +1,37 @@ +/* + * Copyright 2005-2008 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.support; + +import org.springframework.ldap.core.DirContextOperations; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapEntryIdentification; +import org.springframework.ldap.core.support.AbstractContextMapper; + +/** + * ContextMapper implementation that maps the found entries to the + * {@link LdapEntryIdentification} of each respective entry. + * + * @author Mattias Hellborg Arthursson + * @since 1.3 + */ +public class LdapEntryIdentificationContextMapper extends AbstractContextMapper { + + protected Object doMapFromContext(DirContextOperations ctx) { + return new LdapEntryIdentification(new DistinguishedName(ctx.getNameInNamespace()), new DistinguishedName(ctx + .getDn())); + } + +} diff --git a/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java b/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java index b75510e5..3d7570f7 100644 --- a/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java +++ b/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java @@ -32,332 +32,317 @@ import junit.framework.TestCase; import org.easymock.AbstractMatcher; import org.easymock.MockControl; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.ldap.LimitExceededException; import org.springframework.ldap.NameNotFoundException; import org.springframework.ldap.PartialResultException; +import org.springframework.ldap.UncategorizedLdapException; public class LdapTemplateTest extends TestCase { - private static final String DEFAULT_BASE_STRING = "o=example.com"; + private static final String DEFAULT_BASE_STRING = "o=example.com"; - private MockControl contextSourceControl; + private MockControl contextSourceControl; - private ContextSource contextSourceMock; + private ContextSource contextSourceMock; - private MockControl dirContextControl; + private MockControl dirContextControl; - private DirContext dirContextMock; + private DirContext dirContextMock; - private MockControl attributesMapperControl; + private MockControl attributesMapperControl; - private AttributesMapper attributesMapperMock; + private AttributesMapper attributesMapperMock; - private MockControl namingEnumerationControl; + private MockControl namingEnumerationControl; - private NamingEnumeration namingEnumerationMock; + private NamingEnumeration namingEnumerationMock; - private MockControl nameControl; + private MockControl nameControl; - private Name nameMock; + private Name nameMock; - private MockControl handlerControl; + private MockControl handlerControl; - private NameClassPairCallbackHandler handlerMock; + private NameClassPairCallbackHandler handlerMock; - private MockControl contextMapperControl; + private MockControl contextMapperControl; - private ContextMapper contextMapperMock; + private ContextMapper contextMapperMock; - private MockControl contextExecutorControl; + private MockControl contextExecutorControl; - private ContextExecutor contextExecutorMock; + private ContextExecutor contextExecutorMock; - private MockControl searchExecutorControl; + private MockControl searchExecutorControl; - private SearchExecutor searchExecutorMock; + private SearchExecutor searchExecutorMock; - private LdapTemplate tested; + private LdapTemplate tested; - private MockControl dirContextProcessorControl; + private MockControl dirContextProcessorControl; - private DirContextProcessor dirContextProcessorMock; + private DirContextProcessor dirContextProcessorMock; - private MockControl dirContextOperationsConrol; + private MockControl dirContextOperationsConrol; - private DirContextOperations dirContextOperationsMock; + private DirContextOperations dirContextOperationsMock; - protected void setUp() throws Exception { - super.setUp(); + protected void setUp() throws Exception { + super.setUp(); - // Setup ContextSource mock - contextSourceControl = MockControl.createControl(ContextSource.class); - contextSourceMock = (ContextSource) contextSourceControl.getMock(); + // Setup ContextSource mock + contextSourceControl = MockControl.createControl(ContextSource.class); + contextSourceMock = (ContextSource) contextSourceControl.getMock(); - // Setup LdapContext mock - dirContextControl = MockControl.createControl(LdapContext.class); - dirContextMock = (LdapContext) dirContextControl.getMock(); + // Setup LdapContext mock + dirContextControl = MockControl.createControl(LdapContext.class); + dirContextMock = (LdapContext) dirContextControl.getMock(); - // Setup NamingEnumeration mock - namingEnumerationControl = MockControl - .createControl(NamingEnumeration.class); - namingEnumerationMock = (NamingEnumeration) namingEnumerationControl - .getMock(); + // Setup NamingEnumeration mock + namingEnumerationControl = MockControl.createControl(NamingEnumeration.class); + namingEnumerationMock = (NamingEnumeration) namingEnumerationControl.getMock(); - // Setup Name mock - nameControl = MockControl.createControl(Name.class); - nameMock = (Name) nameControl.getMock(); + // Setup Name mock + nameControl = MockControl.createControl(Name.class); + nameMock = (Name) nameControl.getMock(); - // Setup Handler mock - handlerControl = MockControl - .createControl(NameClassPairCallbackHandler.class); - handlerMock = (NameClassPairCallbackHandler) handlerControl.getMock(); + // Setup Handler mock + handlerControl = MockControl.createControl(NameClassPairCallbackHandler.class); + handlerMock = (NameClassPairCallbackHandler) handlerControl.getMock(); - contextMapperControl = MockControl.createControl(ContextMapper.class); - contextMapperMock = (ContextMapper) contextMapperControl.getMock(); + contextMapperControl = MockControl.createControl(ContextMapper.class); + contextMapperMock = (ContextMapper) contextMapperControl.getMock(); - attributesMapperControl = MockControl - .createControl(AttributesMapper.class); - attributesMapperMock = (AttributesMapper) attributesMapperControl - .getMock(); + attributesMapperControl = MockControl.createControl(AttributesMapper.class); + attributesMapperMock = (AttributesMapper) attributesMapperControl.getMock(); - contextExecutorControl = MockControl - .createControl(ContextExecutor.class); - contextExecutorMock = (ContextExecutor) contextExecutorControl - .getMock(); + contextExecutorControl = MockControl.createControl(ContextExecutor.class); + contextExecutorMock = (ContextExecutor) contextExecutorControl.getMock(); - searchExecutorControl = MockControl.createControl(SearchExecutor.class); - searchExecutorMock = (SearchExecutor) searchExecutorControl.getMock(); + searchExecutorControl = MockControl.createControl(SearchExecutor.class); + searchExecutorMock = (SearchExecutor) searchExecutorControl.getMock(); - dirContextProcessorControl = MockControl - .createControl(DirContextProcessor.class); - dirContextProcessorMock = (DirContextProcessor) dirContextProcessorControl - .getMock(); + dirContextProcessorControl = MockControl.createControl(DirContextProcessor.class); + dirContextProcessorMock = (DirContextProcessor) dirContextProcessorControl.getMock(); - dirContextOperationsConrol = MockControl - .createControl(DirContextOperations.class); - dirContextOperationsMock = (DirContextOperations) dirContextOperationsConrol - .getMock(); + dirContextOperationsConrol = MockControl.createControl(DirContextOperations.class); + dirContextOperationsMock = (DirContextOperations) dirContextOperationsConrol.getMock(); - tested = new LdapTemplate(contextSourceMock); - } + tested = new LdapTemplate(contextSourceMock); + } - protected void tearDown() throws Exception { - super.tearDown(); + protected void tearDown() throws Exception { + super.tearDown(); - contextSourceControl = null; - contextSourceMock = null; + contextSourceControl = null; + contextSourceMock = null; - dirContextControl = null; - dirContextMock = null; + dirContextControl = null; + dirContextMock = null; - namingEnumerationControl = null; - namingEnumerationMock = null; + namingEnumerationControl = null; + namingEnumerationMock = null; - nameControl = null; - nameMock = null; + nameControl = null; + nameMock = null; - handlerControl = null; - handlerMock = null; + handlerControl = null; + handlerMock = null; - contextMapperControl = null; - contextMapperMock = null; + contextMapperControl = null; + contextMapperMock = null; - attributesMapperControl = null; - attributesMapperMock = null; + attributesMapperControl = null; + attributesMapperMock = null; - contextExecutorControl = null; - contextExecutorMock = null; + contextExecutorControl = null; + contextExecutorMock = null; - searchExecutorControl = null; - searchExecutorMock = null; + searchExecutorControl = null; + searchExecutorMock = null; - dirContextProcessorControl = null; - dirContextProcessorMock = null; + dirContextProcessorControl = null; + dirContextProcessorMock = null; - dirContextOperationsConrol = null; - dirContextOperationsMock = null; + dirContextOperationsConrol = null; + dirContextOperationsMock = null; - } + } - protected void replay() { - contextSourceControl.replay(); - dirContextControl.replay(); - namingEnumerationControl.replay(); - nameControl.replay(); - handlerControl.replay(); - contextMapperControl.replay(); - attributesMapperControl.replay(); - contextExecutorControl.replay(); - searchExecutorControl.replay(); - dirContextProcessorControl.replay(); - dirContextOperationsConrol.replay(); - } + protected void replay() { + contextSourceControl.replay(); + dirContextControl.replay(); + namingEnumerationControl.replay(); + nameControl.replay(); + handlerControl.replay(); + contextMapperControl.replay(); + attributesMapperControl.replay(); + contextExecutorControl.replay(); + searchExecutorControl.replay(); + dirContextProcessorControl.replay(); + dirContextOperationsConrol.replay(); + } - protected void verify() { - contextSourceControl.verify(); - dirContextControl.verify(); - namingEnumerationControl.verify(); - nameControl.verify(); - handlerControl.verify(); - contextMapperControl.verify(); - attributesMapperControl.verify(); - contextExecutorControl.verify(); - searchExecutorControl.verify(); - dirContextProcessorControl.verify(); - dirContextOperationsConrol.verify(); - } + protected void verify() { + contextSourceControl.verify(); + dirContextControl.verify(); + namingEnumerationControl.verify(); + nameControl.verify(); + handlerControl.verify(); + contextMapperControl.verify(); + attributesMapperControl.verify(); + contextExecutorControl.verify(); + searchExecutorControl.verify(); + dirContextProcessorControl.verify(); + dirContextOperationsConrol.verify(); + } - private void expectGetReadWriteContext() { - contextSourceControl.expectAndReturn(contextSourceMock - .getReadWriteContext(), dirContextMock); - } + private void expectGetReadWriteContext() { + contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), dirContextMock); + } - private void expectGetReadOnlyContext() { - contextSourceControl.expectAndReturn(contextSourceMock - .getReadOnlyContext(), dirContextMock); - } + private void expectGetReadOnlyContext() { + contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock); + } - public void testSearch_CallbackHandler() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_CallbackHandler() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(nameMock, "(ou=somevalue)", 1, true, handlerMock); + tested.search(nameMock, "(ou=somevalue)", 1, true, handlerMock); - verify(); - } + verify(); + } - public void testSearch_StringBase_CallbackHandler() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_StringBase_CallbackHandler() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, true, - handlerMock); + tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, true, handlerMock); - verify(); - } + verify(); + } - private void setupStringSearchAndNamingEnumeration(SearchControls controls, - SearchResult searchResult) throws Exception { - dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); - dirContextControl.expectAndReturn(dirContextMock.search( - DEFAULT_BASE_STRING, "(ou=somevalue)", controls), - namingEnumerationMock); + private void setupStringSearchAndNamingEnumeration(SearchControls controls, SearchResult searchResult) + throws Exception { + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + dirContextControl.expectAndReturn(dirContextMock.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls), + namingEnumerationMock); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - searchResult); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - } + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + } - public void testSearch_CallbackHandler_Defaults() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_CallbackHandler_Defaults() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(nameMock, "(ou=somevalue)", handlerMock); + tested.search(nameMock, "(ou=somevalue)", handlerMock); - verify(); - } + verify(); + } - public void testSearch_String_CallbackHandler_Defaults() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_CallbackHandler_Defaults() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", handlerMock); + tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", handlerMock); - verify(); - } + verify(); + } - private void setupSearchAndNamingEnumeration(SearchControls controls, - SearchResult searchResult) throws Exception { - dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); - dirContextControl.expectAndReturn(dirContextMock.search(nameMock, - "(ou=somevalue)", controls), namingEnumerationMock); + private void setupSearchAndNamingEnumeration(SearchControls controls, SearchResult searchResult) throws Exception { + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + dirContextControl.expectAndReturn(dirContextMock.search(nameMock, "(ou=somevalue)", controls), + namingEnumerationMock); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - searchResult); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - } + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + } - public void testSearch_NameNotFoundException() throws Exception { - expectGetReadOnlyContext(); + private void setupSearchAndNamingEnumerationForNoHits(SearchControls controls) throws Exception { + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + dirContextControl.expectAndReturn(dirContextMock.search(nameMock, "(ou=somevalue)", controls), + namingEnumerationMock); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + } - dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); - javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException("some text"); - dirContextControl.expectAndThrow(dirContextMock.search(nameMock, - "(ou=somevalue)", controls), ne); + public void testSearch_NameNotFoundException() throws Exception { + expectGetReadOnlyContext(); - dirContextMock.close(); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - replay(); + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException("some text"); + dirContextControl.expectAndThrow(dirContextMock.search(nameMock, "(ou=somevalue)", controls), ne); - try { + dirContextMock.close(); + + replay(); + + try { tested.search(nameMock, "(ou=somevalue)", handlerMock); fail("NameNotFoundException expected"); } @@ -365,1433 +350,1540 @@ public class LdapTemplateTest extends TestCase { assertTrue(true); } - verify(); - } + verify(); + } - public void testSearch_NamingException() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_NamingException() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); - javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); - dirContextControl.expectAndThrow(dirContextMock.search(nameMock, - "(ou=somevalue)", controls), ne); + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); + dirContextControl.expectAndThrow(dirContextMock.search(nameMock, "(ou=somevalue)", controls), ne); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - try { - tested.search(nameMock, "(ou=somevalue)", handlerMock); - fail("LimitExceededException expected"); - } catch (LimitExceededException expected) { - // expected - } + try { + tested.search(nameMock, "(ou=somevalue)", handlerMock); + fail("LimitExceededException expected"); + } + catch (LimitExceededException expected) { + // expected + } - verify(); - } + verify(); + } - public void testSearch_CallbackHandler_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_CallbackHandler_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - dirContextProcessorMock.preProcess(dirContextMock); + dirContextProcessorMock.preProcess(dirContextMock); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextProcessorMock.postProcess(dirContextMock); + dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(nameMock, "(ou=somevalue)", controls, handlerMock, - dirContextProcessorMock); + tested.search(nameMock, "(ou=somevalue)", controls, handlerMock, dirContextProcessorMock); - verify(); - } + verify(); + } - public void testSearch_String_CallbackHandler_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_CallbackHandler_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - SearchResult searchResult = new SearchResult("", new Object(), - new BasicAttributes()); + SearchResult searchResult = new SearchResult("", new Object(), new BasicAttributes()); - dirContextProcessorMock.preProcess(dirContextMock); + dirContextProcessorMock.preProcess(dirContextMock); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - handlerMock.handleNameClassPair(searchResult); + handlerMock.handleNameClassPair(searchResult); - dirContextProcessorMock.postProcess(dirContextMock); + dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, - handlerMock, dirContextProcessorMock); + tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, handlerMock, dirContextProcessorMock); - verify(); - } + verify(); + } - public void testSearch_String_AttributesMapper_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_AttributesMapper_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - dirContextProcessorMock.preProcess(dirContextMock); - setupStringSearchAndNamingEnumeration(controls, searchResult); + dirContextProcessorMock.preProcess(dirContextMock); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - controls, attributesMapperMock, dirContextProcessorMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, attributesMapperMock, + dirContextProcessorMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_Name_AttributesMapper_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_Name_AttributesMapper_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - dirContextProcessorMock.preProcess(dirContextMock); - setupSearchAndNamingEnumeration(controls, searchResult); + dirContextProcessorMock.preProcess(dirContextMock); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", controls, - attributesMapperMock, dirContextProcessorMock); + List list = tested.search(nameMock, "(ou=somevalue)", controls, attributesMapperMock, dirContextProcessorMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_SearchControls_ContextMapper_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_SearchControls_ContextMapper_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - dirContextProcessorMock.preProcess(dirContextMock); - setupStringSearchAndNamingEnumeration(controls, searchResult); + dirContextProcessorMock.preProcess(dirContextMock); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - controls, contextMapperMock, dirContextProcessorMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, contextMapperMock, + dirContextProcessorMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_Name_SearchControls_ContextMapper_DirContextProcessor() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_Name_SearchControls_ContextMapper_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - dirContextProcessorMock.preProcess(dirContextMock); - setupSearchAndNamingEnumeration(controls, searchResult); + dirContextProcessorMock.preProcess(dirContextMock); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", controls, - contextMapperMock, dirContextProcessorMock); + List list = tested.search(nameMock, "(ou=somevalue)", controls, contextMapperMock, dirContextProcessorMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_AttributesMapper_ReturningAttrs() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_AttributesMapper_ReturningAttrs() throws Exception { + expectGetReadOnlyContext(); - String[] attrs = new String[0]; - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); - controls.setReturningAttributes(attrs); + String[] attrs = new String[0]; + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); + controls.setReturningAttributes(attrs); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", 1, attrs, - attributesMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", 1, attrs, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_AttributesMapper_ReturningAttrs() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_AttributesMapper_ReturningAttrs() throws Exception { + expectGetReadOnlyContext(); - String[] attrs = new String[0]; - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); - controls.setReturningAttributes(attrs); + String[] attrs = new String[0]; + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); + controls.setReturningAttributes(attrs); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, - attrs, attributesMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, attrs, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_AttributesMapper() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_AttributesMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", 1, - attributesMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", 1, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_AttributesMapper() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_AttributesMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, - attributesMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_AttributesMapper_Default() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_AttributesMapper_Default() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", - attributesMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_AttributesMapper_Default() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_AttributesMapper_Default() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - attributesMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_ContextMapper() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_ContextMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", 1, - contextMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", 1, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_ContextMapper_ReturningAttrs() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_ContextMapper_ReturningAttrs() throws Exception { + expectGetReadOnlyContext(); - String[] attrs = new String[0]; + String[] attrs = new String[0]; - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); - controls.setReturningAttributes(attrs); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); + controls.setReturningAttributes(attrs); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", 1, attrs, - contextMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", 1, attrs, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_ContextMapper_ReturningAttrs() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_ContextMapper_ReturningAttrs() throws Exception { + expectGetReadOnlyContext(); - String[] attrs = new String[0]; + String[] attrs = new String[0]; - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); - controls.setReturningAttributes(attrs); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); + controls.setReturningAttributes(attrs); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, - attrs, contextMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, attrs, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_ContextMapper() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_ContextMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, - contextMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", 1, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_ContextMapper_Default() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_ContextMapper_Default() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested - .search(nameMock, "(ou=somevalue)", contextMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_ContextMapper_Default() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_ContextMapper_Default() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - contextMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_SearchControls_ContextMapper() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_SearchControls_ContextMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - controls, contextMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_SearchControls_ContextMapper_ReturningObjFlagNotSet() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_SearchControls_ContextMapper_ReturningObjFlagNotSet() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - SearchControls expectedControls = new SearchControls(); - expectedControls.setSearchScope(SearchControls.SUBTREE_SCOPE); - expectedControls.setReturningObjFlag(true); + SearchControls expectedControls = new SearchControls(); + expectedControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + expectedControls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupStringSearchAndNamingEnumeration(expectedControls, searchResult); + setupStringSearchAndNamingEnumeration(expectedControls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - controls, contextMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_Name_SearchControls_ContextMapper() throws Exception { - expectGetReadOnlyContext(); + public void testSearch_Name_SearchControls_ContextMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + controls.setReturningObjFlag(true); - Object expectedObject = new Object(); - SearchResult searchResult = new SearchResult("", expectedObject, - new BasicAttributes()); + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = expectedObject; - contextMapperControl.expectAndReturn(contextMapperMock - .mapFromContext(expectedObject), expectedResult); + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", controls, - contextMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", controls, contextMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_String_SearchControls_AttributesMapper() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_String_SearchControls_AttributesMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupStringSearchAndNamingEnumeration(controls, searchResult); + setupStringSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", - controls, attributesMapperMock); + List list = tested.search(DEFAULT_BASE_STRING, "(ou=somevalue)", controls, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testSearch_Name_SearchControls_AttributesMapper() - throws Exception { - expectGetReadOnlyContext(); + public void testSearch_Name_SearchControls_AttributesMapper() throws Exception { + expectGetReadOnlyContext(); - SearchControls controls = new SearchControls(); - controls.setSearchScope(1); - controls.setReturningObjFlag(false); + SearchControls controls = new SearchControls(); + controls.setSearchScope(1); + controls.setReturningObjFlag(false); - BasicAttributes expectedAttributes = new BasicAttributes(); - SearchResult searchResult = new SearchResult("", null, - expectedAttributes); + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); - setupSearchAndNamingEnumeration(controls, searchResult); + setupSearchAndNamingEnumeration(controls, searchResult); - Object expectedResult = new Object(); - attributesMapperControl.expectAndReturn(attributesMapperMock - .mapFromAttributes(expectedAttributes), expectedResult); + Object expectedResult = new Object(); + attributesMapperControl.expectAndReturn(attributesMapperMock.mapFromAttributes(expectedAttributes), + expectedResult); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - List list = tested.search(nameMock, "(ou=somevalue)", controls, - attributesMapperMock); + List list = tested.search(nameMock, "(ou=somevalue)", controls, attributesMapperMock); - verify(); + verify(); - assertNotNull(list); - assertEquals(1, list.size()); - assertSame(expectedResult, list.get(0)); - } + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } - public void testModifyAttributes() throws Exception { - expectGetReadWriteContext(); + public void testModifyAttributes() throws Exception { + expectGetReadWriteContext(); - ModificationItem[] mods = new ModificationItem[0]; - dirContextMock.modifyAttributes(nameMock, mods); + ModificationItem[] mods = new ModificationItem[0]; + dirContextMock.modifyAttributes(nameMock, mods); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.modifyAttributes(nameMock, mods); + tested.modifyAttributes(nameMock, mods); - verify(); - } + verify(); + } - public void testModifyAttributes_String() throws Exception { - expectGetReadWriteContext(); + public void testModifyAttributes_String() throws Exception { + expectGetReadWriteContext(); - ModificationItem[] mods = new ModificationItem[0]; - dirContextMock.modifyAttributes(DEFAULT_BASE_STRING, mods); + ModificationItem[] mods = new ModificationItem[0]; + dirContextMock.modifyAttributes(DEFAULT_BASE_STRING, mods); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - tested.modifyAttributes(DEFAULT_BASE_STRING, mods); + tested.modifyAttributes(DEFAULT_BASE_STRING, mods); - verify(); - } + verify(); + } - public void testModifyAttributes_NamingException() throws Exception { - expectGetReadWriteContext(); + public void testModifyAttributes_NamingException() throws Exception { + expectGetReadWriteContext(); - ModificationItem[] mods = new ModificationItem[0]; - dirContextMock.modifyAttributes(nameMock, mods); - javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); - dirContextControl.setThrowable(ne); + ModificationItem[] mods = new ModificationItem[0]; + dirContextMock.modifyAttributes(nameMock, mods); + javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); + dirContextControl.setThrowable(ne); - dirContextMock.close(); + dirContextMock.close(); - replay(); + replay(); - try { - tested.modifyAttributes(nameMock, mods); - fail("LimitExceededException expected"); - } catch (LimitExceededException expected) { - assertTrue(true); - } + try { + tested.modifyAttributes(nameMock, mods); + fail("LimitExceededException expected"); + } + catch (LimitExceededException expected) { + assertTrue(true); + } - verify(); - } + verify(); + } - public void testBind() throws Exception { - expectGetReadWriteContext(); + public void testBind() throws Exception { + expectGetReadWriteContext(); - Object expectedObject = new Object(); - BasicAttributes expectedAttributes = new BasicAttributes(); - dirContextMock.bind(nameMock, expectedObject, expectedAttributes); - dirContextMock.close(); + Object expectedObject = new Object(); + BasicAttributes expectedAttributes = new BasicAttributes(); + dirContextMock.bind(nameMock, expectedObject, expectedAttributes); + dirContextMock.close(); - replay(); + replay(); - tested.bind(nameMock, expectedObject, expectedAttributes); + tested.bind(nameMock, expectedObject, expectedAttributes); - verify(); + verify(); - } + } - public void testBind_String() throws Exception { - expectGetReadWriteContext(); + public void testBind_String() throws Exception { + expectGetReadWriteContext(); - Object expectedObject = new Object(); - BasicAttributes expectedAttributes = new BasicAttributes(); - dirContextMock.bind(DEFAULT_BASE_STRING, expectedObject, - expectedAttributes); - dirContextMock.close(); + Object expectedObject = new Object(); + BasicAttributes expectedAttributes = new BasicAttributes(); + dirContextMock.bind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); + dirContextMock.close(); - replay(); + replay(); - tested.bind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); + tested.bind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); - verify(); + verify(); - } + } - public void testBind_NamingException() throws Exception { - expectGetReadWriteContext(); + public void testBind_NamingException() throws Exception { + expectGetReadWriteContext(); - Object expectedObject = new Object(); - BasicAttributes expectedAttributes = new BasicAttributes(); - dirContextMock.bind(nameMock, expectedObject, expectedAttributes); - javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); - dirContextControl.setThrowable(ne); - dirContextMock.close(); + Object expectedObject = new Object(); + BasicAttributes expectedAttributes = new BasicAttributes(); + dirContextMock.bind(nameMock, expectedObject, expectedAttributes); + javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); + dirContextControl.setThrowable(ne); + dirContextMock.close(); - replay(); + replay(); - try { - tested.bind(nameMock, expectedObject, expectedAttributes); - fail("NameNotFoundException expected"); - } catch (NameNotFoundException expected) { - assertTrue(true); - } - - verify(); - - } - - public void testUnbind() throws Exception { - expectGetReadWriteContext(); - - dirContextMock.unbind(nameMock); - dirContextMock.close(); - replay(); - - tested.unbind(nameMock); - - verify(); - } - - public void testUnbind_String() throws Exception { - expectGetReadWriteContext(); - - dirContextMock.unbind(DEFAULT_BASE_STRING); - dirContextMock.close(); - replay(); - - tested.unbind(DEFAULT_BASE_STRING); - - verify(); - } - - public void testUnbindRecursive() throws Exception { - expectGetReadWriteContext(); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - Binding binding = new Binding("cn=Some name", null); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - binding); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - DistinguishedName listDn = new DistinguishedName(DEFAULT_BASE_STRING); - dirContextMock.listBindings(listDn); - dirContextControl.setReturnValue(namingEnumerationMock); - DistinguishedName subListDn = new DistinguishedName( - "cn=Some name, o=example.com"); - dirContextMock.listBindings(subListDn); - dirContextControl.setReturnValue(namingEnumerationMock); - - dirContextMock.unbind(subListDn); - dirContextMock.unbind(listDn); - dirContextMock.close(); - - // Caused by creating a DistinguishedName from a Name - nameControl.expectAndReturn(nameMock.size(), 1, 2); - nameControl.expectAndReturn(nameMock.get(0), "o=example.com"); - - replay(); - - tested.unbind(nameMock, true); - - verify(); - } - - public void testUnbindRecursive_String() throws Exception { - expectGetReadWriteContext(); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - Binding binding = new Binding("cn=Some name", null); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - binding); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - DistinguishedName listDn = new DistinguishedName(DEFAULT_BASE_STRING); - dirContextMock.listBindings(listDn); - dirContextControl.setReturnValue(namingEnumerationMock); - DistinguishedName subListDn = new DistinguishedName( - "cn=Some name, o=example.com"); - dirContextMock.listBindings(subListDn); - dirContextControl.setReturnValue(namingEnumerationMock); - - dirContextMock.unbind(subListDn); - dirContextMock.unbind(listDn); - dirContextMock.close(); - replay(); - - tested.unbind(DEFAULT_BASE_STRING, true); - - verify(); - } - - public void testRebind() throws Exception { - expectGetReadWriteContext(); - - Object expectedObject = new Object(); - BasicAttributes expectedAttributes = new BasicAttributes(); - dirContextMock.rebind(nameMock, expectedObject, expectedAttributes); - - dirContextMock.close(); - - replay(); - - tested.rebind(nameMock, expectedObject, expectedAttributes); - - verify(); - } - - public void testRebind_String() throws Exception { - expectGetReadWriteContext(); - - Object expectedObject = new Object(); - BasicAttributes expectedAttributes = new BasicAttributes(); - dirContextMock.rebind(DEFAULT_BASE_STRING, expectedObject, - expectedAttributes); - - dirContextMock.close(); - - replay(); - - tested.rebind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); - - verify(); - } - - public void testUnbind_NamingException() throws Exception { - expectGetReadWriteContext(); - - dirContextMock.unbind(nameMock); - javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); - dirContextControl.setThrowable(ne); - dirContextMock.close(); - - replay(); - - try { - tested.unbind(nameMock); - fail("NameNotFoundException expected"); - } catch (NameNotFoundException expected) { - assertTrue(true); - } - - verify(); - } - - public void testExecuteReadOnly() throws Exception { - expectGetReadOnlyContext(); - - Object object = new Object(); - contextExecutorControl.expectAndReturn(contextExecutorMock - .executeWithContext(dirContextMock), object); - - dirContextMock.close(); - - replay(); - - Object result = tested.executeReadOnly(contextExecutorMock); - - verify(); - - assertSame(object, result); - } - - public void testExecuteReadOnly_NamingException() throws Exception { - expectGetReadOnlyContext(); - - javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); - contextExecutorControl.expectAndThrow(contextExecutorMock - .executeWithContext(dirContextMock), ne); - - dirContextMock.close(); - - replay(); - - try { - tested.executeReadOnly(contextExecutorMock); - fail("NameNotFoundException expected"); - } catch (NameNotFoundException expected) { - assertTrue(true); - } - - verify(); - } - - public void testExecuteReadWrite() throws Exception { - expectGetReadWriteContext(); - - Object object = new Object(); - contextExecutorControl.expectAndReturn(contextExecutorMock - .executeWithContext(dirContextMock), object); - - dirContextMock.close(); - - replay(); - - Object result = tested.executeReadWrite(contextExecutorMock); - - verify(); - - assertSame(object, result); - } - - public void testExecuteReadWrite_NamingException() throws Exception { - expectGetReadWriteContext(); - - javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); - contextExecutorControl.expectAndThrow(contextExecutorMock - .executeWithContext(dirContextMock), ne); - - dirContextMock.close(); - - replay(); - - try { - tested.executeReadWrite(contextExecutorMock); - fail("NameNotFoundException expected"); - } catch (NameNotFoundException expected) { - assertTrue(true); - } - - verify(); - } - - public void testDoSearch_DirContextProcessor() throws Exception { - expectGetReadOnlyContext(); - - SearchResult searchResult = new SearchResult(null, null, null); - - dirContextProcessorMock.preProcess(dirContextMock); - - searchExecutorControl.expectAndReturn(searchExecutorMock - .executeSearch(dirContextMock), namingEnumerationMock); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - searchResult); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - handlerMock.handleNameClassPair(searchResult); - - dirContextProcessorMock.postProcess(dirContextMock); - - dirContextMock.close(); - - replay(); - - tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); - - verify(); - } - - public void testDoSearch_DirContextProcessor_NamingException() - throws Exception { - expectGetReadOnlyContext(); - - dirContextProcessorMock.preProcess(dirContextMock); - - javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); - searchExecutorControl.expectAndThrow(searchExecutorMock - .executeSearch(dirContextMock), ne); - - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); - - replay(); - - try { - tested.search(searchExecutorMock, handlerMock, - dirContextProcessorMock); - fail("LimitExceededException expected"); - } catch (LimitExceededException expected) { - assertTrue(true); - } - - verify(); - } - - public void testDoSearch() throws Exception { - expectGetReadOnlyContext(); - - SearchResult searchResult = new SearchResult(null, null, null); - - searchExecutorControl.expectAndReturn(searchExecutorMock - .executeSearch(dirContextMock), namingEnumerationMock); - - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), true); - namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), - searchResult); - namingEnumerationControl.expectAndReturn(namingEnumerationMock - .hasMore(), false); - namingEnumerationMock.close(); - - handlerMock.handleNameClassPair(searchResult); - - dirContextMock.close(); - - replay(); - - tested.search(searchExecutorMock, handlerMock); - - verify(); - } - - public void testDoSearch_NamingException() throws Exception { - expectGetReadOnlyContext(); - - javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); - searchExecutorControl.expectAndThrow(searchExecutorMock - .executeSearch(dirContextMock), ne); - - dirContextMock.close(); - - replay(); - - try { - tested.search(searchExecutorMock, handlerMock); - fail("LimitExceededException expected"); - } catch (LimitExceededException expected) { - assertTrue(true); - } - - verify(); - } - - public void testDoSearch_NamingException_NamingEnumeration() - throws Exception { - expectGetReadOnlyContext(); - - searchExecutorControl.expectAndReturn(searchExecutorMock - .executeSearch(dirContextMock), namingEnumerationMock); - - javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); - namingEnumerationControl.expectAndThrow( - namingEnumerationMock.hasMore(), ne); - namingEnumerationMock.close(); - - dirContextMock.close(); - - replay(); - - try { - tested.search(searchExecutorMock, handlerMock); - fail("LimitExceededException expected"); - } catch (LimitExceededException expected) { - assertTrue(true); - } - - verify(); - } - - public void testDoSearch_NameNotFoundException() throws Exception { - expectGetReadOnlyContext(); - - searchExecutorControl.expectAndThrow(searchExecutorMock - .executeSearch(dirContextMock), - new javax.naming.NameNotFoundException()); - dirContextMock.close(); - - replay(); - - try { - tested.search(searchExecutorMock, handlerMock); + try { + tested.bind(nameMock, expectedObject, expectedAttributes); fail("NameNotFoundException expected"); } catch (NameNotFoundException expected) { assertTrue(true); } - verify(); - } + verify(); - public void testSearch_PartialResult_IgnoreNotSet() throws Exception { - expectGetReadOnlyContext(); + } - dirContextProcessorMock.preProcess(dirContextMock); + public void testUnbind() throws Exception { + expectGetReadWriteContext(); - javax.naming.PartialResultException ex = new javax.naming.PartialResultException(); - searchExecutorControl.expectAndThrow(searchExecutorMock - .executeSearch(dirContextMock), ex); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + dirContextMock.unbind(nameMock); + dirContextMock.close(); + replay(); - replay(); + tested.unbind(nameMock); - try { - tested.search(searchExecutorMock, handlerMock, - dirContextProcessorMock); - fail("PartialResultException expected"); - } catch (PartialResultException expected) { - assertTrue(true); - } + verify(); + } - verify(); - } + public void testUnbind_String() throws Exception { + expectGetReadWriteContext(); - public void testSearch_PartialResult_IgnoreSet() throws Exception { - tested.setIgnorePartialResultException(true); + dirContextMock.unbind(DEFAULT_BASE_STRING); + dirContextMock.close(); + replay(); - expectGetReadOnlyContext(); + tested.unbind(DEFAULT_BASE_STRING); - dirContextProcessorMock.preProcess(dirContextMock); + verify(); + } - searchExecutorControl.expectAndThrow(searchExecutorMock - .executeSearch(dirContextMock), - new javax.naming.PartialResultException()); + public void testUnbindRecursive() throws Exception { + expectGetReadWriteContext(); - dirContextProcessorMock.postProcess(dirContextMock); - dirContextMock.close(); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + Binding binding = new Binding("cn=Some name", null); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), binding); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); - replay(); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); - tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); + DistinguishedName listDn = new DistinguishedName(DEFAULT_BASE_STRING); + dirContextMock.listBindings(listDn); + dirContextControl.setReturnValue(namingEnumerationMock); + DistinguishedName subListDn = new DistinguishedName("cn=Some name, o=example.com"); + dirContextMock.listBindings(subListDn); + dirContextControl.setReturnValue(namingEnumerationMock); - verify(); - } + dirContextMock.unbind(subListDn); + dirContextMock.unbind(listDn); + dirContextMock.close(); - public void testLookupContextWithName() { - final DirContextAdapter expectedResult = new DirContextAdapter(); + // Caused by creating a DistinguishedName from a Name + nameControl.expectAndReturn(nameMock.size(), 1, 2); + nameControl.expectAndReturn(nameMock.get(0), "o=example.com"); - LdapTemplate tested = new LdapTemplate() { - public Object lookup(Name dn) { - assertSame(DistinguishedName.EMPTY_PATH, dn); - return expectedResult; - } - }; + replay(); - DirContextOperations result = tested - .lookupContext(DistinguishedName.EMPTY_PATH); - assertSame(expectedResult, result); + tested.unbind(nameMock, true); - } + verify(); + } - public void testLookupContextWithString() { - final DirContextAdapter expectedResult = new DirContextAdapter(); - final String expectedName = "cn=John Doe"; + public void testUnbindRecursive_String() throws Exception { + expectGetReadWriteContext(); - LdapTemplate tested = new LdapTemplate() { - public Object lookup(String dn) { - assertSame(expectedName, dn); - return expectedResult; - } - }; + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + Binding binding = new Binding("cn=Some name", null); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), binding); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); - DirContextOperations result = tested.lookupContext(expectedName); - assertSame(expectedResult, result); - } + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); - public void testModifyAttributesWithDirContextOperations() throws Exception { - final ModificationItem[] expectedModifications = new ModificationItem[0]; + DistinguishedName listDn = new DistinguishedName(DEFAULT_BASE_STRING); + dirContextMock.listBindings(listDn); + dirContextControl.setReturnValue(namingEnumerationMock); + DistinguishedName subListDn = new DistinguishedName("cn=Some name, o=example.com"); + dirContextMock.listBindings(subListDn); + dirContextControl.setReturnValue(namingEnumerationMock); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .getDn(), DistinguishedName.EMPTY_PATH); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .isUpdateMode(), true); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .getModificationItems(), expectedModifications); + dirContextMock.unbind(subListDn); + dirContextMock.unbind(listDn); + dirContextMock.close(); + replay(); - LdapTemplate tested = new LdapTemplate() { - public void modifyAttributes(Name dn, ModificationItem[] mods) { - assertSame(DistinguishedName.EMPTY_PATH, dn); - assertSame(expectedModifications, mods); - } - }; + tested.unbind(DEFAULT_BASE_STRING, true); - replay(); + verify(); + } - tested.modifyAttributes(dirContextOperationsMock); + public void testRebind() throws Exception { + expectGetReadWriteContext(); - verify(); - } + Object expectedObject = new Object(); + BasicAttributes expectedAttributes = new BasicAttributes(); + dirContextMock.rebind(nameMock, expectedObject, expectedAttributes); - public void testModifyAttributesWithDirContextOperationsNotInitializedDn() - throws Exception { + dirContextMock.close(); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .getDn(), DistinguishedName.EMPTY_PATH); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .isUpdateMode(), false); + replay(); - LdapTemplate tested = new LdapTemplate() { - public void modifyAttributes(Name dn, ModificationItem[] mods) { - fail("The call to the base modifyAttributes should not have occured."); - } - }; + tested.rebind(nameMock, expectedObject, expectedAttributes); - replay(); + verify(); + } - try { - tested.modifyAttributes(dirContextOperationsMock); - fail("IllegalStateException expected"); - } catch (IllegalStateException expected) { - assertTrue(true); - } - verify(); - } + public void testRebind_String() throws Exception { + expectGetReadWriteContext(); - public void testModifyAttributesWithDirContextOperationsNotInitializedInUpdateMode() - throws Exception { + Object expectedObject = new Object(); + BasicAttributes expectedAttributes = new BasicAttributes(); + dirContextMock.rebind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); - dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock - .getDn(), null); + dirContextMock.close(); - LdapTemplate tested = new LdapTemplate() { - public void modifyAttributes(Name dn, ModificationItem[] mods) { - fail("The call to the base modifyAttributes should not have occured."); - } - }; + replay(); - replay(); + tested.rebind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes); - try { - tested.modifyAttributes(dirContextOperationsMock); - fail("IllegalStateException expected"); - } catch (IllegalStateException expected) { - assertTrue(true); - } - verify(); - } + verify(); + } - /** - * Needed to verify search control values. - * - * @author Mattias Hellborg Arthursson - */ - private static class SearchControlsMatcher extends AbstractMatcher { - protected boolean argumentMatches(Object arg0, Object arg1) { - if (arg0 instanceof SearchControls - && arg1 instanceof SearchControls) { - SearchControls s0 = (SearchControls) arg0; - SearchControls s1 = (SearchControls) arg1; + public void testUnbind_NamingException() throws Exception { + expectGetReadWriteContext(); - return s0.getSearchScope() == s1.getSearchScope() - && s0.getReturningObjFlag() == s1.getReturningObjFlag() - && s0.getDerefLinkFlag() == s1.getDerefLinkFlag() - && s0.getCountLimit() == s1.getCountLimit() - && s0.getTimeLimit() == s1.getTimeLimit() - && s0.getReturningAttributes() == s1 - .getReturningAttributes(); - } else { - return super.argumentMatches(arg0, arg1); - } - } - } + dirContextMock.unbind(nameMock); + javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); + dirContextControl.setThrowable(ne); + dirContextMock.close(); + + replay(); + + try { + tested.unbind(nameMock); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + verify(); + } + + public void testExecuteReadOnly() throws Exception { + expectGetReadOnlyContext(); + + Object object = new Object(); + contextExecutorControl.expectAndReturn(contextExecutorMock.executeWithContext(dirContextMock), object); + + dirContextMock.close(); + + replay(); + + Object result = tested.executeReadOnly(contextExecutorMock); + + verify(); + + assertSame(object, result); + } + + public void testExecuteReadOnly_NamingException() throws Exception { + expectGetReadOnlyContext(); + + javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); + contextExecutorControl.expectAndThrow(contextExecutorMock.executeWithContext(dirContextMock), ne); + + dirContextMock.close(); + + replay(); + + try { + tested.executeReadOnly(contextExecutorMock); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + verify(); + } + + public void testExecuteReadWrite() throws Exception { + expectGetReadWriteContext(); + + Object object = new Object(); + contextExecutorControl.expectAndReturn(contextExecutorMock.executeWithContext(dirContextMock), object); + + dirContextMock.close(); + + replay(); + + Object result = tested.executeReadWrite(contextExecutorMock); + + verify(); + + assertSame(object, result); + } + + public void testExecuteReadWrite_NamingException() throws Exception { + expectGetReadWriteContext(); + + javax.naming.NameNotFoundException ne = new javax.naming.NameNotFoundException(); + contextExecutorControl.expectAndThrow(contextExecutorMock.executeWithContext(dirContextMock), ne); + + dirContextMock.close(); + + replay(); + + try { + tested.executeReadWrite(contextExecutorMock); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + verify(); + } + + public void testDoSearch_DirContextProcessor() throws Exception { + expectGetReadOnlyContext(); + + SearchResult searchResult = new SearchResult(null, null, null); + + dirContextProcessorMock.preProcess(dirContextMock); + + searchExecutorControl.expectAndReturn(searchExecutorMock.executeSearch(dirContextMock), namingEnumerationMock); + + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + + handlerMock.handleNameClassPair(searchResult); + + dirContextProcessorMock.postProcess(dirContextMock); + + dirContextMock.close(); + + replay(); + + tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); + + verify(); + } + + public void testDoSearch_DirContextProcessor_NamingException() throws Exception { + expectGetReadOnlyContext(); + + dirContextProcessorMock.preProcess(dirContextMock); + + javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); + searchExecutorControl.expectAndThrow(searchExecutorMock.executeSearch(dirContextMock), ne); + + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); + + replay(); + + try { + tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); + fail("LimitExceededException expected"); + } + catch (LimitExceededException expected) { + assertTrue(true); + } + + verify(); + } + + public void testDoSearch() throws Exception { + expectGetReadOnlyContext(); + + SearchResult searchResult = new SearchResult(null, null, null); + + searchExecutorControl.expectAndReturn(searchExecutorMock.executeSearch(dirContextMock), namingEnumerationMock); + + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + + handlerMock.handleNameClassPair(searchResult); + + dirContextMock.close(); + + replay(); + + tested.search(searchExecutorMock, handlerMock); + + verify(); + } + + public void testDoSearch_NamingException() throws Exception { + expectGetReadOnlyContext(); + + javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); + searchExecutorControl.expectAndThrow(searchExecutorMock.executeSearch(dirContextMock), ne); + + dirContextMock.close(); + + replay(); + + try { + tested.search(searchExecutorMock, handlerMock); + fail("LimitExceededException expected"); + } + catch (LimitExceededException expected) { + assertTrue(true); + } + + verify(); + } + + public void testDoSearch_NamingException_NamingEnumeration() throws Exception { + expectGetReadOnlyContext(); + + searchExecutorControl.expectAndReturn(searchExecutorMock.executeSearch(dirContextMock), namingEnumerationMock); + + javax.naming.LimitExceededException ne = new javax.naming.LimitExceededException(); + namingEnumerationControl.expectAndThrow(namingEnumerationMock.hasMore(), ne); + namingEnumerationMock.close(); + + dirContextMock.close(); + + replay(); + + try { + tested.search(searchExecutorMock, handlerMock); + fail("LimitExceededException expected"); + } + catch (LimitExceededException expected) { + assertTrue(true); + } + + verify(); + } + + public void testDoSearch_NameNotFoundException() throws Exception { + expectGetReadOnlyContext(); + + searchExecutorControl.expectAndThrow(searchExecutorMock.executeSearch(dirContextMock), + new javax.naming.NameNotFoundException()); + dirContextMock.close(); + + replay(); + + try { + tested.search(searchExecutorMock, handlerMock); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + verify(); + } + + public void testSearch_PartialResult_IgnoreNotSet() throws Exception { + expectGetReadOnlyContext(); + + dirContextProcessorMock.preProcess(dirContextMock); + + javax.naming.PartialResultException ex = new javax.naming.PartialResultException(); + searchExecutorControl.expectAndThrow(searchExecutorMock.executeSearch(dirContextMock), ex); + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); + + replay(); + + try { + tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); + fail("PartialResultException expected"); + } + catch (PartialResultException expected) { + assertTrue(true); + } + + verify(); + } + + public void testSearch_PartialResult_IgnoreSet() throws Exception { + tested.setIgnorePartialResultException(true); + + expectGetReadOnlyContext(); + + dirContextProcessorMock.preProcess(dirContextMock); + + searchExecutorControl.expectAndThrow(searchExecutorMock.executeSearch(dirContextMock), + new javax.naming.PartialResultException()); + + dirContextProcessorMock.postProcess(dirContextMock); + dirContextMock.close(); + + replay(); + + tested.search(searchExecutorMock, handlerMock, dirContextProcessorMock); + + verify(); + } + + public void testLookupContextWithName() { + final DirContextAdapter expectedResult = new DirContextAdapter(); + + LdapTemplate tested = new LdapTemplate() { + public Object lookup(Name dn) { + assertSame(DistinguishedName.EMPTY_PATH, dn); + return expectedResult; + } + }; + + DirContextOperations result = tested.lookupContext(DistinguishedName.EMPTY_PATH); + assertSame(expectedResult, result); + + } + + public void testLookupContextWithString() { + final DirContextAdapter expectedResult = new DirContextAdapter(); + final String expectedName = "cn=John Doe"; + + LdapTemplate tested = new LdapTemplate() { + public Object lookup(String dn) { + assertSame(expectedName, dn); + return expectedResult; + } + }; + + DirContextOperations result = tested.lookupContext(expectedName); + assertSame(expectedResult, result); + } + + public void testModifyAttributesWithDirContextOperations() throws Exception { + final ModificationItem[] expectedModifications = new ModificationItem[0]; + + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.getDn(), DistinguishedName.EMPTY_PATH); + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.isUpdateMode(), true); + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.getModificationItems(), + expectedModifications); + + LdapTemplate tested = new LdapTemplate() { + public void modifyAttributes(Name dn, ModificationItem[] mods) { + assertSame(DistinguishedName.EMPTY_PATH, dn); + assertSame(expectedModifications, mods); + } + }; + + replay(); + + tested.modifyAttributes(dirContextOperationsMock); + + verify(); + } + + public void testModifyAttributesWithDirContextOperationsNotInitializedDn() throws Exception { + + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.getDn(), DistinguishedName.EMPTY_PATH); + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.isUpdateMode(), false); + + LdapTemplate tested = new LdapTemplate() { + public void modifyAttributes(Name dn, ModificationItem[] mods) { + fail("The call to the base modifyAttributes should not have occured."); + } + }; + + replay(); + + try { + tested.modifyAttributes(dirContextOperationsMock); + fail("IllegalStateException expected"); + } + catch (IllegalStateException expected) { + assertTrue(true); + } + verify(); + } + + public void testModifyAttributesWithDirContextOperationsNotInitializedInUpdateMode() throws Exception { + + dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock.getDn(), null); + + LdapTemplate tested = new LdapTemplate() { + public void modifyAttributes(Name dn, ModificationItem[] mods) { + fail("The call to the base modifyAttributes should not have occured."); + } + }; + + replay(); + + try { + tested.modifyAttributes(dirContextOperationsMock); + fail("IllegalStateException expected"); + } + catch (IllegalStateException expected) { + assertTrue(true); + } + verify(); + } + + public void testSearchForObject() throws Exception { + expectGetReadOnlyContext(); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); + + setupSearchAndNamingEnumeration(controls, searchResult); + + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); + + dirContextMock.close(); + + replay(); + + Object result = tested.searchForObject(nameMock, "(ou=somevalue)", contextMapperMock); + + verify(); + + assertNotNull(result); + assertSame(expectedResult, result); + } + + public void testSearchForObjectWithMultipleResults() throws Exception { + expectGetReadOnlyContext(); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + Object expectedObject = new Object(); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); + + dirContextControl.setDefaultMatcher(new SearchControlsMatcher()); + dirContextControl.expectAndReturn(dirContextMock.search(nameMock, "(ou=somevalue)", controls), + namingEnumerationMock); + + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), true); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.next(), searchResult); + namingEnumerationControl.expectAndReturn(namingEnumerationMock.hasMore(), false); + namingEnumerationMock.close(); + + Object expectedResult = expectedObject; + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); + contextMapperControl.expectAndReturn(contextMapperMock.mapFromContext(expectedObject), expectedResult); + + dirContextMock.close(); + + replay(); + + try { + tested.searchForObject(nameMock, "(ou=somevalue)", contextMapperMock); + fail("IncorrectResultSizeDataAccessException expected"); + } + catch (IncorrectResultSizeDataAccessException expected) { + assertTrue(true); + } + + verify(); + } + + public void testSearchForObjectWithNoResults() throws Exception { + expectGetReadOnlyContext(); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + setupSearchAndNamingEnumerationForNoHits(controls); + + dirContextMock.close(); + + replay(); + + try { + tested.searchForObject(nameMock, "(ou=somevalue)", contextMapperMock); + fail("EmptyResultDataAccessException expected"); + } + catch (EmptyResultDataAccessException expected) { + assertTrue(true); + } + verify(); + } + + public void testAuthenticate() throws Exception { + contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + Object expectedObject = new DirContextAdapter(new BasicAttributes(), new DistinguishedName("cn=john doe"), + new DistinguishedName("dc=jayway, dc=se")); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); + + setupSearchAndNamingEnumeration(controls, searchResult); + + MockControl authenticatedContextControl = MockControl.createControl(DirContext.class); + DirContext authenticatedContextMock = (DirContext) authenticatedContextControl.getMock(); + + MockControl entryContextCallbackControl = MockControl + .createControl(AuthenticatedLdapEntryContextCallback.class); + AuthenticatedLdapEntryContextCallback entryContextCallbackMock = (AuthenticatedLdapEntryContextCallback) entryContextCallbackControl + .getMock(); + + contextSourceControl.expectAndReturn(contextSourceMock.getContext("cn=john doe,dc=jayway,dc=se", "password"), + authenticatedContextMock); + entryContextCallbackMock.executeWithContext(authenticatedContextMock, new LdapEntryIdentification( + new DistinguishedName("cn=john doe,dc=jayway,dc=se"), new DistinguishedName("cn=john doe"))); + + authenticatedContextMock.close(); + dirContextMock.close(); + + replay(); + authenticatedContextControl.replay(); + entryContextCallbackControl.replay(); + + boolean result = tested.authenticate(nameMock, "(ou=somevalue)", "password", entryContextCallbackMock); + + verify(); + authenticatedContextControl.verify(); + entryContextCallbackControl.verify(); + + assertTrue(result); + } + + public void testAuthenticateWithFailedAuthentication() throws Exception { + contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + Object expectedObject = new DirContextAdapter(new BasicAttributes(), new DistinguishedName("cn=john doe"), + new DistinguishedName("dc=jayway, dc=se")); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); + + setupSearchAndNamingEnumeration(controls, searchResult); + + MockControl entryContextCallbackControl = MockControl + .createControl(AuthenticatedLdapEntryContextCallback.class); + AuthenticatedLdapEntryContextCallback entryContextCallbackMock = (AuthenticatedLdapEntryContextCallback) entryContextCallbackControl + .getMock(); + + contextSourceControl.expectAndThrow(contextSourceMock.getContext("cn=john doe,dc=jayway,dc=se", "password"), + new UncategorizedLdapException("Authentication failed")); + + dirContextMock.close(); + + replay(); + entryContextCallbackControl.replay(); + + boolean result = tested.authenticate(nameMock, "(ou=somevalue)", "password", entryContextCallbackMock); + + verify(); + entryContextCallbackControl.verify(); + + assertFalse(result); + } + + public void testAuthenticateWithErrorInCallback() throws Exception { + contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock); + + SearchControls controls = new SearchControls(); + controls.setSearchScope(2); + controls.setReturningObjFlag(true); + + Object expectedObject = new DirContextAdapter(new BasicAttributes(), new DistinguishedName("cn=john doe"), + new DistinguishedName("dc=jayway, dc=se")); + SearchResult searchResult = new SearchResult("", expectedObject, new BasicAttributes()); + + setupSearchAndNamingEnumeration(controls, searchResult); + + MockControl authenticatedContextControl = MockControl.createControl(DirContext.class); + DirContext authenticatedContextMock = (DirContext) authenticatedContextControl.getMock(); + + MockControl entryContextCallbackControl = MockControl + .createControl(AuthenticatedLdapEntryContextCallback.class); + AuthenticatedLdapEntryContextCallback entryContextCallbackMock = (AuthenticatedLdapEntryContextCallback) entryContextCallbackControl + .getMock(); + + contextSourceControl.expectAndReturn(contextSourceMock.getContext("cn=john doe,dc=jayway,dc=se", "password"), + authenticatedContextMock); + entryContextCallbackMock.executeWithContext(authenticatedContextMock, new LdapEntryIdentification( + new DistinguishedName("cn=john doe,dc=jayway,dc=se"), new DistinguishedName("cn=john doe"))); + entryContextCallbackControl.setThrowable(new UncategorizedLdapException("Authentication failed")); + + authenticatedContextMock.close(); + dirContextMock.close(); + + replay(); + authenticatedContextControl.replay(); + entryContextCallbackControl.replay(); + + boolean result = tested.authenticate(nameMock, "(ou=somevalue)", "password", entryContextCallbackMock); + + verify(); + authenticatedContextControl.verify(); + entryContextCallbackControl.verify(); + + assertFalse(result); + } + /** + * Needed to verify search control values. + * + * @author Mattias Hellborg Arthursson + */ + private static class SearchControlsMatcher extends AbstractMatcher { + protected boolean argumentMatches(Object arg0, Object arg1) { + if (arg0 instanceof SearchControls && arg1 instanceof SearchControls) { + SearchControls s0 = (SearchControls) arg0; + SearchControls s1 = (SearchControls) arg1; + + return s0.getSearchScope() == s1.getSearchScope() + && s0.getReturningObjFlag() == s1.getReturningObjFlag() + && s0.getDerefLinkFlag() == s1.getDerefLinkFlag() && s0.getCountLimit() == s1.getCountLimit() + && s0.getTimeLimit() == s1.getTimeLimit() + && s0.getReturningAttributes() == s1.getReturningAttributes(); + } + else { + return super.argumentMatches(arg0, arg1); + } + } + } } diff --git a/test-support/src/main/java/org/springframework/ldap/test/AttributeCheckContextMapper.java b/test-support/src/main/java/org/springframework/ldap/test/AttributeCheckContextMapper.java index d2cedaef..434d7103 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/AttributeCheckContextMapper.java +++ b/test-support/src/main/java/org/springframework/ldap/test/AttributeCheckContextMapper.java @@ -49,7 +49,7 @@ public class AttributeCheckContextMapper implements ContextMapper { Assert.assertNull(adapter.getStringAttribute(absentAttributes[i])); } - return null; + return adapter; } public void setAbsentAttributes(String[] absentAttributes) { diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java new file mode 100644 index 00000000..c9110628 --- /dev/null +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2005-2008 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; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + +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; +import org.springframework.ldap.core.ContextMapper; +import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.core.support.AbstractContextSource; +import org.springframework.ldap.filter.AndFilter; +import org.springframework.ldap.filter.EqualsFilter; +import org.springframework.ldap.filter.WhitespaceWildcardsFilter; +import org.springframework.test.context.ContextConfiguration; + +/** + * Tests the lookup methods of LdapTemplate. + * + * @author Mattias Hellborg Arthursson + * @author Ulrik Sandberg + */ +@ContextConfiguration(locations = { "/conf/ldapTemplateTestContext.xml" }) +public class LdapTemplateAuthenticationITest extends AbstractLdapTemplateIntegrationTest { + + @Autowired + private LdapTemplate tested; + + @Test + public void testAuthenticate() { + AndFilter filter = new AndFilter(); + filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("uid", "some.person3")); + assertTrue(tested.authenticate("", filter.toString(), "password")); + } + + @Test + public void testAuthenticateWithInvalidPassword() { + AndFilter filter = new AndFilter(); + filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("uid", "some.person3")); + assertFalse(tested.authenticate("", filter.toString(), "invalidpassword")); + } + + @Test + public void testAuthenticateWithFilterThatDoesNotMatchAnything() { + AndFilter filter = new AndFilter(); + filter.and(new EqualsFilter("objectclass", "person")).and( + new EqualsFilter("uid", "some.person.that.isnt.there")); + assertFalse(tested.authenticate("", filter.toString(), "password")); + } + + @Test + public void testAuthenticateWithFilterThatMatchesSeveralEntries() { + AndFilter filter = new AndFilter(); + filter.and(new EqualsFilter("objectclass", "person")).and(new WhitespaceWildcardsFilter("uid", "some.person")); + assertFalse(tested.authenticate("", filter.toString(), "password")); + } +} diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateSearchResultITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateSearchResultITest.java index 4684e6de..7b0f764e 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateSearchResultITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateSearchResultITest.java @@ -16,6 +16,7 @@ package org.springframework.ldap; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; @@ -28,8 +29,13 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +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.test.AttributeCheckAttributesMapper; import org.springframework.ldap.test.AttributeCheckContextMapper; import org.springframework.test.context.ContextConfiguration; @@ -140,6 +146,35 @@ public class LdapTemplateSearchResultITest extends AbstractLdapTemplateIntegrati assertEquals(1, list.size()); } + @Test + public void testSearchForObject() { + contextMapper.setExpectedAttributes(ALL_ATTRIBUTES); + contextMapper.setExpectedValues(ALL_VALUES); + DirContextAdapter result = (DirContextAdapter) tested + .searchForObject(BASE_STRING, FILTER_STRING, contextMapper); + assertNotNull(result); + } + + @Test(expected = IncorrectResultSizeDataAccessException.class) + public void testSearchForObjectWithMultipleHits() { + tested.searchForObject(BASE_STRING, "(&(objectclass=person)(sn=*))", new AbstractContextMapper() { + @Override + protected Object doMapFromContext(DirContextOperations ctx) { + return ctx; + } + }); + } + + @Test(expected = EmptyResultDataAccessException.class) + public void testSearchForObjectNoHits() { + tested.searchForObject(BASE_STRING, "(&(objectclass=person)(sn=Person does not exist))", new AbstractContextMapper() { + @Override + protected Object doMapFromContext(DirContextOperations ctx) { + return ctx; + } + }); + } + @Test public void testSearch_SearchScope_ContextMapper() { contextMapper.setExpectedAttributes(ALL_ATTRIBUTES); diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/core/simple/SimpleLdapTemplateITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/core/simple/SimpleLdapTemplateITest.java index 60831853..36197ef4 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/core/simple/SimpleLdapTemplateITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/core/simple/SimpleLdapTemplateITest.java @@ -33,6 +33,8 @@ import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextOperations; import org.springframework.ldap.core.DirContextProcessor; import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.filter.AndFilter; +import org.springframework.ldap.filter.EqualsFilter; import org.springframework.test.context.ContextConfiguration; @ContextConfiguration(locations = { "/conf/simpleLdapTemplateTestContext.xml" }) @@ -65,6 +67,12 @@ public class SimpleLdapTemplateITest extends AbstractLdapTemplateIntegrationTest assertEquals("Some Person3", cns.get(0)); } + @Test + public void testSearchForObject() { + String cn = ldapTemplate.searchForObject("", "(&(objectclass=person)(sn=Person3))", new CnContextMapper()); + assertEquals("Some Person3", cn); + } + @Test public void testSearchProcessor() { SearchControls searchControls = new SearchControls(); @@ -184,6 +192,13 @@ public class SimpleLdapTemplateITest extends AbstractLdapTemplateIntegrationTest verifyCleanup(); } + @Test + public void testAuthenticate() { + AndFilter filter = new AndFilter(); + filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("uid", "some.person3")); + assertTrue(ldapTemplate.authenticate("", filter.toString(), "password")); + } + private void verifyBoundCorrectData() { DirContextOperations result = ldapTemplate.lookupContext(DN_STRING); assertEquals("Some Person4", result.getStringAttribute("cn"));