This section covers how to add your own overloaded API methods to implement new functionality.
LdapTemplate
contains several overloaded versions of the most common operations in DirContext
. However, 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.
Suppose 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, as follows:
public interface SearchExecutor {
public NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
}
In your custom executor, you have access to a DirContext
object, which you can use to call the method you want. You can 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 collects the mapped results in an internal list. In order to actually perform the search, you need to call the search
method in LdapTemplate
that takes an executor and a handler as arguments. Finally, you need to return whatever your handler has collected. The following example shows how to do all of that:
SearchExecutor
and AttributesMapper
package com.example.repo;
public class PersonRepoImpl implements PersonRepo {
...
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
, the following example shows what it would look like:
SearchExecutor
and ContextMapper
package com.example.repo;
public class PersonRepoImpl implements PersonRepo {
...
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();
}
}
Note
|
When you use 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 call any method in DirContext
by using a ContextExecutor
, as follows:
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. Suppose you want to call the following method:
Object lookupLink(Name name)
The method is available in DirContext
, but there is no matching method in LdapTemplate
. It is a lookup method, so it should be read-only. We can implement it as follows:
DirContext
method using ContextExecutor
package com.example.repo;
public class PersonRepoImpl implements PersonRepo {
...
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 perform a read-write operation by using the executeReadWrite()
method.