12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */
2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others.
3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/*
52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
698d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert * Copyright (C) 2012-2016, Google, International Business Machines Corporation and
72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved.
82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text;
112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ArrayList;
132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Arrays;
142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collection;
152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Iterator;
162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Locale;
172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.ICUCache;
19f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUData;
202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.ICUResourceBundle;
212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.SimpleCache;
221c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubertimport android.icu.impl.SimpleFormatterImpl;
232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale;
242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.UResourceBundle;
252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/**
272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Immutable class for formatting a list, using data from CLDR (or supplied
282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * separately). The class is not subclassable.
292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Mark Davis
312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerfinal public class ListFormatter {
331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert    // Compiled SimpleFormatter patterns.
3498d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private final String two;
3598d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private final String start;
3698d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private final String middle;
3798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private final String end;
382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private final ULocale locale;
392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Indicates the style of Listformatter
422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
43836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public enum Style {
472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Standard style.
492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
50836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        STANDARD("standard"),
542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Style for full durations
562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
57836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DURATION("unit"),
612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Style for durations in abbrevated form
632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
64836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DURATION_SHORT("unit-short"),
682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Style for durations in narrow form
702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
71836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DURATION_NARROW("unit-narrow");
752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final String name;
772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Style(String name) {
792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.name = name;
802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
83836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String getName() {
872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return name;
882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>Internal:</b> Create a ListFormatter from component strings,
942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * with definitions as in LDML.
952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param two
972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            string for two items, containing {0} for the first, and {1}
982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            for the second.
992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param start
1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            string for the start of a list items, containing {0} for the
1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            first, and {1} for the rest.
1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param middle
1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            string for the start of a list items, containing {0} for the
1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            first part of the list, and {1} for the rest of the list.
1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param end
1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            string for the end of a list items, containing {0} for the
1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            first part of the list, and {1} for the last item.
1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
109836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ListFormatter(String two, String start, String middle, String end) {
1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this(
11498d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(two, new StringBuilder()),
11598d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(start, new StringBuilder()),
11698d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(middle, new StringBuilder()),
11798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(end, new StringBuilder()),
1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                null);
1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
12098d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert
12198d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private ListFormatter(String two, String start, String middle, String end, ULocale locale) {
1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.two = two;
1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.start = start;
1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.middle = middle;
1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.end = end;
1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.locale = locale;
1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12998d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    private static String compilePattern(String pattern, StringBuilder sb) {
1301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert        return SimpleFormatterImpl.compileToStringMinMaxArguments(pattern, sb, 2, 2);
13198d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    }
13298d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert
1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Create a list formatter that is appropriate for a locale.
1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale
1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the locale in question.
1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return ListFormatter
1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ListFormatter getInstance(ULocale locale) {
1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller      return getInstance(locale, Style.STANDARD);
1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Create a list formatter that is appropriate for a locale.
1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale
1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the locale in question.
1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return ListFormatter
1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ListFormatter getInstance(Locale locale) {
1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getInstance(ULocale.forLocale(locale), Style.STANDARD);
1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Create a list formatter that is appropriate for a locale and style.
1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale the locale in question.
1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param style the style
1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return ListFormatter
1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
162836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ListFormatter getInstance(ULocale locale, Style style) {
1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return cache.get(locale, style.getName());
1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Create a list formatter that is appropriate for the default FORMAT locale.
1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return ListFormatter
1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ListFormatter getInstance() {
1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getInstance(ULocale.getDefault(ULocale.Category.FORMAT));
1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Format a list of objects.
1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param items
1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            items to format. The toString() method is called on each.
1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return items formatted into a string
1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String format(Object... items) {
1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return format(Arrays.asList(items));
1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Format a collection of objects. The toString() method is called on each.
1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param items
1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            items to format. The toString() method is called on each.
1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return items formatted into a string
1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String format(Collection<?> items) {
1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return format(items, -1).toString();
1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // Formats a collection of objects and returns the formatted string plus the offset
2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // in the string where the index th element appears. index is zero based. If index is
2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // negative or greater than or equal to the size of items then this function returns -1 for
2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // the offset.
2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    FormattedListBuilder format(Collection<?> items, int index) {
2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Iterator<?> it = items.iterator();
2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int count = items.size();
2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        switch (count) {
2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case 0:
2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new FormattedListBuilder("", false);
2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case 1:
2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new FormattedListBuilder(it.next(), index == 0);
2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case 2:
2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new FormattedListBuilder(it.next(), index == 0).append(two, it.next(), index == 1);
2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        FormattedListBuilder builder = new FormattedListBuilder(it.next(), index == 0);
2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        builder.append(start, it.next(), index == 1);
2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int idx = 2; idx < count - 1; ++idx) {
2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            builder.append(middle, it.next(), index == idx);
2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return builder.append(end, it.next(), index == count - 1);
2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the pattern to use for a particular item count.
2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param count the item count.
2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the pattern with {0}, {1}, {2}, etc. For English,
2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * getPatternForNumItems(3) == "{0}, {1}, and {2}"
2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @throws IllegalArgumentException when count is 0 or negative.
2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String getPatternForNumItems(int count) {
2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (count <= 0) {
2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("count must be > 0");
2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ArrayList<String> list = new ArrayList<String>();
2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < count; i++) {
2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            list.add(String.format("{%d}", i));
2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return format(list);
2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the locale of this object.
2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
244836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ULocale getLocale() {
2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return locale;
2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // Builds a formatted list
2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static class FormattedListBuilder {
2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private StringBuilder current;
2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private int offset;
2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Start is the first object in the list; If recordOffset is true, records the offset of
2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // this first object.
2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FormattedListBuilder(Object start, boolean recordOffset) {
2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.current = new StringBuilder(start.toString());
2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.offset = recordOffset ? 0 : -1;
2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Appends additional object. pattern is a template indicating where the new object gets
2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // added in relation to the rest of the list. {0} represents the rest of the list; {1}
2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // represents the new object in pattern. next is the object to be added. If recordOffset
2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // is true, records the offset of next in the formatted string.
26798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert        public FormattedListBuilder append(String pattern, Object next, boolean recordOffset) {
26898d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert            int[] offsets = (recordOffset || offsetRecorded()) ? new int[2] : null;
2691c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert            SimpleFormatterImpl.formatAndReplace(
27098d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                    pattern, current, offsets, current, next.toString());
27198d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert            if (offsets != null) {
27298d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                if (offsets[0] == -1 || offsets[1] == -1) {
27398d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                    throw new IllegalArgumentException(
27498d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                            "{0} or {1} missing from pattern " + pattern);
27598d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                }
27698d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                if (recordOffset) {
27798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                    offset = offsets[1];
27898d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                } else {
27998d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                    offset += offsets[0];
28098d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                }
2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
28298d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert            return this;
2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return current.toString();
2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Gets the last recorded offset or -1 if no offset recorded.
2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int getOffset() {
2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return offset;
2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private boolean offsetRecorded() {
2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return offset >= 0;
2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class Cache {
3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final ICUCache<String, ListFormatter> cache =
3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            new SimpleCache<String, ListFormatter>();
3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public ListFormatter get(ULocale locale, String style) {
3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String key = String.format("%s:%s", locale.toString(), style);
3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ListFormatter result = cache.get(key);
3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (result == null) {
3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = load(locale, style);
3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                cache.put(key, result);
3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result;
3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static ListFormatter load(ULocale ulocale, String style) {
3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ICUResourceBundle r = (ICUResourceBundle)UResourceBundle.
316f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                    getBundleInstance(ICUData.ICU_BASE_NAME, ulocale);
31798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert            StringBuilder sb = new StringBuilder();
3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new ListFormatter(
31998d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(r.getWithFallback("listPattern/" + style + "/2").getString(), sb),
32098d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(r.getWithFallback("listPattern/" + style + "/start").getString(), sb),
32198d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(r.getWithFallback("listPattern/" + style + "/middle").getString(), sb),
32298d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert                compilePattern(r.getWithFallback("listPattern/" + style + "/end").getString(), sb),
3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ulocale);
3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static Cache cache = new Cache();
3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}
329