LocalePriorityList.java revision 836e6b40a94ec3fb7545a76cb072960442b7eee9
12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (C) 2010-2014, Google, Inc.; International Business Machines * 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Corporation and others. All Rights Reserved. * 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.util; 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections; 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Comparator; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Iterator; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.LinkedHashMap; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.LinkedHashSet; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map.Entry; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Set; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.TreeMap; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.regex.Matcher; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.regex.Pattern; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Provides an immutable list of languages (locales) in priority order. 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The string format is based on the Accept-Language format 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@link "http://www.ietf.org/rfc/rfc2616.txt"}, such as 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "af, en, fr;q=0.9". Syntactically it is slightly 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * more lenient, in allowing extra whitespace between elements, extra commas, 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and more than 3 decimals (on input), and pins between 0 and 1. 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>In theory, Accept-Language indicates the relative 'quality' of each item, 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but in practice, all of the browsers just take an ordered list, like 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "en, fr, de", and synthesize arbitrary quality values that put these in the 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * right order, like: "en, fr;q=0.7, de;q=0.3". The quality values in these de facto 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * semantics thus have <b>nothing</b> to do with the relative qualities of the 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * original. Accept-Language also doesn't 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * specify the interpretation of multiple instances, eg what "en, fr, en;q=.5" 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * means. 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>There are various ways to build a LanguagePriorityList, such 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as using the following equivalent patterns: 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * list = LanguagePriorityList.add("af, en, fr;q=0.9").build(); 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * list2 = LanguagePriorityList 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * .add(ULocale.forString("af")) 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * .add(ULocale.ENGLISH) 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * .add(ULocale.FRENCH, 0.9d) 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * .build(); 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * When the list is built, the internal values are sorted in descending order by 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * weight, and then by input order. That is, if two languages have the same weight, the first one in the original order 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * comes first. If exactly the same language tag appears multiple times, 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the last one wins. 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There are two options when building. If preserveWeights are on, then "de;q=0.3, ja;q=0.3, en, fr;q=0.7, de " would result in the following: 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> en;q=1.0 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * de;q=1.0 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fr;q=0.7 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ja;q=0.3</pre> 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If it is off (the default), then all weights are reset to 1.0 after reordering. 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is to match the effect of the Accept-Language semantics as used in browsers, and results in the following: 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * * <pre> en;q=1.0 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * de;q=1.0 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fr;q=1.0 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ja;q=1.0</pre> 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author markdavis@google.com 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 68836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 69704056c96cc5de08c2425fa1679a5c0a92c5a88eNeil Fuller * @hide All android.icu classes are currently hidden 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class LocalePriorityList implements Iterable<ULocale> { 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final double D0 = 0.0d; 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final Double D1 = 1.0d; 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final Pattern languageSplitter = Pattern.compile("\\s*,\\s*"); 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final Pattern weightSplitter = Pattern 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller .compile("\\s*(\\S*)\\s*;\\s*q\\s*=\\s*(\\S*)"); 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final Map<ULocale, Double> languagesAndWeights; 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Add a language code to the list being built, with weight 1.0. 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languageCode locale/language to be added 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return internal builder, for chaining 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Builder add(ULocale... languageCode) { 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Builder().add(languageCode); 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Add a language code to the list being built, with specified weight. 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languageCode locale/language to be added 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param weight value from 0.0 to 1.0 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return internal builder, for chaining 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Builder add(ULocale languageCode, final double weight) { 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Builder().add(languageCode, weight); 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Add a language priority list. 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languagePriorityList list to add all the members of 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return internal builder, for chaining 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Builder add(LocalePriorityList languagePriorityList) { 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Builder().add(languagePriorityList); 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Add language codes to the list being built, using a string in rfc2616 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (lenient) format, where each language is a valid {@link ULocale}. 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param acceptLanguageString String in rfc2616 format (but leniently parsed) 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return internal builder, for chaining 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Builder add(String acceptLanguageString) { 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Builder().add(acceptLanguageString); 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the weight for a given language, or null if there is none. Note that 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the weights may be adjusted from those used to build the list. 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param language to get weight of 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return weight 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Double getWeight(ULocale language) { 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return languagesAndWeights.get(language); 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@inheritDoc} 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final StringBuilder result = new StringBuilder(); 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final ULocale language : languagesAndWeights.keySet()) { 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (result.length() != 0) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.append(", "); 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.append(language); 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller double weight = languagesAndWeights.get(language); 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (weight != D1) { 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.append(";q=").append(weight); 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result.toString(); 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@inheritDoc} 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Iterator<ULocale> iterator() { 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return languagesAndWeights.keySet().iterator(); 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@inheritDoc} 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean equals(final Object o) { 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (o == null) { 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (this == o) { 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final LocalePriorityList that = (LocalePriorityList) o; 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return languagesAndWeights.equals(that.languagesAndWeights); 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (final RuntimeException e) { 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@inheritDoc} 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int hashCode() { 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return languagesAndWeights.hashCode(); 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ==================== Privates ==================== 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private LocalePriorityList(final Map<ULocale, Double> languageToWeight) { 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.languagesAndWeights = languageToWeight; 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Class used for building LanguagePriorityLists 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static class Builder { 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * These store the input languages and weights, in chronological order, 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * where later additions override previous ones. 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final Map<ULocale, Double> languageToWeight 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller = new LinkedHashMap<ULocale, Double>(); 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Private constructor, only used by LocalePriorityList 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Builder() { 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Creates a LocalePriorityList. This is equivalent to 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@link Builder#build(boolean) Builder.build(false)}. 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A LocalePriorityList 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public LocalePriorityList build() { 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return build(false); 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Creates a LocalePriorityList. 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param preserveWeights when true, the weights originally came 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * from a language priority list specified by add() are preserved. 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A LocalePriorityList 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public LocalePriorityList build(boolean preserveWeights) { 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Walk through the input list, collecting the items with the same weights. 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final Map<Double, Set<ULocale>> doubleCheck = new TreeMap<Double, Set<ULocale>>( 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller myDescendingDouble); 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final ULocale lang : languageToWeight.keySet()) { 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Double weight = languageToWeight.get(lang); 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<ULocale> s = doubleCheck.get(weight); 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (s == null) { 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller doubleCheck.put(weight, s = new LinkedHashSet<ULocale>()); 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller s.add(lang); 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We now have a bunch of items sorted by weight, then chronologically. 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We can now create a list in the right order 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final Map<ULocale, Double> temp = new LinkedHashMap<ULocale, Double>(); 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (Entry<Double, Set<ULocale>> langEntry : doubleCheck.entrySet()) { 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final Double weight = langEntry.getKey(); 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final ULocale lang : langEntry.getValue()) { 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp.put(lang, preserveWeights ? weight : D1); 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new LocalePriorityList(Collections.unmodifiableMap(temp)); 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adds a LocalePriorityList 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languagePriorityList a LocalePriorityList 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return this, for chaining 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Builder add( 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final LocalePriorityList languagePriorityList) { 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final ULocale language : languagePriorityList.languagesAndWeights 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller .keySet()) { 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller add(language, languagePriorityList.languagesAndWeights.get(language)); 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adds a new language code, with weight = 1.0. 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languageCode to add with weight 1.0 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return this, for chaining 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Builder add(final ULocale languageCode) { 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return add(languageCode, D1); 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adds language codes, with each having weight = 1.0. 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languageCodes List of language codes. 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return this, for chaining. 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Builder add(ULocale... languageCodes) { 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final ULocale languageCode : languageCodes) { 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller add(languageCode, D1); 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adds a new supported languageCode, with specified weight. Overrides any 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * previous weight for the language. 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param languageCode language/locale to add 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param weight value between 0.0 and 1.1 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return this, for chaining. 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Builder add(final ULocale languageCode, 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller double weight) { 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (languageToWeight.containsKey(languageCode)) { 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller languageToWeight.remove(languageCode); 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (weight <= D0) { 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; // skip zeros 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (weight > D1) { 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller weight = D1; 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller languageToWeight.put(languageCode, weight); 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adds rfc2616 list. 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param acceptLanguageList in rfc2616 format 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return this, for chaining. 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @stable ICU 4.4 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Builder add(final String acceptLanguageList) { 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final String[] items = languageSplitter.split(acceptLanguageList.trim()); 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final Matcher itemMatcher = weightSplitter.matcher(""); 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (final String item : items) { 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (itemMatcher.reset(item).matches()) { 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final ULocale language = new ULocale(itemMatcher.group(1)); 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final double weight = Double.parseDouble(itemMatcher.group(2)); 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!(weight >= D0 && weight <= D1)) { // do ! for NaN 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal weight, must be 0..1: " 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller + weight); 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller add(language, weight); 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (item.length() != 0) { 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller add(new ULocale(item)); 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static Comparator<Double> myDescendingDouble = new Comparator<Double>() { 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int compare(Double o1, Double o2) { 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return -o1.compareTo(o2); 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 360