163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer// © 2017 and later: Unicode, Inc. and others.
263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer// License & terms of use: http://www.unicode.org/copyright.html#License
363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererpackage com.ibm.icu.text;
463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererimport java.util.Locale;
663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererimport com.ibm.icu.impl.CaseMapImpl;
863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererimport com.ibm.icu.impl.UCaseProps;
963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererimport com.ibm.icu.lang.UCharacter;
1063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererimport com.ibm.icu.util.ULocale;
1163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
1263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer/**
1363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer * Low-level case mapping options and methods. Immutable.
1463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer * "Setters" return instances with the union of the current and new options set.
1563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer *
1663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer * This class is not intended for public subclassing.
1763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer *
1863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer * @draft ICU 59
1963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer * @provisional This API might change or be removed in a future release.
2063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer */
2163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Schererpublic abstract class CaseMap {
2263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
2363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @internal
2463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @deprecated This API is ICU internal only.
2563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
2663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    @Deprecated
2763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    protected int internalOptions;
2863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
2963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    private CaseMap(int opt) { internalOptions = opt; }
3063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
3163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    private static int getCaseLocale(Locale locale) {
3263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        if (locale == null) {
3363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            locale = Locale.getDefault();
3463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
3563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        return UCaseProps.getCaseLocale(locale);
3663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    }
3763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
3863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
3963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @return Lowercasing object with default options.
4063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
4163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
4263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
4363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static Lower toLower() { return Lower.DEFAULT; }
4463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
4563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @return Uppercasing object with default options.
4663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
4763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
4863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
4963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static Upper toUpper() { return Upper.DEFAULT; }
5063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
5163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @return Titlecasing object with default options.
5263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
5363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
5463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
5563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static Title toTitle() { return Title.DEFAULT; }
5663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
5763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @return Case folding object with default options.
5863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
5963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
6063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
6163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static Fold fold() { return Fold.DEFAULT; }
6263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
6363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
6463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * Returns an instance that behaves like this one but
6563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * omits unchanged text when case-mapping with {@link Edits}.
6663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     *
6763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @return an options object with this option.
6863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
6963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
7063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
7163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public abstract CaseMap omitUnchangedText();
7263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
7363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
7463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * Lowercasing options and methods. Immutable.
7563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     *
7663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @see #toLower()
7763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
7863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
7963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
8063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static final class Lower extends CaseMap {
8163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Lower DEFAULT = new Lower(0);
8263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Lower OMIT_UNCHANGED = new Lower(CaseMapImpl.OMIT_UNCHANGED_TEXT);
8363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private Lower(int opt) { super(opt); }
8463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
8563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
8663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * {@inheritDoc}
8763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
8863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
8963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
9063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        @Override
9163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Lower omitUnchangedText() {
9263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return OMIT_UNCHANGED;
9363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
9463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
9563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
96fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Lowercases a string.
97fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Casing is locale-dependent and context-sensitive.
98fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The result may be longer or shorter than the original.
99fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
100fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
101fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  (See {@link ULocale#toLocale}.)
102fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param src       The original string.
103fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return the result string.
104fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
105fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see UCharacter#toLowerCase(Locale, String)
106fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
107fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
108fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
109fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public String apply(Locale locale, CharSequence src) {
110fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return CaseMapImpl.toLower(getCaseLocale(locale), internalOptions, src);
111fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
112fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
113fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
11463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Lowercases a string and optionally records edits (see {@link #omitUnchangedText}).
11563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Casing is locale-dependent and context-sensitive.
11663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * The result may be longer or shorter than the original.
11763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
11863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
11963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  (See {@link ULocale#toLocale}.)
12063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param src       The original string.
12163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param dest      A buffer for the result string. Must not be null.
12263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param edits     Records edits for index mapping, working with styled text,
12363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  and getting only changes (if any).
12463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  This function calls edits.reset() first. edits can be null.
12563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return dest with the result string (or only changes) appended.
12663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
12763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#toLowerCase(Locale, String)
12863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
12963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
13063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
13163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         public <A extends Appendable> A apply(
13263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                 Locale locale, CharSequence src, A dest, Edits edits) {
13363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer             return CaseMapImpl.toLower(getCaseLocale(locale), internalOptions, src, dest, edits);
13463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         }
13563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    }
13663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
13763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
13863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * Uppercasing options and methods. Immutable.
13963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     *
14063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @see #toUpper()
14163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
14263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
14363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
14463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static final class Upper extends CaseMap {
14563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Upper DEFAULT = new Upper(0);
14663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Upper OMIT_UNCHANGED = new Upper(CaseMapImpl.OMIT_UNCHANGED_TEXT);
14763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private Upper(int opt) { super(opt); }
14863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
14963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
15063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * {@inheritDoc}
15163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
15263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
15363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
15463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        @Override
15563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Upper omitUnchangedText() {
15663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return OMIT_UNCHANGED;
15763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
15863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
15963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
160fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Uppercases a string.
161fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Casing is locale-dependent and context-sensitive.
162fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The result may be longer or shorter than the original.
163fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
164fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
165fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  (See {@link ULocale#toLocale}.)
166fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param src       The original string.
167fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return the result string.
168fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
169fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see UCharacter#toUpperCase(Locale, String)
170fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
171fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
172fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
173fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public String apply(Locale locale, CharSequence src) {
174fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return CaseMapImpl.toUpper(getCaseLocale(locale), internalOptions, src);
175fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
176fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
177fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
17863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Uppercases a string and optionally records edits (see {@link #omitUnchangedText}).
17963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Casing is locale-dependent and context-sensitive.
18063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * The result may be longer or shorter than the original.
18163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
18263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
18363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  (See {@link ULocale#toLocale}.)
18463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param src       The original string.
18563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param dest      A buffer for the result string. Must not be null.
18663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param edits     Records edits for index mapping, working with styled text,
18763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  and getting only changes (if any).
18863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  This function calls edits.reset() first. edits can be null.
18963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return dest with the result string (or only changes) appended.
19063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
19163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#toUpperCase(Locale, String)
19263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
19363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
19463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
19563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         public <A extends Appendable> A apply(
19663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                 Locale locale, CharSequence src, A dest, Edits edits) {
19763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer             return CaseMapImpl.toUpper(getCaseLocale(locale), internalOptions, src, dest, edits);
19863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         }
19963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    }
20063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
20163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
20263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * Titlecasing options and methods. Immutable.
20363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     *
20463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @see #toTitle()
20563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
20663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
20763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
20863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static final class Title extends CaseMap {
20963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Title DEFAULT = new Title(0);
21063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Title OMIT_UNCHANGED = new Title(CaseMapImpl.OMIT_UNCHANGED_TEXT);
21163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private Title(int opt) { super(opt); }
21263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
21363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
214fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Returns an instance that behaves like this one but
215fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * titlecases the string as a whole rather than each word.
216fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * (Titlecases only the character at index 0, possibly adjusted.)
217fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
218fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>It is an error to specify multiple titlecasing iterator options together,
219fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * including both an option and an explicit BreakIterator.
220fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
221fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return an options object with this option.
222fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see #adjustToCased()
223fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
224fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
225fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
226fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public Title wholeString() {
227fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return new Title(CaseMapImpl.addTitleIteratorOption(
228fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                    internalOptions, CaseMapImpl.TITLECASE_WHOLE_STRING));
229fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
230fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
231fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
232fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Returns an instance that behaves like this one but
233fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * titlecases sentences rather than words.
234fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * (Titlecases only the first character of each sentence, possibly adjusted.)
235fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
236fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>It is an error to specify multiple titlecasing iterator options together,
237fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * including both an option and an explicit BreakIterator.
238fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
239fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return an options object with this option.
240fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see #adjustToCased()
241fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
242fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
243fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
244fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public Title sentences() {
245fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return new Title(CaseMapImpl.addTitleIteratorOption(
246fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                    internalOptions, CaseMapImpl.TITLECASE_SENTENCES));
247fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
248fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
249fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
25063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * {@inheritDoc}
25163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
25263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
25363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
25463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        @Override
25563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Title omitUnchangedText() {
25663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            if (internalOptions == 0 || internalOptions == CaseMapImpl.OMIT_UNCHANGED_TEXT) {
25763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                return OMIT_UNCHANGED;
25863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            }
25963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return new Title(internalOptions | CaseMapImpl.OMIT_UNCHANGED_TEXT);
26063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
26163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
26263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
26363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Returns an instance that behaves like this one but
26463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * does not lowercase non-initial parts of words when titlecasing.
26563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
266fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>By default, titlecasing will titlecase the character at each
267fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * (possibly adjusted) BreakIterator index and
268fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * lowercase all other characters up to the next iterator index.
26963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * With this option, the other characters will not be modified.
27063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
27163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return an options object with this option.
27263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#TITLECASE_NO_LOWERCASE
273fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see #adjustToCased()
27463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
27563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
27663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
27763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Title noLowercase() {
27863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return new Title(internalOptions | UCharacter.TITLECASE_NO_LOWERCASE);
27963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
28063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
28163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
28263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Returns an instance that behaves like this one but
283fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * does not adjust the titlecasing BreakIterator indexes;
28463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * titlecases exactly the characters at breaks from the iterator.
28563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
28663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * <p>By default, titlecasing will take each break iterator index,
287fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * adjust it to the next relevant character (see {@link #adjustToCased()}),
288fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * and titlecase that one.
28963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
290fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>Other characters are lowercased.
29163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
29263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return an options object with this option.
29363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#TITLECASE_NO_BREAK_ADJUSTMENT
29463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
29563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
29663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
29763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Title noBreakAdjustment() {
298fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return new Title(CaseMapImpl.addTitleAdjustmentOption(
299fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                    internalOptions, UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT));
300fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
301fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
302fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
303fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Returns an instance that behaves like this one but
304fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * adjusts each titlecasing BreakIterator index to the next cased character.
305fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * (See the Unicode Standard, chapter 3, Default Case Conversion, R3 toTitlecase(X).)
306fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
307fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>This used to be the default index adjustment in ICU.
308fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Since ICU 60, the default index adjustment is to the next character that is
309fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * a letter, number, symbol, or private use code point.
310fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * (Uncased modifier letters are skipped.)
311fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The difference in behavior is small for word titlecasing,
312fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * but the new adjustment is much better for whole-string and sentence titlecasing:
313fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * It yields "49ers" and "«丰(abc)»" instead of "49Ers" and "«丰(Abc)»".
314fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
315fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>It is an error to specify multiple titlecasing adjustment options together.
316fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
317fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return an options object with this option.
318fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see #noBreakAdjustment()
319fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
320fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
321fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
322fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public Title adjustToCased() {
323fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return new Title(CaseMapImpl.addTitleAdjustmentOption(
324fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                    internalOptions, CaseMapImpl.TITLECASE_ADJUST_TO_CASED));
325fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
326fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
327fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
328fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Titlecases a string.
329fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Casing is locale-dependent and context-sensitive.
330fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The result may be longer or shorter than the original.
331fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
332fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>Titlecasing uses a break iterator to find the first characters of words
333fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * that are to be titlecased. It titlecases those characters and lowercases
334fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * all others. (This can be modified with options bits.)
335fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
336fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
337fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  (See {@link ULocale#toLocale}.)
338fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param iter      A break iterator to find the first characters of words that are to be titlecased.
339fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  It is set to the source string (setText())
340fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  and used one or more times for iteration (first() and next()).
341fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  If null, then a word break iterator for the locale is used
342fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *                  (or something equivalent).
343fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param src       The original string.
344fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return the result string.
345fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
346fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see UCharacter#toUpperCase(Locale, String)
347fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
348fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
349fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
350fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public String apply(Locale locale, BreakIterator iter, CharSequence src) {
351fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            if (iter == null && locale == null) {
352fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                locale = Locale.getDefault();
353fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            }
354fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            iter = CaseMapImpl.getTitleBreakIterator(locale, internalOptions, iter);
355fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            iter.setText(src);
356fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return CaseMapImpl.toTitle(getCaseLocale(locale), internalOptions, iter, src);
35763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
35863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
35963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
36063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Titlecases a string and optionally records edits (see {@link #omitUnchangedText}).
36163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Casing is locale-dependent and context-sensitive.
36263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * The result may be longer or shorter than the original.
36363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
36463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * <p>Titlecasing uses a break iterator to find the first characters of words
36563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * that are to be titlecased. It titlecases those characters and lowercases
36663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * all others. (This can be modified with options bits.)
36763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
36863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param locale    The locale ID. Can be null for {@link Locale#getDefault}.
36963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  (See {@link ULocale#toLocale}.)
37063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param iter      A break iterator to find the first characters of words that are to be titlecased.
37163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  It is set to the source string (setText())
37263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  and used one or more times for iteration (first() and next()).
37363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  If null, then a word break iterator for the locale is used
37463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  (or something equivalent).
37563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param src       The original string.
37663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param dest      A buffer for the result string. Must not be null.
37763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param edits     Records edits for index mapping, working with styled text,
37863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  and getting only changes (if any).
37963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  This function calls edits.reset() first. edits can be null.
38063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return dest with the result string (or only changes) appended.
38163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
38263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#toTitleCase(Locale, String, BreakIterator, int)
38363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
38463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
38563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
38663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         public <A extends Appendable> A apply(
38763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                 Locale locale, BreakIterator iter, CharSequence src, A dest, Edits edits) {
388fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert             if (iter == null && locale == null) {
389fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                 locale = Locale.getDefault();
39063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer             }
391fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert             iter = CaseMapImpl.getTitleBreakIterator(locale, internalOptions, iter);
392fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert             iter.setText(src);
39363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer             return CaseMapImpl.toTitle(
39463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                     getCaseLocale(locale), internalOptions, iter, src, dest, edits);
39563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         }
39663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    }
39763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
39863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    /**
39963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * Case folding options and methods. Immutable.
40063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     *
40163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @see #fold()
40263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @draft ICU 59
40363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     * @provisional This API might change or be removed in a future release.
40463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer     */
40563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    public static final class Fold extends CaseMap {
40663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Fold DEFAULT = new Fold(0);
40763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Fold TURKIC = new Fold(UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I);
40863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Fold OMIT_UNCHANGED = new Fold(CaseMapImpl.OMIT_UNCHANGED_TEXT);
40963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private static final Fold TURKIC_OMIT_UNCHANGED = new Fold(
41063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I | CaseMapImpl.OMIT_UNCHANGED_TEXT);
41163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        private Fold(int opt) { super(opt); }
41263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
41363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
41463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * {@inheritDoc}
41563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
41663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
41763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
41863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        @Override
41963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Fold omitUnchangedText() {
42063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return (internalOptions & UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I) == 0 ?
42163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                    OMIT_UNCHANGED : TURKIC_OMIT_UNCHANGED;
42263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
42363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
42463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
42563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * Returns an instance that behaves like this one but
42663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * handles dotted I and dotless i appropriately for Turkic languages (tr, az).
42763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
42863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * <p>Uses the Unicode CaseFolding.txt mappings marked with 'T' that
42963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * are to be excluded for default mappings and
43063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * included for the Turkic-specific mappings.
43163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
43263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return an options object with this option.
43363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#FOLD_CASE_EXCLUDE_SPECIAL_I
43463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
43563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
43663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
43763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        public Fold turkic() {
43863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer            return (internalOptions & CaseMapImpl.OMIT_UNCHANGED_TEXT) == 0 ?
43963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer                    TURKIC : TURKIC_OMIT_UNCHANGED;
44063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        }
44163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer
44263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer        /**
443fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Case-folds a string.
444fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The result may be longer or shorter than the original.
44563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
44663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * <p>Case-folding is locale-independent and not context-sensitive,
44763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * but there is an option for whether to include or exclude mappings for dotted I
44863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * and dotless i that are marked with 'T' in CaseFolding.txt.
44963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
450fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @param src       The original string.
451fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @return the result string.
452fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
453fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @see UCharacter#foldCase(String, int)
454fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @draft ICU 60
455fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * @provisional This API might change or be removed in a future release.
456fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         */
457fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        public String apply(CharSequence src) {
458fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert            return CaseMapImpl.fold(internalOptions, src);
459fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        }
460fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
461fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert        /**
462fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * Case-folds a string and optionally records edits (see {@link #omitUnchangedText}).
463fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * The result may be longer or shorter than the original.
464fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         *
465fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * <p>Case-folding is locale-independent and not context-sensitive,
466fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * but there is an option for whether to include or exclude mappings for dotted I
467fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         * and dotless i that are marked with 'T' in CaseFolding.txt.
46863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
46963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param src       The original string.
47063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param dest      A buffer for the result string. Must not be null.
47163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @param edits     Records edits for index mapping, working with styled text,
47263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  and getting only changes (if any).
47363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *                  This function calls edits.reset() first. edits can be null.
47463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @return dest with the result string (or only changes) appended.
47563cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         *
47663cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @see UCharacter#foldCase(String, int)
47763cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @draft ICU 59
47863cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         * @provisional This API might change or be removed in a future release.
47963cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         */
48063cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         public <A extends Appendable> A apply(CharSequence src, A dest, Edits edits) {
48163cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer             return CaseMapImpl.fold(internalOptions, src, dest, edits);
48263cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer         }
48363cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer    }
48463cafec8b8cb135e7c06ef6b9fc8c128ed55b140Markus Scherer}
485