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 import com.unboundid.util.Extensible;
032 import com.unboundid.util.ThreadSafety;
033 import com.unboundid.util.ThreadSafetyLevel;
034
035 import 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)
046 public 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 }