1 package org.unicode.cldr.tool; 2 3 import java.io.IOException; 4 import java.util.Collections; 5 import java.util.LinkedHashSet; 6 import java.util.Locale; 7 import java.util.Map; 8 import java.util.Set; 9 import java.util.TreeMap; 10 11 import org.unicode.cldr.util.CldrUtility; 12 import org.unicode.cldr.util.CldrUtility.LineHandler; 13 import org.unicode.cldr.util.StandardCodes; 14 15 import com.ibm.icu.text.UTF16; 16 import com.ibm.icu.util.ICUUncheckedIOException; 17 import com.ibm.icu.util.ULocale; 18 19 public class CountryCodeConverter { 20 21 private static final boolean SHOW_SKIP = CldrUtility.getProperty("SHOW_SKIP", false); 22 23 private static Map<String, String> nameToCountryCode = new TreeMap<>(new UTF16.StringComparator(true, true, 0)); 24 private static Set<String> parseErrors = new LinkedHashSet<>(); 25 getCodeFromName(String display, boolean showMissing)26 public static String getCodeFromName(String display, boolean showMissing) { 27 return getCodeFromName(display, showMissing, null); 28 } 29 30 /** 31 * 32 * @param display 33 * @param showMissing 34 * @param missing will contain a list of missing names (if showMissing is true) 35 * @return 36 */ getCodeFromName(String display, boolean showMissing, Set<String> missing)37 public static String getCodeFromName(String display, boolean showMissing, Set<String> missing) { 38 String trial = display.trim().toLowerCase(Locale.ENGLISH); 39 if (trial.startsWith("\"") && trial.endsWith("\"")) { 40 trial = trial.substring(1, trial.length() - 2); 41 } 42 if (trial.startsWith("the ")) { 43 trial = trial.substring(4); 44 } 45 String result = nameToCountryCode.get(trial); 46 if ("skip".equals(result)) { 47 return null; 48 } 49 if (result == null) { 50 trial = reverseComma(display); 51 if (trial != null) { 52 result = nameToCountryCode.get(trial); 53 // if (result != null) { 54 // addName(trial, result); 55 // } 56 } 57 } 58 if (result == null && (showMissing || SHOW_SKIP)) { 59 System.err.println("ERROR: CountryCodeConverter missing code for " + display + ".\n" + 60 "To fix: add to external/alternate_country_names.txt a line such as:\n" + 61 "\t<code>;\t<name>;\t" + display); 62 if (missing != null ) { 63 missing.add(display); 64 } 65 } 66 return result; 67 } 68 names()69 public static Set<String> names() { 70 return nameToCountryCode.keySet(); 71 } 72 reverseComma(String display)73 private static String reverseComma(String display) { 74 String trial; 75 trial = null; 76 int comma = display.indexOf(','); 77 if (comma >= 0) { 78 trial = display.substring(comma + 1).trim() + " " + display.substring(0, comma).trim(); 79 } 80 return trial; 81 } 82 83 static { 84 try { loadNames()85 loadNames(); 86 } catch (IOException e) { 87 throw new ICUUncheckedIOException(e); 88 } 89 } 90 loadNames()91 static void loadNames() throws IOException { 92 for (String country : ULocale.getISOCountries()) { 93 addName(ULocale.getDisplayCountry("und-" + country, "en"), country); 94 } 95 StandardCodes sc = StandardCodes.make(); 96 Set<String> goodAvailableCodes = sc.getGoodAvailableCodes("territory"); 97 98 for (String country : goodAvailableCodes) { 99 String description = sc.getFullData("territory", country).get(0); 100 if (country.equals("057")) continue; 101 addName(description, country); 102 } 103 CldrUtility.handleFile("external/alternate_country_names.txt", new MyHandler(goodAvailableCodes)); 104 nameToCountryCode = CldrUtility.protectCollection(nameToCountryCode); 105 parseErrors = Collections.unmodifiableSet(parseErrors); 106 } 107 108 static class MyHandler implements LineHandler { 109 private Set<String> goodAvailableCodes; 110 MyHandler(Set<String> goodAvailableCodes)111 public MyHandler(Set<String> goodAvailableCodes) { 112 this.goodAvailableCodes = goodAvailableCodes; 113 } 114 115 @Override handle(String line)116 public boolean handle(String line) { 117 if (line.trim().length() == 0) { 118 return true; // don't show skips 119 } 120 String[] pieces = line.split(";"); 121 String country = pieces[0].trim(); 122 if (!goodAvailableCodes.contains(country)) { 123 124 } 125 addName(pieces[2].trim(), country); 126 return true; 127 } 128 } 129 addName(String key, String code)130 static void addName(String key, String code) { 131 addName2(key, code); 132 String trial = reverseComma(key); 133 if (trial != null) { 134 addName2(trial, code); 135 } 136 } 137 addName2(String key, String code)138 private static void addName2(String key, String code) { 139 key = key.toLowerCase(Locale.ENGLISH); 140 if (key.startsWith("the ")) { 141 key = key.substring(4); 142 } 143 String old = nameToCountryCode.get(key); 144 if (old != null && !code.equals(old)) { 145 System.err.println("Conflict!!" + key + "\t" + old + "\t" + code); 146 return; 147 } 148 nameToCountryCode.put(key, code); 149 } 150 getParseErrors()151 public static Set<String> getParseErrors() { 152 return parseErrors; 153 } 154 155 } 156