1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2017 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4package android.icu.text;
5
6import java.util.Locale;
7
8import android.icu.impl.CaseMapImpl;
9import android.icu.impl.UCaseProps;
10import android.icu.lang.UCharacter;
11import android.icu.util.ULocale;
12
13/**
14 * Low-level case mapping options and methods. Immutable.
15 * "Setters" return instances with the union of the current and new options set.
16 *
17 * This class is not intended for public subclassing.
18 *
19 * @hide Only a subset of ICU is exposed in Android
20 * @hide draft / provisional / internal are hidden on Android
21 */
22public abstract class CaseMap {
23    /**
24     * @deprecated This API is ICU internal only.
25     * @hide draft / provisional / internal are hidden on Android
26     */
27    @Deprecated
28    protected int internalOptions;
29
30    private CaseMap(int opt) { internalOptions = opt; }
31
32    private static int getCaseLocale(Locale locale) {
33        if (locale == null) {
34            locale = Locale.getDefault();
35        }
36        return UCaseProps.getCaseLocale(locale);
37    }
38
39    /**
40     * @return Lowercasing object with default options.
41     * @hide draft / provisional / internal are hidden on Android
42     */
43    public static Lower toLower() { return Lower.DEFAULT; }
44    /**
45     * @return Uppercasing object with default options.
46     * @hide draft / provisional / internal are hidden on Android
47     */
48    public static Upper toUpper() { return Upper.DEFAULT; }
49    /**
50     * @return Titlecasing object with default options.
51     * @hide draft / provisional / internal are hidden on Android
52     */
53    public static Title toTitle() { return Title.DEFAULT; }
54    /**
55     * @return Case folding object with default options.
56     * @hide draft / provisional / internal are hidden on Android
57     */
58    public static Fold fold() { return Fold.DEFAULT; }
59
60    /**
61     * Returns an instance that behaves like this one but
62     * omits unchanged text when case-mapping with {@link Edits}.
63     *
64     * @return an options object with this option.
65     * @hide draft / provisional / internal are hidden on Android
66     */
67    public abstract CaseMap omitUnchangedText();
68
69    /**
70     * Lowercasing options and methods. Immutable.
71     *
72     * @see #toLower()
73     * @hide draft / provisional / internal are hidden on Android
74     */
75    public static final class Lower extends CaseMap {
76        private static final Lower DEFAULT = new Lower(0);
77        private static final Lower OMIT_UNCHANGED = new Lower(CaseMapImpl.OMIT_UNCHANGED_TEXT);
78        private Lower(int opt) { super(opt); }
79
80        /**
81         * {@inheritDoc}
82         * @hide draft / provisional / internal are hidden on Android
83         */
84        @Override
85        public Lower omitUnchangedText() {
86            return OMIT_UNCHANGED;
87        }
88
89        /**
90         * Lowercases a string.
91         * Casing is locale-dependent and context-sensitive.
92         * The result may be longer or shorter than the original.
93         *
94         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
95         *                  (See {@link ULocale#toLocale}.)
96         * @param src       The original string.
97         * @return the result string.
98         *
99         * @see UCharacter#toLowerCase(Locale, String)
100         * @hide draft / provisional / internal are hidden on Android
101         */
102        public String apply(Locale locale, CharSequence src) {
103            return CaseMapImpl.toLower(getCaseLocale(locale), internalOptions, src);
104        }
105
106        /**
107         * Lowercases a string and optionally records edits (see {@link #omitUnchangedText}).
108         * Casing is locale-dependent and context-sensitive.
109         * The result may be longer or shorter than the original.
110         *
111         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
112         *                  (See {@link ULocale#toLocale}.)
113         * @param src       The original string.
114         * @param dest      A buffer for the result string. Must not be null.
115         * @param edits     Records edits for index mapping, working with styled text,
116         *                  and getting only changes (if any).
117         *                  This function calls edits.reset() first. edits can be null.
118         * @return dest with the result string (or only changes) appended.
119         *
120         * @see UCharacter#toLowerCase(Locale, String)
121         * @hide draft / provisional / internal are hidden on Android
122         */
123         public <A extends Appendable> A apply(
124                 Locale locale, CharSequence src, A dest, Edits edits) {
125             return CaseMapImpl.toLower(getCaseLocale(locale), internalOptions, src, dest, edits);
126         }
127    }
128
129    /**
130     * Uppercasing options and methods. Immutable.
131     *
132     * @see #toUpper()
133     * @hide draft / provisional / internal are hidden on Android
134     */
135    public static final class Upper extends CaseMap {
136        private static final Upper DEFAULT = new Upper(0);
137        private static final Upper OMIT_UNCHANGED = new Upper(CaseMapImpl.OMIT_UNCHANGED_TEXT);
138        private Upper(int opt) { super(opt); }
139
140        /**
141         * {@inheritDoc}
142         * @hide draft / provisional / internal are hidden on Android
143         */
144        @Override
145        public Upper omitUnchangedText() {
146            return OMIT_UNCHANGED;
147        }
148
149        /**
150         * Uppercases a string.
151         * Casing is locale-dependent and context-sensitive.
152         * The result may be longer or shorter than the original.
153         *
154         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
155         *                  (See {@link ULocale#toLocale}.)
156         * @param src       The original string.
157         * @return the result string.
158         *
159         * @see UCharacter#toUpperCase(Locale, String)
160         * @hide draft / provisional / internal are hidden on Android
161         */
162        public String apply(Locale locale, CharSequence src) {
163            return CaseMapImpl.toUpper(getCaseLocale(locale), internalOptions, src);
164        }
165
166        /**
167         * Uppercases a string and optionally records edits (see {@link #omitUnchangedText}).
168         * Casing is locale-dependent and context-sensitive.
169         * The result may be longer or shorter than the original.
170         *
171         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
172         *                  (See {@link ULocale#toLocale}.)
173         * @param src       The original string.
174         * @param dest      A buffer for the result string. Must not be null.
175         * @param edits     Records edits for index mapping, working with styled text,
176         *                  and getting only changes (if any).
177         *                  This function calls edits.reset() first. edits can be null.
178         * @return dest with the result string (or only changes) appended.
179         *
180         * @see UCharacter#toUpperCase(Locale, String)
181         * @hide draft / provisional / internal are hidden on Android
182         */
183         public <A extends Appendable> A apply(
184                 Locale locale, CharSequence src, A dest, Edits edits) {
185             return CaseMapImpl.toUpper(getCaseLocale(locale), internalOptions, src, dest, edits);
186         }
187    }
188
189    /**
190     * Titlecasing options and methods. Immutable.
191     *
192     * @see #toTitle()
193     * @hide draft / provisional / internal are hidden on Android
194     */
195    public static final class Title extends CaseMap {
196        private static final Title DEFAULT = new Title(0);
197        private static final Title OMIT_UNCHANGED = new Title(CaseMapImpl.OMIT_UNCHANGED_TEXT);
198        private Title(int opt) { super(opt); }
199
200        /**
201         * Returns an instance that behaves like this one but
202         * titlecases the string as a whole rather than each word.
203         * (Titlecases only the character at index 0, possibly adjusted.)
204         *
205         * <p>It is an error to specify multiple titlecasing iterator options together,
206         * including both an option and an explicit BreakIterator.
207         *
208         * @return an options object with this option.
209         * @see #adjustToCased()
210         * @hide draft / provisional / internal are hidden on Android
211         */
212        public Title wholeString() {
213            return new Title(CaseMapImpl.addTitleIteratorOption(
214                    internalOptions, CaseMapImpl.TITLECASE_WHOLE_STRING));
215        }
216
217        /**
218         * Returns an instance that behaves like this one but
219         * titlecases sentences rather than words.
220         * (Titlecases only the first character of each sentence, possibly adjusted.)
221         *
222         * <p>It is an error to specify multiple titlecasing iterator options together,
223         * including both an option and an explicit BreakIterator.
224         *
225         * @return an options object with this option.
226         * @see #adjustToCased()
227         * @hide draft / provisional / internal are hidden on Android
228         */
229        public Title sentences() {
230            return new Title(CaseMapImpl.addTitleIteratorOption(
231                    internalOptions, CaseMapImpl.TITLECASE_SENTENCES));
232        }
233
234        /**
235         * {@inheritDoc}
236         * @hide draft / provisional / internal are hidden on Android
237         */
238        @Override
239        public Title omitUnchangedText() {
240            if (internalOptions == 0 || internalOptions == CaseMapImpl.OMIT_UNCHANGED_TEXT) {
241                return OMIT_UNCHANGED;
242            }
243            return new Title(internalOptions | CaseMapImpl.OMIT_UNCHANGED_TEXT);
244        }
245
246        /**
247         * Returns an instance that behaves like this one but
248         * does not lowercase non-initial parts of words when titlecasing.
249         *
250         * <p>By default, titlecasing will titlecase the character at each
251         * (possibly adjusted) BreakIterator index and
252         * lowercase all other characters up to the next iterator index.
253         * With this option, the other characters will not be modified.
254         *
255         * @return an options object with this option.
256         * @see UCharacter#TITLECASE_NO_LOWERCASE
257         * @see #adjustToCased()
258         * @hide draft / provisional / internal are hidden on Android
259         */
260        public Title noLowercase() {
261            return new Title(internalOptions | UCharacter.TITLECASE_NO_LOWERCASE);
262        }
263
264        /**
265         * Returns an instance that behaves like this one but
266         * does not adjust the titlecasing BreakIterator indexes;
267         * titlecases exactly the characters at breaks from the iterator.
268         *
269         * <p>By default, titlecasing will take each break iterator index,
270         * adjust it to the next relevant character (see {@link #adjustToCased()}),
271         * and titlecase that one.
272         *
273         * <p>Other characters are lowercased.
274         *
275         * @return an options object with this option.
276         * @see UCharacter#TITLECASE_NO_BREAK_ADJUSTMENT
277         * @hide draft / provisional / internal are hidden on Android
278         */
279        public Title noBreakAdjustment() {
280            return new Title(CaseMapImpl.addTitleAdjustmentOption(
281                    internalOptions, UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT));
282        }
283
284        /**
285         * Returns an instance that behaves like this one but
286         * adjusts each titlecasing BreakIterator index to the next cased character.
287         * (See the Unicode Standard, chapter 3, Default Case Conversion, R3 toTitlecase(X).)
288         *
289         * <p>This used to be the default index adjustment in ICU.
290         * Since ICU 60, the default index adjustment is to the next character that is
291         * a letter, number, symbol, or private use code point.
292         * (Uncased modifier letters are skipped.)
293         * The difference in behavior is small for word titlecasing,
294         * but the new adjustment is much better for whole-string and sentence titlecasing:
295         * It yields "49ers" and "«丰(abc)»" instead of "49Ers" and "«丰(Abc)»".
296         *
297         * <p>It is an error to specify multiple titlecasing adjustment options together.
298         *
299         * @return an options object with this option.
300         * @see #noBreakAdjustment()
301         * @hide draft / provisional / internal are hidden on Android
302         */
303        public Title adjustToCased() {
304            return new Title(CaseMapImpl.addTitleAdjustmentOption(
305                    internalOptions, CaseMapImpl.TITLECASE_ADJUST_TO_CASED));
306        }
307
308        /**
309         * Titlecases a string.
310         * Casing is locale-dependent and context-sensitive.
311         * The result may be longer or shorter than the original.
312         *
313         * <p>Titlecasing uses a break iterator to find the first characters of words
314         * that are to be titlecased. It titlecases those characters and lowercases
315         * all others. (This can be modified with options bits.)
316         *
317         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
318         *                  (See {@link ULocale#toLocale}.)
319         * @param iter      A break iterator to find the first characters of words that are to be titlecased.
320         *                  It is set to the source string (setText())
321         *                  and used one or more times for iteration (first() and next()).
322         *                  If null, then a word break iterator for the locale is used
323         *                  (or something equivalent).
324         * @param src       The original string.
325         * @return the result string.
326         *
327         * @see UCharacter#toUpperCase(Locale, String)
328         * @hide draft / provisional / internal are hidden on Android
329         */
330        public String apply(Locale locale, BreakIterator iter, CharSequence src) {
331            if (iter == null && locale == null) {
332                locale = Locale.getDefault();
333            }
334            iter = CaseMapImpl.getTitleBreakIterator(locale, internalOptions, iter);
335            iter.setText(src);
336            return CaseMapImpl.toTitle(getCaseLocale(locale), internalOptions, iter, src);
337        }
338
339        /**
340         * Titlecases a string and optionally records edits (see {@link #omitUnchangedText}).
341         * Casing is locale-dependent and context-sensitive.
342         * The result may be longer or shorter than the original.
343         *
344         * <p>Titlecasing uses a break iterator to find the first characters of words
345         * that are to be titlecased. It titlecases those characters and lowercases
346         * all others. (This can be modified with options bits.)
347         *
348         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
349         *                  (See {@link ULocale#toLocale}.)
350         * @param iter      A break iterator to find the first characters of words that are to be titlecased.
351         *                  It is set to the source string (setText())
352         *                  and used one or more times for iteration (first() and next()).
353         *                  If null, then a word break iterator for the locale is used
354         *                  (or something equivalent).
355         * @param src       The original string.
356         * @param dest      A buffer for the result string. Must not be null.
357         * @param edits     Records edits for index mapping, working with styled text,
358         *                  and getting only changes (if any).
359         *                  This function calls edits.reset() first. edits can be null.
360         * @return dest with the result string (or only changes) appended.
361         *
362         * @see UCharacter#toTitleCase(Locale, String, BreakIterator, int)
363         * @hide draft / provisional / internal are hidden on Android
364         */
365         public <A extends Appendable> A apply(
366                 Locale locale, BreakIterator iter, CharSequence src, A dest, Edits edits) {
367             if (iter == null && locale == null) {
368                 locale = Locale.getDefault();
369             }
370             iter = CaseMapImpl.getTitleBreakIterator(locale, internalOptions, iter);
371             iter.setText(src);
372             return CaseMapImpl.toTitle(
373                     getCaseLocale(locale), internalOptions, iter, src, dest, edits);
374         }
375    }
376
377    /**
378     * Case folding options and methods. Immutable.
379     *
380     * @see #fold()
381     * @hide draft / provisional / internal are hidden on Android
382     */
383    public static final class Fold extends CaseMap {
384        private static final Fold DEFAULT = new Fold(0);
385        private static final Fold TURKIC = new Fold(UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I);
386        private static final Fold OMIT_UNCHANGED = new Fold(CaseMapImpl.OMIT_UNCHANGED_TEXT);
387        private static final Fold TURKIC_OMIT_UNCHANGED = new Fold(
388                UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I | CaseMapImpl.OMIT_UNCHANGED_TEXT);
389        private Fold(int opt) { super(opt); }
390
391        /**
392         * {@inheritDoc}
393         * @hide draft / provisional / internal are hidden on Android
394         */
395        @Override
396        public Fold omitUnchangedText() {
397            return (internalOptions & UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I) == 0 ?
398                    OMIT_UNCHANGED : TURKIC_OMIT_UNCHANGED;
399        }
400
401        /**
402         * Returns an instance that behaves like this one but
403         * handles dotted I and dotless i appropriately for Turkic languages (tr, az).
404         *
405         * <p>Uses the Unicode CaseFolding.txt mappings marked with 'T' that
406         * are to be excluded for default mappings and
407         * included for the Turkic-specific mappings.
408         *
409         * @return an options object with this option.
410         * @see UCharacter#FOLD_CASE_EXCLUDE_SPECIAL_I
411         * @hide draft / provisional / internal are hidden on Android
412         */
413        public Fold turkic() {
414            return (internalOptions & CaseMapImpl.OMIT_UNCHANGED_TEXT) == 0 ?
415                    TURKIC : TURKIC_OMIT_UNCHANGED;
416        }
417
418        /**
419         * Case-folds a string.
420         * The result may be longer or shorter than the original.
421         *
422         * <p>Case-folding is locale-independent and not context-sensitive,
423         * but there is an option for whether to include or exclude mappings for dotted I
424         * and dotless i that are marked with 'T' in CaseFolding.txt.
425         *
426         * @param src       The original string.
427         * @return the result string.
428         *
429         * @see UCharacter#foldCase(String, int)
430         * @hide draft / provisional / internal are hidden on Android
431         */
432        public String apply(CharSequence src) {
433            return CaseMapImpl.fold(internalOptions, src);
434        }
435
436        /**
437         * Case-folds a string and optionally records edits (see {@link #omitUnchangedText}).
438         * The result may be longer or shorter than the original.
439         *
440         * <p>Case-folding is locale-independent and not context-sensitive,
441         * but there is an option for whether to include or exclude mappings for dotted I
442         * and dotless i that are marked with 'T' in CaseFolding.txt.
443         *
444         * @param src       The original string.
445         * @param dest      A buffer for the result string. Must not be null.
446         * @param edits     Records edits for index mapping, working with styled text,
447         *                  and getting only changes (if any).
448         *                  This function calls edits.reset() first. edits can be null.
449         * @return dest with the result string (or only changes) appended.
450         *
451         * @see UCharacter#foldCase(String, int)
452         * @hide draft / provisional / internal are hidden on Android
453         */
454         public <A extends Appendable> A apply(CharSequence src, A dest, Edits edits) {
455             return CaseMapImpl.fold(internalOptions, src, dest, edits);
456         }
457    }
458}
459