1
<?xml version="1.0" encoding="UTF-8"?>
3
<title>Basic Operations</title>
5
<sect1 id="basic-searches">
6
<title>Search and Lookup Using AttributesMapper</title>
8
<para>In this example we will use an <literal>AttributesMapper</literal>
9
to easily build a List of all common names of all person objects.</para>
12
<title>AttributesMapper that returns a single attribute</title>
14
<programlisting>package com.example.dao;
16
public class PersonDaoImpl implements PersonDao {
17
private LdapTemplate ldapTemplate;
19
public void setLdapTemplate(LdapTemplate ldapTemplate) {
20
this.ldapTemplate = ldapTemplate;
23
public List getAllPersonNames() {
24
return ldapTemplate.search(
25
"", "(objectclass=person)",
26
<emphasis role="bold"> new AttributesMapper() {
27
public Object mapFromAttributes(Attributes attrs)
28
throws NamingException {
29
return attrs.get("cn").get();
36
<para>The inline implementation of <literal>AttributesMapper</literal>
37
just gets the desired attribute value from the
38
<literal>Attributes</literal> and returns it. Internally,
39
<literal>LdapTemplate</literal> iterates over all entries found, calling
40
the given <literal>AttributesMapper</literal> for each entry, and collects
41
the results in a list. The list is then returned by the
42
<literal>search</literal> method.</para>
44
<para>Note that the <literal>AttributesMapper</literal> implementation
45
could easily be modified to return a full <literal>Person</literal>
49
<title>AttributesMapper that returns a Person object</title>
51
<programlisting>package com.example.dao;
53
public class PersonDaoImpl implements PersonDao {
54
private LdapTemplate ldapTemplate;
56
<emphasis role="bold"> private class PersonAttributesMapper implements AttributesMapper {
57
public Object mapFromAttributes(Attributes attrs) throws NamingException {
58
Person person = new Person();
59
person.setFullName((String)attrs.get("cn").get());
60
person.setLastName((String)attrs.get("sn").get());
61
person.setDescription((String)attrs.get("description").get());
66
public List getAllPersons() {
67
return ldapTemplate.search("", "(objectclass=person)", <emphasis
68
role="bold">new PersonAttributesMapper()</emphasis>);
73
<para>If you have the distinguished name (<literal>dn</literal>) that
74
identifies an entry, you can retrieve the entry directly, without
75
searching for it. This is called a <emphasis>lookup</emphasis> in Java
76
LDAP. The following example shows how a lookup results in a Person
80
<title>A lookup resulting in a Person object</title>
82
<programlisting>package com.example.dao;
84
public class PersonDaoImpl implements PersonDao {
85
private LdapTemplate ldapTemplate;
87
public Person findPerson(String dn) {
88
return (Person) ldapTemplate.lookup(dn, new PersonAttributesMapper());
93
<para>This will look up the specified <literal>dn</literal> and pass the
94
found attributes to the supplied <literal>AttributesMapper</literal>, in
95
this case resulting in a <literal>Person</literal> object.</para>
98
<sect1 id="basic-filters">
99
<title>Building Dynamic Filters</title>
101
<para>We can build dynamic filters to use in searches, using the classes
102
from the <literal>org.springframework.ldap.filter</literal>
103
package. Let's say that we want the following filter:
104
<literal>(&(objectclass=person)(sn=?))</literal>, where we want the
105
<literal>?</literal> to be replaced with the value of the parameter
106
<literal>lastName</literal>. This is how we do it using the filter support
110
<title>Building a search filter dynamically</title>
112
<programlisting>package com.example.dao;
114
public class PersonDaoImpl implements PersonDao {
115
private LdapTemplate ldapTemplate;
117
public List getPersonNamesByLastName(String lastName) {
118
<emphasis role="bold"> AndFilter filter = new AndFilter();
119
filter.and(new EqualsFilter("objectclass", "person"));
120
filter.and(new EqualsFilter("sn", lastName));
121
</emphasis> return ldapTemplate.search(
122
"", <emphasis role="bold">filter.encode()</emphasis>,
123
new AttributesMapper() {
124
public Object mapFromAttributes(Attributes attrs)
125
throws NamingException {
126
return attrs.get("cn").get();
133
<para>To perform a wildcard search, it's possible to use the
134
<literal>WhitespaceWildcardsFilter</literal>:</para>
137
<title>Building a wildcard search filter</title>
139
<programlisting>AndFilter filter = new AndFilter();
140
filter.and(new EqualsFilter("objectclass", "person"));
141
filter.and(new WhitespaceWildcardsFilter("cn", cn));</programlisting>
146
In addition to simplifying building of complex search filters,
147
the <literal>Filter</literal> classes also provide proper escaping
148
of any unsafe characters. This prevents "ldap injection",
149
where a user might use such characters to inject unwanted operations
150
into your LDAP operations.
156
<title>Building Dynamic Distinguished Names</title>
158
<para>The standard <ulink
159
url="http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Name.html">Name</ulink>
160
interface represents a generic name, which is basically an ordered
161
sequence of components. The <literal>Name</literal> interface also
162
provides operations on that sequence; e.g., <literal>add</literal> or
163
<literal>remove</literal>. LdapTemplate provides an implementation of the
164
<literal>Name</literal> interface: <literal>DistinguishedName</literal>.
165
Using this class will greatly simplify building distinguished names,
166
especially considering the sometimes complex rules regarding escapings and
167
encodings. As with the <literal>Filter</literal> classes this helps preventing
168
potentially malicious data being injected into your LDAP operations.
171
The following example illustrates how
172
<literal>DistinguishedName</literal> can be used to dynamically construct
173
a distinguished name:</para>
176
<title>Building a distinguished name dynamically</title>
178
<programlisting>package com.example.dao;
180
import org.springframework.ldap.core.support.DistinguishedName;
181
import javax.naming.Name;
183
public class PersonDaoImpl implements PersonDao {
184
public static final String BASE_DN = "dc=example,dc=com";
186
protected Name buildDn(Person p) {
187
<emphasis role="bold"> DistinguishedName dn = new DistinguishedName(BASE_DN);
188
dn.add("c", p.getCountry());
189
dn.add("ou", p.getCompany());
190
dn.add("cn", p.getFullname());
191
</emphasis> return dn;
196
<para>Assuming that a Person has the following attributes:</para>
202
<entry><literal>country</literal></entry>
204
<entry>Sweden</entry>
208
<entry><literal>company</literal></entry>
210
<entry>Some Company</entry>
214
<entry><literal>fullname</literal></entry>
216
<entry>Some Person</entry>
222
<para>The code above would then result in the following distinguished
225
<para><programlisting>cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com</programlisting></para>
227
<para>In Java 5, there is an implementation of the Name interface: <ulink
228
url="http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/ldap/LdapName.html">LdapName</ulink>.
229
If you are in the Java 5 world, you might as well use
230
<literal>LdapName</literal>. However, you may still use
231
<literal>DistinguishedName</literal> if you so wish.</para>
234
<sect1 id="basic-binding-unbinding">
235
<title>Binding and Unbinding</title>
237
<sect2 id="basic-binding-data">
238
<title>Binding Data</title>
240
<para>Inserting data in Java LDAP is called binding. In order to do
241
that, a distinguished name that uniquely identifies the new entry is
242
required. The following example shows how data is bound using
246
<title>Binding data using Attributes</title>
248
<programlisting>package com.example.dao;
250
public class PersonDaoImpl implements PersonDao {
251
private LdapTemplate ldapTemplate;
253
public void create(Person p) {
254
Name dn = buildDn(p);
255
<emphasis role="bold"> ldapTemplate.bind(dn, null, buildAttributes(p));
258
private Attributes buildAttributes(Person p) {
259
Attributes attrs = new BasicAttributes();
260
BasicAttribute ocattr = new BasicAttribute("objectclass");
262
ocattr.add("person");
264
attrs.put("cn", "Some Person");
265
attrs.put("sn", "Person");
271
<para>The Attributes building is--while dull and verbose--sufficient for
272
many purposes. It is, however, possible to simplify the binding
273
operation further, which will be described in <xref
274
linkend="dirobjectfactory" />.</para>
277
<sect2 id="basic-unbinding-data">
278
<title>Unbinding Data</title>
280
<para>Removing data in Java LDAP is called unbinding. A distinguished
281
name (dn) is required to identify the entry, just as in the binding
282
operation. The following example shows how data is unbound using
286
<title>Unbinding data</title>
288
<programlisting>package com.example.dao;
290
public class PersonDaoImpl implements PersonDao {
291
private LdapTemplate ldapTemplate;
293
public void delete(Person p) {
294
Name dn = buildDn(p);
295
<emphasis role="bold"> ldapTemplate.unbind(dn);
302
<sect1 id="basic-modifying">
303
<title>Modifying</title>
305
<para>In Java LDAP, data can be modified in two ways: either using
306
<emphasis>rebind</emphasis> or
307
<emphasis>modifyAttributes</emphasis>.</para>
310
<title>Modifying using <literal>rebind</literal></title>
312
<para>A <literal>rebind</literal> is a very crude way to modify data.
313
It's basically an <literal>unbind</literal> followed by a
314
<literal>bind</literal>. It looks like this:</para>
317
<title>Modifying using rebind</title>
319
<programlisting>package com.example.dao;
321
public class PersonDaoImpl implements PersonDao {
322
private LdapTemplate ldapTemplate;
324
public void update(Person p) {
325
Name dn = buildDn(p);
326
<emphasis role="bold"> ldapTemplate.rebind(dn, null, buildAttributes(p));
332
<sect2 id="modify-modifyAttributes">
333
<title>Modifying using <literal>modifyAttributes</literal></title>
335
<para>If only the modified attributes should be replaced, there is a
336
method called <literal>modifyAttributes</literal> that takes an array of
337
modifications:</para>
340
<title>Modifying using modifyAttributes</title>
342
<programlisting>package com.example.dao;
344
public class PersonDaoImpl implements PersonDao {
345
private LdapTemplate ldapTemplate;
347
public void updateDescription(Person p) {
348
Name dn = buildDn(p);
349
Attribute attr = new BasicAttribute("description", p.getDescription())
350
ModificationItem item = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
351
<emphasis role="bold"> ldapTemplate.modifyAttributes(dn, new ModificationItem[] {item});
356
<para>Building <literal>Attributes</literal> and
357
<literal>ModificationItem</literal> arrays is a lot of work, but as you
358
will see in <xref linkend="dirobjectfactory" />, the update operations
359
can be simplified.</para>
364
<title>Sample applications</title>
366
<para>It is recommended that you review the Spring LDAP sample
367
applications included in the release distribution for best-practice
368
illustrations of the features of this library. A description of each
369
sample is provided below:</para>
373
<para>spring-ldap-person - the sample demonstrating most
378
<para>spring-ldap-article - the sample application that was written
379
to accompany a <ulink
380
url="http://today.java.net/pub/a/today/2006/04/18/ldaptemplate-java-ldap-made-simple.html">java.net
381
article</ulink> about Spring LDAP.</para>
383
</orderedlist></para>
b'\\ No newline at end of file'