1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.message;
21
22
23 import java.text.ParseException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException;
31 import org.apache.directory.api.ldap.model.filter.BranchNormalizedVisitor;
32 import org.apache.directory.api.ldap.model.filter.ExprNode;
33 import org.apache.directory.api.ldap.model.filter.FilterParser;
34 import org.apache.directory.api.ldap.model.name.Dn;
35 import org.apache.directory.api.util.Strings;
36
37
38
39
40
41
42
43 public class SearchRequestImpl extends AbstractAbandonableRequest implements SearchRequest
44 {
45 static final long serialVersionUID = -5655881944020886218L;
46
47
48 private Dn baseDn;
49
50
51 private ExprNode filterNode;
52
53
54 private SearchScope scope;
55
56
57 private boolean typesOnly;
58
59
60 private long sizeLimit;
61
62
63 private int timeLimit;
64
65
66 private AliasDerefMode aliasDerefMode = AliasDerefMode.DEREF_ALWAYS;
67
68
69 private List<String> attributes = new ArrayList<String>();
70
71
72 private SearchResultDone response;
73
74
75 private ReferralsPolicyEnum referralHandling = ReferralsPolicyEnum.THROW;
76
77
78
79
80
81
82
83
84
85 public SearchRequestImpl()
86 {
87 super( -1, MessageTypeEnum.SEARCH_REQUEST );
88 }
89
90
91
92
93
94
95
96
97
98 public List<String> getAttributes()
99 {
100 return Collections.unmodifiableList( attributes );
101 }
102
103
104
105
106
107
108
109 public Dn getBase()
110 {
111 return baseDn;
112 }
113
114
115
116
117
118 public SearchRequest setBase( Dn base )
119 {
120 baseDn = base;
121
122 return this;
123 }
124
125
126
127
128
129 public AliasDerefMode getDerefAliases()
130 {
131 return aliasDerefMode;
132 }
133
134
135
136
137
138 public SearchRequest setDerefAliases( AliasDerefMode aliasDerefAliases )
139 {
140 this.aliasDerefMode = aliasDerefAliases;
141
142 return this;
143 }
144
145
146
147
148
149 public ExprNode getFilter()
150 {
151 return filterNode;
152 }
153
154
155
156
157
158 public SearchRequest setFilter( ExprNode filter )
159 {
160 this.filterNode = filter;
161 return this;
162 }
163
164
165
166
167
168 public SearchRequest setFilter( String filter ) throws LdapException
169 {
170 try
171 {
172 filterNode = FilterParser.parse( Strings.getBytesUtf8( filter ) );
173 }
174 catch ( ParseException pe )
175 {
176 String msg = "The filter " + filter + " is invalid.";
177 throw new LdapProtocolErrorException( msg, pe );
178 }
179
180 return this;
181 }
182
183
184
185
186
187 public MessageTypeEnum[] getResponseTypes()
188 {
189 return RESPONSE_TYPES.clone();
190 }
191
192
193
194
195
196 public SearchScope getScope()
197 {
198 return scope;
199 }
200
201
202
203
204
205 public SearchRequest setScope( SearchScope scope )
206 {
207 this.scope = scope;
208
209 return this;
210 }
211
212
213
214
215
216 public long getSizeLimit()
217 {
218 return sizeLimit;
219 }
220
221
222
223
224
225 public SearchRequest setSizeLimit( long entriesMax )
226 {
227 sizeLimit = entriesMax;
228
229 return this;
230 }
231
232
233
234
235
236 public int getTimeLimit()
237 {
238 return timeLimit;
239 }
240
241
242
243
244
245 public SearchRequest setTimeLimit( int secondsMax )
246 {
247 timeLimit = secondsMax;
248
249 return this;
250 }
251
252
253
254
255
256 public boolean getTypesOnly()
257 {
258 return typesOnly;
259 }
260
261
262
263
264
265 public SearchRequest setTypesOnly( boolean typesOnly )
266 {
267 this.typesOnly = typesOnly;
268
269 return this;
270 }
271
272
273
274
275
276 public SearchRequest addAttributes( String... attributesToAdd )
277 {
278 this.attributes.addAll( Arrays.asList( attributesToAdd ) );
279
280 return this;
281 }
282
283
284
285
286
287 public SearchRequest removeAttribute( String attribute )
288 {
289 attributes.remove( attribute );
290
291 return this;
292 }
293
294
295
296
297
298 public SearchResultDone getResultResponse()
299 {
300 if ( response == null )
301 {
302 response = new SearchResultDoneImpl( getMessageId() );
303 }
304
305 return response;
306 }
307
308
309
310
311
312 public SearchRequest setMessageId( int messageId )
313 {
314 super.setMessageId( messageId );
315
316 return this;
317 }
318
319
320
321
322
323 public SearchRequest addControl( Control control )
324 {
325 return ( SearchRequest ) super.addControl( control );
326 }
327
328
329
330
331
332 public SearchRequest addAllControls( Control[] controls )
333 {
334 return ( SearchRequest ) super.addAllControls( controls );
335 }
336
337
338
339
340
341 public SearchRequest removeControl( Control control )
342 {
343 return ( SearchRequest ) super.removeControl( control );
344 }
345
346
347
348
349
350 @Override
351 public int hashCode()
352 {
353 int hash = 37;
354
355 if ( baseDn != null )
356 {
357 hash = hash * 17 + baseDn.hashCode();
358 }
359
360 hash = hash * 17 + aliasDerefMode.hashCode();
361 hash = hash * 17 + scope.hashCode();
362 hash = hash * 17 + Long.valueOf( sizeLimit ).hashCode();
363 hash = hash * 17 + timeLimit;
364 hash = hash * 17 + ( typesOnly ? 0 : 1 );
365
366 if ( attributes != null )
367 {
368 hash = hash * 17 + attributes.size();
369
370
371 for ( String attr : attributes )
372 {
373 if ( attr != null )
374 {
375 hash = hash + attr.hashCode();
376 }
377 }
378 }
379
380 BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
381 filterNode.accept( visitor );
382 hash = hash * 17 + filterNode.toString().hashCode();
383 hash = hash * 17 + super.hashCode();
384
385 return hash;
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 public boolean equals( Object obj )
402 {
403 if ( obj == this )
404 {
405 return true;
406 }
407
408 if ( !super.equals( obj ) )
409 {
410 return false;
411 }
412
413 SearchRequest req = ( SearchRequest ) obj;
414
415 if ( !req.getBase().equals( baseDn ) )
416 {
417 return false;
418 }
419
420 if ( req.getDerefAliases() != aliasDerefMode )
421 {
422 return false;
423 }
424
425 if ( req.getScope() != scope )
426 {
427 return false;
428 }
429
430 if ( req.getSizeLimit() != sizeLimit )
431 {
432 return false;
433 }
434
435 if ( req.getTimeLimit() != timeLimit )
436 {
437 return false;
438 }
439
440 if ( req.getTypesOnly() != typesOnly )
441 {
442 return false;
443 }
444
445 if ( req.getAttributes() == null && attributes != null && attributes.size() > 0 )
446 {
447 return false;
448 }
449
450 if ( req.getAttributes() != null && attributes == null && req.getAttributes().size() > 0 )
451 {
452 return false;
453 }
454
455 if ( req.getAttributes() != null && attributes != null )
456 {
457 if ( req.getAttributes().size() != attributes.size() )
458 {
459 return false;
460 }
461
462 for ( String attribute : attributes )
463 {
464 if ( !req.getAttributes().contains( attribute ) )
465 {
466 return false;
467 }
468 }
469 }
470
471 BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
472 req.getFilter().accept( visitor );
473 filterNode.accept( visitor );
474
475 String myFilterString = filterNode.toString();
476 String reqFilterString = req.getFilter().toString();
477
478 return myFilterString.equals( reqFilterString );
479 }
480
481
482
483
484
485
486 public String toString()
487 {
488 StringBuilder sb = new StringBuilder();
489
490 sb.append( " SearchRequest\n" );
491 sb.append( " baseDn : '" ).append( baseDn ).append( "'\n" );
492
493 if ( filterNode != null )
494 {
495 sb.append( " filter : '" );
496 sb.append( filterNode.toString() );
497 sb.append( "'\n" );
498 }
499
500 sb.append( " scope : " );
501
502 switch ( scope )
503 {
504 case OBJECT:
505 sb.append( "base object" );
506 break;
507
508 case ONELEVEL:
509 sb.append( "single level" );
510 break;
511
512 case SUBTREE:
513 sb.append( "whole subtree" );
514 break;
515 }
516
517 sb.append( '\n' );
518
519 sb.append( " typesOnly : " ).append( typesOnly ).append( '\n' );
520
521 sb.append( " Size Limit : " );
522
523 if ( sizeLimit == 0L )
524 {
525 sb.append( "no limit" );
526 }
527 else
528 {
529 sb.append( sizeLimit );
530 }
531
532 sb.append( '\n' );
533
534 sb.append( " Time Limit : " );
535
536 if ( timeLimit == 0 )
537 {
538 sb.append( "no limit" );
539 }
540 else
541 {
542 sb.append( timeLimit );
543 }
544
545 sb.append( '\n' );
546
547 sb.append( " Deref Aliases : " );
548
549 switch ( aliasDerefMode )
550 {
551 case NEVER_DEREF_ALIASES:
552 sb.append( "never Deref Aliases" );
553 break;
554
555 case DEREF_IN_SEARCHING:
556 sb.append( "deref In Searching" );
557 break;
558
559 case DEREF_FINDING_BASE_OBJ:
560 sb.append( "deref Finding Base Obj" );
561 break;
562
563 case DEREF_ALWAYS:
564 sb.append( "deref Always" );
565 break;
566 }
567
568 sb.append( '\n' );
569 sb.append( " attributes : " );
570
571 boolean isFirst = true;
572
573 if ( attributes != null )
574 {
575 for ( String attribute : attributes )
576 {
577 if ( isFirst )
578 {
579 isFirst = false;
580 }
581 else
582 {
583 sb.append( ", " );
584 }
585
586 sb.append( '\'' ).append( attribute ).append( '\'' );
587 }
588 }
589
590 sb.append( '\n' );
591
592
593 sb.append( super.toString() );
594
595 return super.toString( sb.toString() );
596 }
597
598
599
600
601
602 public boolean isFollowReferrals()
603 {
604 return referralHandling == ReferralsPolicyEnum.FOLLOW;
605 }
606
607
608
609
610
611 public SearchRequest followReferrals()
612 {
613 referralHandling = ReferralsPolicyEnum.FOLLOW;
614
615 return this;
616 }
617
618
619
620
621
622 public boolean isIgnoreReferrals()
623 {
624 return referralHandling == ReferralsPolicyEnum.IGNORE;
625 }
626
627
628
629
630
631 public SearchRequest ignoreReferrals()
632 {
633 referralHandling = ReferralsPolicyEnum.IGNORE;
634
635 return this;
636 }
637 }