1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.directory.ldap.client.api;
22
23
24 import java.io.IOException;
25 import java.util.concurrent.TimeUnit;
26
27 import org.apache.directory.api.i18n.I18n;
28 import org.apache.directory.api.ldap.model.constants.Loggers;
29 import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
30 import org.apache.directory.api.ldap.model.cursor.CursorException;
31 import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException;
32 import org.apache.directory.api.ldap.model.cursor.SearchCursor;
33 import org.apache.directory.api.ldap.model.entry.Entry;
34 import org.apache.directory.api.ldap.model.exception.LdapException;
35 import org.apache.directory.api.ldap.model.exception.LdapReferralException;
36 import org.apache.directory.api.ldap.model.message.IntermediateResponse;
37 import org.apache.directory.api.ldap.model.message.Referral;
38 import org.apache.directory.api.ldap.model.message.Response;
39 import org.apache.directory.api.ldap.model.message.SearchResultDone;
40 import org.apache.directory.api.ldap.model.message.SearchResultEntry;
41 import org.apache.directory.api.ldap.model.message.SearchResultReference;
42 import org.apache.directory.ldap.client.api.exception.LdapConnectionTimeOutException;
43 import org.apache.directory.ldap.client.api.future.SearchFuture;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50
51
52
53
54
55 public class SearchCursorImpl extends AbstractCursor<Response> implements SearchCursor
56 {
57
58 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
59
60
61 private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
62
63
64 private SearchFuture future;
65
66
67 private long timeout;
68
69
70 private TimeUnit timeUnit;
71
72
73 private Response response;
74
75
76 private boolean done;
77
78
79 private SearchResultDone searchDoneResp;
80
81
82
83
84
85
86
87
88
89 public SearchCursorImpl( SearchFuture future, long timeout, TimeUnit timeUnit )
90 {
91 if ( IS_DEBUG )
92 {
93 LOG_CURSOR.debug( "Creating SearchCursorImpl {}", this );
94 }
95
96 this.future = future;
97 this.timeout = timeout;
98 this.timeUnit = timeUnit;
99 }
100
101
102
103
104
105 @Override
106 public boolean next() throws LdapException, CursorException
107 {
108 if ( done )
109 {
110 return false;
111 }
112
113 try
114 {
115 if ( future.isCancelled() )
116 {
117 response = null;
118 done = true;
119 return false;
120 }
121
122 response = future.get( timeout, timeUnit );
123 }
124 catch ( Exception e )
125 {
126 LdapException ldapException = new LdapException( LdapNetworkConnection.NO_RESPONSE_ERROR, e );
127
128
129 if ( !future.isCancelled() )
130 {
131 future.cancel( true );
132 }
133
134
135 try
136 {
137 close( ldapException );
138 }
139 catch ( IOException ioe )
140 {
141 throw new LdapException( ioe.getMessage(), ioe );
142 }
143
144 throw ldapException;
145 }
146
147 if ( response == null )
148 {
149 future.cancel( true );
150
151 throw new LdapConnectionTimeOutException( LdapNetworkConnection.TIME_OUT_ERROR );
152 }
153
154 done = response instanceof SearchResultDone;
155
156 if ( done )
157 {
158 searchDoneResp = ( SearchResultDone ) response;
159
160 response = null;
161 }
162
163 return !done;
164 }
165
166
167
168
169
170 @Override
171 public Response get() throws InvalidCursorPositionException
172 {
173 if ( !available() )
174 {
175 throw new InvalidCursorPositionException();
176 }
177
178 return response;
179 }
180
181
182
183
184
185 @Override
186 public SearchResultDone getSearchResultDone()
187 {
188 return searchDoneResp;
189 }
190
191
192
193
194
195 @Override
196 public boolean available()
197 {
198 return response != null;
199 }
200
201
202
203
204
205 @Override
206 public void close() throws IOException
207 {
208 if ( IS_DEBUG )
209 {
210 LOG_CURSOR.debug( "Closing SearchCursorImpl {}", this );
211 }
212
213 close( null );
214 }
215
216
217
218
219
220 @Override
221 public void close( Exception cause ) throws IOException
222 {
223 if ( IS_DEBUG )
224 {
225 LOG_CURSOR.debug( "Closing SearchCursorImpl {}", this );
226 }
227
228 if ( done )
229 {
230 super.close();
231 return;
232 }
233
234 if ( !future.isCancelled() )
235 {
236 future.cancel( true );
237 }
238
239 if ( cause != null )
240 {
241 super.close( cause );
242 }
243 else
244 {
245 super.close();
246 }
247 }
248
249
250
251
252
253
254
255
256 @Override
257 public void after( Response element ) throws LdapException, CursorException
258 {
259 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
260 .concat( "." ).concat( "after( Response element )" ) ) );
261 }
262
263
264
265
266
267
268 @Override
269 public void afterLast() throws LdapException, CursorException
270 {
271 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
272 .concat( "." ).concat( "afterLast()" ) ) );
273 }
274
275
276
277
278
279
280 @Override
281 public void before( Response element ) throws LdapException, CursorException
282 {
283 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
284 .concat( "." ).concat( "before( Response element )" ) ) );
285 }
286
287
288
289
290
291
292 @Override
293 public void beforeFirst() throws LdapException, CursorException
294 {
295 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
296 .concat( "." ).concat( "beforeFirst()" ) ) );
297 }
298
299
300
301
302
303
304 @Override
305 public boolean first() throws LdapException, CursorException
306 {
307 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
308 .concat( "." ).concat( "first()" ) ) );
309 }
310
311
312
313
314
315
316 @Override
317 public boolean last() throws LdapException, CursorException
318 {
319 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
320 .concat( "." ).concat( "last()" ) ) );
321 }
322
323
324
325
326
327
328 @Override
329 public boolean previous() throws LdapException, CursorException
330 {
331 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName()
332 .concat( "." ).concat( "previous()" ) ) );
333 }
334
335
336
337
338
339 @Override
340 public boolean isDone()
341 {
342 return done;
343 }
344
345
346
347
348
349 @Override
350 public boolean isReferral()
351 {
352 return response instanceof SearchResultReference;
353 }
354
355
356
357
358
359 @Override
360 public Referral getReferral() throws LdapException
361 {
362 if ( isReferral() )
363 {
364 return ( ( SearchResultReference ) response ).getReferral();
365 }
366
367 throw new LdapException();
368 }
369
370
371
372
373
374 @Override
375 public boolean isEntry()
376 {
377 return response instanceof SearchResultEntry;
378 }
379
380
381
382
383
384 @Override
385 public Entry getEntry() throws LdapException
386 {
387 if ( isEntry() )
388 {
389 return ( ( SearchResultEntry ) response ).getEntry();
390 }
391
392 if ( isReferral() )
393 {
394 Referral referral = ( ( SearchResultReference ) response ).getReferral();
395 throw new LdapReferralException( referral.getLdapUrls() );
396 }
397
398 throw new LdapException();
399 }
400
401
402
403
404
405 @Override
406 public boolean isIntermediate()
407 {
408 return response instanceof IntermediateResponse;
409 }
410
411
412
413
414
415 @Override
416 public IntermediateResponse getIntermediate() throws LdapException
417 {
418 if ( isEntry() )
419 {
420 return ( IntermediateResponse ) response;
421 }
422
423 throw new LdapException();
424 }
425 }