• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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