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."); + } + + } }