001/* 002 * Copyright 2007-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.matchingrules; 022 023 024 025import java.io.Serializable; 026 027import com.unboundid.asn1.ASN1OctetString; 028import com.unboundid.ldap.sdk.LDAPException; 029import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition; 030import com.unboundid.ldap.sdk.schema.Schema; 031import com.unboundid.util.Extensible; 032import com.unboundid.util.ThreadSafety; 033import com.unboundid.util.ThreadSafetyLevel; 034 035import static com.unboundid.util.StaticUtils.*; 036 037 038 039/** 040 * This class defines the API for an LDAP matching rule, which may be used to 041 * determine whether two values are equal to each other, and to normalize values 042 * so that they may be more easily compared. 043 */ 044@Extensible() 045@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 046public abstract class MatchingRule 047 implements Serializable 048{ 049 /** 050 * The substring element type used for subInitial substring assertion 051 * components. 052 */ 053 public static final byte SUBSTRING_TYPE_SUBINITIAL = (byte) 0x80; 054 055 056 057 /** 058 * The substring element type used for subAny substring assertion components. 059 */ 060 public static final byte SUBSTRING_TYPE_SUBANY = (byte) 0x81; 061 062 063 064 /** 065 * The substring element type used for subFinal substring assertion 066 * components. 067 */ 068 public static final byte SUBSTRING_TYPE_SUBFINAL = (byte) 0x82; 069 070 071 072 /** 073 * The serial version UID for this serializable class. 074 */ 075 private static final long serialVersionUID = 6050276733546358513L; 076 077 078 079 /** 080 * Creates a new instance of this matching rule. 081 */ 082 protected MatchingRule() 083 { 084 // No implementation is required. 085 } 086 087 088 089 /** 090 * Retrieves the name for this matching rule when used to perform equality 091 * matching, if appropriate. 092 * 093 * @return The name for this matching rule when used to perform equality 094 * matching, or {@code null} if this matching rule is not intended 095 * to be used for equality matching. 096 */ 097 public abstract String getEqualityMatchingRuleName(); 098 099 100 101 /** 102 * Retrieves the OID for this matching rule when used to perform equality 103 * matching, if appropriate. 104 * 105 * @return The OID for this matching rule when used to perform equality 106 * matching, or {@code null} if this matching rule is not intended 107 * to be used for equality matching. 108 */ 109 public abstract String getEqualityMatchingRuleOID(); 110 111 112 113 /** 114 * Retrieves the name for this matching rule when used to perform equality 115 * matching if defined, or the OID if no name is available. 116 * 117 * @return The name or OID for this matching rule when used to perform 118 * equality matching, or {@code null} if this matching rule cannot 119 * be used to perform equality matching. 120 */ 121 public String getEqualityMatchingRuleNameOrOID() 122 { 123 final String name = getEqualityMatchingRuleName(); 124 if (name == null) 125 { 126 return getEqualityMatchingRuleOID(); 127 } 128 else 129 { 130 return name; 131 } 132 } 133 134 135 136 /** 137 * Retrieves the name for this matching rule when used to perform ordering 138 * matching, if appropriate. 139 * 140 * @return The name for this matching rule when used to perform ordering 141 * matching, or {@code null} if this matching rule is not intended 142 * to be used for ordering matching. 143 */ 144 public abstract String getOrderingMatchingRuleName(); 145 146 147 148 /** 149 * Retrieves the OID for this matching rule when used to perform ordering 150 * matching, if appropriate. 151 * 152 * @return The OID for this matching rule when used to perform ordering 153 * matching, or {@code null} if this matching rule is not intended 154 * to be used for ordering matching. 155 */ 156 public abstract String getOrderingMatchingRuleOID(); 157 158 159 160 /** 161 * Retrieves the name for this matching rule when used to perform ordering 162 * matching if defined, or the OID if no name is available. 163 * 164 * @return The name or OID for this matching rule when used to perform 165 * ordering matching, or {@code null} if this matching rule cannot 166 * be used to perform equality matching. 167 */ 168 public String getOrderingMatchingRuleNameOrOID() 169 { 170 final String name = getOrderingMatchingRuleName(); 171 if (name == null) 172 { 173 return getOrderingMatchingRuleOID(); 174 } 175 else 176 { 177 return name; 178 } 179 } 180 181 182 183 /** 184 * Retrieves the name for this matching rule when used to perform substring 185 * matching, if appropriate. 186 * 187 * @return The name for this matching rule when used to perform substring 188 * matching, or {@code null} if this matching rule is not intended 189 * to be used for substring matching. 190 */ 191 public abstract String getSubstringMatchingRuleName(); 192 193 194 195 /** 196 * Retrieves the OID for this matching rule when used to perform substring 197 * matching, if appropriate. 198 * 199 * @return The OID for this matching rule when used to perform substring 200 * matching, or {@code null} if this matching rule is not intended 201 * to be used for substring matching. 202 */ 203 public abstract String getSubstringMatchingRuleOID(); 204 205 206 207 /** 208 * Retrieves the name for this matching rule when used to perform substring 209 * matching if defined, or the OID if no name is available. 210 * 211 * @return The name or OID for this matching rule when used to perform 212 * substring matching, or {@code null} if this matching rule cannot 213 * be used to perform equality matching. 214 */ 215 public String getSubstringMatchingRuleNameOrOID() 216 { 217 final String name = getSubstringMatchingRuleName(); 218 if (name == null) 219 { 220 return getSubstringMatchingRuleOID(); 221 } 222 else 223 { 224 return name; 225 } 226 } 227 228 229 230 /** 231 * Indicates whether the provided values are equal to each other, according to 232 * the constraints of this matching rule. 233 * 234 * @param value1 The first value for which to make the determination. 235 * @param value2 The second value for which to make the determination. 236 * 237 * @return {@code true} if the provided values are considered equal, or 238 * {@code false} if not. 239 * 240 * @throws LDAPException If a problem occurs while making the determination, 241 * or if this matching rule does not support equality 242 * matching. 243 */ 244 public abstract boolean valuesMatch(final ASN1OctetString value1, 245 final ASN1OctetString value2) 246 throws LDAPException; 247 248 249 250 /** 251 * Indicates whether the provided value matches the given substring assertion, 252 * according to the constraints of this matching rule. 253 * 254 * @param value The value for which to make the determination. 255 * @param subInitial The subInitial portion of the substring assertion, or 256 * {@code null} if there is no subInitial element. 257 * @param subAny The subAny elements of the substring assertion, or 258 * {@code null} if there are no subAny elements. 259 * @param subFinal The subFinal portion of the substring assertion, or 260 * {@code null} if there is no subFinal element. 261 * 262 * @return {@code true} if the provided value matches the substring 263 * assertion, or {@code false} if not. 264 * 265 * @throws LDAPException If a problem occurs while making the determination, 266 * or if this matching rule does not support substring 267 * matching. 268 */ 269 public abstract boolean matchesSubstring(final ASN1OctetString value, 270 final ASN1OctetString subInitial, 271 final ASN1OctetString[] subAny, 272 final ASN1OctetString subFinal) 273 throws LDAPException; 274 275 276 277 /** 278 * Compares the provided values to determine their relative order in a sorted 279 * list. 280 * 281 * @param value1 The first value to compare. 282 * @param value2 The second value to compare. 283 * 284 * @return A negative value if {@code value1} should come before 285 * {@code value2} in a sorted list, a positive value if 286 * {@code value1} should come after {@code value2} in a sorted list, 287 * or zero if the values are equal or there is no distinction between 288 * their orders in a sorted list. 289 * 290 * @throws LDAPException If a problem occurs while making the determination, 291 * or if this matching rule does not support ordering 292 * matching. 293 */ 294 public abstract int compareValues(final ASN1OctetString value1, 295 final ASN1OctetString value2) 296 throws LDAPException; 297 298 299 300 /** 301 * Normalizes the provided value for easier matching. 302 * 303 * @param value The value to be normalized. 304 * 305 * @return The normalized form of the provided value. 306 * 307 * @throws LDAPException If a problem occurs while normalizing the provided 308 * value. 309 */ 310 public abstract ASN1OctetString normalize(final ASN1OctetString value) 311 throws LDAPException; 312 313 314 315 /** 316 * Normalizes the provided value for use as part of a substring assertion. 317 * 318 * @param value The value to be normalized for use as part of a 319 * substring assertion. 320 * @param substringType The substring assertion component type for the 321 * provided value. It should be one of 322 * {@code SUBSTRING_TYPE_SUBINITIAL}, 323 * {@code SUBSTRING_TYPE_SUBANY}, or 324 * {@code SUBSTRING_TYPE_SUBFINAL}. 325 * 326 * @return The normalized form of the provided value. 327 * 328 * @throws LDAPException If a problem occurs while normalizing the provided 329 * value. 330 */ 331 public abstract ASN1OctetString normalizeSubstring( 332 final ASN1OctetString value, 333 final byte substringType) 334 throws LDAPException; 335 336 337 338 /** 339 * Attempts to select the appropriate matching rule to use for equality 340 * matching against the specified attribute. If an appropriate matching rule 341 * cannot be determined, then the default equality matching rule will be 342 * selected. 343 * 344 * @param attrName The name of the attribute to examine in the provided 345 * schema. 346 * @param schema The schema to examine to make the appropriate 347 * determination. If this is {@code null}, then the default 348 * equality matching rule will be selected. 349 * 350 * @return The selected matching rule. 351 */ 352 public static MatchingRule selectEqualityMatchingRule(final String attrName, 353 final Schema schema) 354 { 355 return selectEqualityMatchingRule(attrName, null, schema); 356 } 357 358 359 360 /** 361 * Attempts to select the appropriate matching rule to use for equality 362 * matching against the specified attribute. If an appropriate matching rule 363 * cannot be determined, then the default equality matching rule will be 364 * selected. 365 * 366 * @param attrName The name of the attribute to examine in the provided 367 * schema. It may be {@code null} if the matching rule 368 * should be selected using the matching rule ID. 369 * @param ruleID The OID of the desired matching rule. It may be 370 * {@code null} if the matching rule should be selected only 371 * using the attribute name. If a rule ID is provided, then 372 * it will be the only criteria used to select the matching 373 * rule. 374 * @param schema The schema to examine to make the appropriate 375 * determination. If this is {@code null} and no rule ID 376 * was provided, then the default equality matching rule 377 * will be selected. 378 * 379 * @return The selected matching rule. 380 */ 381 public static MatchingRule selectEqualityMatchingRule(final String attrName, 382 final String ruleID, final Schema schema) 383 { 384 if (ruleID != null) 385 { 386 return selectEqualityMatchingRule(ruleID); 387 } 388 389 if ((attrName == null) || (schema == null)) 390 { 391 return getDefaultEqualityMatchingRule(); 392 } 393 394 final AttributeTypeDefinition attrType = schema.getAttributeType(attrName); 395 if (attrType == null) 396 { 397 return getDefaultEqualityMatchingRule(); 398 } 399 400 final String mrName = attrType.getEqualityMatchingRule(schema); 401 if (mrName != null) 402 { 403 return selectEqualityMatchingRule(mrName); 404 } 405 406 final String syntaxOID = attrType.getBaseSyntaxOID(schema); 407 if (syntaxOID != null) 408 { 409 return selectMatchingRuleForSyntax(syntaxOID); 410 } 411 412 return getDefaultEqualityMatchingRule(); 413 } 414 415 416 417 /** 418 * Attempts to select the appropriate matching rule to use for equality 419 * matching using the specified matching rule. If an appropriate matching 420 * rule cannot be determined, then the default equality matching rule will be 421 * selected. 422 * 423 * @param ruleID The name or OID of the desired matching rule. 424 * 425 * @return The selected matching rule. 426 */ 427 public static MatchingRule selectEqualityMatchingRule(final String ruleID) 428 { 429 if ((ruleID == null) || (ruleID.length() == 0)) 430 { 431 return getDefaultEqualityMatchingRule(); 432 } 433 434 final String lowerName = toLowerCase(ruleID); 435 if (lowerName.equals(BooleanMatchingRule.LOWER_EQUALITY_RULE_NAME) || 436 lowerName.equals(BooleanMatchingRule.EQUALITY_RULE_OID)) 437 { 438 return BooleanMatchingRule.getInstance(); 439 } 440 else if (lowerName.equals( 441 CaseExactStringMatchingRule.LOWER_EQUALITY_RULE_NAME) || 442 lowerName.equals(CaseExactStringMatchingRule.EQUALITY_RULE_OID) || 443 lowerName.equals("caseexactia5match") || 444 lowerName.equals("1.3.6.1.4.1.1466.109.114.1")) 445 { 446 return CaseExactStringMatchingRule.getInstance(); 447 } 448 else if (lowerName.equals( 449 CaseIgnoreListMatchingRule.LOWER_EQUALITY_RULE_NAME) || 450 lowerName.equals(CaseIgnoreListMatchingRule.EQUALITY_RULE_OID)) 451 { 452 return CaseIgnoreListMatchingRule.getInstance(); 453 } 454 else if (lowerName.equals( 455 CaseIgnoreStringMatchingRule.LOWER_EQUALITY_RULE_NAME) || 456 lowerName.equals(CaseIgnoreStringMatchingRule.EQUALITY_RULE_OID) || 457 lowerName.equals("caseignoreia5match") || 458 lowerName.equals("1.3.6.1.4.1.1466.109.114.2")) 459 { 460 return CaseIgnoreStringMatchingRule.getInstance(); 461 } 462 else if (lowerName.equals( 463 DistinguishedNameMatchingRule.LOWER_EQUALITY_RULE_NAME) || 464 lowerName.equals( 465 DistinguishedNameMatchingRule.EQUALITY_RULE_OID) || 466 lowerName.equals("uniquemembermatch") || 467 lowerName.equals("2.5.13.23")) 468 { 469 // NOTE -- Technically uniqueMember should use a name and optional UID 470 // matching rule, but the SDK doesn't currently provide one and the 471 // distinguished name matching rule should be sufficient the vast 472 // majority of the time. 473 return DistinguishedNameMatchingRule.getInstance(); 474 } 475 else if (lowerName.equals( 476 GeneralizedTimeMatchingRule.LOWER_EQUALITY_RULE_NAME) || 477 lowerName.equals(GeneralizedTimeMatchingRule.EQUALITY_RULE_OID)) 478 { 479 return GeneralizedTimeMatchingRule.getInstance(); 480 } 481 else if (lowerName.equals(IntegerMatchingRule.LOWER_EQUALITY_RULE_NAME) || 482 lowerName.equals(IntegerMatchingRule.EQUALITY_RULE_OID)) 483 { 484 return IntegerMatchingRule.getInstance(); 485 } 486 else if (lowerName.equals( 487 NumericStringMatchingRule.LOWER_EQUALITY_RULE_NAME) || 488 lowerName.equals(NumericStringMatchingRule.EQUALITY_RULE_OID)) 489 { 490 return NumericStringMatchingRule.getInstance(); 491 } 492 else if (lowerName.equals( 493 OctetStringMatchingRule.LOWER_EQUALITY_RULE_NAME) || 494 lowerName.equals(OctetStringMatchingRule.EQUALITY_RULE_OID)) 495 { 496 return OctetStringMatchingRule.getInstance(); 497 } 498 else if (lowerName.equals( 499 TelephoneNumberMatchingRule.LOWER_EQUALITY_RULE_NAME) || 500 lowerName.equals(TelephoneNumberMatchingRule.EQUALITY_RULE_OID)) 501 { 502 return TelephoneNumberMatchingRule.getInstance(); 503 } 504 else 505 { 506 return getDefaultEqualityMatchingRule(); 507 } 508 } 509 510 511 512 /** 513 * Retrieves the default matching rule that will be used for equality matching 514 * if no other matching rule is specified or available. The rule returned 515 * will perform case-ignore string matching. 516 * 517 * @return The default matching rule that will be used for equality matching 518 * if no other matching rule is specified or available. 519 */ 520 public static MatchingRule getDefaultEqualityMatchingRule() 521 { 522 return CaseIgnoreStringMatchingRule.getInstance(); 523 } 524 525 526 527 /** 528 * Attempts to select the appropriate matching rule to use for ordering 529 * matching against the specified attribute. If an appropriate matching rule 530 * cannot be determined, then the default ordering matching rule will be 531 * selected. 532 * 533 * @param attrName The name of the attribute to examine in the provided 534 * schema. 535 * @param schema The schema to examine to make the appropriate 536 * determination. If this is {@code null}, then the default 537 * ordering matching rule will be selected. 538 * 539 * @return The selected matching rule. 540 */ 541 public static MatchingRule selectOrderingMatchingRule(final String attrName, 542 final Schema schema) 543 { 544 return selectOrderingMatchingRule(attrName, null, schema); 545 } 546 547 548 549 /** 550 * Attempts to select the appropriate matching rule to use for ordering 551 * matching against the specified attribute. If an appropriate matching rule 552 * cannot be determined, then the default ordering matching rule will be 553 * selected. 554 * 555 * @param attrName The name of the attribute to examine in the provided 556 * schema. It may be {@code null} if the matching rule 557 * should be selected using the matching rule ID. 558 * @param ruleID The OID of the desired matching rule. It may be 559 * {@code null} if the matching rule should be selected only 560 * using the attribute name. If a rule ID is provided, then 561 * it will be the only criteria used to select the matching 562 * rule. 563 * @param schema The schema to examine to make the appropriate 564 * determination. If this is {@code null} and no rule ID 565 * was provided, then the default ordering matching rule 566 * will be selected. 567 * 568 * @return The selected matching rule. 569 */ 570 public static MatchingRule selectOrderingMatchingRule(final String attrName, 571 final String ruleID, 572 final Schema schema) 573 { 574 if (ruleID != null) 575 { 576 return selectOrderingMatchingRule(ruleID); 577 } 578 579 if ((attrName == null) || (schema == null)) 580 { 581 return getDefaultOrderingMatchingRule(); 582 } 583 584 final AttributeTypeDefinition attrType = schema.getAttributeType(attrName); 585 if (attrType == null) 586 { 587 return getDefaultOrderingMatchingRule(); 588 } 589 590 final String mrName = attrType.getOrderingMatchingRule(schema); 591 if (mrName != null) 592 { 593 return selectOrderingMatchingRule(mrName); 594 } 595 596 final String syntaxOID = attrType.getBaseSyntaxOID(schema); 597 if (syntaxOID != null) 598 { 599 return selectMatchingRuleForSyntax(syntaxOID); 600 } 601 602 return getDefaultOrderingMatchingRule(); 603 } 604 605 606 607 /** 608 * Attempts to select the appropriate matching rule to use for ordering 609 * matching using the specified matching rule. If an appropriate matching 610 * rule cannot be determined, then the default ordering matching rule will be 611 * selected. 612 * 613 * @param ruleID The name or OID of the desired matching rule. 614 * 615 * @return The selected matching rule. 616 */ 617 public static MatchingRule selectOrderingMatchingRule(final String ruleID) 618 { 619 if ((ruleID == null) || (ruleID.length() == 0)) 620 { 621 return getDefaultOrderingMatchingRule(); 622 } 623 624 final String lowerName = toLowerCase(ruleID); 625 if (lowerName.equals( 626 CaseExactStringMatchingRule.LOWER_ORDERING_RULE_NAME) || 627 lowerName.equals(CaseExactStringMatchingRule.ORDERING_RULE_OID)) 628 { 629 return CaseExactStringMatchingRule.getInstance(); 630 } 631 else if (lowerName.equals( 632 CaseIgnoreStringMatchingRule.LOWER_ORDERING_RULE_NAME) || 633 lowerName.equals(CaseIgnoreStringMatchingRule.ORDERING_RULE_OID)) 634 { 635 return CaseIgnoreStringMatchingRule.getInstance(); 636 } 637 else if (lowerName.equals( 638 GeneralizedTimeMatchingRule.LOWER_ORDERING_RULE_NAME) || 639 lowerName.equals(GeneralizedTimeMatchingRule.ORDERING_RULE_OID)) 640 { 641 return GeneralizedTimeMatchingRule.getInstance(); 642 } 643 else if (lowerName.equals(IntegerMatchingRule.LOWER_ORDERING_RULE_NAME) || 644 lowerName.equals(IntegerMatchingRule.ORDERING_RULE_OID)) 645 { 646 return IntegerMatchingRule.getInstance(); 647 } 648 else if (lowerName.equals( 649 NumericStringMatchingRule.LOWER_ORDERING_RULE_NAME) || 650 lowerName.equals(NumericStringMatchingRule.ORDERING_RULE_OID)) 651 { 652 return NumericStringMatchingRule.getInstance(); 653 } 654 else if (lowerName.equals( 655 OctetStringMatchingRule.LOWER_ORDERING_RULE_NAME) || 656 lowerName.equals(OctetStringMatchingRule.ORDERING_RULE_OID)) 657 { 658 return OctetStringMatchingRule.getInstance(); 659 } 660 else 661 { 662 return getDefaultOrderingMatchingRule(); 663 } 664 } 665 666 667 668 /** 669 * Retrieves the default matching rule that will be used for ordering matching 670 * if no other matching rule is specified or available. The rule returned 671 * will perform case-ignore string matching. 672 * 673 * @return The default matching rule that will be used for ordering matching 674 * if no other matching rule is specified or available. 675 */ 676 public static MatchingRule getDefaultOrderingMatchingRule() 677 { 678 return CaseIgnoreStringMatchingRule.getInstance(); 679 } 680 681 682 683 /** 684 * Attempts to select the appropriate matching rule to use for substring 685 * matching against the specified attribute. If an appropriate matching rule 686 * cannot be determined, then the default substring matching rule will be 687 * selected. 688 * 689 * @param attrName The name of the attribute to examine in the provided 690 * schema. 691 * @param schema The schema to examine to make the appropriate 692 * determination. If this is {@code null}, then the default 693 * substring matching rule will be selected. 694 * 695 * @return The selected matching rule. 696 */ 697 public static MatchingRule selectSubstringMatchingRule(final String attrName, 698 final Schema schema) 699 { 700 return selectSubstringMatchingRule(attrName, null, schema); 701 } 702 703 704 705 /** 706 * Attempts to select the appropriate matching rule to use for substring 707 * matching against the specified attribute. If an appropriate matching rule 708 * cannot be determined, then the default substring matching rule will be 709 * selected. 710 * 711 * @param attrName The name of the attribute to examine in the provided 712 * schema. It may be {@code null} if the matching rule 713 * should be selected using the matching rule ID. 714 * @param ruleID The OID of the desired matching rule. It may be 715 * {@code null} if the matching rule should be selected only 716 * using the attribute name. If a rule ID is provided, then 717 * it will be the only criteria used to select the matching 718 * rule. 719 * @param schema The schema to examine to make the appropriate 720 * determination. If this is {@code null} and no rule ID 721 * was provided, then the default substring matching rule 722 * will be selected. 723 * 724 * @return The selected matching rule. 725 */ 726 public static MatchingRule selectSubstringMatchingRule(final String attrName, 727 final String ruleID, 728 final Schema schema) 729 { 730 if (ruleID != null) 731 { 732 return selectSubstringMatchingRule(ruleID); 733 } 734 735 if ((attrName == null) || (schema == null)) 736 { 737 return getDefaultSubstringMatchingRule(); 738 } 739 740 final AttributeTypeDefinition attrType = schema.getAttributeType(attrName); 741 if (attrType == null) 742 { 743 return getDefaultSubstringMatchingRule(); 744 } 745 746 final String mrName = attrType.getSubstringMatchingRule(schema); 747 if (mrName != null) 748 { 749 return selectSubstringMatchingRule(mrName); 750 } 751 752 final String syntaxOID = attrType.getBaseSyntaxOID(schema); 753 if (syntaxOID != null) 754 { 755 return selectMatchingRuleForSyntax(syntaxOID); 756 } 757 758 return getDefaultSubstringMatchingRule(); 759 } 760 761 762 763 /** 764 * Attempts to select the appropriate matching rule to use for substring 765 * matching using the specified matching rule. If an appropriate matching 766 * rule cannot be determined, then the default substring matching rule will be 767 * selected. 768 * 769 * @param ruleID The name or OID of the desired matching rule. 770 * 771 * @return The selected matching rule. 772 */ 773 public static MatchingRule selectSubstringMatchingRule(final String ruleID) 774 { 775 if ((ruleID == null) || (ruleID.length() == 0)) 776 { 777 return getDefaultSubstringMatchingRule(); 778 } 779 780 final String lowerName = toLowerCase(ruleID); 781 if (lowerName.equals( 782 CaseExactStringMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 783 lowerName.equals(CaseExactStringMatchingRule.SUBSTRING_RULE_OID) || 784 lowerName.equals("caseexactia5substringsmatch")) 785 { 786 return CaseExactStringMatchingRule.getInstance(); 787 } 788 else if (lowerName.equals( 789 CaseIgnoreListMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 790 lowerName.equals(CaseIgnoreListMatchingRule.SUBSTRING_RULE_OID)) 791 { 792 return CaseIgnoreListMatchingRule.getInstance(); 793 } 794 else if (lowerName.equals( 795 CaseIgnoreStringMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 796 lowerName.equals( 797 CaseIgnoreStringMatchingRule.SUBSTRING_RULE_OID) || 798 lowerName.equals("caseignoreia5substringsmatch") || 799 lowerName.equals("1.3.6.1.4.1.1466.109.114.3")) 800 { 801 return CaseIgnoreStringMatchingRule.getInstance(); 802 } 803 else if (lowerName.equals( 804 NumericStringMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 805 lowerName.equals(NumericStringMatchingRule.SUBSTRING_RULE_OID)) 806 { 807 return NumericStringMatchingRule.getInstance(); 808 } 809 else if (lowerName.equals( 810 OctetStringMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 811 lowerName.equals(OctetStringMatchingRule.SUBSTRING_RULE_OID)) 812 { 813 return OctetStringMatchingRule.getInstance(); 814 } 815 else if (lowerName.equals( 816 TelephoneNumberMatchingRule.LOWER_SUBSTRING_RULE_NAME) || 817 lowerName.equals(TelephoneNumberMatchingRule.SUBSTRING_RULE_OID)) 818 { 819 return TelephoneNumberMatchingRule.getInstance(); 820 } 821 else 822 { 823 return getDefaultSubstringMatchingRule(); 824 } 825 } 826 827 828 829 /** 830 * Retrieves the default matching rule that will be used for substring 831 * matching if no other matching rule is specified or available. The rule 832 * returned will perform case-ignore string matching. 833 * 834 * @return The default matching rule that will be used for substring matching 835 * if no other matching rule is specified or available. 836 */ 837 public static MatchingRule getDefaultSubstringMatchingRule() 838 { 839 return CaseIgnoreStringMatchingRule.getInstance(); 840 } 841 842 843 844 /** 845 * Attempts to select the appropriate matching rule for use with the syntax 846 * with the specified OID. If an appropriate matching rule cannot be 847 * determined, then the case-ignore string matching rule will be selected. 848 * 849 * @param syntaxOID The OID of the attribute syntax for which to make the 850 * determination. 851 * 852 * @return The selected matching rule. 853 */ 854 public static MatchingRule selectMatchingRuleForSyntax(final String syntaxOID) 855 { 856 if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.7")) 857 { 858 return BooleanMatchingRule.getInstance(); 859 } 860 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.41")) // Postal addr. 861 { 862 return CaseIgnoreListMatchingRule.getInstance(); 863 } 864 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.12") || 865 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.34")) // name&optional UID 866 { 867 return DistinguishedNameMatchingRule.getInstance(); 868 } 869 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.24") || 870 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.53")) // UTC time 871 { 872 return GeneralizedTimeMatchingRule.getInstance(); 873 } 874 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.27")) 875 { 876 return IntegerMatchingRule.getInstance(); 877 } 878 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.36")) 879 { 880 return NumericStringMatchingRule.getInstance(); 881 } 882 else if (syntaxOID.equals("1.3.6.1.4.1.4203.1.1.2") || // auth password 883 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.5") || // binary 884 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.8") || // certificate 885 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.9") || // cert list 886 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.10") || // cert pair 887 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.28") || // JPEG 888 syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.40")) // octet string 889 { 890 return OctetStringMatchingRule.getInstance(); 891 } 892 else if (syntaxOID.equals("1.3.6.1.4.1.1466.115.121.1.50")) 893 { 894 return TelephoneNumberMatchingRule.getInstance(); 895 } 896 else 897 { 898 return CaseIgnoreStringMatchingRule.getInstance(); 899 } 900 } 901}