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