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