1 package org.unicode.cldr.test;
2 
3 import java.io.File;
4 import java.util.Collections;
5 import java.util.HashSet;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.SortedSet;
9 import java.util.TreeMap;
10 import java.util.concurrent.ConcurrentHashMap;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13 
14 import org.unicode.cldr.draft.FileUtilities;
15 import org.unicode.cldr.util.CLDRConfig;
16 import org.unicode.cldr.util.CLDRFile;
17 import org.unicode.cldr.util.CLDRPaths;
18 import org.unicode.cldr.util.EmojiConstants;
19 import org.unicode.cldr.util.LanguageGroup;
20 import org.unicode.cldr.util.LocaleIDParser;
21 import org.unicode.cldr.util.Organization;
22 import org.unicode.cldr.util.StandardCodes;
23 
24 import com.google.common.collect.ImmutableMap;
25 import com.google.common.collect.ImmutableSet;
26 import com.google.common.collect.ImmutableSortedSet;
27 import com.ibm.icu.util.ULocale;
28 
29 public class EmojiSubdivisionNames {
30     private static final String subdivisionPathPrefix = "//ldml/localeDisplayNames/subdivisions/subdivision[@type=\"";
31     private static final String subdivisionPathSuffix = "\"]";
32     private static final Map<String,Map<String,String>> localeToNameToSubdivisionId = new ConcurrentHashMap<>();
33     private static final Map<String,Map<String,String>> localeToSubdivisionIdToName = new ConcurrentHashMap<>();
34 
35     private static final Pattern SUBDIVISION_PATTERN = Pattern.compile("\\s*<subdivision\\s+type=\"(gb(?:eng|sct|wls))\">([^<]+)</subdivision>");
36     private static final SortedSet<String> SUBDIVISION_FILE_NAMES = ImmutableSortedSet.copyOf(
37         new File(CLDRPaths.SUBDIVISIONS_DIRECTORY).list()
38         );
39 
40     static {
41         localeToNameToSubdivisionId.put("root", Collections.emptyMap());
42     }
43 
getSubdivisionIdToName(String localeID)44     public static Map<String, String> getSubdivisionIdToName(String localeID) {
45         Map<String,String> result = localeToSubdivisionIdToName.get(localeID);
46         if (result == null) {
47             load(localeID);
48             result = localeToSubdivisionIdToName.get(localeID);
49             if (result == null) {
50                 result = Collections.emptyMap();
51             }
52         }
53         return result;
54     }
55 
getNameToSubdivisionPath(String localeID)56     public static Map<String, String> getNameToSubdivisionPath(String localeID) {
57         Map<String,String> result = localeToNameToSubdivisionId.get(localeID);
58         if (result == null) {
59             load(localeID);
60             result = localeToNameToSubdivisionId.get(localeID);
61             if (result == null) {
62                 result = Collections.emptyMap();
63             }
64         }
65         return result;
66     }
67 
load(String localeID)68     private static void load(String localeID) {
69         try {
70             Map<String,String> _subdivisionIdToName;
71             Map<String, String> _nameToSubdivisionId;
72 
73             String fileName = localeID + ".xml";
74             if (SUBDIVISION_FILE_NAMES.contains(fileName)) {
75                 _nameToSubdivisionId = new TreeMap<>();
76                 _subdivisionIdToName = new TreeMap<>();
77                 Matcher m = SUBDIVISION_PATTERN.matcher("");
78                 for (String line : FileUtilities.in(new File(CLDRPaths.SUBDIVISIONS_DIRECTORY, fileName))) {
79                     if (m.reset(line).matches()) {
80                         String xpath = subdivisionPathPrefix + EmojiConstants.toTagSeq(m.group(1)) + subdivisionPathSuffix;
81                         _nameToSubdivisionId.put(m.group(2), xpath);
82                         _subdivisionIdToName.put(m.group(1), m.group(2));
83                     }
84                 }
85                 _nameToSubdivisionId = _nameToSubdivisionId.isEmpty() ? Collections.emptyMap()
86                     : ImmutableMap.copyOf(_nameToSubdivisionId);
87                 _subdivisionIdToName = _subdivisionIdToName.isEmpty() ? Collections.emptyMap()
88                     : ImmutableMap.copyOf(_subdivisionIdToName);
89             } else {
90                 String parentLocaleId = LocaleIDParser.getParent(localeID);
91                 _nameToSubdivisionId = getNameToSubdivisionPath(parentLocaleId);
92                 _subdivisionIdToName = localeToSubdivisionIdToName.get(parentLocaleId);
93             }
94             /*
95              * In practice _subdivisionIdToName == null actually happens here.
96              * Check for null rather than triggering NullPointerException.
97              */
98             if (_nameToSubdivisionId != null) {
99                 localeToNameToSubdivisionId.put(localeID, _nameToSubdivisionId);
100             }
101             if (_subdivisionIdToName != null) {
102                 localeToSubdivisionIdToName.put(localeID, _subdivisionIdToName);
103             }
104         } catch (Exception e) {
105             /*
106              * TODO: If there is a valid rationale for catching and ignoring all exceptions here,
107              * document it. Otherwise it should be avoided since it tends to hide programming errors.
108              */
109         }
110     }
111 
112     static Set<String> SUBDIVISIONS = ImmutableSet.of("gbeng", "gbsct", "gbwls");
113 
main(String[] args)114     public static void main(String[] args) {
115         System.out.print("Group\tOrd.\tLocale\tCode");
116         for (String sd : SUBDIVISIONS) {
117             System.out.print('\t');
118             System.out.print(sd);
119 
120         }
121         System.out.println();
122         CLDRFile english = CLDRConfig.getInstance().getEnglish();
123         Set<String> locales = new HashSet<>();
124         for (String filename : SUBDIVISION_FILE_NAMES) {
125             if (filename.endsWith(".xml")) {
126                 String locale = filename.substring(0, filename.length()-4);
127                 Map<String, String> map = getSubdivisionIdToName(locale);
128                 if (!map.isEmpty()) {
129                     locales.add(locale);
130                     ULocale ulocale = new ULocale(locale);
131                     LanguageGroup group = LanguageGroup.get(ulocale);
132                     int rank = LanguageGroup.rankInGroup(ulocale);
133                     System.out.print(group + "\t" + rank + "\t" + english.getName(locale) + "\t" + locale);
134                     for (String sd : SUBDIVISIONS) {
135                         System.out.print('\t');
136                         System.out.print(map.get(sd));
137                     }
138                     System.out.println();
139                 }
140             }
141         }
142         for (String locale : StandardCodes.make().getLocaleCoverageLocales(Organization.cldr)) {
143             if (locales.contains(locale)) {
144                 continue;
145             }
146             ULocale ulocale = new ULocale(locale);
147             String region = ulocale.getCountry();
148             if (!region.isEmpty() && !region.equals("PT") && !region.equals("GB")) {
149                 continue;
150             }
151             LanguageGroup group = LanguageGroup.get(ulocale);
152             int rank = LanguageGroup.rankInGroup(ulocale);
153             System.out.println(group + "\t" + rank + "\t" + english.getName(locale) + "\t" + locale);
154         }
155 
156 //        System.out.println(getSubdivisionIdToName("fr"));
157 //        System.out.println(getNameToSubdivisionPath("fr"));
158     }
159 }