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.dsmlv2.request;
21
22
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.directory.api.asn1.DecoderException;
27 import org.apache.directory.api.dsmlv2.ParserUtils;
28 import org.apache.directory.api.ldap.codec.api.LdapApiService;
29 import org.apache.directory.api.ldap.codec.api.LdapConstants;
30 import org.apache.directory.api.ldap.model.entry.Value;
31 import org.apache.directory.api.ldap.model.exception.LdapException;
32 import org.apache.directory.api.ldap.model.filter.AndNode;
33 import org.apache.directory.api.ldap.model.filter.ApproximateNode;
34 import org.apache.directory.api.ldap.model.filter.BranchNode;
35 import org.apache.directory.api.ldap.model.filter.EqualityNode;
36 import org.apache.directory.api.ldap.model.filter.ExprNode;
37 import org.apache.directory.api.ldap.model.filter.ExtensibleNode;
38 import org.apache.directory.api.ldap.model.filter.GreaterEqNode;
39 import org.apache.directory.api.ldap.model.filter.LeafNode;
40 import org.apache.directory.api.ldap.model.filter.LessEqNode;
41 import org.apache.directory.api.ldap.model.filter.NotNode;
42 import org.apache.directory.api.ldap.model.filter.OrNode;
43 import org.apache.directory.api.ldap.model.filter.PresenceNode;
44 import org.apache.directory.api.ldap.model.filter.SimpleNode;
45 import org.apache.directory.api.ldap.model.filter.SubstringNode;
46 import org.apache.directory.api.ldap.model.message.AliasDerefMode;
47 import org.apache.directory.api.ldap.model.message.Control;
48 import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
49 import org.apache.directory.api.ldap.model.message.SearchRequest;
50 import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
51 import org.apache.directory.api.ldap.model.message.SearchResultDone;
52 import org.apache.directory.api.ldap.model.message.SearchScope;
53 import org.apache.directory.api.ldap.model.name.Dn;
54 import org.dom4j.Element;
55 import org.dom4j.Namespace;
56 import org.dom4j.QName;
57
58
59
60
61
62
63
64 public class SearchRequestDsml
65 extends AbstractResultResponseRequestDsml<SearchRequest, SearchResultDone>
66 implements SearchRequest
67 {
68
69 private Filter terminalFilter;
70
71
72 private Filter currentFilter;
73
74
75 private Filter topFilter;
76
77
78
79
80
81 public SearchRequestDsml( LdapApiService codec )
82 {
83 super( codec, new SearchRequestImpl() );
84 }
85
86
87
88
89
90
91
92
93 public SearchRequestDsml( LdapApiService codec, SearchRequest ldapMessage )
94 {
95 super( codec, ldapMessage );
96 }
97
98
99
100
101
102
103
104 public Filter getCodecFilter()
105 {
106 return topFilter;
107 }
108
109
110
111
112
113
114
115 public ExprNode getFilterNode()
116 {
117 return transform( topFilter );
118 }
119
120
121
122
123
124
125
126 public Filter getTerminalFilter()
127 {
128 return terminalFilter;
129 }
130
131
132
133
134
135
136
137 public void setTerminalFilter( Filter terminalFilter )
138 {
139 this.terminalFilter = terminalFilter;
140 }
141
142
143
144
145
146 public void endCurrentConnectorFilter()
147 {
148 currentFilter = currentFilter.getParent();
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 public void addCurrentFilter( Filter localFilter ) throws DecoderException
165 {
166 if ( currentFilter != null )
167 {
168
169
170 ( ( ConnectorFilter ) currentFilter ).addFilter( localFilter );
171 localFilter.setParent( currentFilter );
172
173 if ( localFilter instanceof ConnectorFilter )
174 {
175 currentFilter = localFilter;
176 }
177 }
178 else
179 {
180
181 currentFilter = localFilter;
182 currentFilter.setParent( null );
183 topFilter = localFilter;
184 }
185 }
186
187
188
189
190
191
192
193
194 @SuppressWarnings(
195 { "unchecked", "rawtypes" })
196 private ExprNode transform( Filter filter )
197 {
198 if ( filter != null )
199 {
200
201 if ( filter instanceof ConnectorFilter )
202 {
203 BranchNode branch = null;
204
205 if ( filter instanceof AndFilter )
206 {
207 branch = new AndNode();
208 }
209 else if ( filter instanceof OrFilter )
210 {
211 branch = new OrNode();
212 }
213 else if ( filter instanceof NotFilter )
214 {
215 branch = new NotNode();
216 }
217
218 List<Filter> filtersSet = ( ( ConnectorFilter ) filter ).getFilterSet();
219
220
221 if ( filtersSet != null )
222 {
223 for ( Filter node : filtersSet )
224 {
225 branch.addNode( transform( node ) );
226 }
227 }
228
229 return branch;
230 }
231 else
232 {
233
234 LeafNode branch = null;
235
236 if ( filter instanceof PresentFilter )
237 {
238 branch = new PresenceNode( ( ( PresentFilter ) filter ).getAttributeDescription() );
239 }
240 else if ( filter instanceof AttributeValueAssertionFilter )
241 {
242 AttributeValueAssertion ava = ( ( AttributeValueAssertionFilter ) filter ).getAssertion();
243
244
245 switch ( ( ( AttributeValueAssertionFilter ) filter ).getFilterType() )
246 {
247 case LdapConstants.EQUALITY_MATCH_FILTER:
248 branch = new EqualityNode( ava.getAttributeDesc(), ava.getAssertionValue() );
249
250 break;
251
252 case LdapConstants.GREATER_OR_EQUAL_FILTER:
253 branch = new GreaterEqNode( ava.getAttributeDesc(), ava.getAssertionValue() );
254
255 break;
256
257 case LdapConstants.LESS_OR_EQUAL_FILTER:
258 branch = new LessEqNode( ava.getAttributeDesc(), ava.getAssertionValue() );
259
260 break;
261
262 case LdapConstants.APPROX_MATCH_FILTER:
263 branch = new ApproximateNode( ava.getAttributeDesc(), ava.getAssertionValue() );
264
265 break;
266 }
267
268 }
269 else if ( filter instanceof SubstringFilter )
270 {
271
272 SubstringFilter substrFilter = ( SubstringFilter ) filter;
273 String initialString = null;
274 String finalString = null;
275 List<String> anyString = null;
276
277 if ( substrFilter.getInitialSubstrings() != null )
278 {
279 initialString = substrFilter.getInitialSubstrings();
280 }
281
282 if ( substrFilter.getFinalSubstrings() != null )
283 {
284 finalString = substrFilter.getFinalSubstrings();
285 }
286
287 if ( substrFilter.getAnySubstrings() != null )
288 {
289 anyString = new ArrayList<String>();
290
291 for ( String any : substrFilter.getAnySubstrings() )
292 {
293 anyString.add( any );
294 }
295 }
296
297 branch = new SubstringNode( anyString, substrFilter.getType(), initialString, finalString );
298 }
299 else if ( filter instanceof ExtensibleMatchFilter )
300 {
301
302 ExtensibleMatchFilter extFilter = ( ExtensibleMatchFilter ) filter;
303 String matchingRule = null;
304
305 Value<?> value = extFilter.getMatchValue();
306
307 if ( extFilter.getMatchingRule() != null )
308 {
309 matchingRule = extFilter.getMatchingRule();
310 }
311
312 branch = new ExtensibleNode( extFilter.getType(), value, matchingRule, extFilter.isDnAttributes() );
313 }
314
315 return branch;
316 }
317 }
318 else
319 {
320
321 return null;
322 }
323 }
324
325
326
327
328
329 public MessageTypeEnum getType()
330 {
331 return getDecorated().getType();
332 }
333
334
335
336
337
338 public Element toDsml( Element root )
339 {
340 Element element = super.toDsml( root );
341
342 SearchRequest request = getDecorated();
343
344
345 if ( request.getBase() != null )
346 {
347 element.addAttribute( "dn", request.getBase().getName() );
348 }
349
350
351 SearchScope scope = request.getScope();
352 if ( scope != null )
353 {
354 if ( scope == SearchScope.OBJECT )
355 {
356 element.addAttribute( "scope", "baseObject" );
357 }
358 else if ( scope == SearchScope.ONELEVEL )
359 {
360 element.addAttribute( "scope", "singleLevel" );
361 }
362 else if ( scope == SearchScope.SUBTREE )
363 {
364 element.addAttribute( "scope", "wholeSubtree" );
365 }
366 }
367
368
369 AliasDerefMode derefAliases = request.getDerefAliases();
370
371 switch ( derefAliases )
372 {
373 case NEVER_DEREF_ALIASES:
374 element.addAttribute( "derefAliases", "neverDerefAliases" );
375 break;
376
377 case DEREF_ALWAYS:
378 element.addAttribute( "derefAliases", "derefAlways" );
379 break;
380
381 case DEREF_FINDING_BASE_OBJ:
382 element.addAttribute( "derefAliases", "derefFindingBaseObj" );
383 break;
384
385 case DEREF_IN_SEARCHING:
386 element.addAttribute( "derefAliases", "derefInSearching" );
387 break;
388
389 default:
390 throw new IllegalStateException( "Unexpected deref alias mode " + derefAliases );
391 }
392
393
394 if ( request.getSizeLimit() != 0L )
395 {
396 element.addAttribute( "sizeLimit", "" + request.getSizeLimit() );
397 }
398
399
400 if ( request.getTimeLimit() != 0 )
401 {
402 element.addAttribute( "timeLimit", "" + request.getTimeLimit() );
403 }
404
405
406 if ( request.getTypesOnly() )
407 {
408 element.addAttribute( "typesOnly", "true" );
409 }
410
411
412 Element filterElement = element.addElement( "filter" );
413 toDsml( filterElement, request.getFilter() );
414
415
416 List<String> attributes = request.getAttributes();
417
418 if ( attributes.size() > 0 )
419 {
420 Element attributesElement = element.addElement( "attributes" );
421
422 for ( String entryAttribute : attributes )
423 {
424 attributesElement.addElement( "attribute" ).addAttribute( "name", entryAttribute );
425 }
426 }
427
428 return element;
429 }
430
431
432
433
434
435
436
437
438
439
440
441 private void toDsml( Element element, ExprNode filter )
442 {
443
444 if ( filter instanceof AndNode )
445 {
446 Element newElement = element.addElement( "and" );
447
448 List<ExprNode> filterList = ( ( AndNode ) filter ).getChildren();
449
450 for ( int i = 0; i < filterList.size(); i++ )
451 {
452 toDsml( newElement, filterList.get( i ) );
453 }
454 }
455
456
457 else if ( filter instanceof OrNode )
458 {
459 Element newElement = element.addElement( "or" );
460
461 List<ExprNode> filterList = ( ( OrNode ) filter ).getChildren();
462
463 for ( int i = 0; i < filterList.size(); i++ )
464 {
465 toDsml( newElement, filterList.get( i ) );
466 }
467 }
468
469
470 else if ( filter instanceof NotNode )
471 {
472 Element newElement = element.addElement( "not" );
473
474 toDsml( newElement, ( ( NotNode ) filter ).getFirstChild() );
475 }
476
477
478 else if ( filter instanceof SubstringNode )
479 {
480 Element newElement = element.addElement( "substrings" );
481
482 SubstringNode substringFilter = ( SubstringNode ) filter;
483
484 newElement.addAttribute( "name", substringFilter.getAttribute() );
485
486 String initial = substringFilter.getInitial();
487
488 if ( ( initial != null ) && ( !"".equals( initial ) ) )
489 {
490 newElement.addElement( "initial" ).setText( initial );
491 }
492
493 List<String> anyList = substringFilter.getAny();
494
495 for ( int i = 0; i < anyList.size(); i++ )
496 {
497 newElement.addElement( "any" ).setText( anyList.get( i ) );
498 }
499
500 String finalString = substringFilter.getFinal();
501
502 if ( ( finalString != null ) && ( !"".equals( finalString ) ) )
503 {
504 newElement.addElement( "final" ).setText( finalString );
505 }
506 }
507
508
509 else if ( filter instanceof SimpleNode )
510 {
511 Element newElement = null;
512
513 if ( filter instanceof ApproximateNode )
514 {
515 newElement = element.addElement( "approxMatch" );
516 }
517 else if ( filter instanceof EqualityNode )
518 {
519 newElement = element.addElement( "equalityMatch" );
520 }
521 else if ( filter instanceof GreaterEqNode )
522 {
523 newElement = element.addElement( "greaterOrEqual" );
524 }
525 else if ( filter instanceof LessEqNode )
526 {
527 newElement = element.addElement( "lessOrEqual" );
528 }
529
530 String attributeName = ( ( SimpleNode<?> ) filter ).getAttribute();
531 newElement.addAttribute( "name", attributeName );
532
533 Value<?> value = ( ( SimpleNode<?> ) filter ).getValue();
534 if ( value != null )
535 {
536 if ( ParserUtils.needsBase64Encoding( value ) )
537 {
538 Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
539 Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
540 element.getDocument().getRootElement().add( xsdNamespace );
541 element.getDocument().getRootElement().add( xsiNamespace );
542
543 Element valueElement = newElement.addElement( "value" ).addText(
544 ParserUtils.base64Encode( value ) );
545 valueElement
546 .addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY );
547 }
548 else
549 {
550 newElement.addElement( "value" ).setText( value.getString() );
551 }
552 }
553 }
554
555
556 else if ( filter instanceof PresenceNode )
557 {
558 Element newElement = element.addElement( "present" );
559
560 newElement.addAttribute( "name", ( ( PresenceNode ) filter ).getAttribute() );
561 }
562
563
564 else if ( filter instanceof ExtensibleNode )
565 {
566 Element newElement = element.addElement( "extensibleMatch" );
567
568 Value<?> value = ( ( ExtensibleNode ) filter ).getValue();
569 if ( value != null )
570 {
571 if ( ParserUtils.needsBase64Encoding( value ) )
572 {
573 Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
574 Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
575 element.getDocument().getRootElement().add( xsdNamespace );
576 element.getDocument().getRootElement().add( xsiNamespace );
577
578 Element valueElement = newElement.addElement( "value" ).addText(
579 ParserUtils.base64Encode( value.getValue() ) );
580 valueElement.addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY );
581 }
582 else
583 {
584 newElement.addElement( "value" ).setText( value.getString() );
585 }
586 }
587
588 if ( ( ( ExtensibleNode ) filter ).hasDnAttributes() )
589 {
590 newElement.addAttribute( "dnAttributes", "true" );
591 }
592
593 String matchingRule = ( ( ExtensibleNode ) filter ).getMatchingRuleId();
594 if ( ( matchingRule != null ) && ( "".equals( matchingRule ) ) )
595 {
596 newElement.addAttribute( "matchingRule", matchingRule );
597 }
598 }
599 }
600
601
602
603
604
605 public MessageTypeEnum[] getResponseTypes()
606 {
607 return getDecorated().getResponseTypes();
608 }
609
610
611
612
613
614 public Dn getBase()
615 {
616 return getDecorated().getBase();
617 }
618
619
620
621
622
623 public SearchRequest setBase( Dn baseDn )
624 {
625 getDecorated().setBase( baseDn );
626
627 return this;
628 }
629
630
631
632
633
634 public SearchScope getScope()
635 {
636 return getDecorated().getScope();
637 }
638
639
640
641
642
643 public SearchRequest setScope( SearchScope scope )
644 {
645 getDecorated().setScope( scope );
646
647 return this;
648 }
649
650
651
652
653
654 public AliasDerefMode getDerefAliases()
655 {
656 return getDecorated().getDerefAliases();
657 }
658
659
660
661
662
663 public SearchRequest setDerefAliases( AliasDerefMode aliasDerefAliases )
664 {
665 getDecorated().setDerefAliases( aliasDerefAliases );
666
667 return this;
668 }
669
670
671
672
673
674 public long getSizeLimit()
675 {
676 return getDecorated().getSizeLimit();
677 }
678
679
680
681
682
683 public SearchRequest setSizeLimit( long entriesMax )
684 {
685 getDecorated().setSizeLimit( entriesMax );
686
687 return this;
688 }
689
690
691
692
693
694 public int getTimeLimit()
695 {
696 return getDecorated().getTimeLimit();
697 }
698
699
700
701
702
703 public SearchRequest setTimeLimit( int secondsMax )
704 {
705 getDecorated().setTimeLimit( secondsMax );
706
707 return this;
708 }
709
710
711
712
713
714 public boolean getTypesOnly()
715 {
716 return getDecorated().getTypesOnly();
717 }
718
719
720
721
722
723 public SearchRequest setTypesOnly( boolean typesOnly )
724 {
725 getDecorated().setTypesOnly( typesOnly );
726
727 return this;
728 }
729
730
731
732
733
734 public ExprNode getFilter()
735 {
736 return getDecorated().getFilter();
737 }
738
739
740
741
742
743 public SearchRequest setFilter( ExprNode filter )
744 {
745 getDecorated().setFilter( filter );
746
747 return this;
748 }
749
750
751
752
753
754 public SearchRequest setFilter( String filter ) throws LdapException
755 {
756 getDecorated().setFilter( filter );
757
758 return this;
759 }
760
761
762
763
764
765 public List<String> getAttributes()
766 {
767 return getDecorated().getAttributes();
768 }
769
770
771
772
773
774 public SearchRequest addAttributes( String... attributes )
775 {
776 getDecorated().addAttributes( attributes );
777
778 return this;
779 }
780
781
782
783
784
785 public SearchRequest removeAttribute( String attribute )
786 {
787 getDecorated().removeAttribute( attribute );
788
789 return this;
790 }
791
792
793
794
795
796 public SearchRequest setMessageId( int messageId )
797 {
798 return ( SearchRequest ) super.setMessageId( messageId );
799 }
800
801
802
803
804
805 public SearchRequest addControl( Control control )
806 {
807 return ( SearchRequest ) super.addControl( control );
808 }
809
810
811
812
813
814 public SearchRequest addAllControls( Control[] controls )
815 {
816 return ( SearchRequest ) super.addAllControls( controls );
817 }
818
819
820
821
822
823 public SearchRequest removeControl( Control control )
824 {
825 return ( SearchRequest ) super.removeControl( control );
826 }
827
828
829
830
831
832 public boolean isFollowReferrals()
833 {
834 return getDecorated().isFollowReferrals();
835 }
836
837
838
839
840
841 public SearchRequest followReferrals()
842 {
843 return getDecorated().followReferrals();
844 }
845
846
847
848
849
850 public boolean isIgnoreReferrals()
851 {
852 return getDecorated().isIgnoreReferrals();
853 }
854
855
856
857
858
859 public SearchRequest ignoreReferrals()
860 {
861 return getDecorated().ignoreReferrals();
862 }
863 }