diff --git a/mvn-build/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java b/mvn-build/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java index 6769c249..d4519495 100644 --- a/mvn-build/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/mvn-build/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -59,1281 +59,1190 @@ import org.springframework.ldap.support.LdapUtils; */ public class LdapTemplate implements LdapOperations, InitializingBean { - private static final Log log = LogFactory.getLog(LdapTemplate.class); - - private static final int DEFAULT_SEARCH_SCOPE = SearchControls.SUBTREE_SCOPE; - - private static final boolean DONT_RETURN_OBJ_FLAG = false; - - private static final boolean RETURN_OBJ_FLAG = true; - - private static final String[] ALL_ATTRIBUTES = null; - - private ContextSource contextSource; - - private boolean ignorePartialResultException = false; - - /** - * Constructor for bean usage. - */ - public LdapTemplate() { - } - - /** - * Constructor to setup instance directly. - * - * @param contextSource - * the ContextSource to use. - */ - public LdapTemplate(ContextSource contextSource) { - this.contextSource = contextSource; - } - - /** - * Set the ContextSource. Call this method when the default constructor has - * been used. - * - * @param contextSource - * the ContextSource. - */ - public void setContextSource(ContextSource contextSource) { - this.contextSource = contextSource; - } - - /** - * Get the ContextSource. - * - * @return the ContextSource. - */ - public ContextSource getContextSource() { - return contextSource; - } - - /** - * Specify whether PartialResultException should be ignored - * in searches. AD servers typically have a problem with referrals. Normally - * a referral should be followed automatically, but this does not seem to - * work with AD servers. The problem manifests itself with a a - * PartialResultException being thrown when a referral is - * encountered by the server. Setting this property to true - * presents a workaround to this problem by causing - * PartialResultException to be ignored, so that the search - * method returns normally. Default value of this parameter is - * false. - * - * @param ignore - * true if PartialResultException - * should be ignored in searches, false otherwise. - * Default is false. - */ - public void setIgnorePartialResultException(boolean ignore) { - this.ignorePartialResultException = ignore; - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, boolean, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(Name base, String filter, int searchScope, - boolean returningObjFlag, NameClassPairCallbackHandler handler) { - - search(base, filter, getDefaultSearchControls(searchScope, - returningObjFlag, ALL_ATTRIBUTES), handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, int, boolean, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(String base, String filter, int searchScope, - boolean returningObjFlag, NameClassPairCallbackHandler handler) { - - search(base, filter, getDefaultSearchControls(searchScope, - returningObjFlag, ALL_ATTRIBUTES), handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(final Name base, final String filter, - final SearchControls controls, NameClassPairCallbackHandler handler) { - - // Create a SearchExecutor to perform the search. - SearchExecutor se = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.search(base, filter, controls); - } - }; - - search(se, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(final String base, final String filter, - final SearchControls controls, NameClassPairCallbackHandler handler) { - - // Create a SearchExecutor to perform the search. - SearchExecutor se = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.search(base, filter, controls); - } - }; - - search(se, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.NameClassPairCallbackHandler, - * org.springframework.ldap.core.DirContextProcessor) - */ - public void search(final Name base, final String filter, - final SearchControls controls, - NameClassPairCallbackHandler handler, DirContextProcessor processor) { - - // Create a SearchExecutor to perform the search. - SearchExecutor se = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.search(base, filter, controls); - } - }; - - search(se, handler, processor); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.NameClassPairCallbackHandler, - * org.springframework.ldap.core.DirContextProcessor) - */ - public void search(final String base, final String filter, - final SearchControls controls, - NameClassPairCallbackHandler handler, DirContextProcessor processor) { - - // Create a SearchExecutor to perform the search. - SearchExecutor se = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.search(base, filter, controls); - } - }; - - search(se, handler, processor); - } - - /** - * Perform a search operation, such as a search(), list() or listBindings(). - * This method handles all the plumbing; getting a readonly context; looping - * through the NamingEnumeration and closing the context and enumeration. It - * also calls the supplied DirContextProcessor before and after the search, - * respectively. This enables custom pre-processing and post-processing, - * like for example when handling paged results or other search controls. - *

- * The actual list is delegated to the {@link SearchExecutor} and each - * {@link NameClassPair} (this might be a NameClassPair or a subclass - * thereof) is passed to the CallbackHandler. Any encountered - * NamingException will be translated using the NamingExceptionTranslator. - * - * @param se - * the SearchExecutor to use for performing the actual list. - * @param handler - * the NameClassPairCallbackHandler to which each found entry - * will be passed. - * @param processor - * DirContextProcessor for custom pre- and post-processing. May - * be null if no custom processing should take - * place. - * @throws NamingException - * if any error occurs. Note that a NameNotFoundException will - * be ignored. Instead this is interpreted that no entries were - * found. - */ - public void search(SearchExecutor se, NameClassPairCallbackHandler handler, - DirContextProcessor processor) { - DirContext ctx = contextSource.getReadOnlyContext(); - - NamingEnumeration results = null; - RuntimeException ex = null; - try { - processor.preProcess(ctx); - results = se.executeSearch(ctx); - - while (results.hasMore()) { - NameClassPair result = (NameClassPair) results.next(); - handler.handleNameClassPair(result); - } - } catch (NameNotFoundException e) { - // The base context was not found, which basically means - // that the search did not return any results. Just clean up and - // exit. - // Note that this may present problems if a DirContextProcessor was - // supplied - there's no guarantee that the postProcess() operation - // will go well after a NamingException has been thrown. It is - // however quite possible that information will be available for - // retrieval either way. - } catch (PartialResultException e) { - // Workaround for AD servers not handling referrals correctly. - if (ignorePartialResultException) { - log.debug("PartialResultException encountered and ignored", e); - } else { - ex = LdapUtils.convertLdapException(e); - } - } catch (javax.naming.NamingException e) { - ex = LdapUtils.convertLdapException(e); - } finally { - try { - processor.postProcess(ctx); - } catch (javax.naming.NamingException e) { - if (ex == null) { - ex = LdapUtils.convertLdapException(e); - } else { - // We already had an exception from above and should ignore - // this one. - log.debug("Ignoring Exception from postProcess, " - + "main exception thrown instead", e); - } - } - closeContextAndNamingEnumeration(ctx, results); - // If we got an exception it should be thrown. - if (ex != null) { - throw ex; - } - } - } - - /** - * Perform a search operation, such as a search(), list() or listBindings(). - * This method handles all the plumbing; getting a readonly context; looping - * through the NamingEnumeration and closing the context and enumeration. - *

- * The actual list is delegated to the {@link SearchExecutor} and each - * {@link NameClassPair} (this might be a NameClassPair or a subclass - * thereof) is passed to the CallbackHandler. Any encountered - * NamingException will be translated using the NamingExceptionTranslator. - * - * @param se - * the SearchExecutor to use for performing the actual list. - * @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 that no entries were - * found. - */ - public void search(SearchExecutor se, NameClassPairCallbackHandler handler) { - search(se, handler, new NullDirContextProcessor()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(Name base, String filter, - NameClassPairCallbackHandler handler) { - - SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, - DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); - if (handler instanceof ContextMapperCallbackHandler) { - assureReturnObjFlagSet(controls); - } - search(base, filter, controls, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void search(String base, String filter, - NameClassPairCallbackHandler handler) { - - SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, - DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); - if (handler instanceof ContextMapperCallbackHandler) { - assureReturnObjFlagSet(controls); - } - search(base, filter, controls, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, java.lang.String[], - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(Name base, String filter, int searchScope, - String[] attrs, AttributesMapper mapper) { - return search(base, filter, getDefaultSearchControls(searchScope, - DONT_RETURN_OBJ_FLAG, attrs), mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, int, java.lang.String[], - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(String base, String filter, int searchScope, - String[] attrs, AttributesMapper mapper) { - return search(base, filter, getDefaultSearchControls(searchScope, - DONT_RETURN_OBJ_FLAG, attrs), mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(Name base, String filter, int searchScope, - AttributesMapper mapper) { - - return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, int, - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(String base, String filter, int searchScope, - AttributesMapper mapper) { - - return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, org.springframework.ldap.core.AttributesMapper) - */ - public List search(Name base, String filter, AttributesMapper mapper) { - - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, org.springframework.ldap.core.AttributesMapper) - */ - public List search(String base, String filter, AttributesMapper mapper) { - - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, java.lang.String[], - * org.springframework.ldap.core.ContextMapper) - */ - public List search(Name base, String filter, int searchScope, - String[] attrs, ContextMapper mapper) { - - return search(base, filter, getDefaultSearchControls(searchScope, - RETURN_OBJ_FLAG, attrs), mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, int, java.lang.String[], - * org.springframework.ldap.core.ContextMapper) - */ - public List search(String base, String filter, int searchScope, - String[] attrs, ContextMapper mapper) { - - return search(base, filter, getDefaultSearchControls(searchScope, - RETURN_OBJ_FLAG, attrs), mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, org.springframework.ldap.core.ContextMapper) - */ - public List search(Name base, String filter, int searchScope, - ContextMapper mapper) { - - return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, int, org.springframework.ldap.core.ContextMapper) - */ - public List search(String base, String filter, int searchScope, - ContextMapper mapper) { - - return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, org.springframework.ldap.core.ContextMapper) - */ - public List search(Name base, String filter, ContextMapper mapper) { - - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, org.springframework.ldap.core.ContextMapper) - */ - public List search(String base, String filter, ContextMapper mapper) { - - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.ContextMapper) - */ - public List search(String base, String filter, SearchControls controls, - ContextMapper mapper) { - - return search(base, filter, controls, mapper, - new NullDirContextProcessor()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.ContextMapper) - */ - public List search(Name base, String filter, SearchControls controls, - ContextMapper mapper) { - - return search(base, filter, controls, mapper, - new NullDirContextProcessor()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(Name base, String filter, SearchControls controls, - AttributesMapper mapper) { - - return search(base, filter, controls, mapper, - new NullDirContextProcessor()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.AttributesMapper) - */ - public List search(String base, String filter, SearchControls controls, - AttributesMapper mapper) { - return search(base, filter, controls, mapper, - new NullDirContextProcessor()); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.AttributesMapper, - * org.springframework.ldap.core.DirContextProcessor) - */ - public List search(String base, String filter, SearchControls controls, - AttributesMapper mapper, DirContextProcessor processor) { - AttributesMapperCallbackHandler handler = new AttributesMapperCallbackHandler( - mapper); - search(base, filter, controls, handler, processor); - - return handler.getList(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.AttributesMapper, - * org.springframework.ldap.core.DirContextProcessor) - */ - public List search(Name base, String filter, SearchControls controls, - AttributesMapper mapper, DirContextProcessor processor) { - AttributesMapperCallbackHandler handler = new AttributesMapperCallbackHandler( - mapper); - search(base, filter, controls, handler, processor); - - return handler.getList(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.ContextMapper, - * org.springframework.ldap.core.DirContextProcessor) - */ - public List search(String base, String filter, SearchControls controls, - ContextMapper mapper, DirContextProcessor processor) { - assureReturnObjFlagSet(controls); - ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler( - mapper); - search(base, filter, controls, handler, processor); - - return handler.getList(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, javax.naming.directory.SearchControls, - * org.springframework.ldap.core.ContextMapper, - * org.springframework.ldap.core.DirContextProcessor) - */ - public List search(Name base, String filter, SearchControls controls, - ContextMapper mapper, DirContextProcessor processor) { - assureReturnObjFlagSet(controls); - ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler( - mapper); - search(base, filter, controls, handler, processor); - - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void list(final String base, NameClassPairCallbackHandler handler) { - SearchExecutor searchExecutor = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.list(base); - } - }; - - search(searchExecutor, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void list(final Name base, NameClassPairCallbackHandler handler) { - SearchExecutor searchExecutor = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.list(base); - } - }; - - search(searchExecutor, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String, - * org.springframework.ldap.core.NameClassPairMapper) - */ - public List list(String base, NameClassPairMapper mapper) { - CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler( - mapper); - list(base, handler); - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name, - * org.springframework.ldap.core.NameClassPairMapper) - */ - public List list(Name base, NameClassPairMapper mapper) { - CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler( - mapper); - list(base, handler); - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name) - */ - public List list(final Name base) { - return list(base, new DefaultNameClassPairMapper()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String) - */ - public List list(final String base) { - return list(base, new DefaultNameClassPairMapper()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void listBindings(final String base, - NameClassPairCallbackHandler handler) { - SearchExecutor searchExecutor = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.listBindings(base); - } - }; - - search(searchExecutor, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ - public void listBindings(final Name base, - NameClassPairCallbackHandler handler) { - SearchExecutor searchExecutor = new SearchExecutor() { - public NamingEnumeration executeSearch(DirContext ctx) - throws javax.naming.NamingException { - return ctx.listBindings(base); - } - }; - - search(searchExecutor, handler); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, - * org.springframework.ldap.core.NameClassPairMapper) - */ - public List listBindings(String base, NameClassPairMapper mapper) { - CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler( - mapper); - listBindings(base, handler); - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, - * org.springframework.ldap.core.NameClassPairMapper) - */ - public List listBindings(Name base, NameClassPairMapper mapper) { - CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler( - mapper); - listBindings(base, handler); - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String) - */ - public List listBindings(final String base) { - return listBindings(base, new DefaultNameClassPairMapper()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name) - */ - public List listBindings(final Name base) { - return listBindings(base, new DefaultNameClassPairMapper()); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, - * org.springframework.ldap.core.ContextMapper) - */ - public List listBindings(String base, ContextMapper mapper) { - - ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler( - mapper); - listBindings(base, handler); - - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, - * org.springframework.ldap.core.ContextMapper) - */ - public List listBindings(Name base, ContextMapper mapper) { - - ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler( - mapper); - listBindings(base, handler); - - return handler.getList(); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#executeReadOnly(org.springframework.ldap.core.DirContextProcessor) - */ - public Object executeReadOnly(ContextExecutor ce) { - DirContext ctx = contextSource.getReadOnlyContext(); - return executeWithContext(ce, ctx); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#executeReadWrite(org.springframework.ldap.core.DirContextProcessor) - */ - public Object executeReadWrite(ContextExecutor ce) { - DirContext ctx = contextSource.getReadWriteContext(); - return executeWithContext(ce, ctx); - } - - private Object executeWithContext(ContextExecutor ce, DirContext ctx) { - try { - return ce.executeWithContext(ctx); - } catch (javax.naming.NamingException e) { - throw LdapUtils.convertLdapException(e); - } finally { - closeContext(ctx); - } - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name) - */ - public Object lookup(final Name dn) { - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - return ctx.lookup(dn); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String) - */ - public Object lookup(final String dn) { - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - return ctx.lookup(dn); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, - * org.springframework.ldap.core.AttributesMapper) - */ - public Object lookup(final Name dn, final AttributesMapper mapper) { - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes attributes = ctx.getAttributes(dn); - return mapper.mapFromAttributes(attributes); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, - * org.springframework.ldap.core.AttributesMapper) - */ - public Object lookup(final String dn, final AttributesMapper mapper) { - - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes attributes = ctx.getAttributes(dn); - return mapper.mapFromAttributes(attributes); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, - * org.springframework.ldap.core.ContextMapper) - */ - public Object lookup(final Name dn, final ContextMapper mapper) { - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Object object = ctx.lookup(dn); - return mapper.mapFromContext(object); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, - * org.springframework.ldap.core.ContextMapper) - */ - public Object lookup(final String dn, final ContextMapper mapper) { - - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Object object = ctx.lookup(dn); - return mapper.mapFromContext(object); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, - * java.lang.String[], org.springframework.ldap.core.AttributesMapper) - */ - public Object lookup(final Name dn, final String[] attributes, - final AttributesMapper mapper) { - - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes filteredAttributes = ctx.getAttributes(dn, - attributes); - return mapper.mapFromAttributes(filteredAttributes); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, - * java.lang.String[], org.springframework.ldap.core.AttributesMapper) - */ - public Object lookup(final String dn, final String[] attributes, - final AttributesMapper mapper) { - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes filteredAttributes = ctx.getAttributes(dn, - attributes); - return mapper.mapFromAttributes(filteredAttributes); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, - * java.lang.String[], org.springframework.ldap.core.ContextMapper) - */ - public Object lookup(final Name dn, final String[] attributes, - final ContextMapper mapper) { - - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes filteredAttributes = ctx.getAttributes(dn, - attributes); - DirContextAdapter contextAdapter = new DirContextAdapter( - filteredAttributes, dn); - return mapper.mapFromContext(contextAdapter); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, - * java.lang.String[], org.springframework.ldap.core.ContextMapper) - */ - public Object lookup(final String dn, final String[] attributes, - final ContextMapper mapper) { - - return executeReadOnly(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - Attributes filteredAttributes = ctx.getAttributes(dn, - attributes); - DistinguishedName name = new DistinguishedName(dn); - DirContextAdapter contextAdapter = new DirContextAdapter( - filteredAttributes, name); - return mapper.mapFromContext(contextAdapter); - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(javax.naming.Name, - * javax.naming.directory.ModificationItem[]) - */ - public void modifyAttributes(final Name dn, final ModificationItem[] mods) { - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.modifyAttributes(dn, mods); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(java.lang.String, - * javax.naming.directory.ModificationItem[]) - */ - public void modifyAttributes(final String dn, final ModificationItem[] mods) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.modifyAttributes(dn, mods); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#bind(javax.naming.Name, - * java.lang.Object, javax.naming.directory.Attributes) - */ - public void bind(final Name dn, final Object obj, - final Attributes attributes) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.bind(dn, obj, attributes); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#bind(java.lang.String, - * java.lang.Object, javax.naming.directory.Attributes) - */ - public void bind(final String dn, final Object obj, - final Attributes attributes) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.bind(dn, obj, attributes); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#unbind(javax.naming.Name) - */ - public void unbind(final Name dn) { - doUnbind(dn); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#unbind(java.lang.String) - */ - public void unbind(final String dn) { - doUnbind(dn); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#unbind(javax.naming.Name, - * boolean) - */ - public void unbind(final Name dn, boolean recursive) { - if (!recursive) { - doUnbind(dn); - } else { - doUnbindRecursively(dn); - } - } - - /* - * @see org.springframework.ldap.core.LdapOperations#unbind(java.lang.String, - * boolean) - */ - public void unbind(final String dn, boolean recursive) { - if (!recursive) { - doUnbind(dn); - } else { - doUnbindRecursively(dn); - } - } - - private void doUnbind(final Name dn) { - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.unbind(dn); - return null; - } - }); - } - - private void doUnbind(final String dn) { - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.unbind(dn); - return null; - } - }); - } - - private void doUnbindRecursively(final Name dn) { - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) { - deleteRecursively(ctx, new DistinguishedName(dn)); - return null; - } - }); - } - - private void doUnbindRecursively(final String dn) { - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - deleteRecursively(ctx, new DistinguishedName(dn)); - return null; - } - }); - } - - /** - * Delete all subcontexts including the current one recursively. - * - * @param ctx - * The context to use for deleting. - * @param name - * The starting point to delete recursively. - * @throws NamingException - * if any error occurs - */ - protected void deleteRecursively(DirContext ctx, DistinguishedName name) { - - NamingEnumeration enumeration = null; - try { - enumeration = ctx.listBindings(name); - while (enumeration.hasMore()) { - Binding binding = (Binding) enumeration.next(); - DistinguishedName childName = new DistinguishedName(binding - .getName()); - childName.prepend((DistinguishedName) name); - deleteRecursively(ctx, childName); - } - ctx.unbind(name); - if (log.isDebugEnabled()) { - log.debug("Entry " + name + " deleted"); - } - } catch (javax.naming.NamingException e) { - throw LdapUtils.convertLdapException(e); - } finally { - try { - enumeration.close(); - } catch (Exception e) { - // Never mind this - } - } - } - - /* - * @see org.springframework.ldap.core.LdapOperations#rebind(javax.naming.Name, - * java.lang.Object, javax.naming.directory.Attributes) - */ - public void rebind(final Name dn, final Object obj, - final Attributes attributes) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.rebind(dn, obj, attributes); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#rebind(java.lang.String, - * java.lang.Object, javax.naming.directory.Attributes) - */ - public void rebind(final String dn, final Object obj, - final Attributes attributes) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.rebind(dn, obj, attributes); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#rename(javax.naming.Name, - * javax.naming.Name) - */ - public void rename(final Name oldDn, final Name newDn) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.rename(oldDn, newDn); - return null; - } - }); - } - - /* - * @see org.springframework.ldap.core.LdapOperations#rename(java.lang.String, - * java.lang.String) - */ - public void rename(final String oldDn, final String newDn) { - - executeReadWrite(new ContextExecutor() { - public Object executeWithContext(DirContext ctx) - throws javax.naming.NamingException { - ctx.rename(oldDn, newDn); - return null; - } - }); - } - - /* - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - public void afterPropertiesSet() throws Exception { - if (contextSource == null) { - throw new IllegalArgumentException( - "Property 'contextSource' must be set."); - } - } - - private void closeContextAndNamingEnumeration(DirContext ctx, - NamingEnumeration results) { - - closeNamingEnumeration(results); - closeContext(ctx); - } - - /** - * Close the supplied DirContext if it is not null. Swallow any exceptions, - * as this is only for cleanup. - * - * @param ctx - * the context to close. - */ - private void closeContext(DirContext ctx) { - if (ctx != null) { - try { - ctx.close(); - } catch (Exception e) { - // Never mind this. - } - } - } - - /** - * Close the supplied NamingEnumeration if it is not null. Swallow any - * exceptions, as this is only for cleanup. - * - * @param results - * the NamingEnumeration to close. - */ - private void closeNamingEnumeration(NamingEnumeration results) { - if (results != null) { - try { - results.close(); - } catch (Exception e) { - // Never mind this. - } - } - } - - private SearchControls getDefaultSearchControls(int searchScope, - boolean returningObjFlag, String[] attrs) { - - SearchControls controls = new SearchControls(); - controls.setSearchScope(searchScope); - controls.setReturningObjFlag(returningObjFlag); - controls.setReturningAttributes(attrs); - return controls; - } - - /** - * Make sure the returnObjFlag is set in the supplied SearchControls. Set it - * and log if it's not set. - * - * @param controls - * the SearchControls to check. - */ - private void assureReturnObjFlagSet(SearchControls controls) { - Validate.notNull(controls); - if (!controls.getReturningObjFlag()) { - log.info("The returnObjFlag of supplied SearchControls is not set" - + " but a ContextMapper is used - setting flag to true"); - controls.setReturningObjFlag(true); - } - } - - private final class NullDirContextProcessor implements DirContextProcessor { - public void postProcess(DirContext ctx) throws NamingException { - // Do nothing - } - - public void preProcess(DirContext ctx) throws NamingException { - // Do nothing - } - } - - /** - * A {@link NameClassPairCallbackHandler} that passes the NameClassPairs - * found to a NameClassPairMapper and collects the results in a list. - * - * @author Mattias Arthursson - */ - public class MappingCollectingNameClassPairCallbackHandler extends - CollectingNameClassPairCallbackHandler { - - private NameClassPairMapper mapper; - - public MappingCollectingNameClassPairCallbackHandler( - NameClassPairMapper mapper) { - this.mapper = mapper; - } - - /* - * @see org.springframework.ldap.CollectingNameClassPairCallbackHandler#getObjectFromNameClassPair(javax.naming.NameClassPair) - */ - public Object getObjectFromNameClassPair(NameClassPair nameClassPair) { - try { - return mapper.mapFromNameClassPair(nameClassPair); - } catch (javax.naming.NamingException e) { - throw LdapUtils.convertLdapException(e); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#lookupContext(javax.naming.Name) - */ - public DirContextOperations lookupContext(Name dn) { - return (DirContextOperations) lookup(dn); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#lookupContext(java.lang.String) - */ - public DirContextOperations lookupContext(String dn) { - return (DirContextOperations) lookup(dn); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(org.springframework.ldap.core.DirContextOperations) - */ - public void modifyAttributes(DirContextOperations ctx) { - Name dn = ctx.getDn(); - if (dn != null && ctx.isUpdateMode()) { - modifyAttributes(dn, ctx.getModificationItems()); - } else { - throw new IllegalStateException( - "The DirContextOperations instance needs to be properly initialized."); - } - - } + private static final Log log = LogFactory.getLog(LdapTemplate.class); + + private static final int DEFAULT_SEARCH_SCOPE = SearchControls.SUBTREE_SCOPE; + + private static final boolean DONT_RETURN_OBJ_FLAG = false; + + private static final boolean RETURN_OBJ_FLAG = true; + + private static final String[] ALL_ATTRIBUTES = null; + + private ContextSource contextSource; + + private boolean ignorePartialResultException = false; + + /** + * Constructor for bean usage. + */ + public LdapTemplate() { + } + + /** + * Constructor to setup instance directly. + * + * @param contextSource the ContextSource to use. + */ + public LdapTemplate(ContextSource contextSource) { + this.contextSource = contextSource; + } + + /** + * Set the ContextSource. Call this method when the default constructor has + * been used. + * + * @param contextSource the ContextSource. + */ + public void setContextSource(ContextSource contextSource) { + this.contextSource = contextSource; + } + + /** + * Get the ContextSource. + * + * @return the ContextSource. + */ + public ContextSource getContextSource() { + return contextSource; + } + + /** + * Specify whether PartialResultException should be ignored + * in searches. AD servers typically have a problem with referrals. Normally + * a referral should be followed automatically, but this does not seem to + * work with AD servers. The problem manifests itself with a a + * PartialResultException being thrown when a referral is + * encountered by the server. Setting this property to true + * presents a workaround to this problem by causing + * PartialResultException to be ignored, so that the search + * method returns normally. Default value of this parameter is + * false. + * + * @param ignore true if PartialResultException + * should be ignored in searches, false otherwise. Default is + * false. + */ + public void setIgnorePartialResultException(boolean ignore) { + this.ignorePartialResultException = ignore; + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, boolean, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(Name base, String filter, int searchScope, boolean returningObjFlag, + NameClassPairCallbackHandler handler) { + + search(base, filter, getDefaultSearchControls(searchScope, returningObjFlag, ALL_ATTRIBUTES), handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, int, boolean, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(String base, String filter, int searchScope, boolean returningObjFlag, + NameClassPairCallbackHandler handler) { + + search(base, filter, getDefaultSearchControls(searchScope, returningObjFlag, ALL_ATTRIBUTES), handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(final Name base, final String filter, final SearchControls controls, + NameClassPairCallbackHandler handler) { + + // Create a SearchExecutor to perform the search. + SearchExecutor se = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.search(base, filter, controls); + } + }; + + search(se, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(final String base, final String filter, final SearchControls controls, + NameClassPairCallbackHandler handler) { + + // Create a SearchExecutor to perform the search. + SearchExecutor se = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.search(base, filter, controls); + } + }; + + search(se, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.NameClassPairCallbackHandler, + * org.springframework.ldap.core.DirContextProcessor) + */ + public void search(final Name base, final String filter, final SearchControls controls, + NameClassPairCallbackHandler handler, DirContextProcessor processor) { + + // Create a SearchExecutor to perform the search. + SearchExecutor se = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.search(base, filter, controls); + } + }; + + search(se, handler, processor); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.NameClassPairCallbackHandler, + * org.springframework.ldap.core.DirContextProcessor) + */ + public void search(final String base, final String filter, final SearchControls controls, + NameClassPairCallbackHandler handler, DirContextProcessor processor) { + + // Create a SearchExecutor to perform the search. + SearchExecutor se = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.search(base, filter, controls); + } + }; + + search(se, handler, processor); + } + + /** + * Perform a search operation, such as a search(), list() or listBindings(). + * This method handles all the plumbing; getting a readonly context; looping + * through the NamingEnumeration and closing the context and enumeration. It + * also calls the supplied DirContextProcessor before and after the search, + * respectively. This enables custom pre-processing and post-processing, + * like for example when handling paged results or other search controls. + *

+ * The actual list is delegated to the {@link SearchExecutor} and each + * {@link NameClassPair} (this might be a NameClassPair or a subclass + * thereof) is passed to the CallbackHandler. Any encountered + * NamingException will be translated using the NamingExceptionTranslator. + * + * @param se the SearchExecutor to use for performing the actual list. + * @param handler the NameClassPairCallbackHandler to which each found entry + * will be passed. + * @param processor DirContextProcessor for custom pre- and post-processing. + * Must not be null. If no custom processing should take + * place, please use e.g. + * {@link #search(SearchExecutor, NameClassPairCallbackHandler)}. + * @throws NamingException if any error occurs. Note that a + * NameNotFoundException will be ignored. Instead this is interpreted that + * no entries were found. + */ + public void search(SearchExecutor se, NameClassPairCallbackHandler handler, DirContextProcessor processor) { + DirContext ctx = contextSource.getReadOnlyContext(); + + NamingEnumeration results = null; + RuntimeException ex = null; + try { + processor.preProcess(ctx); + results = se.executeSearch(ctx); + + while (results.hasMore()) { + NameClassPair result = (NameClassPair) results.next(); + handler.handleNameClassPair(result); + } + } + catch (NameNotFoundException e) { + // The base context was not found, which basically means + // that the search did not return any results. Just clean up and + // exit. + // Note that this may present problems if a DirContextProcessor was + // supplied - there's no guarantee that the postProcess() operation + // will go well after a NamingException has been thrown. It is + // however quite possible that information will be available for + // retrieval either way. + } + catch (PartialResultException e) { + // Workaround for AD servers not handling referrals correctly. + if (ignorePartialResultException) { + log.debug("PartialResultException encountered and ignored", e); + } + else { + ex = LdapUtils.convertLdapException(e); + } + } + catch (javax.naming.NamingException e) { + ex = LdapUtils.convertLdapException(e); + } + finally { + try { + processor.postProcess(ctx); + } + catch (javax.naming.NamingException e) { + if (ex == null) { + ex = LdapUtils.convertLdapException(e); + } + else { + // We already had an exception from above and should ignore + // this one. + log.debug("Ignoring Exception from postProcess, " + "main exception thrown instead", e); + } + } + closeContextAndNamingEnumeration(ctx, results); + // If we got an exception it should be thrown. + if (ex != null) { + throw ex; + } + } + } + + /** + * Perform a search operation, such as a search(), list() or listBindings(). + * This method handles all the plumbing; getting a readonly context; looping + * through the NamingEnumeration and closing the context and enumeration. + *

+ * The actual list is delegated to the {@link SearchExecutor} and each + * {@link NameClassPair} (this might be a NameClassPair or a subclass + * thereof) is passed to the CallbackHandler. Any encountered + * NamingException will be translated using the NamingExceptionTranslator. + * + * @param se the SearchExecutor to use for performing the actual list. + * @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 that + * no entries were found. + */ + public void search(SearchExecutor se, NameClassPairCallbackHandler handler) { + search(se, handler, new NullDirContextProcessor()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(Name base, String filter, NameClassPairCallbackHandler handler) { + + SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); + if (handler instanceof ContextMapperCallbackHandler) { + assureReturnObjFlagSet(controls); + } + search(base, filter, controls, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void search(String base, String filter, NameClassPairCallbackHandler handler) { + + SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); + if (handler instanceof ContextMapperCallbackHandler) { + assureReturnObjFlagSet(controls); + } + search(base, filter, controls, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, java.lang.String[], + * org.springframework.ldap.core.AttributesMapper) + */ + public List search(Name base, String filter, int searchScope, String[] attrs, AttributesMapper mapper) { + return search(base, filter, getDefaultSearchControls(searchScope, DONT_RETURN_OBJ_FLAG, attrs), mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, int, java.lang.String[], + * org.springframework.ldap.core.AttributesMapper) + */ + public List search(String base, String filter, int searchScope, String[] attrs, AttributesMapper mapper) { + return search(base, filter, getDefaultSearchControls(searchScope, DONT_RETURN_OBJ_FLAG, attrs), mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, org.springframework.ldap.core.AttributesMapper) + */ + public List search(Name base, String filter, int searchScope, AttributesMapper mapper) { + + return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, int, org.springframework.ldap.core.AttributesMapper) + */ + public List search(String base, String filter, int searchScope, AttributesMapper mapper) { + + return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, org.springframework.ldap.core.AttributesMapper) + */ + public List search(Name base, String filter, AttributesMapper mapper) { + + return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, org.springframework.ldap.core.AttributesMapper) + */ + public List search(String base, String filter, AttributesMapper mapper) { + + return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, java.lang.String[], + * org.springframework.ldap.core.ContextMapper) + */ + public List search(Name base, String filter, int searchScope, String[] attrs, ContextMapper mapper) { + + return search(base, filter, getDefaultSearchControls(searchScope, RETURN_OBJ_FLAG, attrs), mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, int, java.lang.String[], + * org.springframework.ldap.core.ContextMapper) + */ + public List search(String base, String filter, int searchScope, String[] attrs, ContextMapper mapper) { + + return search(base, filter, getDefaultSearchControls(searchScope, RETURN_OBJ_FLAG, attrs), mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, org.springframework.ldap.core.ContextMapper) + */ + public List search(Name base, String filter, int searchScope, ContextMapper mapper) { + + return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, int, org.springframework.ldap.core.ContextMapper) + */ + public List search(String base, String filter, int searchScope, ContextMapper mapper) { + + return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, org.springframework.ldap.core.ContextMapper) + */ + public List search(Name base, String filter, ContextMapper mapper) { + + return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, org.springframework.ldap.core.ContextMapper) + */ + public List search(String base, String filter, ContextMapper mapper) { + + return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.ContextMapper) + */ + public List search(String base, String filter, SearchControls controls, ContextMapper mapper) { + + return search(base, filter, controls, mapper, new NullDirContextProcessor()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.ContextMapper) + */ + public List search(Name base, String filter, SearchControls controls, ContextMapper mapper) { + + return search(base, filter, controls, mapper, new NullDirContextProcessor()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.AttributesMapper) + */ + public List search(Name base, String filter, SearchControls controls, AttributesMapper mapper) { + + return search(base, filter, controls, mapper, new NullDirContextProcessor()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.AttributesMapper) + */ + public List search(String base, String filter, SearchControls controls, AttributesMapper mapper) { + return search(base, filter, controls, mapper, new NullDirContextProcessor()); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.AttributesMapper, + * org.springframework.ldap.core.DirContextProcessor) + */ + public List search(String base, String filter, SearchControls controls, AttributesMapper mapper, + DirContextProcessor processor) { + AttributesMapperCallbackHandler handler = new AttributesMapperCallbackHandler(mapper); + search(base, filter, controls, handler, processor); + + return handler.getList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.AttributesMapper, + * org.springframework.ldap.core.DirContextProcessor) + */ + public List search(Name base, String filter, SearchControls controls, AttributesMapper mapper, + DirContextProcessor processor) { + AttributesMapperCallbackHandler handler = new AttributesMapperCallbackHandler(mapper); + search(base, filter, controls, handler, processor); + + return handler.getList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#search(java.lang.String, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.ContextMapper, + * org.springframework.ldap.core.DirContextProcessor) + */ + public List search(String base, String filter, SearchControls controls, ContextMapper mapper, + DirContextProcessor processor) { + assureReturnObjFlagSet(controls); + ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper); + search(base, filter, controls, handler, processor); + + return handler.getList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, javax.naming.directory.SearchControls, + * org.springframework.ldap.core.ContextMapper, + * org.springframework.ldap.core.DirContextProcessor) + */ + public List search(Name base, String filter, SearchControls controls, ContextMapper mapper, + DirContextProcessor processor) { + assureReturnObjFlagSet(controls); + ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper); + search(base, filter, controls, handler, processor); + + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void list(final String base, NameClassPairCallbackHandler handler) { + SearchExecutor searchExecutor = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.list(base); + } + }; + + search(searchExecutor, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void list(final Name base, NameClassPairCallbackHandler handler) { + SearchExecutor searchExecutor = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.list(base); + } + }; + + search(searchExecutor, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String, + * org.springframework.ldap.core.NameClassPairMapper) + */ + public List list(String base, NameClassPairMapper mapper) { + CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper); + list(base, handler); + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name, + * org.springframework.ldap.core.NameClassPairMapper) + */ + public List list(Name base, NameClassPairMapper mapper) { + CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper); + list(base, handler); + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(javax.naming.Name) + */ + public List list(final Name base) { + return list(base, new DefaultNameClassPairMapper()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#list(java.lang.String) + */ + public List list(final String base) { + return list(base, new DefaultNameClassPairMapper()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void listBindings(final String base, NameClassPairCallbackHandler handler) { + SearchExecutor searchExecutor = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.listBindings(base); + } + }; + + search(searchExecutor, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ + public void listBindings(final Name base, NameClassPairCallbackHandler handler) { + SearchExecutor searchExecutor = new SearchExecutor() { + public NamingEnumeration executeSearch(DirContext ctx) throws javax.naming.NamingException { + return ctx.listBindings(base); + } + }; + + search(searchExecutor, handler); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, + * org.springframework.ldap.core.NameClassPairMapper) + */ + public List listBindings(String base, NameClassPairMapper mapper) { + CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper); + listBindings(base, handler); + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, + * org.springframework.ldap.core.NameClassPairMapper) + */ + public List listBindings(Name base, NameClassPairMapper mapper) { + CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper); + listBindings(base, handler); + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String) + */ + public List listBindings(final String base) { + return listBindings(base, new DefaultNameClassPairMapper()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name) + */ + public List listBindings(final Name base) { + return listBindings(base, new DefaultNameClassPairMapper()); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(java.lang.String, + * org.springframework.ldap.core.ContextMapper) + */ + public List listBindings(String base, ContextMapper mapper) { + + ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper); + listBindings(base, handler); + + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#listBindings(javax.naming.Name, + * org.springframework.ldap.core.ContextMapper) + */ + public List listBindings(Name base, ContextMapper mapper) { + + ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper); + listBindings(base, handler); + + return handler.getList(); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#executeReadOnly(org.springframework.ldap.core.DirContextProcessor) + */ + public Object executeReadOnly(ContextExecutor ce) { + DirContext ctx = contextSource.getReadOnlyContext(); + return executeWithContext(ce, ctx); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#executeReadWrite(org.springframework.ldap.core.DirContextProcessor) + */ + public Object executeReadWrite(ContextExecutor ce) { + DirContext ctx = contextSource.getReadWriteContext(); + return executeWithContext(ce, ctx); + } + + private Object executeWithContext(ContextExecutor ce, DirContext ctx) { + try { + return ce.executeWithContext(ctx); + } + catch (javax.naming.NamingException e) { + throw LdapUtils.convertLdapException(e); + } + finally { + closeContext(ctx); + } + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name) + */ + public Object lookup(final Name dn) { + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + return ctx.lookup(dn); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String) + */ + public Object lookup(final String dn) { + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + return ctx.lookup(dn); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, + * org.springframework.ldap.core.AttributesMapper) + */ + public Object lookup(final Name dn, final AttributesMapper mapper) { + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes attributes = ctx.getAttributes(dn); + return mapper.mapFromAttributes(attributes); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, + * org.springframework.ldap.core.AttributesMapper) + */ + public Object lookup(final String dn, final AttributesMapper mapper) { + + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes attributes = ctx.getAttributes(dn); + return mapper.mapFromAttributes(attributes); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, + * org.springframework.ldap.core.ContextMapper) + */ + public Object lookup(final Name dn, final ContextMapper mapper) { + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Object object = ctx.lookup(dn); + return mapper.mapFromContext(object); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, + * org.springframework.ldap.core.ContextMapper) + */ + public Object lookup(final String dn, final ContextMapper mapper) { + + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Object object = ctx.lookup(dn); + return mapper.mapFromContext(object); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, + * java.lang.String[], org.springframework.ldap.core.AttributesMapper) + */ + public Object lookup(final Name dn, final String[] attributes, final AttributesMapper mapper) { + + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes filteredAttributes = ctx.getAttributes(dn, attributes); + return mapper.mapFromAttributes(filteredAttributes); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, + * java.lang.String[], org.springframework.ldap.core.AttributesMapper) + */ + public Object lookup(final String dn, final String[] attributes, final AttributesMapper mapper) { + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes filteredAttributes = ctx.getAttributes(dn, attributes); + return mapper.mapFromAttributes(filteredAttributes); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(javax.naming.Name, + * java.lang.String[], org.springframework.ldap.core.ContextMapper) + */ + public Object lookup(final Name dn, final String[] attributes, final ContextMapper mapper) { + + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes filteredAttributes = ctx.getAttributes(dn, attributes); + DirContextAdapter contextAdapter = new DirContextAdapter(filteredAttributes, dn); + return mapper.mapFromContext(contextAdapter); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#lookup(java.lang.String, + * java.lang.String[], org.springframework.ldap.core.ContextMapper) + */ + public Object lookup(final String dn, final String[] attributes, final ContextMapper mapper) { + + return executeReadOnly(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + Attributes filteredAttributes = ctx.getAttributes(dn, attributes); + DistinguishedName name = new DistinguishedName(dn); + DirContextAdapter contextAdapter = new DirContextAdapter(filteredAttributes, name); + return mapper.mapFromContext(contextAdapter); + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(javax.naming.Name, + * javax.naming.directory.ModificationItem[]) + */ + public void modifyAttributes(final Name dn, final ModificationItem[] mods) { + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.modifyAttributes(dn, mods); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(java.lang.String, + * javax.naming.directory.ModificationItem[]) + */ + public void modifyAttributes(final String dn, final ModificationItem[] mods) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.modifyAttributes(dn, mods); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#bind(javax.naming.Name, + * java.lang.Object, javax.naming.directory.Attributes) + */ + public void bind(final Name dn, final Object obj, final Attributes attributes) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.bind(dn, obj, attributes); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#bind(java.lang.String, + * java.lang.Object, javax.naming.directory.Attributes) + */ + public void bind(final String dn, final Object obj, final Attributes attributes) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.bind(dn, obj, attributes); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#unbind(javax.naming.Name) + */ + public void unbind(final Name dn) { + doUnbind(dn); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#unbind(java.lang.String) + */ + public void unbind(final String dn) { + doUnbind(dn); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#unbind(javax.naming.Name, + * boolean) + */ + public void unbind(final Name dn, boolean recursive) { + if (!recursive) { + doUnbind(dn); + } + else { + doUnbindRecursively(dn); + } + } + + /* + * @see org.springframework.ldap.core.LdapOperations#unbind(java.lang.String, + * boolean) + */ + public void unbind(final String dn, boolean recursive) { + if (!recursive) { + doUnbind(dn); + } + else { + doUnbindRecursively(dn); + } + } + + private void doUnbind(final Name dn) { + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.unbind(dn); + return null; + } + }); + } + + private void doUnbind(final String dn) { + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.unbind(dn); + return null; + } + }); + } + + private void doUnbindRecursively(final Name dn) { + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) { + deleteRecursively(ctx, new DistinguishedName(dn)); + return null; + } + }); + } + + private void doUnbindRecursively(final String dn) { + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + deleteRecursively(ctx, new DistinguishedName(dn)); + return null; + } + }); + } + + /** + * Delete all subcontexts including the current one recursively. + * + * @param ctx The context to use for deleting. + * @param name The starting point to delete recursively. + * @throws NamingException if any error occurs + */ + protected void deleteRecursively(DirContext ctx, DistinguishedName name) { + + NamingEnumeration enumeration = null; + try { + enumeration = ctx.listBindings(name); + while (enumeration.hasMore()) { + Binding binding = (Binding) enumeration.next(); + DistinguishedName childName = new DistinguishedName(binding.getName()); + childName.prepend((DistinguishedName) name); + deleteRecursively(ctx, childName); + } + ctx.unbind(name); + if (log.isDebugEnabled()) { + log.debug("Entry " + name + " deleted"); + } + } + catch (javax.naming.NamingException e) { + throw LdapUtils.convertLdapException(e); + } + finally { + try { + enumeration.close(); + } + catch (Exception e) { + // Never mind this + } + } + } + + /* + * @see org.springframework.ldap.core.LdapOperations#rebind(javax.naming.Name, + * java.lang.Object, javax.naming.directory.Attributes) + */ + public void rebind(final Name dn, final Object obj, final Attributes attributes) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.rebind(dn, obj, attributes); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#rebind(java.lang.String, + * java.lang.Object, javax.naming.directory.Attributes) + */ + public void rebind(final String dn, final Object obj, final Attributes attributes) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.rebind(dn, obj, attributes); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#rename(javax.naming.Name, + * javax.naming.Name) + */ + public void rename(final Name oldDn, final Name newDn) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.rename(oldDn, newDn); + return null; + } + }); + } + + /* + * @see org.springframework.ldap.core.LdapOperations#rename(java.lang.String, + * java.lang.String) + */ + public void rename(final String oldDn, final String newDn) { + + executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { + ctx.rename(oldDn, newDn); + return null; + } + }); + } + + /* + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (contextSource == null) { + throw new IllegalArgumentException("Property 'contextSource' must be set."); + } + } + + private void closeContextAndNamingEnumeration(DirContext ctx, NamingEnumeration results) { + + closeNamingEnumeration(results); + closeContext(ctx); + } + + /** + * Close the supplied DirContext if it is not null. Swallow any exceptions, + * as this is only for cleanup. + * + * @param ctx the context to close. + */ + private void closeContext(DirContext ctx) { + if (ctx != null) { + try { + ctx.close(); + } + catch (Exception e) { + // Never mind this. + } + } + } + + /** + * Close the supplied NamingEnumeration if it is not null. Swallow any + * exceptions, as this is only for cleanup. + * + * @param results the NamingEnumeration to close. + */ + private void closeNamingEnumeration(NamingEnumeration results) { + if (results != null) { + try { + results.close(); + } + catch (Exception e) { + // Never mind this. + } + } + } + + private SearchControls getDefaultSearchControls(int searchScope, boolean returningObjFlag, String[] attrs) { + + SearchControls controls = new SearchControls(); + controls.setSearchScope(searchScope); + controls.setReturningObjFlag(returningObjFlag); + controls.setReturningAttributes(attrs); + return controls; + } + + /** + * Make sure the returnObjFlag is set in the supplied SearchControls. Set it + * and log if it's not set. + * + * @param controls the SearchControls to check. + */ + private void assureReturnObjFlagSet(SearchControls controls) { + Validate.notNull(controls); + if (!controls.getReturningObjFlag()) { + log.info("The returnObjFlag of supplied SearchControls is not set" + + " but a ContextMapper is used - setting flag to true"); + controls.setReturningObjFlag(true); + } + } + + private final class NullDirContextProcessor implements DirContextProcessor { + public void postProcess(DirContext ctx) throws NamingException { + // Do nothing + } + + public void preProcess(DirContext ctx) throws NamingException { + // Do nothing + } + } + + /** + * A {@link NameClassPairCallbackHandler} that passes the NameClassPairs + * found to a NameClassPairMapper and collects the results in a list. + * + * @author Mattias Arthursson + */ + public class MappingCollectingNameClassPairCallbackHandler extends CollectingNameClassPairCallbackHandler { + + private NameClassPairMapper mapper; + + public MappingCollectingNameClassPairCallbackHandler(NameClassPairMapper mapper) { + this.mapper = mapper; + } + + /* + * @see org.springframework.ldap.CollectingNameClassPairCallbackHandler#getObjectFromNameClassPair(javax.naming.NameClassPair) + */ + public Object getObjectFromNameClassPair(NameClassPair nameClassPair) { + try { + return mapper.mapFromNameClassPair(nameClassPair); + } + catch (javax.naming.NamingException e) { + throw LdapUtils.convertLdapException(e); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#lookupContext(javax.naming.Name) + */ + public DirContextOperations lookupContext(Name dn) { + return (DirContextOperations) lookup(dn); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#lookupContext(java.lang.String) + */ + public DirContextOperations lookupContext(String dn) { + return (DirContextOperations) lookup(dn); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.LdapOperations#modifyAttributes(org.springframework.ldap.core.DirContextOperations) + */ + public void modifyAttributes(DirContextOperations ctx) { + Name dn = ctx.getDn(); + if (dn != null && ctx.isUpdateMode()) { + modifyAttributes(dn, ctx.getModificationItems()); + } + else { + throw new IllegalStateException("The DirContextOperations instance needs to be properly initialized."); + } + + } }