| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.i18n.server; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Generated maps of regions into parent regions, used for locale inheritance. |
| * |
| * TODO(jat): make this actually be generated. |
| */ |
| public class RegionInheritance { |
| |
| private static Map<String, String> parentRegionMap; |
| |
| static { |
| // TODO(jat): add support for multiple parent regions |
| parentRegionMap = new HashMap<String, String>(); |
| // Data from CLDR supplementalData/territoryContainment |
| // manually edited to remove multiple parents and non-UN data |
| addChildren("001", "002", "009", "019", "142", "150"); // World |
| addChildren("011", "BF", "BJ", "CI", "CV", "GH", "GM", "GN", "GW", "LR", |
| "ML", "MR", "NE", "NG", "SH", "SL", "SN", "TG"); // Western", "Africa |
| addChildren("013", "BZ", "CR", "GT", "HN", "MX", "NI", "PA", |
| "SV"); // Central America |
| addChildren("014", "BI", "DJ", "ER", "ET", "KE", "KM", "MG", "MU", "MW", |
| "MZ", "RE", "RW", "SC", "SO", "TZ", "UG", "YT", "ZM", |
| "ZW"); // Eastern Africa |
| addChildren("142", "030", "035", "143", "145", "034", "062"); // Asia |
| addChildren("143", "TM", "TJ", "KG", "KZ", "UZ"); // Central Asia |
| addChildren("145", "AE", "AM", "AZ", "BH", "CY", "GE", "IL", "IQ", "JO", |
| "KW", "LB", "OM", "PS", "QA", "SA", "NT", "SY", "TR", "YE", |
| "YD"); // Western Asia |
| addChildren("015", "DZ", "EG", "EH", "LY", "MA", "SD", |
| "TN"); //Northern Africa |
| addChildren("150", "039", "151", "154", "155"); // Europe |
| addChildren("151", "BG", "BY", "CZ", "HU", "MD", "PL", "RO", "RU", "SU", |
| "SK", "UA"); // Eastern Europe |
| addChildren("154", "GG", "JE", "AX", "DK", "EE", "FI", "FO", "GB", |
| "IE", "IM", "IS", "LT", "LV", "NO", "SE", "SJ"); // Northern Europe |
| addChildren("155", "AT", "BE", "CH", "DE", "DD", "FR", "FX", "LI", "LU", |
| "MC", "NL"); // Western Europe |
| addChildren("017", "AO", "CD", "ZR", "CF", "CG", "CM", "GA", "GQ", "ST", |
| "TD"); // Middle Africa |
| addChildren("018", "BW", "LS", "NA", "SZ", "ZA"); // Southern Africa |
| addChildren("019", "021", "419"); // Americas |
| addChildren("002", "011", "014", "015", "017", "018"); // Africa |
| addChildren("021", "BM", "CA", "GL", "PM", "US"); // Northern America |
| addChildren("029", "AG", "AI", "AN", "AW", "BB", "BL", "BS", "CU", "DM", |
| "DO", "GD", "GP", "HT", "JM", "KN", "KY", "LC", "MF", "MQ", "MS", "PR", |
| "TC", "TT", "VC", "VG", "VI"); // Caribbean |
| addChildren("030", "CN", "HK", "JP", "KP", "KR", "MN", "MO", |
| "TW"); // Eastern Asia |
| addChildren("035", "BN", "ID", "KH", "LA", "MM", "BU", "MY", "PH", "SG", |
| "TH", "TL", "TP", "VN"); // South-Eastern Asia |
| addChildren("039", "AD", "AL", "BA", "ES", "GI", "GR", "HR", "IT", "ME", |
| "MK", "MT", "CS", "RS", "PT", "SI", "SM", "VA", |
| "YU"); // Southern Europe |
| addChildren("419", "005", "013", "029"); //Latin America and the Caribbean |
| addChildren("005", "AR", "BO", "BR", "CL", "CO", "EC", "FK", "GF", "GY", |
| "PE", "PY", "SR", "UY", "VE"); // South America |
| addChildren("053", "AU", "NF", "NZ"); // Australia and New Zealand |
| addChildren("054", "FJ", "NC", "PG", "SB", "VU"); // Melanesia |
| addChildren("057", "FM", "GU", "KI", "MH", "MP", "NR", "PW"); // Micronesia |
| addChildren("061", "AS", "CK", "NU", "PF", "PN", "TK", "TO", "TV", "WF", |
| "WS"); // Polynesia |
| addChildren("034", "AF", "BD", "BT", "IN", "IR", "LK", "MV", "NP", |
| "PK"); // Southern Asia |
| addChildren("009", "053", "054", "057", "061", "QO"); // Oceania |
| addChildren("QO", "AQ", "BV", "CC", "CX", "GS", "HM", "IO", "TF", |
| "UM"); // Outlying Oceania |
| } |
| |
| /** |
| * Finds the first region which is a common parent of two regions. If either |
| * region is null or if there is no common parent, returns null. Otherwise, |
| * returns the region which contains both regions. |
| * |
| * @param region1 |
| * @param region2 |
| * @return common parent or null if none |
| */ |
| public static String findCommonParent(String region1, String region2) { |
| if (region1 == null || region2 == null) { |
| return null; |
| } |
| List<String> parents1 = new ArrayList<String>(); |
| for (String parent = region1; parent != null; |
| parent = parentRegionMap.get(parent)) { |
| parents1.add(parent); |
| } |
| for (String parent = region2; parent != null; |
| parent = parentRegionMap.get(parent)) { |
| if (parents1.contains(parent)) { |
| return parent; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns a set of all ancestors of a given region, including the region |
| * itself, in order of inheritance (ie, this region first, top-most region |
| * last). |
| * |
| * @param child |
| * @return list of ancestors |
| */ |
| public static List<String> getAllAncestors(String child) { |
| List<String> returnVal = new ArrayList<String>(); |
| Set<String> nextGroup = new HashSet<String>(); |
| if (child != null) { |
| nextGroup.add(child); |
| } |
| while (!nextGroup.isEmpty()) { |
| Set<String> ancestors = new HashSet<String>(); |
| for (String region : nextGroup) { |
| ancestors.addAll(getImmediateParents(region)); |
| } |
| ancestors.removeAll(returnVal); |
| nextGroup.clear(); |
| nextGroup.addAll(ancestors); |
| returnVal.addAll(ancestors); |
| } |
| return returnVal; |
| } |
| |
| /** |
| * Returns the set of immediate parents of a given region, not including |
| * this region. |
| * |
| * @param region |
| * @return set of immediate parents |
| */ |
| public static Set<String> getImmediateParents(String region) { |
| Set<String> returnVal = new HashSet<String>(); |
| if (parentRegionMap.containsKey(region)) { |
| returnVal.add(parentRegionMap.get(region)); |
| } |
| return returnVal; |
| } |
| |
| /** |
| * Returns true if parent is equal to the child or is an ancestor. If both |
| * are null, true is returned; otherwise if either is null false is returned. |
| * |
| * @param parent |
| * @param child |
| * @return true if parent is an ancestor of child |
| */ |
| public static boolean isParentOf(String parent, String child) { |
| if (parent == child) { |
| return true; |
| } |
| while (child != null) { |
| if (child.equals(parent)) { |
| return true; |
| } |
| child = parentRegionMap.get(child); |
| } |
| return false; |
| } |
| |
| // @VisibleForTesting |
| static Map<String, String> getInheritanceMap() { |
| return parentRegionMap; |
| } |
| |
| private static void addChildren(String parent, String... children) { |
| for (String child : children) { |
| String oldParent = parentRegionMap.put(child, parent); |
| assert oldParent == null; |
| } |
| } |
| } |