001 /*
002 * Copyright 2010-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2010-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.listener;
022
023
024
025 import java.io.Serializable;
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.Collections;
029 import java.util.List;
030
031 import com.unboundid.ldap.protocol.AddRequestProtocolOp;
032 import com.unboundid.ldap.protocol.AddResponseProtocolOp;
033 import com.unboundid.ldap.protocol.BindRequestProtocolOp;
034 import com.unboundid.ldap.protocol.BindResponseProtocolOp;
035 import com.unboundid.ldap.protocol.CompareRequestProtocolOp;
036 import com.unboundid.ldap.protocol.CompareResponseProtocolOp;
037 import com.unboundid.ldap.protocol.DeleteRequestProtocolOp;
038 import com.unboundid.ldap.protocol.DeleteResponseProtocolOp;
039 import com.unboundid.ldap.protocol.ExtendedRequestProtocolOp;
040 import com.unboundid.ldap.protocol.ExtendedResponseProtocolOp;
041 import com.unboundid.ldap.protocol.LDAPMessage;
042 import com.unboundid.ldap.protocol.ModifyRequestProtocolOp;
043 import com.unboundid.ldap.protocol.ModifyResponseProtocolOp;
044 import com.unboundid.ldap.protocol.ModifyDNRequestProtocolOp;
045 import com.unboundid.ldap.protocol.ModifyDNResponseProtocolOp;
046 import com.unboundid.ldap.protocol.SearchRequestProtocolOp;
047 import com.unboundid.ldap.protocol.SearchResultDoneProtocolOp;
048 import com.unboundid.ldap.protocol.SearchResultEntryProtocolOp;
049 import com.unboundid.ldap.protocol.SearchResultReferenceProtocolOp;
050 import com.unboundid.ldap.sdk.Control;
051 import com.unboundid.ldap.sdk.Entry;
052 import com.unboundid.ldap.sdk.LDAPException;
053 import com.unboundid.ldap.sdk.ResultCode;
054 import com.unboundid.ldap.sdk.SearchResultReference;
055 import com.unboundid.util.Debug;
056 import com.unboundid.util.NotMutable;
057 import com.unboundid.util.ThreadSafety;
058 import com.unboundid.util.ThreadSafetyLevel;
059 import com.unboundid.util.Validator;
060
061
062
063 /**
064 * This class provides a very simple LDAP listener request handler
065 * implementation that simply returns a canned response to the client for each
066 * type of operation.
067 */
068 @NotMutable()
069 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
070 public final class CannedResponseRequestHandler
071 extends LDAPListenerRequestHandler
072 implements Serializable
073 {
074 /**
075 * The serial version UID for this serializable class.
076 */
077 private static final long serialVersionUID = 6199105854736880833L;
078
079
080
081 // The protocol ops that will be used in responses.
082 private final AddResponseProtocolOp addResponseProtocolOp;
083 private final BindResponseProtocolOp bindResponseProtocolOp;
084 private final CompareResponseProtocolOp compareResponseProtocolOp;
085 private final DeleteResponseProtocolOp deleteResponseProtocolOp;
086 private final ExtendedResponseProtocolOp extendedResponseProtocolOp;
087 private final ModifyResponseProtocolOp modifyResponseProtocolOp;
088 private final ModifyDNResponseProtocolOp modifyDNResponseProtocolOp;
089 private final List<SearchResultEntryProtocolOp> searchEntryProtocolOps;
090 private final List<SearchResultReferenceProtocolOp>
091 searchReferenceProtocolOps;
092 private final SearchResultDoneProtocolOp searchResultDoneProtocolOp;
093
094 // The connection that will be used to communicate with the client.
095 private final LDAPListenerClientConnection clientConnection;
096
097
098
099 /**
100 * Creates a new instance of this canned response request handler that will
101 * immediately return a "SUCCESS" response to any request that is received.
102 */
103 public CannedResponseRequestHandler()
104 {
105 this(ResultCode.SUCCESS, null, null, null);
106 }
107
108
109
110 /**
111 * Creates a new instance of this canned response request handler that will
112 * immediately return a response with the provided information to any request
113 * that is received.
114 *
115 * @param resultCode The result code to use for the responses. It
116 * must not be {@code null}.
117 * @param matchedDN The matched DN to use for the responses. It may
118 * be {@code null} if no matched DN should be
119 * included.
120 * @param diagnosticMessage The diagnostic message to use for the responses.
121 * It may be {@code null} if no diagnostic message
122 * should be included.
123 * @param referralURLs The referral URLs to use for the responses. It
124 * may be empty or {@code null} if no referral URLs
125 * should be included.
126 */
127 public CannedResponseRequestHandler(final ResultCode resultCode,
128 final String matchedDN,
129 final String diagnosticMessage,
130 final List<String> referralURLs)
131 {
132 this(resultCode, matchedDN, diagnosticMessage, referralURLs, null, null);
133 }
134
135
136
137 /**
138 * Creates a new instance of this canned response request handler that will
139 * immediately return a response with the provided information to any request
140 * that is received.
141 *
142 * @param resultCode The result code to use for the responses. It
143 * must not be {@code null}.
144 * @param matchedDN The matched DN to use for the responses. It may
145 * be {@code null} if no matched DN should be
146 * included.
147 * @param diagnosticMessage The diagnostic message to use for the responses.
148 * It may be {@code null} if no diagnostic message
149 * should be included.
150 * @param referralURLs The referral URLs to use for the responses. It
151 * may be empty or {@code null} if no referral URLs
152 * should be included.
153 * @param searchEntries The set of search result entries that should be
154 * returned for every search. It may be
155 * {@code null} or empty if no entries are
156 * required.
157 * @param searchReferences The set of search result references that should
158 * be returned for every search. It may be
159 * {@code null} or empty if no references are
160 * required.
161 */
162 public CannedResponseRequestHandler(final ResultCode resultCode,
163 final String matchedDN, final String diagnosticMessage,
164 final List<String> referralURLs,
165 final Collection<? extends Entry> searchEntries,
166 final Collection<SearchResultReference> searchReferences)
167 {
168 Validator.ensureNotNull(resultCode);
169
170 clientConnection = null;
171
172 final int rc = resultCode.intValue();
173 addResponseProtocolOp = new AddResponseProtocolOp(rc, matchedDN,
174 diagnosticMessage, referralURLs);
175 bindResponseProtocolOp = new BindResponseProtocolOp(rc, matchedDN,
176 diagnosticMessage, referralURLs, null);
177 compareResponseProtocolOp = new CompareResponseProtocolOp(rc, matchedDN,
178 diagnosticMessage, referralURLs);
179 deleteResponseProtocolOp = new DeleteResponseProtocolOp(rc, matchedDN,
180 diagnosticMessage, referralURLs);
181 extendedResponseProtocolOp = new ExtendedResponseProtocolOp(rc, matchedDN,
182 diagnosticMessage, referralURLs, null, null);
183 modifyResponseProtocolOp = new ModifyResponseProtocolOp(rc, matchedDN,
184 diagnosticMessage, referralURLs);
185 modifyDNResponseProtocolOp = new ModifyDNResponseProtocolOp(rc, matchedDN,
186 diagnosticMessage, referralURLs);
187 searchResultDoneProtocolOp = new SearchResultDoneProtocolOp(rc, matchedDN,
188 diagnosticMessage, referralURLs);
189
190 if ((searchEntries == null) || searchEntries.isEmpty())
191 {
192 searchEntryProtocolOps = Collections.emptyList();
193 }
194 else
195 {
196 final ArrayList<SearchResultEntryProtocolOp> l =
197 new ArrayList<SearchResultEntryProtocolOp>(searchEntries.size());
198 for (final Entry e : searchEntries)
199 {
200 l.add(new SearchResultEntryProtocolOp(e));
201 }
202
203 searchEntryProtocolOps = Collections.unmodifiableList(l);
204 }
205
206 if ((searchReferences == null) || searchReferences.isEmpty())
207 {
208 searchReferenceProtocolOps = Collections.emptyList();
209 }
210 else
211 {
212 final ArrayList<SearchResultReferenceProtocolOp> l =
213 new ArrayList<SearchResultReferenceProtocolOp>(
214 searchReferences.size());
215 for (final SearchResultReference r : searchReferences)
216 {
217 l.add(new SearchResultReferenceProtocolOp(r));
218 }
219
220 searchReferenceProtocolOps = Collections.unmodifiableList(l);
221 }
222 }
223
224
225
226 /**
227 * Creates a new instance of this canned response request handler using the
228 * information of the provided handler and the given client connection.
229 *
230 * @param h The request handler from which to take the canned responses.
231 * @param c The connection to use to communicate with the client.
232 */
233 private CannedResponseRequestHandler(final CannedResponseRequestHandler h,
234 final LDAPListenerClientConnection c)
235 {
236 addResponseProtocolOp = h.addResponseProtocolOp;
237 bindResponseProtocolOp = h.bindResponseProtocolOp;
238 compareResponseProtocolOp = h.compareResponseProtocolOp;
239 deleteResponseProtocolOp = h.deleteResponseProtocolOp;
240 extendedResponseProtocolOp = h.extendedResponseProtocolOp;
241 modifyResponseProtocolOp = h.modifyResponseProtocolOp;
242 modifyDNResponseProtocolOp = h.modifyDNResponseProtocolOp;
243 searchEntryProtocolOps = h.searchEntryProtocolOps;
244 searchReferenceProtocolOps = h.searchReferenceProtocolOps;
245 searchResultDoneProtocolOp = h.searchResultDoneProtocolOp;
246
247 clientConnection = c;
248 }
249
250
251
252 /**
253 * {@inheritDoc}
254 */
255 @Override()
256 public CannedResponseRequestHandler newInstance(
257 final LDAPListenerClientConnection connection)
258 throws LDAPException
259 {
260 return new CannedResponseRequestHandler(this, connection);
261 }
262
263
264
265 /**
266 * {@inheritDoc}
267 */
268 @Override()
269 public LDAPMessage processAddRequest(final int messageID,
270 final AddRequestProtocolOp request,
271 final List<Control> controls)
272 {
273 return new LDAPMessage(messageID, addResponseProtocolOp,
274 Collections.<Control>emptyList());
275 }
276
277
278
279 /**
280 * {@inheritDoc}
281 */
282 @Override()
283 public LDAPMessage processBindRequest(final int messageID,
284 final BindRequestProtocolOp request,
285 final List<Control> controls)
286 {
287 return new LDAPMessage(messageID, bindResponseProtocolOp,
288 Collections.<Control>emptyList());
289 }
290
291
292
293 /**
294 * {@inheritDoc}
295 */
296 @Override()
297 public LDAPMessage processCompareRequest(final int messageID,
298 final CompareRequestProtocolOp request,
299 final List<Control> controls)
300 {
301 return new LDAPMessage(messageID, compareResponseProtocolOp,
302 Collections.<Control>emptyList());
303 }
304
305
306
307 /**
308 * {@inheritDoc}
309 */
310 @Override()
311 public LDAPMessage processDeleteRequest(final int messageID,
312 final DeleteRequestProtocolOp request,
313 final List<Control> controls)
314 {
315 return new LDAPMessage(messageID, deleteResponseProtocolOp,
316 Collections.<Control>emptyList());
317 }
318
319
320
321 /**
322 * {@inheritDoc}
323 */
324 @Override()
325 public LDAPMessage processExtendedRequest(final int messageID,
326 final ExtendedRequestProtocolOp request,
327 final List<Control> controls)
328 {
329 return new LDAPMessage(messageID, extendedResponseProtocolOp,
330 Collections.<Control>emptyList());
331 }
332
333
334
335 /**
336 * {@inheritDoc}
337 */
338 @Override()
339 public LDAPMessage processModifyRequest(final int messageID,
340 final ModifyRequestProtocolOp request,
341 final List<Control> controls)
342 {
343 return new LDAPMessage(messageID, modifyResponseProtocolOp,
344 Collections.<Control>emptyList());
345 }
346
347
348
349 /**
350 * {@inheritDoc}
351 */
352 @Override()
353 public LDAPMessage processModifyDNRequest(final int messageID,
354 final ModifyDNRequestProtocolOp request,
355 final List<Control> controls)
356 {
357 return new LDAPMessage(messageID, modifyDNResponseProtocolOp,
358 Collections.<Control>emptyList());
359 }
360
361
362
363 /**
364 * {@inheritDoc}
365 */
366 @Override()
367 public LDAPMessage processSearchRequest(final int messageID,
368 final SearchRequestProtocolOp request,
369 final List<Control> controls)
370 {
371 for (final SearchResultEntryProtocolOp e : searchEntryProtocolOps)
372 {
373 try
374 {
375 clientConnection.sendSearchResultEntry(messageID, e);
376 }
377 catch (final Exception ex)
378 {
379 Debug.debugException(ex);
380 }
381 }
382
383 for (final SearchResultReferenceProtocolOp r : searchReferenceProtocolOps)
384 {
385 try
386 {
387 clientConnection.sendSearchResultReference(messageID, r);
388 }
389 catch (final Exception ex)
390 {
391 Debug.debugException(ex);
392 }
393 }
394
395 return new LDAPMessage(messageID, searchResultDoneProtocolOp,
396 Collections.<Control>emptyList());
397 }
398 }