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 }