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