While LdapTemplate
contains several overloaded
versions of the most common operations in DirContext
,
we have not provided an alternative for each and every method signature,
mostly because there are so many of them. We have, however, provided a
means to call whichever DirContext
method you want
and still get the benefits that LdapTemplate provides.
Let's say that you want to call the following DirContext
method:
NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls ctls)
There is no corresponding overloaded method in LdapTemplate. The way to solve
this is to use a custom SearchExecutor
implementation:
public interface SearchExecutor { public NamingEnumeration executeSearch(DirContext ctx) throws NamingException; }
In your custom executor, you have access to a DirContext
object, which you use to call the method you want. You then provide a handler
that is responsible for mapping attributes and collecting the results. You can
for example use one of the available implementations of
CollectingNameClassPairCallbackHandler
, which will collect
the mapped results in an internal list. In order to
actually execute the search, you call the search
method in LdapTemplate that takes an executor and a handler as arguments. Finally,
you return whatever your handler has collected.
Example 4.1. A custom search method using SearchExecutor and AttributesMapper
package com.example.dao; public class PersonDaoImpl implements PersonDao { ... public List search(final Name base, final String filter, final String[] params, final SearchControls ctls) { SearchExecutor executor = new SearchExecutor() { public NamingEnumeration executeSearch(DirContext ctx) { return ctx.search(base, filter, params, ctls); } }; CollectingNameClassPairCallbackHandler handler = new AttributesMapperCallbackHandler(new PersonAttributesMapper()); ldapTemplate.search(executor, handler); return handler.getList(); } }
If you prefer the ContextMapper
to the
AttributesMapper
, this is what it would look
like:
Example 4.2. A custom search method using SearchExecutor and ContextMapper
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public List search(final Name base, final String filter, final String[] params,
final SearchControls ctls) {
SearchExecutor executor = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) {
return ctx.search(base, filter, params, ctls);
}
};
CollectingNameClassPairCallbackHandler handler =
new ContextMapperCallbackHandler(new PersonContextMapper());
ldapTemplate.search(executor, handler);
return handler.getList();
}
}
When using the
ContextMapperCallbackHandler
you must
make sure that you have called
setReturningObjFlag(true)
on your
SearchControls
instance.
In the same manner as for custom search
methods,
you can actually execute any method in DirContext
by
using a ContextExecutor
.
public interface ContextExecutor { public Object executeWithContext(DirContext ctx) throws NamingException; }
When implementing a custom ContextExecutor
, you
can choose between using the executeReadOnly()
or the
executeReadWrite()
method. Let's say that we want to
call this method:
Object lookupLink(Name name)
It's available in DirContext
, but there is no
matching method in LdapTemplate
. It's a lookup method,
so it should be read-only. We can implement it like this:
Example 4.3. A custom DirContext method using ContextExecutor
package com.example.dao; public class PersonDaoImpl implements PersonDao { ... public Object lookupLink(final Name name) { ContextExecutor executor = new ContextExecutor() { public Object executeWithContext(DirContext ctx) { return ctx.lookupLink(name); } }; return ldapTemplate.executeReadOnly(executor); } }
In the same manner you can execute a read-write operation using
the executeReadWrite()
method.