~hudson-ubuntu/ubuntu/natty/libspring-ldap-java/hudson-fix

« back to all changes in this revision

Viewing changes to docs/docbkx/basic.xml

  • Committer: Bazaar Package Importer
  • Author(s): Miguel Landaeta
  • Date: 2010-04-16 20:36:56 UTC
  • Revision ID: james.westby@ubuntu.com-20100416203656-257w9tnqwmpmcgv5
Tags: upstream-1.3.0.RELEASE
ImportĀ upstreamĀ versionĀ 1.3.0.RELEASE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="UTF-8"?>
 
2
<chapter id="basic">
 
3
  <title>Basic Operations</title>
 
4
 
 
5
  <sect1 id="basic-searches">
 
6
    <title>Search and Lookup Using AttributesMapper</title>
 
7
 
 
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>
 
10
 
 
11
    <example>
 
12
      <title>AttributesMapper that returns a single attribute</title>
 
13
 
 
14
      <programlisting>package com.example.dao;
 
15
 
 
16
public class PersonDaoImpl implements PersonDao {
 
17
   private LdapTemplate ldapTemplate;
 
18
 
 
19
   public void setLdapTemplate(LdapTemplate ldapTemplate) {
 
20
      this.ldapTemplate = ldapTemplate;
 
21
   }
 
22
 
 
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();
 
30
            }
 
31
         }</emphasis>);
 
32
   }
 
33
}</programlisting>
 
34
    </example>
 
35
 
 
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>
 
43
 
 
44
    <para>Note that the <literal>AttributesMapper</literal> implementation
 
45
    could easily be modified to return a full <literal>Person</literal>
 
46
    object:</para>
 
47
 
 
48
    <example>
 
49
      <title>AttributesMapper that returns a Person object</title>
 
50
 
 
51
      <programlisting>package com.example.dao;
 
52
 
 
53
public class PersonDaoImpl implements PersonDao {
 
54
   private LdapTemplate ldapTemplate;
 
55
   ...
 
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());
 
62
         return person;
 
63
      }
 
64
   }
 
65
</emphasis>
 
66
   public List getAllPersons() {
 
67
      return ldapTemplate.search("", "(objectclass=person)", <emphasis
 
68
          role="bold">new PersonAttributesMapper()</emphasis>);
 
69
   }
 
70
}</programlisting>
 
71
    </example>
 
72
 
 
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
 
77
    object:</para>
 
78
 
 
79
    <example>
 
80
      <title>A lookup resulting in a Person object</title>
 
81
 
 
82
      <programlisting>package com.example.dao;
 
83
 
 
84
public class PersonDaoImpl implements PersonDao {
 
85
   private LdapTemplate ldapTemplate;
 
86
   ...
 
87
   public Person findPerson(String dn) {
 
88
      return (Person) ldapTemplate.lookup(dn, new PersonAttributesMapper());
 
89
   }
 
90
}</programlisting>
 
91
    </example>
 
92
 
 
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>
 
96
  </sect1>
 
97
 
 
98
  <sect1 id="basic-filters">
 
99
    <title>Building Dynamic Filters</title>
 
100
 
 
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>(&amp;(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
 
107
    classes:</para>
 
108
 
 
109
    <example>
 
110
      <title>Building a search filter dynamically</title>
 
111
 
 
112
      <programlisting>package com.example.dao;
 
113
 
 
114
public class PersonDaoImpl implements PersonDao {
 
115
   private LdapTemplate ldapTemplate;
 
116
   ...
 
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();
 
127
            }
 
128
         });
 
129
   }
 
130
}</programlisting>
 
131
    </example>
 
132
 
 
133
    <para>To perform a wildcard search, it's possible to use the
 
134
    <literal>WhitespaceWildcardsFilter</literal>:</para>
 
135
 
 
136
    <example>
 
137
      <title>Building a wildcard search filter</title>
 
138
 
 
139
      <programlisting>AndFilter filter = new AndFilter();
 
140
filter.and(new EqualsFilter("objectclass", "person"));
 
141
filter.and(new WhitespaceWildcardsFilter("cn", cn));</programlisting>
 
142
    </example>
 
143
 
 
144
    <para>
 
145
        <note>
 
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 &quot;ldap injection&quot;,
 
149
                where a user might use such characters to inject unwanted operations
 
150
                into your LDAP operations.
 
151
        </note>
 
152
    </para>
 
153
  </sect1>
 
154
 
 
155
  <sect1>
 
156
    <title>Building Dynamic Distinguished Names</title>
 
157
 
 
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.
 
169
    </para>
 
170
    <para>
 
171
    The following example illustrates how
 
172
    <literal>DistinguishedName</literal> can be used to dynamically construct
 
173
    a distinguished name:</para>
 
174
 
 
175
    <example>
 
176
      <title>Building a distinguished name dynamically</title>
 
177
 
 
178
      <programlisting>package com.example.dao;
 
179
 
 
180
import org.springframework.ldap.core.support.DistinguishedName;
 
181
import javax.naming.Name;
 
182
 
 
183
public class PersonDaoImpl implements PersonDao {
 
184
   public static final String BASE_DN = "dc=example,dc=com";
 
185
   ...
 
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;
 
192
   }
 
193
}</programlisting>
 
194
    </example>
 
195
 
 
196
    <para>Assuming that a Person has the following attributes:</para>
 
197
 
 
198
    <informaltable>
 
