org.springframework.ldap.core.LdapTemplate Maven / Gradle / Ivy
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.odm.core.OdmException;
import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.util.Assert;
import javax.naming.Binding;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.PartialResultException;
import javax.naming.SizeLimitExceededException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.LdapName;
import java.util.List;
/**
* Executes core LDAP functionality and helps to avoid common errors, relieving
* the user of the burden of looking up contexts, looping through
* NamingEnumerations and closing contexts.
*
* Note for Active Directory (AD) users: AD servers are apparently unable
* to handle referrals automatically, which causes a
* PartialResultException
to be thrown whenever a referral is
* encountered in a search. To avoid this, set the
* ignorePartialResultException
property to true
.
* There is currently no way of manually handling these referrals in the form of
* ReferralException
, i.e. either you get the exception (and your
* results are lost) or all referrals are ignored (if the server is unable to
* handle them properly. Neither is there any simple way to get notified that a
* PartialResultException
has been ignored (other than in the log).
*
* @see org.springframework.ldap.core.ContextSource
*
* @author Mattias Hellborg Arthursson
* @author Ulrik Sandberg
*/
public class LdapTemplate implements LdapOperations, InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(LdapTemplate.class);
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;
private boolean ignoreNameNotFoundException = false;
private boolean ignoreSizeLimitExceededException = true;
private int defaultSearchScope = SearchControls.SUBTREE_SCOPE;
private int defaultTimeLimit = 0;
private int defaultCountLimit = 0;
private ObjectDirectoryMapper odm = new DefaultObjectDirectoryMapper();
/**
* 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;
}
/**
* {@inheritDoc}
*/
@Override
public ObjectDirectoryMapper getObjectDirectoryMapper() {
return odm;
}
/**
* Set the ObjectDirectoryMapper instance to use.
*
* @param odm the ObejctDirectoryMapper to use.
* @since 2.0
*/
public void setObjectDirectoryMapper(ObjectDirectoryMapper odm) {
this.odm = odm;
}
/**
* Get the ContextSource.
*
* @return the ContextSource.
*/
public ContextSource getContextSource() {
return contextSource;
}
/**
* Specify whether NameNotFoundException
should be ignored in
* searches. In previous version, NameNotFoundException
caused
* by the search base not being found was silently ignored. The default
* behavior is now to treat this as an error (as it should), and to convert
* and re-throw the exception. The ability to revert to the previous
* behavior still exists. The only difference is that the incident is in
* that case no longer silently ignored, but logged as a warning.
*
* @param ignore true
if NameNotFoundException
* should be ignored in searches, false
otherwise. Default is
* false
.
*
* @since 1.3
*/
public void setIgnoreNameNotFoundException(boolean ignore) {
this.ignoreNameNotFoundException = ignore;
}
/**
* 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;
}
/**
* Specify whether SizeLimitExceededException
should be ignored in searches.
* This is typically what you want if you specify count limit in your search controls.
*
* @param ignore true
if SizeLimitExceededException
* should be ignored in searches, false
otherwise. Default is
* true
.
* @since 2.0
*/
public void setIgnoreSizeLimitExceededException(boolean ignore) {
this.ignoreSizeLimitExceededException = ignore;
}
/**
* Set the default scope to be used in searches if not explicitly specified.
* Default is {@link javax.naming.directory.SearchControls#SUBTREE_SCOPE}.
*
* @param defaultSearchScope the default search scope to use in searches.
* One of {@link SearchControls#OBJECT_SCOPE},
* {@link SearchControls#ONELEVEL_SCOPE},
* or {@link SearchControls#SUBTREE_SCOPE}
* @since 2.0
*/
public void setDefaultSearchScope(int defaultSearchScope) {
this.defaultSearchScope = defaultSearchScope;
}
/**
* Set the default time limit be used in searches if not explicitly specified.
* Default is 0, indicating no time limit.
*
* @param defaultTimeLimit the default time limit to use in searches.
* @since 2.0
*/
public void setDefaultTimeLimit(int defaultTimeLimit) {
this.defaultTimeLimit = defaultTimeLimit;
}
/**
* Set the default count limit be used in searches if not explicitly specified.
* Default is 0, indicating no count limit.
*
* @param defaultCountLimit the default count limit to use in searches.
* @since 2.0
*/
public void setDefaultCountLimit(int defaultCountLimit) {
this.defaultCountLimit = defaultCountLimit;
}
/**
* {@inheritDoc}
*/
@Override
public void search(Name base, String filter, int searchScope, boolean returningObjFlag,
NameClassPairCallbackHandler handler) {
search(base, filter, getDefaultSearchControls(searchScope, returningObjFlag, ALL_ATTRIBUTES), handler);
}
/**
* {@inheritDoc}
*/
@Override
public void search(String base, String filter, int searchScope, boolean returningObjFlag,
NameClassPairCallbackHandler handler) {
search(base, filter, getDefaultSearchControls(searchScope, returningObjFlag, ALL_ATTRIBUTES), handler);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
};
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(controls);
}
search(se, handler);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
};
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(controls);
}
search(se, handler);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
};
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(controls);
}
search(se, handler, processor);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
};
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(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.
*/
@Override
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) {
// It is possible to ignore errors caused by base not found
if (ignoreNameNotFoundException) {
LOG.warn("Base context not found, ignoring: " + e.getMessage());
}
else {
ex = LdapUtils.convertLdapException(e);
}
}
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(SizeLimitExceededException e) {
if(ignoreSizeLimitExceededException) {
LOG.debug("SizeLimitExceededException 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.
*/
@Override
public void search(SearchExecutor se, NameClassPairCallbackHandler handler) {
search(se, handler, new NullDirContextProcessor());
}
/**
* {@inheritDoc}
*/
@Override
public void search(Name base, String filter, NameClassPairCallbackHandler handler) {
SearchControls controls = getDefaultSearchControls(defaultSearchScope, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES);
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(controls);
}
search(base, filter, controls, handler);
}
/**
* {@inheritDoc}
*/
@Override
public void search(String base, String filter, NameClassPairCallbackHandler handler) {
SearchControls controls = getDefaultSearchControls(defaultSearchScope, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES);
if (handler instanceof ContextMapperCallbackHandler) {
assureReturnObjFlagSet(controls);
}
search(base, filter, controls, handler);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, int searchScope, AttributesMapper mapper) {
return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, int searchScope, AttributesMapper mapper) {
return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, AttributesMapper mapper) {
return search(base, filter, defaultSearchScope, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, AttributesMapper mapper) {
return search(base, filter, defaultSearchScope, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, int searchScope, String[] attrs, ContextMapper mapper) {
return search(base, filter, getDefaultSearchControls(searchScope, RETURN_OBJ_FLAG, attrs), mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, int searchScope, String[] attrs, ContextMapper mapper) {
return search(base, filter, getDefaultSearchControls(searchScope, RETURN_OBJ_FLAG, attrs), mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, int searchScope, ContextMapper mapper) {
return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, int searchScope, ContextMapper mapper) {
return search(base, filter, searchScope, ALL_ATTRIBUTES, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, ContextMapper mapper) {
return search(base, filter, defaultSearchScope, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, ContextMapper mapper) {
return search(base, filter, defaultSearchScope, mapper);
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, SearchControls controls, ContextMapper mapper) {
return search(base, filter, controls, mapper, new NullDirContextProcessor());
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, SearchControls controls, ContextMapper mapper) {
return search(base, filter, controls, mapper, new NullDirContextProcessor());
}
/**
* {@inheritDoc}
*/
@Override
public List search(Name base, String filter, SearchControls controls, AttributesMapper mapper) {
return search(base, filter, controls, mapper, new NullDirContextProcessor());
}
/**
* {@inheritDoc}
*/
@Override
public List search(String base, String filter, SearchControls controls, AttributesMapper mapper) {
return search(base, filter, controls, mapper, new NullDirContextProcessor());
}
/**
* {@inheritDoc}
*/
@Override
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();
}
/**
* {@inheritDoc}
*/
@Override
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();
}
/**
* {@inheritDoc}
*/
@Override
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();
}
/**
* {@inheritDoc}
*/
@Override
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();
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
public List list(String base, NameClassPairMapper mapper) {
CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper);
list(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public List list(Name base, NameClassPairMapper mapper) {
CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper);
list(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public List list(final Name base) {
return list(base, new DefaultNameClassPairMapper());
}
/**
* {@inheritDoc}
*/
@Override
public List list(final String base) {
return list(base, new DefaultNameClassPairMapper());
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
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);
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(String base, NameClassPairMapper mapper) {
CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper);
listBindings(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(Name base, NameClassPairMapper mapper) {
CollectingNameClassPairCallbackHandler handler = new MappingCollectingNameClassPairCallbackHandler(mapper);
listBindings(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(final String base) {
return listBindings(base, new DefaultNameClassPairMapper());
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(final Name base) {
return listBindings(base, new DefaultNameClassPairMapper());
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(String base, ContextMapper mapper) {
ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper);
listBindings(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public List listBindings(Name base, ContextMapper mapper) {
ContextMapperCallbackHandler handler = new ContextMapperCallbackHandler(mapper);
listBindings(base, handler);
return handler.getList();
}
/**
* {@inheritDoc}
*/
@Override
public T executeReadOnly(ContextExecutor ce) {
DirContext ctx = contextSource.getReadOnlyContext();
return executeWithContext(ce, ctx);
}
/**
* {@inheritDoc}
*/
@Override
public T executeReadWrite(ContextExecutor ce) {
DirContext ctx = contextSource.getReadWriteContext();
return executeWithContext(ce, ctx);
}
private T executeWithContext(ContextExecutor ce, DirContext ctx) {
try {
return ce.executeWithContext(ctx);
}
catch (javax.naming.NamingException e) {
throw LdapUtils.convertLdapException(e);
}
finally {
closeContext(ctx);
}
}
/**
* {@inheritDoc}
*/
@Override
public Object lookup(final Name dn) {
return executeReadOnly(new ContextExecutor() {
public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException {
return ctx.lookup(dn);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public Object lookup(final String dn) {
return executeReadOnly(new ContextExecutor() {
public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException {
return ctx.lookup(dn);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final Name dn, final AttributesMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes attributes = ctx.getAttributes(dn);
return mapper.mapFromAttributes(attributes);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final String dn, final AttributesMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes attributes = ctx.getAttributes(dn);
return mapper.mapFromAttributes(attributes);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final Name dn, final ContextMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Object object = ctx.lookup(dn);
return mapper.mapFromContext(object);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final String dn, final ContextMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Object object = ctx.lookup(dn);
return mapper.mapFromContext(object);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final Name dn, final String[] attributes, final AttributesMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes filteredAttributes = ctx.getAttributes(dn, attributes);
return mapper.mapFromAttributes(filteredAttributes);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final String dn, final String[] attributes, final AttributesMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes filteredAttributes = ctx.getAttributes(dn, attributes);
return mapper.mapFromAttributes(filteredAttributes);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final Name dn, final String[] attributes, final ContextMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes filteredAttributes = ctx.getAttributes(dn, attributes);
DirContextAdapter contextAdapter = new DirContextAdapter(filteredAttributes, dn);
return mapper.mapFromContext(contextAdapter);
}
});
}
/**
* {@inheritDoc}
*/
@Override
public T lookup(final String dn, final String[] attributes, final ContextMapper mapper) {
return executeReadOnly(new ContextExecutor() {
public T executeWithContext(DirContext ctx) throws javax.naming.NamingException {
Attributes filteredAttributes = ctx.getAttributes(dn, attributes);
LdapName name = LdapUtils.newLdapName(dn);
DirContextAdapter contextAdapter = new DirContextAdapter(filteredAttributes, name);
return mapper.mapFromContext(contextAdapter);
}
});
}
/**
* {@inheritDoc}
*/
@Override
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;
}
});
}
/**
* {@inheritDoc}
*/
@Override
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;
}
});
}
/**
* {@inheritDoc}
*/
@Override
public void bind(final Name dn, final Object obj, final Attributes attributes) {
executeReadWrite(new ContextExecutor