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 ******************************************************************************* 6f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Copyright (C) 2011-2016, International Business Machines Corporation 7f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.util; 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ArrayList; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Arrays; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashMap; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.List; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Set; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.TreeSet; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUData; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.ICUResourceBundle; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>Region</code> is the class representing a Unicode Region Code, also known as a 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Unicode Region Subtag, which is defined based upon the BCP 47 standard. We often think of 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "regions" as "countries" when defining the characteristics of a locale. Region codes There are different 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * types of region codes that are important to distinguish. 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Macroregion - A code for a "macro geographical (continental) region, geographical sub-region, or 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * selected economic and other grouping" as defined in 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * UN M.49 (http://unstats.un.org/unsd/methods/m49/m49regin.htm). 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * These are typically 3-digit codes, but contain some 2-letter codes, such as the LDML code QO 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * added for Outlying Oceania. Not all UNM.49 codes are defined in LDML, but most of them are. 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Macroregions are represented in ICU by one of three region types: WORLD ( region code 001 ), 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * CONTINENTS ( regions contained directly by WORLD ), and SUBCONTINENTS ( things contained directly 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * by a continent ). 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * TERRITORY - A Region that is not a Macroregion. These are typically codes for countries, but also 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * include areas that are not separate countries, such as the code "AQ" for Antarctica or the code 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "HK" for Hong Kong (SAR China). Overseas dependencies of countries may or may not have separate 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * codes. The codes are typically 2-letter codes aligned with the ISO 3166 standard, but BCP47 allows 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for the use of 3-digit codes in the future. 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * UNKNOWN - The code ZZ is defined by Unicode LDML for use to indicate that the Region is unknown, 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or that the value supplied as a region was invalid. 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DEPRECATED - Region codes that have been defined in the past but are no longer in modern usage, 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * usually due to a country splitting into multiple territories or changing its name. 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * GROUPING - A widely understood grouping of territories that has a well defined membership such 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * that a region code has been assigned for it. Some of these are UNM.49 codes that do't fall into 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the world/continent/sub-continent hierarchy, while others are just well known groupings that have 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * their own region code. Region "EU" (European Union) is one such region code that is a grouping. 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Groupings will never be returned by the getContainingRegion() API, since a different type of region 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ( WORLD, CONTINENT, or SUBCONTINENT ) will always be the containing region instead. 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author John Emmons 59836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class Region implements Comparable<Region> { 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * RegionType is an enumeration defining the different types of regions. Current possible 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * values are WORLD, CONTINENT, SUBCONTINENT, TERRITORY, GROUPING, DEPRECATED, and UNKNOWN. 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public enum RegionType { 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing the unknown region. 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UNKNOWN, 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing a territory. 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TERRITORY, 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing the whole world. 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller WORLD, 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing a continent. 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CONTINENT, 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing a sub-continent. 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SUBCONTINENT, 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing a grouping of territories that is not to be used in 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the normal WORLD/CONTINENT/SUBCONTINENT/TERRITORY containment tree. 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller GROUPING, 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Type representing a region whose code has been deprecated, usually 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * due to a country splitting into multiple territories or changing its name. 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DEPRECATED, 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String id; 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int code; 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private RegionType type; 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Region containingRegion = null; 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Set<Region> containedRegions = new TreeSet<Region>(); 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private List<Region> preferredValues = null; 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static boolean regionDataIsLoaded = false; 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static Map<String,Region> regionIDMap = null; // Map from ID the regions 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static Map<Integer,Region> numericCodeMap = null; // Map from numeric code to the regions 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static Map<String,Region> regionAliases = null; // Aliases 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static ArrayList<Region> regions = null; // This is the main data structure where the Regions are stored. 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static ArrayList<Set<Region>> availableRegions = null; 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String UNKNOWN_REGION_ID = "ZZ"; 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String OUTLYING_OCEANIA_REGION_ID = "QO"; 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String WORLD_ID = "001"; 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Private default constructor. Use factory methods only. 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Region () {} 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initializes the region data from the ICU resource bundles. The region data 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * contains the basic relationships such as which regions are known, what the numeric 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * codes are, any known aliases, and the territory containment data. 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the region data has already loaded, then this method simply returns without doing 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * anything meaningful. 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static synchronized void loadRegionData() { 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionDataIsLoaded ) { 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionAliases = new HashMap<String,Region>(); 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionIDMap = new HashMap<String,Region>(); 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericCodeMap = new HashMap<Integer,Region>(); 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller availableRegions = new ArrayList<Set<Region>>(RegionType.values().length); 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle metadataAlias = null; 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle territoryAlias = null; 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle codeMappings = null; 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle idValidity = null; 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle regionList = null; 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle regionRegular = null; 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle regionMacro = null; 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle regionUnknown = null; 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle worldContainment = null; 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle territoryContainment = null; 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle groupingContainment = null; 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 163f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert UResourceBundle metadata = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,"metadata",ICUResourceBundle.ICU_DATA_CLASS_LOADER); 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller metadataAlias = metadata.get("alias"); 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller territoryAlias = metadataAlias.get("territory"); 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 167f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert UResourceBundle supplementalData = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,"supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER); 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller codeMappings = supplementalData.get("codeMappings"); 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller idValidity = supplementalData.get("idValidity"); 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionList = idValidity.get("region"); 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionRegular = regionList.get("regular"); 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionMacro = regionList.get("macroregion"); 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionUnknown = regionList.get("unknown"); 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller territoryContainment = supplementalData.get("territoryContainment"); 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller worldContainment = territoryContainment.get("001"); 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller groupingContainment = territoryContainment.get("grouping"); 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String[] continentsArr = worldContainment.getStringArray(); 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<String> continents = Arrays.asList(continentsArr); 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String[] groupingArr = groupingContainment.getStringArray(); 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<String> groupings = Arrays.asList(groupingArr); 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<String> regionCodes = new ArrayList<String>(); 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<String> allRegions = new ArrayList<String>(); 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller allRegions.addAll(Arrays.asList(regionRegular.getStringArray())); 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller allRegions.addAll(Arrays.asList(regionMacro.getStringArray())); 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller allRegions.add(regionUnknown.getString()); 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( String r : allRegions ) { 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rangeMarkerLocation = r.indexOf("~"); 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( rangeMarkerLocation > 0 ) { 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder regionName = new StringBuilder(r); 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char endRange = regionName.charAt(rangeMarkerLocation+1); 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionName.setLength(rangeMarkerLocation); 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char lastChar = regionName.charAt(rangeMarkerLocation-1); 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while ( lastChar <= endRange ) { 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String newRegion = regionName.toString(); 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionCodes.add(newRegion); 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller lastChar++; 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionName.setCharAt(rangeMarkerLocation-1,lastChar); 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionCodes.add(r); 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regions = new ArrayList<Region>(regionCodes.size()); 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // First process the region codes and create the master array of regions. 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( String id : regionCodes) { 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r = new Region(); 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.id = id; 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.TERRITORY; // Only temporary - figure out the real type later once the aliases are known. 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionIDMap.put(id, r); 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( id.matches("[0-9]{3}")) { 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.code = Integer.valueOf(id).intValue(); 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericCodeMap.put(r.code, r); 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.SUBCONTINENT; 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.code = -1; 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regions.add(r); 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Process the territory aliases 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int i = 0 ; i < territoryAlias.getSize(); i++ ) { 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle res = territoryAlias.get(i); 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String aliasFrom = res.getKey(); 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String aliasTo = res.get("replacement").getString(); 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(aliasTo) && !regionIDMap.containsKey(aliasFrom) ) { // This is just an alias from some string to a region 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionAliases.put(aliasFrom, regionIDMap.get(aliasTo)); 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r; 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(aliasFrom) ) { // This is a deprecated region 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(aliasFrom); 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { // Deprecated region code not in the master codes list - so need to create a deprecated region for it. 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = new Region(); 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.id = aliasFrom; 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionIDMap.put(aliasFrom, r); 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( aliasFrom.matches("[0-9]{3}")) { 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.code = Integer.valueOf(aliasFrom).intValue(); 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericCodeMap.put(r.code, r); 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.code = -1; 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regions.add(r); 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.DEPRECATED; 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<String> aliasToRegionStrings = Arrays.asList(aliasTo.split(" ")); 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.preferredValues = new ArrayList<Region>(); 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( String s : aliasToRegionStrings ) { 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (regionIDMap.containsKey(s)) { 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.preferredValues.add(regionIDMap.get(s)); 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Process the code mappings - This will allow us to assign numeric codes to most of the territories. 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int i = 0 ; i < codeMappings.getSize(); i++ ) { 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle mapping = codeMappings.get(i); 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( mapping.getType() == UResourceBundle.ARRAY ) { 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String [] codeMappingStrings = mapping.getStringArray(); 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String codeMappingID = codeMappingStrings[0]; 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Integer codeMappingNumber = Integer.valueOf(codeMappingStrings[1]); 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String codeMapping3Letter = codeMappingStrings[2]; 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(codeMappingID)) { 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r = regionIDMap.get(codeMappingID); 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.code = codeMappingNumber.intValue(); 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericCodeMap.put(r.code, r); 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionAliases.put(codeMapping3Letter, r); 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPINGS 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r; 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(WORLD_ID)) { 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(WORLD_ID); 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.WORLD; 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(UNKNOWN_REGION_ID)) { 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(UNKNOWN_REGION_ID); 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.UNKNOWN; 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( String continent : continents ) { 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (regionIDMap.containsKey(continent)) { 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(continent); 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.CONTINENT; 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( String grouping : groupings ) { 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (regionIDMap.containsKey(grouping)) { 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(grouping); 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.GROUPING; 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Special case: The region code "QO" (Outlying Oceania) is a subcontinent code added by CLDR 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // even though it looks like a territory code. Need to handle it here. 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( regionIDMap.containsKey(OUTLYING_OCEANIA_REGION_ID)) { 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionIDMap.get(OUTLYING_OCEANIA_REGION_ID); 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.type = RegionType.SUBCONTINENT; 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Load territory containment info from the supplemental data. 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int i = 0 ; i < territoryContainment.getSize(); i++ ) { 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UResourceBundle mapping = territoryContainment.get(i); 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String parent = mapping.getKey(); 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (parent.equals("containedGroupings") || parent.equals("deprecated")) { 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; // handle new pseudo-parent types added in ICU data per cldrbug 7808; for now just skip. 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // #11232 is to do something useful with these. 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region parentRegion = regionIDMap.get(parent); 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int j = 0 ; j < mapping.getSize(); j++ ) { 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String child = mapping.getString(j); 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region childRegion = regionIDMap.get(child); 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( parentRegion != null && childRegion != null ) { 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Add the child region to the set of regions contained by the parent 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parentRegion.containedRegions.add(childRegion); 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set the parent region to be the containing region of the child. 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Regions of type GROUPING can't be set as the parent, since another region 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // such as a SUBCONTINENT, CONTINENT, or WORLD must always be the parent. 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( parentRegion.getType() != RegionType.GROUPING) { 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller childRegion.containingRegion = parentRegion; 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Create the availableRegions lists 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0 ; i < RegionType.values().length ; i++) { 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller availableRegions.add(new TreeSet<Region>()); 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( Region ar : regions ) { 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<Region> currentSet = availableRegions.get(ar.type.ordinal()); 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller currentSet.add(ar); 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller availableRegions.set(ar.type.ordinal(),currentSet); 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller regionDataIsLoaded = true; 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns a Region using the given region ID. The region ID can be either a 2-letter ISO code, 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code as defined by the CLDR. 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param id The id of the region to be retrieved. 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The corresponding region. 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws NullPointerException if the supplied id is null. 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException if the supplied ID cannot be canonicalized to a Region ID that is known by ICU. 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Region getInstance(String id) { 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( id == null ) { 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new NullPointerException(); 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r = regionIDMap.get(id); 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r == null ) { 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionAliases.get(id); 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r == null ) { 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Unknown region id: " + id); 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r.type == RegionType.DEPRECATED && r.preferredValues.size() == 1) { 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = r.preferredValues.get(0); 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return r; 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns a Region using the given numeric code as defined by UNM.49 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param code The numeric code of the region to be retrieved. 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The corresponding region. 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException if the supplied numeric code is not recognized. 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Region getInstance(int code) { 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Region r = numericCodeMap.get(code); 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r == null ) { // Just in case there's an alias that's numeric, try to find it. 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pad = ""; 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( code < 10 ) { 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pad = "00"; 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( code < 100 ) { 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pad = "0"; 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String id = pad + Integer.toString(code); 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = regionAliases.get(id); 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r == null ) { 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Unknown region code: " + code); 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r.type == RegionType.DEPRECATED && r.preferredValues.size() == 1) { 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r = r.preferredValues.get(0); 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return r; 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Used to retrieve all available regions of a specific type. 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param type The type of regions to be returned ( TERRITORY, MACROREGION, etc. ) 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return An unmodifiable set of all known regions that match the given type. 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static Set<Region> getAvailable(RegionType type) { 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collections.unmodifiableSet(availableRegions.get(type.ordinal())); 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Used to determine the macroregion that geographically contains this region. 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The region that geographically contains this region. Returns NULL if this region is 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * code "001" (World) or "ZZ" (Unknown region). For example, calling this method with region "IT" (Italy) 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * returns the region "039" (Southern Europe). 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Region getContainingRegion() { 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return containingRegion; 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Used to determine the macroregion that geographically contains this region and that matches the given type. 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The region that geographically contains this region and matches the given type. May return NULL if 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * no containing region can be found that matches the given type. For example, calling this method with region "IT" (Italy) 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and type CONTINENT returns the region "150" (Europe). 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Region getContainingRegion(RegionType type) { 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( containingRegion == null ) { 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( containingRegion.type.equals(type)) { 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return containingRegion; 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return containingRegion.getContainingRegion(type); 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Used to determine the sub-regions that are contained within this region. 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return An unmodifiable set containing all the regions that are immediate children 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of this region in the region hierarchy. These returned regions could be either macro 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * regions, territories, or a mixture of the two, depending on the containment data as defined 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in CLDR. This API may return an empty set if this region doesn't have any sub-regions. 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, calling this method with region "150" (Europe) returns a set containing 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * - "154" (Northern Europe) and "155" (Western Europe). 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<Region> getContainedRegions() { 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collections.unmodifiableSet(containedRegions); 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Used to determine all the regions that are contained within this region and that match the given type 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return An unmodifiable set containing all the regions that are children of this region 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * anywhere in the region hierarchy and match the given type. This API may return an empty set 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if this region doesn't have any sub-regions that match the given type. 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, calling this method with region "150" (Europe) and type "TERRITORY" returns a set 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. ) 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<Region> getContainedRegions(RegionType type) { 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<Region> result = new TreeSet<Region>(); 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<Region> cr = getContainedRegions(); 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( Region r : cr ) { 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( r.getType() == type ) { 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.add(r); 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.addAll(r.getContainedRegions(type)); 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collections.unmodifiableSet(result); 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return For deprecated regions, return an unmodifiable list of the regions that are the preferred replacement regions for this region. 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns null for a non-deprecated region. For example, calling this method with region "SU" (Soviet Union) would 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * return a list of the regions containing "RU" (Russia), "AM" (Armenia), "AZ" (Azerbaijan), etc... 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public List<Region> getPreferredValues() { 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( type == RegionType.DEPRECATED) { 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collections.unmodifiableList(preferredValues); 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Returns true if this region contains the supplied other region anywhere in the region hierarchy. 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean contains(Region other) { 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller loadRegionData(); 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (containedRegions.contains(other)) { 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (Region cr : containedRegions) { 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cr.contains(other)) { 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns the string representation of this region 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The string representation of this region, which is its ID. 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return id; 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the numeric code for this region 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return The numeric code for this region. Returns a negative value if the given region does not have a numeric 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * code assigned to it. This is a very rare case and only occurs for a few very small territories. 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getNumericCode() { 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return code; 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns this region's type. 5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return This region's type classification, such as MACROREGION or TERRITORY. 5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public RegionType getType() { 5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return type; 5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@inheritDoc} 5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int compareTo(Region other) { 5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return id.compareTo(other.id); 5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 583