001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.controls; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.ArrayList; 033 import java.util.List; 034 035 import org.opends.server.api.ApproximateMatchingRule; 036 import org.opends.server.api.EqualityMatchingRule; 037 import org.opends.server.api.MatchingRule; 038 import org.opends.server.api.OrderingMatchingRule; 039 import org.opends.server.api.SubstringMatchingRule; 040 import org.opends.server.core.DirectoryServer; 041 import org.opends.server.protocols.asn1.ASN1Element; 042 import org.opends.server.protocols.asn1.ASN1OctetString; 043 import org.opends.server.protocols.asn1.ASN1Sequence; 044 import org.opends.server.protocols.ldap.LDAPResultCode; 045 import org.opends.server.types.AttributeType; 046 import org.opends.server.types.AttributeValue; 047 import org.opends.server.types.ByteString; 048 import org.opends.server.types.ConditionResult; 049 import org.opends.server.types.LDAPException; 050 import org.opends.server.types.RawFilter; 051 import org.opends.server.util.Validator; 052 053 import static org.opends.server.loggers.debug.DebugLogger.*; 054 import org.opends.server.loggers.debug.DebugTracer; 055 import org.opends.server.types.DebugLogLevel; 056 import static org.opends.messages.ProtocolMessages.*; 057 import static org.opends.server.protocols.ldap.LDAPConstants.*; 058 import static org.opends.server.util.StaticUtils.*; 059 060 061 062 /** 063 * This class defines a filter that may be used in conjunction with the matched 064 * values control to indicate which particular values of a multivalued attribute 065 * should be returned. The matched values filter is essentially a subset of an 066 * LDAP search filter, lacking support for AND, OR, and NOT components, and 067 * lacking support for the dnAttributes component of extensible matching 068 * filters. 069 */ 070 public class MatchedValuesFilter 071 { 072 /** 073 * The tracer object for the debug logger. 074 */ 075 private static final DebugTracer TRACER = getTracer(); 076 077 078 079 080 /** 081 * The BER type associated with the equalityMatch filter type. 082 */ 083 public static final byte EQUALITY_MATCH_TYPE = (byte) 0xA3; 084 085 086 087 /** 088 * The BER type associated with the substrings filter type. 089 */ 090 public static final byte SUBSTRINGS_TYPE = (byte) 0xA4; 091 092 093 094 /** 095 * The BER type associated with the greaterOrEqual filter type. 096 */ 097 public static final byte GREATER_OR_EQUAL_TYPE = (byte) 0xA5; 098 099 100 101 /** 102 * The BER type associated with the lessOrEqual filter type. 103 */ 104 public static final byte LESS_OR_EQUAL_TYPE = (byte) 0xA6; 105 106 107 108 /** 109 * The BER type associated with the present filter type. 110 */ 111 public static final byte PRESENT_TYPE = (byte) 0x87; 112 113 114 115 /** 116 * The BER type associated with the approxMatch filter type. 117 */ 118 public static final byte APPROXIMATE_MATCH_TYPE = (byte) 0xA8; 119 120 121 122 /** 123 * The BER type associated with the extensibleMatch filter type. 124 */ 125 public static final byte EXTENSIBLE_MATCH_TYPE = (byte) 0xA9; 126 127 128 129 // The approximate matching rule for this matched values filter. 130 private ApproximateMatchingRule approximateMatchingRule; 131 132 // The normalized subFinal value for this matched values filter. 133 private ASN1OctetString normalizedSubFinal; 134 135 // The normalized subInitial value for this matched values filter. 136 private ASN1OctetString normalizedSubInitial; 137 138 // The raw, unprocessed assertion value for this matched values filter. 139 private ByteString rawAssertionValue; 140 141 // The subFinal value for this matched values filter. 142 private ByteString subFinal; 143 144 // The subInitial value for this matched values filter. 145 private ByteString subInitial; 146 147 // The processed attribute type for this matched values filter. 148 private AttributeType attributeType; 149 150 // The processed assertion value for this matched values filter. 151 private AttributeValue assertionValue; 152 153 // Indicates whether the elements of this matched values filter have been 154 // fully decoded. 155 private boolean decoded; 156 157 // The match type for this matched values filter. 158 private byte matchType; 159 160 // The equality matching rule for this matched values filter. 161 private EqualityMatchingRule equalityMatchingRule; 162 163 // The set of normalized subAny values for this matched values filter. 164 private List<ASN1OctetString> normalizedSubAny; 165 166 // The set of subAny values for this matched values filter. 167 private List<ByteString> subAny; 168 169 // The matching rule for this matched values filter. 170 private MatchingRule matchingRule; 171 172 // The ordering matching rule for this matched values filter. 173 private OrderingMatchingRule orderingMatchingRule; 174 175 // The matching rule ID for this matched values filter. 176 private String matchingRuleID; 177 178 // The raw, unprocessed attribute type for this matched values filter. 179 private String rawAttributeType; 180 181 // The substring matching rule for this matched values filter. 182 private SubstringMatchingRule substringMatchingRule; 183 184 185 186 /** 187 * Creates a new matched values filter with the provided information. 188 * 189 * @param matchType The match type for this matched values filter. 190 * @param rawAttributeType The raw, unprocessed attribute type. 191 * @param rawAssertionValue The raw, unprocessed assertion value. 192 * @param subInitial The subInitial element. 193 * @param subAny The set of subAny elements. 194 * @param subFinal The subFinal element. 195 * @param matchingRuleID The matching rule ID. 196 */ 197 private MatchedValuesFilter(byte matchType, String rawAttributeType, 198 ByteString rawAssertionValue, 199 ByteString subInitial, List<ByteString> subAny, 200 ByteString subFinal, String matchingRuleID) 201 { 202 this.matchType = matchType; 203 this.rawAttributeType = rawAttributeType; 204 this.rawAssertionValue = rawAssertionValue; 205 this.subInitial = subInitial; 206 this.subAny = subAny; 207 this.subFinal = subFinal; 208 this.matchingRuleID = matchingRuleID; 209 210 decoded = false; 211 attributeType = null; 212 assertionValue = null; 213 matchingRule = null; 214 normalizedSubInitial = null; 215 normalizedSubAny = null; 216 normalizedSubFinal = null; 217 approximateMatchingRule = null; 218 equalityMatchingRule = null; 219 orderingMatchingRule = null; 220 substringMatchingRule = null; 221 } 222 223 224 225 /** 226 * Creates a new equalityMatch filter with the provided information. 227 * 228 * @param rawAttributeType The raw, unprocessed attribute type. 229 * @param rawAssertionValue The raw, unprocessed assertion value. 230 * 231 * @return The created equalityMatch filter. 232 */ 233 public static MatchedValuesFilter createEqualityFilter( 234 String rawAttributeType, 235 ByteString rawAssertionValue) 236 { 237 Validator.ensureNotNull(rawAttributeType,rawAssertionValue); 238 239 return new MatchedValuesFilter(EQUALITY_MATCH_TYPE, rawAttributeType, 240 rawAssertionValue, null, null, null, null); 241 } 242 243 244 245 /** 246 * Creates a new equalityMatch filter with the provided information. 247 * 248 * @param attributeType The attribute type. 249 * @param assertionValue The assertion value. 250 * 251 * @return The created equalityMatch filter. 252 */ 253 public static MatchedValuesFilter createEqualityFilter( 254 AttributeType attributeType, 255 AttributeValue assertionValue) 256 { 257 Validator.ensureNotNull(attributeType, assertionValue); 258 String rawAttributeType = attributeType.getNameOrOID(); 259 ASN1OctetString rawAssertionValue = assertionValue.getValue() 260 .toASN1OctetString(); 261 262 MatchedValuesFilter filter = 263 new MatchedValuesFilter(EQUALITY_MATCH_TYPE, rawAttributeType, 264 rawAssertionValue, null, null, null, null); 265 filter.attributeType = attributeType; 266 filter.assertionValue = assertionValue; 267 268 return filter; 269 } 270 271 272 273 /** 274 * Creates a new substrings filter with the provided information. 275 * 276 * @param rawAttributeType The raw, unprocessed attribute type. 277 * @param subInitial The subInitial element. 278 * @param subAny The set of subAny elements. 279 * @param subFinal The subFinal element. 280 * 281 * @return The created substrings filter. 282 */ 283 public static MatchedValuesFilter createSubstringsFilter( 284 String rawAttributeType, 285 ByteString subInitial, 286 List<ByteString> subAny, 287 ByteString subFinal) 288 { 289 Validator.ensureNotNull(rawAttributeType); 290 return new MatchedValuesFilter(SUBSTRINGS_TYPE, rawAttributeType, null, 291 subInitial, subAny, subFinal, null); 292 } 293 294 295 296 /** 297 * Creates a new substrings filter with the provided information. 298 * 299 * @param attributeType The raw, unprocessed attribute type. 300 * @param subInitial The subInitial element. 301 * @param subAny The set of subAny elements. 302 * @param subFinal The subFinal element. 303 * 304 * @return The created substrings filter. 305 */ 306 public static MatchedValuesFilter createSubstringsFilter( 307 AttributeType attributeType, 308 ByteString subInitial, 309 List<ByteString> subAny, 310 ByteString subFinal) 311 { 312 Validator.ensureNotNull(attributeType); 313 String rawAttributeType = attributeType.getNameOrOID(); 314 315 MatchedValuesFilter filter = 316 new MatchedValuesFilter(SUBSTRINGS_TYPE, rawAttributeType, null, 317 subInitial, subAny, subFinal, null); 318 filter.attributeType = attributeType; 319 320 return filter; 321 } 322 323 324 325 /** 326 * Creates a new greaterOrEqual filter with the provided information. 327 * 328 * @param rawAttributeType The raw, unprocessed attribute type. 329 * @param rawAssertionValue The raw, unprocessed assertion value. 330 * 331 * @return The created greaterOrEqual filter. 332 */ 333 public static MatchedValuesFilter createGreaterOrEqualFilter( 334 String rawAttributeType, 335 ByteString rawAssertionValue) 336 { 337 Validator.ensureNotNull(rawAttributeType, rawAssertionValue); 338 339 return new MatchedValuesFilter(GREATER_OR_EQUAL_TYPE, rawAttributeType, 340 rawAssertionValue, null, null, null, null); 341 } 342 343 344 345 /** 346 * Creates a new greaterOrEqual filter with the provided information. 347 * 348 * @param attributeType The attribute type. 349 * @param assertionValue The assertion value. 350 * 351 * @return The created greaterOrEqual filter. 352 */ 353 public static MatchedValuesFilter createGreaterOrEqualFilter( 354 AttributeType attributeType, 355 AttributeValue assertionValue) 356 { 357 Validator.ensureNotNull(attributeType, assertionValue); 358 359 String rawAttributeType = attributeType.getNameOrOID(); 360 ASN1OctetString rawAssertionValue = 361 assertionValue.getValue().toASN1OctetString(); 362 363 MatchedValuesFilter filter = 364 new MatchedValuesFilter(GREATER_OR_EQUAL_TYPE, rawAttributeType, 365 rawAssertionValue, null, null, null, null); 366 filter.attributeType = attributeType; 367 filter.assertionValue = assertionValue; 368 369 return filter; 370 } 371 372 373 374 /** 375 * Creates a new lessOrEqual filter with the provided information. 376 * 377 * @param rawAttributeType The raw, unprocessed attribute type. 378 * @param rawAssertionValue The raw, unprocessed assertion value. 379 * 380 * @return The created lessOrEqual filter. 381 */ 382 public static MatchedValuesFilter createLessOrEqualFilter( 383 String rawAttributeType, 384 ByteString rawAssertionValue) 385 { 386 Validator.ensureNotNull(rawAttributeType, rawAssertionValue); 387 return new MatchedValuesFilter(LESS_OR_EQUAL_TYPE, rawAttributeType, 388 rawAssertionValue, null, null, null, null); 389 } 390 391 392 393 /** 394 * Creates a new lessOrEqual filter with the provided information. 395 * 396 * @param attributeType The attribute type. 397 * @param assertionValue The assertion value. 398 * 399 * @return The created lessOrEqual filter. 400 */ 401 public static MatchedValuesFilter createLessOrEqualFilter( 402 AttributeType attributeType, 403 AttributeValue assertionValue) 404 { 405 Validator.ensureNotNull(attributeType, assertionValue); 406 407 String rawAttributeType = attributeType.getNameOrOID(); 408 ASN1OctetString rawAssertionValue = 409 assertionValue.getValue().toASN1OctetString(); 410 411 MatchedValuesFilter filter = 412 new MatchedValuesFilter(LESS_OR_EQUAL_TYPE, rawAttributeType, 413 rawAssertionValue, null, null, null, null); 414 filter.attributeType = attributeType; 415 filter.assertionValue = assertionValue; 416 417 return filter; 418 } 419 420 421 422 /** 423 * Creates a new present filter with the provided information. 424 * 425 * @param rawAttributeType The raw, unprocessed attribute type. 426 * 427 * @return The created present filter. 428 */ 429 public static MatchedValuesFilter createPresentFilter(String rawAttributeType) 430 { 431 Validator.ensureNotNull(rawAttributeType) ; 432 return new MatchedValuesFilter(PRESENT_TYPE, rawAttributeType, null, null, 433 null, null, null); 434 } 435 436 437 438 /** 439 * Creates a new present filter with the provided information. 440 * 441 * @param attributeType The attribute type. 442 * 443 * @return The created present filter. 444 */ 445 public static MatchedValuesFilter createPresentFilter( 446 AttributeType attributeType) 447 { 448 Validator.ensureNotNull(attributeType); 449 String rawAttributeType = attributeType.getNameOrOID(); 450 451 MatchedValuesFilter filter = 452 new MatchedValuesFilter(PRESENT_TYPE, rawAttributeType, null, null, 453 null, null, null); 454 filter.attributeType = attributeType; 455 456 return filter; 457 } 458 459 460 461 /** 462 * Creates a new approxMatch filter with the provided information. 463 * 464 * @param rawAttributeType The raw, unprocessed attribute type. 465 * @param rawAssertionValue The raw, unprocessed assertion value. 466 * 467 * @return The created approxMatch filter. 468 */ 469 public static MatchedValuesFilter createApproximateFilter( 470 String rawAttributeType, 471 ByteString rawAssertionValue) 472 { 473 Validator.ensureNotNull(rawAttributeType,rawAssertionValue); 474 475 return new MatchedValuesFilter(APPROXIMATE_MATCH_TYPE, rawAttributeType, 476 rawAssertionValue, null, null, null, null); 477 } 478 479 480 481 /** 482 * Creates a new approxMatch filter with the provided information. 483 * 484 * @param attributeType The attribute type. 485 * @param assertionValue The assertion value. 486 * 487 * @return The created approxMatch filter. 488 */ 489 public static MatchedValuesFilter createApproximateFilter( 490 AttributeType attributeType, 491 AttributeValue assertionValue) 492 { 493 Validator.ensureNotNull(attributeType,assertionValue); 494 String rawAttributeType = attributeType.getNameOrOID(); 495 ASN1OctetString rawAssertionValue = 496 assertionValue.getValue().toASN1OctetString(); 497 498 MatchedValuesFilter filter = 499 new MatchedValuesFilter(APPROXIMATE_MATCH_TYPE, rawAttributeType, 500 rawAssertionValue, null, null, null, null); 501 filter.attributeType = attributeType; 502 filter.assertionValue = assertionValue; 503 504 return filter; 505 } 506 507 508 509 /** 510 * Creates a new extensibleMatch filter with the provided information. 511 * 512 * @param rawAttributeType The raw, unprocessed attribute type. 513 * @param matchingRuleID The matching rule ID. 514 * @param rawAssertionValue The raw, unprocessed assertion value. 515 * 516 * @return The created extensibleMatch filter. 517 */ 518 public static MatchedValuesFilter createExtensibleMatchFilter( 519 String rawAttributeType, 520 String matchingRuleID, 521 ByteString rawAssertionValue) 522 { 523 Validator 524 .ensureNotNull(rawAttributeType, matchingRuleID, rawAssertionValue); 525 return new MatchedValuesFilter(EXTENSIBLE_MATCH_TYPE, rawAttributeType, 526 rawAssertionValue, null, null, null, 527 matchingRuleID); 528 } 529 530 531 532 /** 533 * Creates a new extensibleMatch filter with the provided information. 534 * 535 * @param attributeType The attribute type. 536 * @param matchingRule The matching rule. 537 * @param assertionValue The assertion value. 538 * 539 * @return The created extensibleMatch filter. 540 */ 541 public static MatchedValuesFilter createExtensibleMatchFilter( 542 AttributeType attributeType, 543 MatchingRule matchingRule, 544 AttributeValue assertionValue) 545 { 546 Validator.ensureNotNull(attributeType, matchingRule, assertionValue); 547 String rawAttributeType = attributeType.getNameOrOID(); 548 String matchingRuleID = matchingRule.getOID(); 549 ASN1OctetString rawAssertionValue = 550 assertionValue.getValue().toASN1OctetString(); 551 552 MatchedValuesFilter filter = 553 new MatchedValuesFilter(EXTENSIBLE_MATCH_TYPE, rawAttributeType, 554 rawAssertionValue, null, null, null, 555 matchingRuleID); 556 filter.attributeType = attributeType; 557 filter.assertionValue = assertionValue; 558 filter.matchingRule = matchingRule; 559 560 return filter; 561 } 562 563 564 565 /** 566 * Creates a new matched values filter from the provided LDAP filter. 567 * 568 * @param filter The LDAP filter to use for this matched values filter. 569 * 570 * @return The corresponding matched values filter. 571 * 572 * @throws LDAPException If the provided LDAP filter cannot be treated as a 573 * matched values filter. 574 */ 575 public static MatchedValuesFilter createFromLDAPFilter(RawFilter filter) 576 throws LDAPException 577 { 578 switch (filter.getFilterType()) 579 { 580 case AND: 581 case OR: 582 case NOT: 583 // These filter types cannot be used in a matched values filter. 584 Message message = ERR_MVFILTER_INVALID_LDAP_FILTER_TYPE.get( 585 String.valueOf(filter), String.valueOf(filter.getFilterType())); 586 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 587 588 589 case EQUALITY: 590 return new MatchedValuesFilter(EQUALITY_MATCH_TYPE, 591 filter.getAttributeType(), 592 filter.getAssertionValue(), null, null, 593 null, null); 594 595 596 case SUBSTRING: 597 return new MatchedValuesFilter(SUBSTRINGS_TYPE, 598 filter.getAttributeType(), null, 599 filter.getSubInitialElement(), 600 filter.getSubAnyElements(), 601 filter.getSubFinalElement(), null); 602 603 604 case GREATER_OR_EQUAL: 605 return new MatchedValuesFilter(GREATER_OR_EQUAL_TYPE, 606 filter.getAttributeType(), 607 filter.getAssertionValue(), null, null, 608 null, null); 609 610 611 case LESS_OR_EQUAL: 612 return new MatchedValuesFilter(LESS_OR_EQUAL_TYPE, 613 filter.getAttributeType(), 614 filter.getAssertionValue(), null, null, 615 null, null); 616 617 618 case PRESENT: 619 return new MatchedValuesFilter(PRESENT_TYPE, filter.getAttributeType(), 620 null, null, null, null, null); 621 622 623 case APPROXIMATE_MATCH: 624 return new MatchedValuesFilter(APPROXIMATE_MATCH_TYPE, 625 filter.getAttributeType(), 626 filter.getAssertionValue(), null, null, 627 null, null); 628 629 630 case EXTENSIBLE_MATCH: 631 if (filter.getDNAttributes()) 632 { 633 // This cannot be represented in a matched values filter. 634 message = ERR_MVFILTER_INVALID_DN_ATTRIBUTES_FLAG.get( 635 String.valueOf(filter)); 636 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 637 } 638 else 639 { 640 return new MatchedValuesFilter(EXTENSIBLE_MATCH_TYPE, 641 filter.getAttributeType(), 642 filter.getAssertionValue(), null, null, 643 null, filter.getMatchingRuleID()); 644 } 645 646 647 default: 648 message = ERR_MVFILTER_INVALID_LDAP_FILTER_TYPE.get( 649 String.valueOf(filter), String.valueOf(filter.getFilterType())); 650 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 651 } 652 } 653 654 655 656 /** 657 * Encodes this matched values filter as an ASN.1 element. 658 * 659 * @return The ASN.1 element containing the encoded matched values filter. 660 */ 661 public ASN1Element encode() 662 { 663 switch (matchType) 664 { 665 case EQUALITY_MATCH_TYPE: 666 case GREATER_OR_EQUAL_TYPE: 667 case LESS_OR_EQUAL_TYPE: 668 case APPROXIMATE_MATCH_TYPE: 669 // These will all be encoded in the same way. 670 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2); 671 elements.add(new ASN1OctetString(rawAttributeType)); 672 elements.add(rawAssertionValue.toASN1OctetString()); 673 return new ASN1Sequence(matchType, elements); 674 675 676 case SUBSTRINGS_TYPE: 677 ArrayList<ASN1Element> subElements = new ArrayList<ASN1Element>(); 678 if (subInitial != null) 679 { 680 ASN1OctetString subInitialOS = subInitial.toASN1OctetString(); 681 subInitialOS.setType(TYPE_SUBINITIAL); 682 subElements.add(subInitialOS); 683 } 684 685 if (subAny != null) 686 { 687 for (ByteString s : subAny) 688 { 689 ASN1OctetString os = s.toASN1OctetString(); 690 os.setType(TYPE_SUBANY); 691 subElements.add(os); 692 } 693 } 694 695 if (subFinal != null) 696 { 697 ASN1OctetString subFinalOS = subFinal.toASN1OctetString(); 698 subFinalOS.setType(TYPE_SUBFINAL); 699 subElements.add(subFinalOS); 700 } 701 702 elements = new ArrayList<ASN1Element>(2); 703 elements.add(new ASN1OctetString(rawAttributeType)); 704 elements.add(new ASN1Sequence(subElements)); 705 return new ASN1Sequence(matchType, elements); 706 707 708 case PRESENT_TYPE: 709 return new ASN1OctetString(matchType, rawAttributeType); 710 711 712 case EXTENSIBLE_MATCH_TYPE: 713 elements = new ArrayList<ASN1Element>(3); 714 if (matchingRuleID != null) 715 { 716 elements.add(new ASN1OctetString(TYPE_MATCHING_RULE_ID, 717 matchingRuleID)); 718 } 719 720 if (rawAttributeType != null) 721 { 722 elements.add(new ASN1OctetString(TYPE_MATCHING_RULE_TYPE, 723 rawAttributeType)); 724 } 725 726 ASN1OctetString valueOS = rawAssertionValue.toASN1OctetString(); 727 valueOS.setType(TYPE_MATCHING_RULE_VALUE); 728 elements.add(valueOS); 729 return new ASN1Sequence(matchType, elements); 730 731 732 default: 733 return null; 734 } 735 } 736 737 738 739 /** 740 * Decodes the provided ASN.1 element as a matched values filter item. 741 * 742 * @param element The ASN.1 element to be decoded. 743 * 744 * @return The decoded matched values filter. 745 * 746 * @throws LDAPException If a problem occurs while attempting to decode the 747 * filter item. 748 */ 749 public static MatchedValuesFilter decode(ASN1Element element) 750 throws LDAPException 751 { 752 switch (element.getType()) 753 { 754 case EQUALITY_MATCH_TYPE: 755 case GREATER_OR_EQUAL_TYPE: 756 case LESS_OR_EQUAL_TYPE: 757 case APPROXIMATE_MATCH_TYPE: 758 // These will all be decoded in the same manner. The element must be a 759 // sequence consisting of the attribute type and assertion value. 760 try 761 { 762 ArrayList<ASN1Element> elements = 763 element.decodeAsSequence().elements(); 764 if (elements.size() != 2) 765 { 766 Message message = 767 ERR_MVFILTER_INVALID_AVA_SEQUENCE_SIZE.get(elements.size()); 768 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 769 } 770 771 String rawAttributeType = 772 elements.get(0).decodeAsOctetString().stringValue(); 773 774 return new MatchedValuesFilter(element.getType(), rawAttributeType, 775 elements.get(1).decodeAsOctetString(), 776 null, null, null, null); 777 } 778 catch (LDAPException le) 779 { 780 throw le; 781 } 782 catch (Exception e) 783 { 784 if (debugEnabled()) 785 { 786 TRACER.debugCaught(DebugLogLevel.ERROR, e); 787 } 788 789 Message message = 790 ERR_MVFILTER_CANNOT_DECODE_AVA.get(getExceptionMessage(e)); 791 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, 792 e); 793 } 794 795 796 case SUBSTRINGS_TYPE: 797 // This must be a sequence of two elements, where the second is a 798 // sequence of substring types. 799 try 800 { 801 ArrayList<ASN1Element> elements = 802 element.decodeAsSequence().elements(); 803 if (elements.size() != 2) 804 { 805 Message message = ERR_MVFILTER_INVALID_SUBSTRING_SEQUENCE_SIZE.get( 806 elements.size()); 807 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 808 } 809 810 ArrayList<ASN1Element> subElements = 811 elements.get(1).decodeAsSequence().elements(); 812 if (subElements.isEmpty()) 813 { 814 Message message = ERR_MVFILTER_NO_SUBSTRING_ELEMENTS.get(); 815 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 816 } 817 818 String rawAttributeType = 819 elements.get(0).decodeAsOctetString().stringValue(); 820 821 ByteString subInitial = null; 822 ArrayList<ByteString> subAny = null; 823 ByteString subFinal = null; 824 for (ASN1Element e : subElements) 825 { 826 switch (e.getType()) 827 { 828 case TYPE_SUBINITIAL: 829 if (subInitial == null) 830 { 831 subInitial = e.decodeAsOctetString(); 832 } 833 else 834 { 835 Message message = ERR_MVFILTER_MULTIPLE_SUBINITIALS.get(); 836 throw new LDAPException( 837 LDAPResultCode.PROTOCOL_ERROR, message); 838 } 839 break; 840 841 case TYPE_SUBANY: 842 if (subAny == null) 843 { 844 subAny = new ArrayList<ByteString>(); 845 } 846 847 subAny.add(e.decodeAsOctetString()); 848 break; 849 850 case TYPE_SUBFINAL: 851 if (subFinal == null) 852 { 853 subFinal = e.decodeAsOctetString(); 854 } 855 else 856 { 857 Message message = ERR_MVFILTER_MULTIPLE_SUBFINALS.get(); 858 throw new LDAPException( 859 LDAPResultCode.PROTOCOL_ERROR, message); 860 } 861 break; 862 863 default: 864 Message message = ERR_MVFILTER_INVALID_SUBSTRING_ELEMENT_TYPE. 865 get(byteToHex(e.getType())); 866 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 867 } 868 } 869 870 return new MatchedValuesFilter(element.getType(), rawAttributeType, 871 null, subInitial, subAny, subFinal, 872 null); 873 } 874 catch (LDAPException le) 875 { 876 throw le; 877 } 878 catch (Exception e) 879 { 880 if (debugEnabled()) 881 { 882 TRACER.debugCaught(DebugLogLevel.ERROR, e); 883 } 884 885 Message message = 886 ERR_MVFILTER_CANNOT_DECODE_SUBSTRINGS.get(getExceptionMessage(e)); 887 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, 888 e); 889 } 890 891 892 case PRESENT_TYPE: 893 // The element must be an ASN.1 octet string holding the attribute type. 894 try 895 { 896 String rawAttributeType = element.decodeAsOctetString().stringValue(); 897 898 return new MatchedValuesFilter(element.getType(), rawAttributeType, 899 null, null, null, null, null); 900 } 901 catch (Exception e) 902 { 903 if (debugEnabled()) 904 { 905 TRACER.debugCaught(DebugLogLevel.ERROR, e); 906 } 907 908 Message message = ERR_MVFILTER_CANNOT_DECODE_PRESENT_TYPE.get( 909 getExceptionMessage(e)); 910 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, 911 e); 912 } 913 914 915 case EXTENSIBLE_MATCH_TYPE: 916 // This must be a two or three element sequence with an assertion value 917 // as the last element and an attribute type and/or matching rule ID as 918 // the first element(s). 919 try 920 { 921 ArrayList<ASN1Element> elements = 922 element.decodeAsSequence().elements(); 923 if ((elements.size() < 2) || (elements.size() > 3)) 924 { 925 Message message = ERR_MVFILTER_INVALID_EXTENSIBLE_SEQUENCE_SIZE.get( 926 elements.size()); 927 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 928 } 929 930 931 String rawAttributeType = null; 932 String matchingRuleID = null; 933 ASN1OctetString rawAssertionValue = null; 934 for (ASN1Element e : elements) 935 { 936 switch (e.getType()) 937 { 938 case TYPE_MATCHING_RULE_ID: 939 if (matchingRuleID == null) 940 { 941 matchingRuleID = e.decodeAsOctetString().stringValue(); 942 } 943 else 944 { 945 Message message = 946 ERR_MVFILTER_MULTIPLE_MATCHING_RULE_IDS.get(); 947 throw new LDAPException( 948 LDAPResultCode.PROTOCOL_ERROR, message); 949 } 950 break; 951 952 case TYPE_MATCHING_RULE_TYPE: 953 if (rawAttributeType == null) 954 { 955 rawAttributeType = e.decodeAsOctetString().stringValue(); 956 } 957 else 958 { 959 Message message = ERR_MVFILTER_MULTIPLE_ATTRIBUTE_TYPES.get(); 960 throw new LDAPException( 961 LDAPResultCode.PROTOCOL_ERROR, message); 962 } 963 break; 964 965 case TYPE_MATCHING_RULE_VALUE: 966 if (rawAssertionValue == null) 967 { 968 rawAssertionValue = e.decodeAsOctetString(); 969 } 970 else 971 { 972 Message message = 973 ERR_MVFILTER_MULTIPLE_ASSERTION_VALUES.get(); 974 throw new LDAPException( 975 LDAPResultCode.PROTOCOL_ERROR, message); 976 } 977 break; 978 979 default: 980 Message message = ERR_MVFILTER_INVALID_EXTENSIBLE_ELEMENT_TYPE. 981 get(byteToHex(e.getType())); 982 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 983 } 984 } 985 986 987 return new MatchedValuesFilter(element.getType(), rawAttributeType, 988 rawAssertionValue, null, null, null, 989 matchingRuleID); 990 } 991 catch (LDAPException le) 992 { 993 throw le; 994 } 995 catch (Exception e) 996 { 997 if (debugEnabled()) 998 { 999 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1000 } 1001 1002 Message message = ERR_MVFILTER_CANNOT_DECODE_EXTENSIBLE_MATCH.get( 1003 getExceptionMessage(e)); 1004 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message, 1005 e); 1006 } 1007 1008 1009 default: 1010 Message message = 1011 ERR_MVFILTER_INVALID_ELEMENT_TYPE.get(byteToHex(element.getType())); 1012 throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message); 1013 } 1014 } 1015 1016 1017 1018 /** 1019 * Retrieves the match type for this matched values filter. 1020 * 1021 * @return The match type for this matched values filter. 1022 */ 1023 public byte getMatchType() 1024 { 1025 return matchType; 1026 } 1027 1028 1029 1030 /** 1031 * Retrieves the raw, unprocessed attribute type for this matched values 1032 * filter. 1033 * 1034 * @return The raw, unprocessed attribute type for this matched values 1035 * filter, or <CODE>null</CODE> if there is none. 1036 */ 1037 public String getRawAttributeType() 1038 { 1039 return rawAttributeType; 1040 } 1041 1042 1043 1044 /** 1045 * Specifies the raw, unprocessed attribute type for this matched values 1046 * filter. 1047 * 1048 * @param rawAttributeType The raw, unprocessed attribute type for this 1049 * matched values filter. 1050 */ 1051 public void setRawAttributeType(String rawAttributeType) 1052 { 1053 this.rawAttributeType = rawAttributeType; 1054 1055 decoded = false; 1056 attributeType = null; 1057 approximateMatchingRule = null; 1058 equalityMatchingRule = null; 1059 orderingMatchingRule = null; 1060 substringMatchingRule = null; 1061 } 1062 1063 1064 1065 /** 1066 * Retrieves the attribute type for this matched values filter. 1067 * 1068 * @return The attribute type for this matched values filter, or 1069 * <CODE>null</CODE> if there is none. 1070 */ 1071 public AttributeType getAttributeType() 1072 { 1073 if (attributeType == null) 1074 { 1075 if (rawAttributeType != null) 1076 { 1077 attributeType = 1078 DirectoryServer.getAttributeType(toLowerCase(rawAttributeType)); 1079 if (attributeType == null) 1080 { 1081 attributeType = 1082 DirectoryServer.getDefaultAttributeType(rawAttributeType); 1083 } 1084 } 1085 } 1086 1087 return attributeType; 1088 } 1089 1090 1091 1092 /** 1093 * Specifies the attribute type for this matched values filter. 1094 * 1095 * @param attributeType The attribute type for this matched values filter. 1096 */ 1097 public void setAttributeType(AttributeType attributeType) 1098 { 1099 this.attributeType = attributeType; 1100 1101 if (attributeType == null) 1102 { 1103 rawAttributeType = null; 1104 } 1105 else 1106 { 1107 rawAttributeType = attributeType.getNameOrOID(); 1108 } 1109 1110 decoded = false; 1111 approximateMatchingRule = null; 1112 equalityMatchingRule = null; 1113 orderingMatchingRule = null; 1114 substringMatchingRule = null; 1115 } 1116 1117 1118 1119 /** 1120 * Retrieves the raw, unprocessed assertion value for this matched values 1121 * filter. 1122 * 1123 * @return The raw, unprocessed assertion value for this matched values 1124 * filter, or <CODE>null</CODE> if there is none. 1125 */ 1126 public ByteString getRawAssertionValue() 1127 { 1128 return rawAssertionValue; 1129 } 1130 1131 1132 1133 /** 1134 * Specifies the raw, unprocessed assertion value for this matched values 1135 * filter. 1136 * 1137 * @param rawAssertionValue The raw, unprocessed assertion value for this 1138 * matched values filter. 1139 */ 1140 public void setRawAssertionValue(ByteString rawAssertionValue) 1141 { 1142 this.rawAssertionValue = rawAssertionValue; 1143 1144 decoded = false; 1145 assertionValue = null; 1146 } 1147 1148 1149 1150 /** 1151 * Retrieves the assertion value for this matched values filter. 1152 * 1153 * @return The assertion value for this matched values filter, or 1154 * <CODE>null</CODE> if there is none. 1155 */ 1156 public AttributeValue getAssertionValue() 1157 { 1158 if (assertionValue == null) 1159 { 1160 if (rawAssertionValue != null) 1161 { 1162 assertionValue = new AttributeValue(getAttributeType(), 1163 rawAssertionValue); 1164 } 1165 } 1166 1167 return assertionValue; 1168 } 1169 1170 1171 1172 /** 1173 * Specifies the assertion value for this matched values filter. 1174 * 1175 * @param assertionValue The assertion value for this matched values filter. 1176 */ 1177 public void setAssertionValue(AttributeValue assertionValue) 1178 { 1179 this.assertionValue = assertionValue; 1180 1181 if (assertionValue == null) 1182 { 1183 rawAssertionValue = null; 1184 } 1185 else 1186 { 1187 rawAssertionValue = assertionValue.getValue().toASN1OctetString(); 1188 } 1189 1190 decoded = false; 1191 } 1192 1193 1194 1195 /** 1196 * Retrieves the subInitial element for this matched values filter. 1197 * 1198 * @return The subInitial element for this matched values filter, or 1199 * <CODE>null</CODE> if there is none. 1200 */ 1201 public ByteString getSubInitialElement() 1202 { 1203 return subInitial; 1204 } 1205 1206 1207 1208 /** 1209 * Specifies the subInitial element for this matched values filter. 1210 * 1211 * @param subInitial The subInitial element for this matched values filter. 1212 */ 1213 public void setSubInitialElement(ByteString subInitial) 1214 { 1215 this.subInitial = subInitial; 1216 1217 decoded = false; 1218 normalizedSubInitial = null; 1219 } 1220 1221 1222 1223 /** 1224 * Retrieves the normalized form of the subInitial element. 1225 * 1226 * @return The normalized form of the subInitial element, or 1227 * <CODE>null</CODE> if there is none. 1228 */ 1229 public ASN1OctetString getNormalizedSubInitialElement() 1230 { 1231 if (normalizedSubInitial == null) 1232 { 1233 if ((subInitial != null) && (getSubstringMatchingRule() != null)) 1234 { 1235 try 1236 { 1237 normalizedSubInitial = 1238 getSubstringMatchingRule().normalizeSubstring(subInitial). 1239 toASN1OctetString(); 1240 } 1241 catch (Exception e) 1242 { 1243 if (debugEnabled()) 1244 { 1245 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1246 } 1247 } 1248 } 1249 } 1250 1251 return normalizedSubInitial; 1252 } 1253 1254 1255 1256 /** 1257 * Retrieves the set of subAny elements for this matched values filter. 1258 * 1259 * @return The set of subAny elements for this matched values filter. If 1260 * there are none, then the return value may be either 1261 * <CODE>null</CODE> or an empty list. 1262 */ 1263 public List<ByteString> getSubAnyElements() 1264 { 1265 return subAny; 1266 } 1267 1268 1269 1270 /** 1271 * Specifies the set of subAny elements for this matched values filter. 1272 * 1273 * @param subAny The set of subAny elements for this matched values filter. 1274 */ 1275 public void setSubAnyElements(List<ByteString> subAny) 1276 { 1277 this.subAny = subAny; 1278 1279 decoded = false; 1280 normalizedSubAny = null; 1281 } 1282 1283 1284 1285 /** 1286 * Retrieves the set of normalized subAny elements for this matched values 1287 * filter. 1288 * 1289 * @return The set of subAny elements for this matched values filter. If 1290 * there are none, then an empty list will be returned. If a 1291 * problem occurs while attempting to perform the normalization, then 1292 * <CODE>null</CODE> will be returned. 1293 */ 1294 public List<ASN1OctetString> getNormalizedSubAnyElements() 1295 { 1296 if (normalizedSubAny == null) 1297 { 1298 if ((subAny == null) || (subAny.isEmpty())) 1299 { 1300 normalizedSubAny = new ArrayList<ASN1OctetString>(0); 1301 } 1302 else 1303 { 1304 if (getSubstringMatchingRule() == null) 1305 { 1306 return null; 1307 } 1308 1309 normalizedSubAny = new ArrayList<ASN1OctetString>(); 1310 try 1311 { 1312 for (ByteString s : subAny) 1313 { 1314 normalizedSubAny.add( 1315 substringMatchingRule.normalizeSubstring(s). 1316 toASN1OctetString()); 1317 } 1318 } 1319 catch (Exception e) 1320 { 1321 if (debugEnabled()) 1322 { 1323 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1324 } 1325 1326 normalizedSubAny = null; 1327 } 1328 } 1329 } 1330 1331 return normalizedSubAny; 1332 } 1333 1334 1335 1336 /** 1337 * Retrieves the subFinal element for this matched values filter. 1338 * 1339 * @return The subFinal element for this matched values filter, or 1340 * <CODE>null</CODE> if there is none. 1341 */ 1342 public ByteString getSubFinalElement() 1343 { 1344 return subFinal; 1345 } 1346 1347 1348 1349 /** 1350 * Specifies the subFinal element for this matched values filter. 1351 * 1352 * @param subFinal The subFinal element for this matched values filter. 1353 */ 1354 public void setSubFinalElement(ByteString subFinal) 1355 { 1356 this.subFinal = subFinal; 1357 1358 decoded = false; 1359 normalizedSubFinal = null; 1360 } 1361 1362 1363 1364 /** 1365 * Retrieves the normalized form of the subFinal element. 1366 * 1367 * @return The normalized form of the subFinal element, or <CODE>null</CODE> 1368 * if there is none. 1369 */ 1370 public ASN1OctetString getNormalizedSubFinalElement() 1371 { 1372 if (normalizedSubFinal == null) 1373 { 1374 if ((subFinal != null) && (getSubstringMatchingRule() != null)) 1375 { 1376 try 1377 { 1378 normalizedSubFinal = 1379 getSubstringMatchingRule().normalizeSubstring(subFinal). 1380 toASN1OctetString(); 1381 } 1382 catch (Exception e) 1383 { 1384 if (debugEnabled()) 1385 { 1386 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1387 } 1388 } 1389 } 1390 } 1391 1392 return normalizedSubFinal; 1393 } 1394 1395 1396 1397 /** 1398 * Retrieves the matching rule ID for this matched values filter. 1399 * 1400 * @return The matching rule ID for this matched values filter, or 1401 * <CODE>null</CODE> if there is none. 1402 */ 1403 public String getMatchingRuleID() 1404 { 1405 return matchingRuleID; 1406 } 1407 1408 1409 1410 /** 1411 * Specifies the matching rule ID for this matched values filter. 1412 * 1413 * @param matchingRuleID The matching rule ID for this matched values 1414 * filter. 1415 */ 1416 public void setMatchingRuleID(String matchingRuleID) 1417 { 1418 this.matchingRuleID = matchingRuleID; 1419 1420 decoded = false; 1421 matchingRule = null; 1422 } 1423 1424 1425 1426 /** 1427 * Retrieves the matching rule for this matched values filter. 1428 * 1429 * @return The matching rule for this matched values filter, or 1430 * <CODE>null</CODE> if there is none. 1431 */ 1432 public MatchingRule getMatchingRule() 1433 { 1434 if (matchingRule == null) 1435 { 1436 if (matchingRuleID != null) 1437 { 1438 matchingRule = 1439 DirectoryServer.getMatchingRule(toLowerCase(matchingRuleID)); 1440 } 1441 } 1442 1443 return matchingRule; 1444 } 1445 1446 1447 1448 /** 1449 * Specifies the matching rule for this matched values filter. 1450 * 1451 * @param matchingRule The matching rule for this matched values filter. 1452 */ 1453 public void setMatchingRule(MatchingRule matchingRule) 1454 { 1455 this.matchingRule = matchingRule; 1456 1457 if (matchingRule == null) 1458 { 1459 matchingRuleID = null; 1460 } 1461 else 1462 { 1463 matchingRuleID = matchingRule.getNameOrOID(); 1464 } 1465 1466 decoded = false; 1467 } 1468 1469 1470 1471 /** 1472 * Retrieves the approximate matching rule that should be used for this 1473 * matched values filter. 1474 * 1475 * @return The approximate matching rule that should be used for this matched 1476 * values filter, or <CODE>null</CODE> if there is none. 1477 */ 1478 public ApproximateMatchingRule getApproximateMatchingRule() 1479 { 1480 if (approximateMatchingRule == null) 1481 { 1482 AttributeType attrType = getAttributeType(); 1483 if (attrType != null) 1484 { 1485 approximateMatchingRule = attrType.getApproximateMatchingRule(); 1486 } 1487 } 1488 1489 return approximateMatchingRule; 1490 } 1491 1492 1493 1494 /** 1495 * Retrieves the equality matching rule that should be used for this matched 1496 * values filter. 1497 * 1498 * @return The equality matching rule that should be used for this matched 1499 * values filter, or <CODE>null</CODE> if there is none. 1500 */ 1501 public EqualityMatchingRule getEqualityMatchingRule() 1502 { 1503 if (equalityMatchingRule == null) 1504 { 1505 AttributeType attrType = getAttributeType(); 1506 if (attrType != null) 1507 { 1508 equalityMatchingRule = attrType.getEqualityMatchingRule(); 1509 } 1510 } 1511 1512 return equalityMatchingRule; 1513 } 1514 1515 1516 1517 /** 1518 * Retrieves the ordering matching rule that should be used for this matched 1519 * values filter. 1520 * 1521 * @return The ordering matching rule that should be used for this matched 1522 * values filter, or <CODE>null</CODE> if there is none. 1523 */ 1524 public OrderingMatchingRule getOrderingMatchingRule() 1525 { 1526 if (orderingMatchingRule == null) 1527 { 1528 AttributeType attrType = getAttributeType(); 1529 if (attrType != null) 1530 { 1531 orderingMatchingRule = attrType.getOrderingMatchingRule(); 1532 } 1533 } 1534 1535 return orderingMatchingRule; 1536 } 1537 1538 1539 1540 /** 1541 * Retrieves the substring matching rule that should be used for this matched 1542 * values filter. 1543 * 1544 * @return The substring matching rule that should be used for this matched 1545 * values filter, or <CODE>null</CODE> if there is none. 1546 */ 1547 public SubstringMatchingRule getSubstringMatchingRule() 1548 { 1549 if (substringMatchingRule == null) 1550 { 1551 AttributeType attrType = getAttributeType(); 1552 if (attrType != null) 1553 { 1554 substringMatchingRule = attrType.getSubstringMatchingRule(); 1555 } 1556 } 1557 1558 return substringMatchingRule; 1559 } 1560 1561 1562 1563 /** 1564 * Decodes all components of the matched values filter so that they can be 1565 * referenced as member variables. 1566 */ 1567 private void fullyDecode() 1568 { 1569 if (! decoded) 1570 { 1571 getAttributeType(); 1572 getAssertionValue(); 1573 getNormalizedSubInitialElement(); 1574 getNormalizedSubAnyElements(); 1575 getNormalizedSubFinalElement(); 1576 getMatchingRule(); 1577 getApproximateMatchingRule(); 1578 getEqualityMatchingRule(); 1579 getOrderingMatchingRule(); 1580 getSubstringMatchingRule(); 1581 decoded = true; 1582 } 1583 } 1584 1585 1586 1587 /** 1588 * Indicates whether the specified attribute value matches the criteria 1589 * defined in this matched values filter. 1590 * 1591 * @param type The attribute type with which the provided value is 1592 * associated. 1593 * @param value The attribute value for which to make the determination. 1594 * 1595 * @return <CODE>true</CODE> if the specified attribute value matches the 1596 * criteria defined in this matched values filter, or 1597 * <CODE>false</CODE> if not. 1598 */ 1599 public boolean valueMatches(AttributeType type, AttributeValue value) 1600 { 1601 fullyDecode(); 1602 1603 switch (matchType) 1604 { 1605 case EQUALITY_MATCH_TYPE: 1606 if ((attributeType != null) && (type != null) && 1607 attributeType.equals(type) && (assertionValue != null) && 1608 (value != null) && (equalityMatchingRule != null)) 1609 { 1610 try 1611 { 1612 return equalityMatchingRule.areEqual( 1613 assertionValue.getNormalizedValue(), 1614 value.getNormalizedValue()); 1615 } 1616 catch (Exception e) 1617 { 1618 if (debugEnabled()) 1619 { 1620 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1621 } 1622 1623 return false; 1624 } 1625 } 1626 else 1627 { 1628 return false; 1629 } 1630 1631 1632 case SUBSTRINGS_TYPE: 1633 if ((attributeType != null) && (type != null) && 1634 attributeType.equals(type) && (substringMatchingRule != null)) 1635 { 1636 try 1637 { 1638 ArrayList<ByteString> normalizedSubAnyBS = 1639 new ArrayList<ByteString>(normalizedSubAny); 1640 1641 return substringMatchingRule.valueMatchesSubstring( 1642 value.getNormalizedValue(), normalizedSubInitial, 1643 normalizedSubAnyBS, normalizedSubFinal); 1644 } 1645 catch (Exception e) 1646 { 1647 if (debugEnabled()) 1648 { 1649 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1650 } 1651 1652 return false; 1653 } 1654 } 1655 else 1656 { 1657 return false; 1658 } 1659 1660 1661 case GREATER_OR_EQUAL_TYPE: 1662 if ((attributeType != null) && (type != null) && 1663 attributeType.equals(type) && (assertionValue != null) && 1664 (value != null) && (orderingMatchingRule != null)) 1665 { 1666 try 1667 { 1668 return (orderingMatchingRule.compareValues( 1669 assertionValue.getNormalizedValue(), 1670 value.getNormalizedValue()) >= 0); 1671 } 1672 catch (Exception e) 1673 { 1674 if (debugEnabled()) 1675 { 1676 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1677 } 1678 1679 return false; 1680 } 1681 } 1682 else 1683 { 1684 return false; 1685 } 1686 1687 1688 case LESS_OR_EQUAL_TYPE: 1689 if ((attributeType != null) && (type != null) && 1690 attributeType.equals(type) && (assertionValue != null) && 1691 (value != null) && (orderingMatchingRule != null)) 1692 { 1693 try 1694 { 1695 return (orderingMatchingRule.compareValues( 1696 assertionValue.getNormalizedValue(), 1697 value.getNormalizedValue()) <= 0); 1698 } 1699 catch (Exception e) 1700 { 1701 if (debugEnabled()) 1702 { 1703 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1704 } 1705 1706 return false; 1707 } 1708 } 1709 else 1710 { 1711 return false; 1712 } 1713 1714 1715 case PRESENT_TYPE: 1716 return ((attributeType != null) && (type != null) && 1717 attributeType.equals(type)); 1718 1719 1720 case APPROXIMATE_MATCH_TYPE: 1721 if ((attributeType != null) && (type != null) && 1722 attributeType.equals(type) && (assertionValue != null) && 1723 (value != null) && (approximateMatchingRule != null)) 1724 { 1725 try 1726 { 1727 ByteString nv1 = approximateMatchingRule.normalizeValue( 1728 assertionValue.getNormalizedValue()); 1729 ByteString nv2 = approximateMatchingRule.normalizeValue( 1730 value.getNormalizedValue()); 1731 1732 return approximateMatchingRule.approximatelyMatch(nv1, nv2); 1733 } 1734 catch (Exception e) 1735 { 1736 if (debugEnabled()) 1737 { 1738 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1739 } 1740 1741 return false; 1742 } 1743 } 1744 else 1745 { 1746 return false; 1747 } 1748 1749 1750 case EXTENSIBLE_MATCH_TYPE: 1751 if ((assertionValue == null) || (value == null)) 1752 { 1753 return false; 1754 } 1755 1756 if (attributeType == null) 1757 { 1758 if (matchingRule == null) 1759 { 1760 return false; 1761 } 1762 1763 try 1764 { 1765 ASN1OctetString nv1 = 1766 matchingRule.normalizeValue(value.getValue()). 1767 toASN1OctetString(); 1768 ASN1OctetString nv2 = 1769 matchingRule.normalizeValue(assertionValue.getValue()). 1770 toASN1OctetString(); 1771 1772 return (matchingRule.valuesMatch(nv1, nv2) == ConditionResult.TRUE); 1773 } 1774 catch (Exception e) 1775 { 1776 if (debugEnabled()) 1777 { 1778 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1779 } 1780 1781 return false; 1782 } 1783 } 1784 else 1785 { 1786 if ((! attributeType.equals(type)) || (equalityMatchingRule == null)) 1787 { 1788 return false; 1789 } 1790 1791 try 1792 { 1793 return equalityMatchingRule.areEqual( 1794 assertionValue.getNormalizedValue(), 1795 value.getNormalizedValue()); 1796 } 1797 catch (Exception e) 1798 { 1799 if (debugEnabled()) 1800 { 1801 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1802 } 1803 1804 return false; 1805 } 1806 } 1807 1808 1809 default: 1810 return false; 1811 } 1812 } 1813 1814 1815 1816 /** 1817 * Retrieves a string representation of this matched values filter, as an RFC 1818 * 2254-compliant filter string. 1819 * 1820 * @return A string representation of this matched values filter. 1821 */ 1822 public String toString() 1823 { 1824 StringBuilder buffer = new StringBuilder(); 1825 toString(buffer); 1826 return buffer.toString(); 1827 } 1828 1829 1830 1831 /** 1832 * Appends a string representation of this matched values filter, as an RFC 1833 * 2254-compliant filter string, to the provided buffer. 1834 * 1835 * @param buffer The buffer to which the filter string should be appended. 1836 */ 1837 public void toString(StringBuilder buffer) 1838 { 1839 switch (matchType) 1840 { 1841 case EQUALITY_MATCH_TYPE: 1842 buffer.append("("); 1843 buffer.append(rawAttributeType); 1844 buffer.append("="); 1845 RawFilter.valueToFilterString(buffer, rawAssertionValue); 1846 buffer.append(")"); 1847 break; 1848 1849 1850 case SUBSTRINGS_TYPE: 1851 buffer.append("("); 1852 buffer.append(rawAttributeType); 1853 buffer.append("="); 1854 if (subInitial != null) 1855 { 1856 RawFilter.valueToFilterString(buffer, subInitial); 1857 } 1858 1859 if (subAny != null) 1860 { 1861 for (ByteString s : subAny) 1862 { 1863 buffer.append("*"); 1864 RawFilter.valueToFilterString(buffer, s); 1865 } 1866 } 1867 1868 buffer.append("*"); 1869 if (subFinal != null) 1870 { 1871 RawFilter.valueToFilterString(buffer, subFinal); 1872 } 1873 buffer.append(")"); 1874 break; 1875 1876 1877 case GREATER_OR_EQUAL_TYPE: 1878 buffer.append("("); 1879 buffer.append(rawAttributeType); 1880 buffer.append(">="); 1881 RawFilter.valueToFilterString(buffer, rawAssertionValue); 1882 buffer.append(")"); 1883 break; 1884 1885 1886 case LESS_OR_EQUAL_TYPE: 1887 buffer.append("("); 1888 buffer.append(rawAttributeType); 1889 buffer.append("<="); 1890 RawFilter.valueToFilterString(buffer, rawAssertionValue); 1891 buffer.append(")"); 1892 break; 1893 1894 1895 case PRESENT_TYPE: 1896 buffer.append("("); 1897 buffer.append(rawAttributeType); 1898 buffer.append("=*)"); 1899 break; 1900 1901 1902 case APPROXIMATE_MATCH_TYPE: 1903 buffer.append("("); 1904 buffer.append(rawAttributeType); 1905 buffer.append("~="); 1906 RawFilter.valueToFilterString(buffer, rawAssertionValue); 1907 buffer.append(")"); 1908 break; 1909 1910 1911 case EXTENSIBLE_MATCH_TYPE: 1912 buffer.append("("); 1913 1914 if (rawAttributeType != null) 1915 { 1916 buffer.append(rawAttributeType); 1917 } 1918 1919 if (matchingRuleID != null) 1920 { 1921 buffer.append(":"); 1922 buffer.append(matchingRuleID); 1923 } 1924 1925 buffer.append(":="); 1926 RawFilter.valueToFilterString(buffer, rawAssertionValue); 1927 buffer.append(")"); 1928 break; 1929 } 1930 } 1931 } 1932