While very useful when extracting attribute values, DirContextAdapter
is even more
powerful for hiding attribute details when binding and modifying data.
This is an example of an improved implementation of the create DAO method. Compare it with the previous implementation in the section called “Binding Data”.
Example 3.4. Binding using DirContextAdapter
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public void create(Person p) {
Name dn = buildDn(p);
DirContextAdapter context = new DirContextAdapter(dn);
context.setAttributeValues("objectclass", new String[] {"top", "person"});
context.setAttributeValue("cn", p.getFullname());
context.setAttributeValue("sn", p.getLastname());
context.setAttributeValue("description", p.getDescription());
ldapTemplate.bind(context);
}
}
Note that we use the DirContextAdapter
instance
as the second parameter to bind, which should be a Context
.
The third parameter is null
, since we're not using any
Attributes
.
Also note the use of the setAttributeValues()
method when setting the
objectclass
attribute values. The objectclass
attribute is
multi-value, and similar to the troubles of extracting muti-value attribute data, building multi-value
attributes is tedious and verbose work. Using the setAttributeValues()
mehtod you can
have DirContextAdapter
handle that work for you.
The code for a rebind
would be pretty much
identical to Example 3.4, “Binding using DirContextAdapter
”, except
that the method called would be rebind
. As we saw in
the section called “Modifying using modifyAttributes
” a more correct approach would be to
build a ModificationItem
array containing the actual
modifications you want to do. This would require you to determine the actual
modifications compared to the data present in the LDAP tree. Again, this
is something that DirContextAdapter
can help you with; the
DirContextAdapter
has the ability to keep track of
its modified attributes. The following example takes advantage of this
feature:
Example 3.5. Modifying using DirContextAdapter
package com.example.dao; public class PersonDaoImpl implements PersonDao { ... public void update(Person p) { Name dn = buildDn(p); DirContextOperations context = ldapTemplate.lookupContext(dn); context.setAttributeValues("objectclass", new String[] {"top", "person"}); context.setAttributeValue("cn", p.getFullname()); context.setAttributeValue("sn", p.getLastname()); context.setAttributeValue("description", p.getDescription()); ldapTemplate.modifyAttributes(context); } }
When no mapper is passed to a ldapTemplate.lookup()
operation,
the result will be a DirContextAdapter
instance.
While the lookup
method returns an Object
, the convenience
method lookupContext
method automatically casts the return value to
a DirContextOperations
(the interface that DirContextAdapter
implements.
The observant reader will see that we have duplicated code in the
create
and update
methods. This
code maps from a domain object to a context. It can be extracted to a
separate method:
Example 3.6. Binding and modifying using DirContextAdapter
package com.example.dao; public class PersonDaoImpl implements PersonDao { private LdapTemplate ldapTemplate; ... public void create(Person p) { Name dn = buildDn(p); DirContextAdapter context = new DirContextAdapter(dn); mapToContext(p, context); ldapTemplate.bind(context); } public void update(Person p) { Name dn = buildDn(p); DirContextOperations context = ldapTemplate.lookupContext(dn); mapToContext(person, context); ldapTemplate.modifyAttributes(context); } protected void mapToContext (Person p, DirContextOperations context) { context.setAttributeValues("objectclass", new String[] {"top", "person"}); context.setAttributeValue("cn", p.getFullName()); context.setAttributeValue("sn", p.getLastName()); context.setAttributeValue("description", p.getDescription()); } }