199
      <tgroup cols="2">
 
200
        <tbody>
 
201
          <row>
 
202
            <entry><literal>country</literal></entry>
 
203
 
 
204
            <entry>Sweden</entry>
 
205
          </row>
 
206
 
 
207
          <row>
 
208
            <entry><literal>company</literal></entry>
 
209
 
 
210
            <entry>Some Company</entry>
 
211
          </row>
 
212
 
 
213
          <row>
 
214
            <entry><literal>fullname</literal></entry>
 
215
 
 
216
            <entry>Some Person</entry>
 
217
          </row>
 
218
        </tbody>
 
219
      </tgroup>
 
220
    </informaltable>
 
221
 
 
222
    <para>The code above would then result in the following distinguished
 
223
    name:</para>
 
224
 
 
225
    <para><programlisting>cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com</programlisting></para>
 
226
 
 
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>
 
232
  </sect1>
 
233
 
 
234
  <sect1 id="basic-binding-unbinding">
 
235
    <title>Binding and Unbinding</title>
 
236
 
 
237
    <sect2 id="basic-binding-data">
 
238
      <title>Binding Data</title>
 
239
 
 
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
 
243
      LdapTemplate:</para>
 
244
 
 
245
      <example>
 
246
        <title>Binding data using Attributes</title>
 
247
 
 
248
        <programlisting>package com.example.dao;
 
249
 
 
250
public class PersonDaoImpl implements PersonDao {
 
251
   private LdapTemplate ldapTemplate;
 
252
   ...
 
253
   public void create(Person p) {
 
254
      Name dn = buildDn(p);
 
255
<emphasis role="bold">      ldapTemplate.bind(dn, null, buildAttributes(p));
 
256
</emphasis>   }
 
257
 
 
258
   private Attributes buildAttributes(Person p) {
 
259
      Attributes attrs = new BasicAttributes();
 
260
      BasicAttribute ocattr = new BasicAttribute("objectclass");
 
261
      ocattr.add("top");
 
262
      ocattr.add("person");
 
263
      attrs.put(ocattr);
 
264
      attrs.put("cn", "Some Person");
 
265
      attrs.put("sn", "Person");
 
266
      return attrs;
 
267
   }
 
268
}</programlisting>
 
269
      </example>
 
270
 
 
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>
 
275
    </sect2>
 
276
 
 
277
    <sect2 id="basic-unbinding-data">
 
278
      <title>Unbinding Data</title>
 
279
 
 
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
 
283
      LdapTemplate:</para>
 
284
 
 
285
      <example>
 
286
        <title>Unbinding data</title>
 
287
 
 
288
        <programlisting>package com.example.dao;
 
289
 
 
290
public class PersonDaoImpl implements PersonDao {
 
291
   private LdapTemplate ldapTemplate;
 
292
   ...
 
293
   public void delete(Person p) {
 
294
      Name dn = buildDn(p);
 
295
<emphasis role="bold">      ldapTemplate.unbind(dn);
 
296
</emphasis>   }
 
297
}</programlisting>
 
298
      </example>
 
299
    </sect2>
 
300
  </sect1>
 
301
 
 
302
  <sect1 id="basic-modifying">
 
303
    <title>Modifying</title>
 
304
 
 
305
    <para>In Java LDAP, data can be modified in two ways: either using
 
306
    <emphasis>rebind</emphasis> or
 
307
    <emphasis>modifyAttributes</emphasis>.</para>
 
308
 
 
309
    <sect2>
 
310
      <title>Modifying using <literal>rebind</literal></title>
 
311
 
 
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>
 
315
 
 
316
      <example>
 
317
        <title>Modifying using rebind</title>
 
318
 
 
319
        <programlisting>package com.example.dao;
 
320
 
 
321
public class PersonDaoImpl implements PersonDao {
 
322
   private LdapTemplate ldapTemplate;
 
323
   ...
 
324
   public void update(Person p) {
 
325
      Name dn = buildDn(p);
 
326
<emphasis role="bold">      ldapTemplate.rebind(dn, null, buildAttributes(p));
 
327
</emphasis>   }
 
328
}</programlisting>
 
329
      </example>
 
330
    </sect2>
 
331
 
 
332
    <sect2 id="modify-modifyAttributes">
 
333
      <title>Modifying using <literal>modifyAttributes</literal></title>
 
334
 
 
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>
 
338
 
 
339
      <example>
 
340
        <title>Modifying using modifyAttributes</title>
 
341
 
 
342
        <programlisting>package com.example.dao;
 
343
 
 
344
public class PersonDaoImpl implements PersonDao {
 
345
   private LdapTemplate ldapTemplate;
 
346
   ...
 
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});
 
352
</emphasis>   }
 
353
}</programlisting>
 
354
      </example>
 
355
 
 
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>
 
360
    </sect2>
 
361
  </sect1>
 
362
 
 
363
  <sect1 id="samples">
 
364
    <title>Sample applications</title>
 
365
 
 
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>
 
370
 
 
371
    <para><orderedlist>
 
372
        <listitem>
 
373
          <para>spring-ldap-person - the sample demonstrating most
 
374
          features.</para>
 
375
        </listitem>
 
376
 
 
377
        <listitem>
 
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>
 
382
        </listitem>
 
383
      </orderedlist></para>
 
384
  </sect1>
 
385
</chapter>
 
 
b'\\ No newline at end of file'