File: executors.xml

package info (click to toggle)
libspring-ldap-java 1.3.1.RELEASE-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,876 kB
  • sloc: java: 12,509; xml: 4,104; jsp: 36; makefile: 31; sh: 13
file content (148 lines) | stat: -rw-r--r-- 5,763 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="executors">
  <title>Adding Missing Overloaded API Methods</title>

  <sect1 id="executors-search">
    <title>Implementing Custom Search Methods</title>

    <para>While <literal>LdapTemplate</literal> contains several overloaded
    versions of the most common operations in <literal>DirContext</literal>,
    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 <literal>DirContext</literal> method you want
    and still get the benefits that LdapTemplate provides.</para>
    
    <para>Let's say that you want to call the following <literal>DirContext</literal>
    method:</para>

    <programlisting>NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls ctls)</programlisting>

    <para>There is no corresponding overloaded method in LdapTemplate. The way to solve
    this is to use a custom <literal>SearchExecutor</literal> implementation:</para>

    <informalexample>
      <programlisting>public interface SearchExecutor {
   public NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
}</programlisting>
    </informalexample>

    <para>In your custom executor, you have access to a <literal>DirContext</literal>
    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
    <literal>CollectingNameClassPairCallbackHandler</literal>, which will collect
    the mapped results in an internal list. In order to
    actually execute the search, you call the <literal>search</literal> 
    method in LdapTemplate that takes an executor and a handler as arguments. Finally,
    you return whatever your handler has collected.</para>

    <example>
      <title>A custom search method using SearchExecutor and
      AttributesMapper</title>

      <programlisting>package com.example.dao;

public class PersonDaoImpl implements PersonDao {
   ...
   public List search(final Name base, final String filter, final String[] params,
         final SearchControls ctls) {
      <emphasis role="bold">SearchExecutor executor = new SearchExecutor() {
         public NamingEnumeration executeSearch(DirContext ctx) {
            return ctx.search(base, filter, params, ctls);
         }
      }</emphasis>;

      CollectingNameClassPairCallbackHandler handler =
         new AttributesMapperCallbackHandler(new PersonAttributesMapper());

      ldapTemplate.search(<emphasis role="bold">executor</emphasis>, handler);
      return handler.getList();
   }
}</programlisting>
    </example>

    <para>If you prefer the <literal>ContextMapper</literal> to the
    <literal>AttributesMapper</literal>, this is what it would look
    like:</para>

    <example>
      <title>A custom search method using SearchExecutor and
      ContextMapper</title>

      <programlisting>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 =
         <emphasis role="bold">new ContextMapperCallbackHandler(new PersonContextMapper())</emphasis>;

      ldapTemplate.search(executor, handler);
      return handler.getList();
   }
}</programlisting>
    </example>

    <note>
      <para>When using the
      <literal>ContextMapperCallbackHandler</literal> you must
      make sure that you have called
      <literal>setReturningObjFlag(true)</literal> on your
      <literal>SearchControls</literal> instance.</para>
    </note>
  </sect1>

  <sect1 id="executors-others">
    <title>Implementing Other Custom Context Methods</title>

    <para>In the same manner as for custom <literal>search</literal> methods,
    you can actually execute any method in <literal>DirContext</literal> by
    using a <literal>ContextExecutor</literal>.</para>

    <informalexample>
      <programlisting>public interface ContextExecutor {
   public Object executeWithContext(DirContext ctx) throws NamingException;
}</programlisting>

      <para>When implementing a custom <literal>ContextExecutor</literal>, you
      can choose between using the <literal>executeReadOnly()</literal> or the
      <literal>executeReadWrite()</literal> method. Let's say that we want to
      call this method:</para>
    </informalexample>

    <programlisting>Object lookupLink(Name name)</programlisting>

    <para>It's available in <literal>DirContext</literal>, but there is no
    matching method in <literal>LdapTemplate</literal>. It's a lookup method,
    so it should be read-only. We can implement it like this:</para>

    <example>
      <title>A custom DirContext method using ContextExecutor</title>

      <programlisting>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);
   }
}</programlisting>

      <para>In the same manner you can execute a read-write operation using
      the <literal>executeReadWrite()</literal> method.</para>
    </example>
  </sect1>
</chapter>