• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html
4 /*
5  *******************************************************************************
6  * Copyright (C) 1996-2015, International Business Machines Corporation and    *
7  * others. All Rights Reserved.                                                *
8  *******************************************************************************
9  */
10 
11 package android.icu.text;
12 
13 import java.text.CharacterIterator;
14 
15 /**
16  * <tt>SearchIterator</tt> is an abstract base class that provides
17  * methods to search for a pattern within a text string. Instances of
18  * <tt>SearchIterator</tt> maintain a current position and scan over the
19  * target text, returning the indices the pattern is matched and the length
20  * of each match.
21  * <p>
22  * <tt>SearchIterator</tt> defines a protocol for text searching.
23  * Subclasses provide concrete implementations of various search algorithms.
24  * For example, <tt>StringSearch</tt> implements language-sensitive pattern
25  * matching based on the comparison rules defined in a
26  * <tt>RuleBasedCollator</tt> object.
27  * <p>
28  * Other options for searching include using a BreakIterator to restrict
29  * the points at which matches are detected.
30  * <p>
31  * <tt>SearchIterator</tt> provides an API that is similar to that of
32  * other text iteration classes such as <tt>BreakIterator</tt>. Using
33  * this class, it is easy to scan through text looking for all occurrences of
34  * a given pattern. The following example uses a <tt>StringSearch</tt>
35  * object to find all instances of "fox" in the target string. Any other
36  * subclass of <tt>SearchIterator</tt> can be used in an identical
37  * manner.
38  * <pre><code>
39  * String target = "The quick brown fox jumped over the lazy fox";
40  * String pattern = "fox";
41  * SearchIterator iter = new StringSearch(pattern, target);
42  * for (int pos = iter.first(); pos != SearchIterator.DONE;
43  *         pos = iter.next()) {
44  *     System.out.println("Found match at " + pos +
45  *             ", length is " + iter.getMatchLength());
46  * }
47  * </code></pre>
48  *
49  * @author Laura Werner, synwee
50  * @see BreakIterator
51  * @see RuleBasedCollator
52  */
53 public abstract class SearchIterator
54 {
55     /**
56      * The BreakIterator to define the boundaries of a logical match.
57      * This value can be a null.
58      * See class documentation for more information.
59      * @see #setBreakIterator(BreakIterator)
60      * @see #getBreakIterator
61      * @see BreakIterator
62      */
63     protected BreakIterator breakIterator;
64 
65     /**
66      * Target text for searching.
67      * @see #setTarget(CharacterIterator)
68      * @see #getTarget
69      */
70     protected CharacterIterator targetText;
71     /**
72      * Length of the most current match in target text.
73      * Value 0 is the default value.
74      * @see #setMatchLength
75      * @see #getMatchLength
76      */
77     protected int matchLength;
78 
79     /**
80      * Java port of ICU4C struct USearch (usrchimp.h)
81      *
82      * Note:
83      *
84      *  ICU4J already exposed some protected members such as
85      * targetText, breakIterator and matchedLength as a part of stable
86      * APIs. In ICU4C, they are exposed through USearch struct,
87      * although USearch struct itself is internal API.
88      *
89      *  This class was created for making ICU4J code parallel to
90      * ICU4C implementation. ICU4J implementation access member
91      * fields like C struct (e.g. search_.isOverlap_) mostly, except
92      * fields already exposed as protected member (e.g. search_.text()).
93      *
94      */
95     final class Search {
96 
text()97         CharacterIterator text() {
98             return SearchIterator.this.targetText;
99         }
100 
setTarget(CharacterIterator text)101         void setTarget(CharacterIterator text) {
102             SearchIterator.this.targetText = text;
103         }
104 
105         /** Flag to indicate if overlapping search is to be done.
106             E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1. */
107         boolean isOverlap_;
108 
109         boolean isCanonicalMatch_;
110 
111         ElementComparisonType elementComparisonType_;
112 
113         BreakIterator internalBreakIter_;
114 
breakIter()115         BreakIterator breakIter() {
116             return SearchIterator.this.breakIterator;
117         }
118 
setBreakIter(BreakIterator breakIter)119         void setBreakIter(BreakIterator breakIter) {
120             SearchIterator.this.breakIterator = breakIter;
121         }
122 
123         int matchedIndex_;
124 
matchedLength()125         int matchedLength() {
126             return SearchIterator.this.matchLength;
127         }
128 
setMatchedLength(int matchedLength)129         void setMatchedLength(int matchedLength) {
130             SearchIterator.this.matchLength = matchedLength;
131         }
132 
133         /** Flag indicates if we are doing a forwards search */
134         boolean isForwardSearching_;
135 
136         /** Flag indicates if we are at the start of a string search.
137             This indicates that we are in forward search and at the start of m_text. */
138         boolean reset_;
139 
140         // Convenient methods for accessing begin/end index of the
141         // target text. These are ICU4J only and are not data fields.
beginIndex()142         int beginIndex() {
143             if (targetText == null) {
144                 return 0;
145             }
146             return targetText.getBeginIndex();
147         }
148 
endIndex()149         int endIndex() {
150             if (targetText == null) {
151                 return 0;
152             }
153             return targetText.getEndIndex();
154         }
155     }
156 
157     Search search_ = new Search();
158 
159     // public data members -------------------------------------------------
160 
161     /**
162      * DONE is returned by previous() and next() after all valid matches have
163      * been returned, and by first() and last() if there are no matches at all.
164      * @see #previous
165      * @see #next
166      */
167     public static final int DONE = -1;
168 
169     // public methods -----------------------------------------------------
170 
171     // public setters -----------------------------------------------------
172 
173     /**
174      * <p>
175      * Sets the position in the target text at which the next search will start.
176      * This method clears any previous match.
177      * </p>
178      * @param position position from which to start the next search
179      * @exception IndexOutOfBoundsException thrown if argument position is out
180      *            of the target text range.
181      * @see #getIndex
182      */
setIndex(int position)183     public void setIndex(int position) {
184         if (position < search_.beginIndex()
185             || position > search_.endIndex()) {
186             throw new IndexOutOfBoundsException(
187                 "setIndex(int) expected position to be between " +
188                 search_.beginIndex() + " and " + search_.endIndex());
189         }
190         search_.reset_ = false;
191         search_.setMatchedLength(0);
192         search_.matchedIndex_ = DONE;
193     }
194 
195     /**
196      * Determines whether overlapping matches are returned. See the class
197      * documentation for more information about overlapping matches.
198      * <p>
199      * The default setting of this property is false
200      *
201      * @param allowOverlap flag indicator if overlapping matches are allowed
202      * @see #isOverlapping
203      */
setOverlapping(boolean allowOverlap)204     public void setOverlapping(boolean allowOverlap) {
205         search_.isOverlap_ = allowOverlap;
206     }
207 
208     /**
209      * Set the BreakIterator that will be used to restrict the points
210      * at which matches are detected.
211      *
212      * @param breakiter A BreakIterator that will be used to restrict the
213      *                points at which matches are detected. If a match is
214      *                found, but the match's start or end index is not a
215      *                boundary as determined by the {@link BreakIterator},
216      *                the match will be rejected and another will be searched
217      *                for. If this parameter is <tt>null</tt>, no break
218      *                detection is attempted.
219      * @see BreakIterator
220      */
setBreakIterator(BreakIterator breakiter)221     public void setBreakIterator(BreakIterator breakiter) {
222         search_.setBreakIter(breakiter);
223         if (search_.breakIter() != null) {
224             // Create a clone of CharacterItearator, so it won't
225             // affect the position currently held by search_.text()
226             if (search_.text() != null) {
227                 search_.breakIter().setText((CharacterIterator)search_.text().clone());
228             }
229         }
230     }
231 
232     /**
233      * Set the target text to be searched. Text iteration will then begin at
234      * the start of the text string. This method is useful if you want to
235      * reuse an iterator to search within a different body of text.
236      *
237      * @param text new text iterator to look for match,
238      * @exception IllegalArgumentException thrown when text is null or has
239      *               0 length
240      * @see #getTarget
241      */
setTarget(CharacterIterator text)242     public void setTarget(CharacterIterator text)
243     {
244         if (text == null || text.getEndIndex() == text.getIndex()) {
245             throw new IllegalArgumentException("Illegal null or empty text");
246         }
247 
248         text.setIndex(text.getBeginIndex());
249         search_.setTarget(text);
250         search_.matchedIndex_ = DONE;
251         search_.setMatchedLength(0);
252         search_.reset_ = true;
253         search_.isForwardSearching_ = true;
254         if (search_.breakIter() != null) {
255             // Create a clone of CharacterItearator, so it won't
256             // affect the position currently held by search_.text()
257             search_.breakIter().setText((CharacterIterator)text.clone());
258         }
259         if (search_.internalBreakIter_ != null) {
260             search_.internalBreakIter_.setText((CharacterIterator)text.clone());
261         }
262     }
263 
264     //TODO: We may add APIs below to match ICU4C APIs
265     // setCanonicalMatch
266 
267     // public getters ----------------------------------------------------
268 
269     /**
270     * Returns the index to the match in the text string that was searched.
271     * This call returns a valid result only after a successful call to
272     * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
273     * Just after construction, or after a searching method returns
274     * {@link #DONE}, this method will return {@link #DONE}.
275     * <p>
276     * Use {@link #getMatchLength} to get the matched string length.
277     *
278     * @return index of a substring within the text string that is being
279     *         searched.
280     * @see #first
281     * @see #next
282     * @see #previous
283     * @see #last
284     */
getMatchStart()285     public int getMatchStart() {
286         return search_.matchedIndex_;
287     }
288 
289     /**
290      * Return the current index in the text being searched.
291      * If the iteration has gone past the end of the text
292      * (or past the beginning for a backwards search), {@link #DONE}
293      * is returned.
294      *
295      * @return current index in the text being searched.
296      */
getIndex()297     public abstract int getIndex();
298 
299     /**
300      * Returns the length of text in the string which matches the search
301      * pattern. This call returns a valid result only after a successful call
302      * to {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
303      * Just after construction, or after a searching method returns
304      * {@link #DONE}, this method will return 0.
305      *
306      * @return The length of the match in the target text, or 0 if there
307      *         is no match currently.
308      * @see #first
309      * @see #next
310      * @see #previous
311      * @see #last
312      */
getMatchLength()313     public int getMatchLength() {
314         return search_.matchedLength();
315     }
316 
317     /**
318      * Returns the BreakIterator that is used to restrict the indexes at which
319      * matches are detected. This will be the same object that was passed to
320      * the constructor or to {@link #setBreakIterator}.
321      * If the {@link BreakIterator} has not been set, <tt>null</tt> will be returned.
322      * See {@link #setBreakIterator} for more information.
323      *
324      * @return the BreakIterator set to restrict logic matches
325      * @see #setBreakIterator
326      * @see BreakIterator
327      */
getBreakIterator()328     public BreakIterator getBreakIterator() {
329         return search_.breakIter();
330     }
331 
332     /**
333      * Return the string text to be searched.
334      * @return text string to be searched.
335      */
getTarget()336     public CharacterIterator getTarget() {
337         return search_.text();
338     }
339 
340     /**
341      * Returns the text that was matched by the most recent call to
342      * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
343      * If the iterator is not pointing at a valid match (e.g. just after
344      * construction or after {@link #DONE} has been returned,
345      * returns an empty string.
346      *
347      * @return  the substring in the target test of the most recent match,
348      *          or null if there is no match currently.
349      * @see #first
350      * @see #next
351      * @see #previous
352      * @see #last
353      */
getMatchedText()354     public String getMatchedText() {
355         if (search_.matchedLength() > 0) {
356             int limit = search_.matchedIndex_ + search_.matchedLength();
357             StringBuilder result = new StringBuilder(search_.matchedLength());
358             CharacterIterator it = search_.text();
359             it.setIndex(search_.matchedIndex_);
360             while (it.getIndex() < limit) {
361                 result.append(it.current());
362                 it.next();
363             }
364             it.setIndex(search_.matchedIndex_);
365             return result.toString();
366         }
367         return null;
368     }
369 
370     // miscellaneous public methods -----------------------------------------
371 
372     /**
373      * Returns the index of the next point at which the text matches the
374      * search pattern, starting from the current position
375      * The iterator is adjusted so that its current index (as returned by
376      * {@link #getIndex}) is the match position if one was found.
377      * If a match is not found, {@link #DONE} will be returned and
378      * the iterator will be adjusted to a position after the end of the text
379      * string.
380      *
381      * @return The index of the next match after the current position,
382      *          or {@link #DONE} if there are no more matches.
383      * @see #getIndex
384      */
next()385     public int next() {
386         int index = getIndex(); // offset = getOffset() in ICU4C
387         int matchindex = search_.matchedIndex_;
388         int matchlength = search_.matchedLength();
389         search_.reset_ = false;
390         if (search_.isForwardSearching_) {
391             int endIdx = search_.endIndex();
392             if (index == endIdx || matchindex == endIdx ||
393                     (matchindex != DONE &&
394                     matchindex + matchlength >= endIdx)) {
395                 setMatchNotFound();
396                 return DONE;
397             }
398         } else {
399             // switching direction.
400             // if matchedIndex == DONE, it means that either a
401             // setIndex (setOffset in C) has been called or that previous ran off the text
402             // string. the iterator would have been set to offset 0 if a
403             // match is not found.
404             search_.isForwardSearching_ = true;
405             if (search_.matchedIndex_ != DONE) {
406                 // there's no need to set the collation element iterator
407                 // the next call to next will set the offset.
408                 return matchindex;
409             }
410         }
411 
412         if (matchlength > 0) {
413             // if matchlength is 0 we are at the start of the iteration
414             if (search_.isOverlap_) {
415                 index++;
416             } else {
417                 index += matchlength;
418             }
419         }
420 
421         return handleNext(index);
422     }
423 
424     /**
425      * Returns the index of the previous point at which the string text
426      * matches the search pattern, starting at the current position.
427      * The iterator is adjusted so that its current index (as returned by
428      * {@link #getIndex}) is the match position if one was found.
429      * If a match is not found, {@link #DONE} will be returned and
430      * the iterator will be adjusted to the index {@link #DONE}.
431      *
432      * @return The index of the previous match before the current position,
433      *          or {@link #DONE} if there are no more matches.
434      * @see #getIndex
435      */
previous()436     public int previous() {
437         int index;  // offset in ICU4C
438         if (search_.reset_) {
439             index = search_.endIndex();   // m_search_->textLength in ICU4C
440             search_.isForwardSearching_ = false;
441             search_.reset_ = false;
442             setIndex(index);
443         } else {
444             index = getIndex();
445         }
446 
447         int matchindex = search_.matchedIndex_;
448         if (search_.isForwardSearching_) {
449             // switching direction.
450             // if matchedIndex == DONE, it means that either a
451             // setIndex (setOffset in C) has been called or that next ran off the text
452             // string. the iterator would have been set to offset textLength if
453             // a match is not found.
454             search_.isForwardSearching_ = false;
455             if (matchindex != DONE) {
456                 return matchindex;
457             }
458         } else {
459             int startIdx = search_.beginIndex();
460             if (index == startIdx || matchindex == startIdx) {
461                 // not enough characters to match
462                 setMatchNotFound();
463                 return DONE;
464             }
465         }
466 
467         if (matchindex != DONE) {
468             if (search_.isOverlap_) {
469                 matchindex += search_.matchedLength() - 2;
470             }
471 
472             return handlePrevious(matchindex);
473         }
474 
475         return handlePrevious(index);
476     }
477 
478     /**
479      * Return true if the overlapping property has been set.
480      * See {@link #setOverlapping(boolean)} for more information.
481      *
482      * @see #setOverlapping
483      * @return true if the overlapping property has been set, false otherwise
484      */
isOverlapping()485     public boolean isOverlapping() {
486         return search_.isOverlap_;
487     }
488 
489     //TODO: We may add APIs below to match ICU4C APIs
490     // isCanonicalMatch
491 
492     /**
493     * Resets the iteration.
494     * Search will begin at the start of the text string if a forward
495     * iteration is initiated before a backwards iteration. Otherwise if a
496     * backwards iteration is initiated before a forwards iteration, the
497     * search will begin at the end of the text string.
498     */
reset()499     public void reset() {
500         setMatchNotFound();
501         setIndex(search_.beginIndex());
502         search_.isOverlap_ = false;
503         search_.isCanonicalMatch_ = false;
504         search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON;
505         search_.isForwardSearching_ = true;
506         search_.reset_ = true;
507     }
508 
509     /**
510      * Returns the first index at which the string text matches the search
511      * pattern. The iterator is adjusted so that its current index (as
512      * returned by {@link #getIndex()}) is the match position if one
513      *
514      * was found.
515      * If a match is not found, {@link #DONE} will be returned and
516      * the iterator will be adjusted to the index {@link #DONE}.
517      * @return The character index of the first match, or
518      *         {@link #DONE} if there are no matches.
519      *
520      * @see #getIndex
521      */
first()522     public final int first() {
523         int startIdx = search_.beginIndex();
524         setIndex(startIdx);
525         return handleNext(startIdx);
526     }
527 
528     /**
529      * Returns the first index equal or greater than <tt>position</tt> at which the
530      * string text matches the search pattern. The iterator is adjusted so
531      * that its current index (as returned by {@link #getIndex()}) is the
532      * match position if one was found.
533      * If a match is not found, {@link #DONE} will be returned and the
534      * iterator will be adjusted to the index {@link #DONE}.
535      *
536      * @param  position where search if to start from.
537      * @return The character index of the first match following
538      *         <tt>position</tt>, or {@link #DONE} if there are no matches.
539      * @throws IndexOutOfBoundsException    If position is less than or greater
540      *      than the text range for searching.
541      * @see #getIndex
542      */
following(int position)543     public final int following(int position) {
544         setIndex(position);
545         return handleNext(position);
546     }
547 
548     /**
549      * Returns the last index in the target text at which it matches the
550      * search pattern. The iterator is adjusted so that its current index
551      * (as returned by {@link #getIndex}) is the match position if one was
552      * found.
553      * If a match is not found, {@link #DONE} will be returned and
554      * the iterator will be adjusted to the index {@link #DONE}.
555      *
556      * @return The index of the first match, or {@link #DONE} if
557      *         there are no matches.
558      * @see #getIndex
559      */
last()560     public final int last() {
561         int endIdx = search_.endIndex();
562         setIndex(endIdx);
563         return handlePrevious(endIdx);
564     }
565 
566     /**
567      * Returns the first index less than <tt>position</tt> at which the string
568      * text matches the search pattern. The iterator is adjusted so that its
569      * current index (as returned by {@link #getIndex}) is the match
570      * position if one was found. If a match is not found,
571      * {@link #DONE} will be returned and the iterator will be
572      * adjusted to the index {@link #DONE}
573      * <p>
574      * When the overlapping option ({@link #isOverlapping}) is off, the last index of the
575      * result match is always less than <tt>position</tt>.
576      * When the overlapping option is on, the result match may span across
577      * <tt>position</tt>.
578      *
579      * @param  position where search is to start from.
580      * @return The character index of the first match preceding
581      *         <tt>position</tt>, or {@link #DONE} if there are
582      *         no matches.
583      * @throws IndexOutOfBoundsException If position is less than or greater than
584      *                                   the text range for searching
585      * @see #getIndex
586      */
preceding(int position)587     public final int preceding(int position) {
588         setIndex(position);
589         return handlePrevious(position);
590     }
591 
592     // protected constructor ----------------------------------------------
593 
594     /**
595      * Protected constructor for use by subclasses.
596      * Initializes the iterator with the argument target text for searching
597      * and sets the BreakIterator.
598      * See class documentation for more details on the use of the target text
599      * and {@link BreakIterator}.
600      *
601      * @param target The target text to be searched.
602      * @param breaker A {@link BreakIterator} that is used to determine the
603      *                boundaries of a logical match. This argument can be null.
604      * @exception IllegalArgumentException thrown when argument target is null,
605      *            or of length 0
606      * @see BreakIterator
607      */
SearchIterator(CharacterIterator target, BreakIterator breaker)608     protected SearchIterator(CharacterIterator target, BreakIterator breaker)
609     {
610         if (target == null
611             || (target.getEndIndex() - target.getBeginIndex()) == 0) {
612                 throw new IllegalArgumentException(
613                                    "Illegal argument target. " +
614                                    " Argument can not be null or of length 0");
615         }
616 
617         search_.setTarget(target);
618         search_.setBreakIter(breaker);
619         if (search_.breakIter() != null) {
620             search_.breakIter().setText((CharacterIterator)target.clone());
621         }
622         search_.isOverlap_ = false;
623         search_.isCanonicalMatch_ = false;
624         search_.elementComparisonType_ = ElementComparisonType.STANDARD_ELEMENT_COMPARISON;
625         search_.isForwardSearching_ = true;
626         search_.reset_ = true;
627         search_.matchedIndex_ = DONE;
628         search_.setMatchedLength(0);
629     }
630 
631     // protected methods --------------------------------------------------
632 
633 
634     /**
635      * Sets the length of the most recent match in the target text.
636      * Subclasses' handleNext() and handlePrevious() methods should call this
637      * after they find a match in the target text.
638      *
639      * @param length new length to set
640      * @see #handleNext
641      * @see #handlePrevious
642      */
setMatchLength(int length)643     protected void setMatchLength(int length)
644     {
645         search_.setMatchedLength(length);
646     }
647 
648     /**
649      * Abstract method which subclasses override to provide the mechanism
650      * for finding the next match in the target text. This allows different
651      * subclasses to provide different search algorithms.
652      * <p>
653      * If a match is found, the implementation should return the index at
654      * which the match starts and should call
655      * {@link #setMatchLength} with the number of characters
656      * in the target text that make up the match. If no match is found, the
657      * method should return {@link #DONE}.
658      *
659      * @param start The index in the target text at which the search
660      *              should start.
661      * @return index at which the match starts, else if match is not found
662      *         {@link #DONE} is returned
663      * @see #setMatchLength
664      */
handleNext(int start)665     protected abstract int handleNext(int start);
666 
667     /**
668      * Abstract method which subclasses override to provide the mechanism for
669      * finding the previous match in the target text. This allows different
670      * subclasses to provide different search algorithms.
671      * <p>
672      * If a match is found, the implementation should return the index at
673      * which the match starts and should call
674      * {@link #setMatchLength} with the number of characters
675      * in the target text that make up the match. If no match is found, the
676      * method should return {@link #DONE}.
677      *
678      * @param startAt   The index in the target text at which the search
679      *                  should start.
680      * @return index at which the match starts, else if match is not found
681      *         {@link #DONE} is returned
682      * @see #setMatchLength
683      */
handlePrevious(int startAt)684     protected abstract int handlePrevious(int startAt);
685 
686     /**
687      * @deprecated This API is ICU internal only.
688      * @hide original deprecated declaration
689      * @hide draft / provisional / internal are hidden on Android
690      */
691     @Deprecated
692     //TODO: This protected method is @stable 2.0 in ICU4C
setMatchNotFound()693     protected void setMatchNotFound() {
694         search_.matchedIndex_ = DONE;
695         search_.setMatchedLength(0);
696     }
697 
698     /**
699      * Option to control how collation elements are compared.
700      * The default value will be {@link #STANDARD_ELEMENT_COMPARISON}.
701      * <p>
702      * PATTERN_BASE_WEIGHT_IS_WILDCARD supports "asymmetric search" as described in
703      * <a href="http://www.unicode.org/reports/tr10/#Asymmetric_Search">
704      * UTS #10 Unicode Collation Algorithm</a>, while ANY_BASE_WEIGHT_IS_WILDCARD
705      * supports a related option in which "unmarked" characters in either the
706      * pattern or the searched text are treated as wildcards that match marked or
707      * unmarked versions of the same character.
708      *
709      * @see #setElementComparisonType(ElementComparisonType)
710      * @see #getElementComparisonType()
711      */
712     public enum ElementComparisonType {
713         /**
714          * Standard collation element comparison at the specified collator strength.
715          */
716         STANDARD_ELEMENT_COMPARISON,
717         /**
718          * Collation element comparison is modified to effectively provide behavior
719          * between the specified strength and strength - 1.
720          * <p>
721          * Collation elements in the pattern that have the base weight for the specified
722          * strength are treated as "wildcards" that match an element with any other
723          * weight at that collation level in the searched text. For example, with a
724          * secondary-strength English collator, a plain 'e' in the pattern will match
725          * a plain e or an e with any diacritic in the searched text, but an e with
726          * diacritic in the pattern will only match an e with the same diacritic in
727          * the searched text.
728          */
729         PATTERN_BASE_WEIGHT_IS_WILDCARD,
730 
731         /**
732          * Collation element comparison is modified to effectively provide behavior
733          * between the specified strength and strength - 1.
734          * <p>
735          * Collation elements in either the pattern or the searched text that have the
736          * base weight for the specified strength are treated as "wildcards" that match
737          * an element with any other weight at that collation level. For example, with
738          * a secondary-strength English collator, a plain 'e' in the pattern will match
739          * a plain e or an e with any diacritic in the searched text, but an e with
740          * diacritic in the pattern will only match an e with the same diacritic or a
741          * plain e in the searched text.
742          */
743         ANY_BASE_WEIGHT_IS_WILDCARD
744     }
745 
746     /**
747      * Sets the collation element comparison type.
748      * <p>
749      * The default comparison type is {@link ElementComparisonType#STANDARD_ELEMENT_COMPARISON}.
750      *
751      * @see ElementComparisonType
752      * @see #getElementComparisonType()
753      */
setElementComparisonType(ElementComparisonType type)754     public void setElementComparisonType(ElementComparisonType type) {
755         search_.elementComparisonType_ = type;
756     }
757 
758     /**
759      * Returns the collation element comparison type.
760      *
761      * @see ElementComparisonType
762      * @see #setElementComparisonType(ElementComparisonType)
763      */
getElementComparisonType()764     public ElementComparisonType getElementComparisonType() {
765         return search_.elementComparisonType_;
766     }
767 }
768