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