1 package org.unicode.cldr.tool; 2 3 import com.google.common.collect.ImmutableMap; 4 import com.google.common.collect.ImmutableSortedSet; 5 import java.io.File; 6 import java.util.ArrayList; 7 import java.util.List; 8 import java.util.Locale; 9 import java.util.Map; 10 import java.util.Map.Entry; 11 import java.util.Set; 12 import java.util.TreeMap; 13 import java.util.TreeSet; 14 import java.util.regex.Pattern; 15 import org.unicode.cldr.util.CLDRConfig; 16 import org.unicode.cldr.util.CLDRPaths; 17 import org.unicode.cldr.util.CldrUtility; 18 import org.unicode.cldr.util.Factory; 19 import org.unicode.cldr.util.LocaleIDParser; 20 import org.unicode.cldr.util.Pair; 21 import org.unicode.cldr.util.XMLFileReader; 22 import org.unicode.cldr.util.XPathParts; 23 24 public class SubdivisionNames { 25 26 public static final String SUBDIVISION_PATH_PREFIX = 27 "//ldml/localeDisplayNames/subdivisions/subdivision"; 28 29 private final Map<String, String> subdivisionToName; 30 SubdivisionNames(String locale)31 public SubdivisionNames(String locale) { 32 this(locale, "subdivisions"); 33 } 34 35 /** 36 * Get the subdivision names for the locale in all the directories 37 * 38 * @param locale 39 * @param dirs 40 */ SubdivisionNames(String locale, String... dirs)41 public SubdivisionNames(String locale, String... dirs) { 42 43 // do inheritance 44 45 Map<String, String> builder = new TreeMap<>(); 46 while (true) { 47 addSubdivisionNames(locale, builder, dirs); 48 String parent = LocaleIDParser.getParent(locale); 49 if (parent == null || parent.equals("root")) { 50 break; 51 } 52 locale = parent; 53 } 54 55 subdivisionToName = ImmutableMap.copyOf(builder); 56 } 57 addSubdivisionNames(String locale, Map<String, String> builder, String... dirs)58 private void addSubdivisionNames(String locale, Map<String, String> builder, String... dirs) { 59 List<Pair<String, String>> data = new ArrayList<>(); 60 for (String dir : dirs) { 61 try { 62 XMLFileReader.loadPathValues( 63 CLDRPaths.COMMON_DIRECTORY + dir + "/" + locale + ".xml", data, true); 64 for (Pair<String, String> pair : data) { 65 String name = pair.getSecond(); 66 if (CldrUtility.INHERITANCE_MARKER.contentEquals(name)) { 67 continue; 68 } 69 // <subdivision type="AD-02">Canillo</subdivision> 70 String rawPath = pair.getFirst(); 71 XPathParts path = XPathParts.getFrozenInstance(rawPath); 72 if (!"subdivision".equals(path.getElement(-1))) { 73 continue; 74 } 75 String type = path.getAttributeValue(-1, "type"); 76 if (!builder.containsKey(type)) { // only add if not there already 77 builder.put(type, name); 78 } 79 } 80 } catch (Exception e) { 81 } // if we can't find it, skip 82 } 83 } 84 getAvailableLocales()85 public static Set<String> getAvailableLocales() { 86 return getAvailableLocales("subdivisions"); 87 } 88 getAvailableLocales(String... dirs)89 public static Set<String> getAvailableLocales(String... dirs) { 90 TreeSet<String> result = new TreeSet<>(); 91 for (String dir : dirs) { 92 File baseDir = new File(CLDRPaths.COMMON_DIRECTORY + dir + "/"); 93 for (String file : baseDir.list()) { 94 if (file.endsWith(".xml")) { 95 result.add(file.substring(0, file.length() - 4)); 96 } 97 } 98 } 99 return ImmutableSortedSet.copyOf(result); 100 } 101 entrySet()102 public Set<Entry<String, String>> entrySet() { 103 return subdivisionToName.entrySet(); 104 } 105 get(String subdivision)106 public String get(String subdivision) { 107 return subdivisionToName.get(subdivision); 108 } 109 keySet()110 public Set<String> keySet() { 111 return subdivisionToName.keySet(); 112 } 113 getPathFromCode(String code)114 public static String getPathFromCode(String code) { 115 // <subdivision type="AD-02">Canillo</subdivision> 116 return SUBDIVISION_PATH_PREFIX + "[@type=\"" + code + "\"]"; 117 } 118 getRegionFromSubdivision(String sdCode)119 public static String getRegionFromSubdivision(String sdCode) { 120 return sdCode.compareTo("A") < 0 121 ? sdCode.substring(0, 3) 122 : sdCode.substring(0, 2).toUpperCase(Locale.ENGLISH); 123 } 124 getSubregion(String sdCode)125 public static String getSubregion(String sdCode) { 126 return sdCode.compareTo("A") < 0 127 ? sdCode.substring(3) 128 : sdCode.substring(2).toUpperCase(Locale.ENGLISH); 129 } 130 isRegionCode(String regionOrSubdivision)131 public static boolean isRegionCode(String regionOrSubdivision) { 132 return regionOrSubdivision.length() == 2 133 || (regionOrSubdivision.length() == 3 && regionOrSubdivision.compareTo("A") < 0); 134 } 135 toIsoFormat(String sdCode)136 public static String toIsoFormat(String sdCode) { 137 sdCode = sdCode.toUpperCase(Locale.ENGLISH); 138 int insertion = sdCode.compareTo("A") < 0 ? 3 : 2; 139 return sdCode.substring(0, insertion) + "-" + sdCode.substring(insertion); 140 } 141 142 static final Pattern OLD_SUBDIVISION = Pattern.compile("[a-zA-Z]{2}[-_][a-zA-Z0-9]{1,4}"); 143 144 public static boolean isOldSubdivisionCode(String item) { 145 return item.length() > 4 && item.length() < 7 && OLD_SUBDIVISION.matcher(item).matches(); 146 } 147 148 public static void main(String[] args) { 149 Factory annotations = CLDRConfig.getInstance().getAnnotationsFactory(); 150 for (String locale : annotations.getAvailable()) { 151 SubdivisionNames sd = new SubdivisionNames(locale, "main", "subdivisions"); 152 /** 153 * <subdivision type="gbeng">England</subdivision> <subdivision 154 * type="gbsct">Scotland</subdivision> <subdivision type="gbwls">Wales</subdivision> 155 */ 156 System.out.println( 157 locale 158 + " gbeng=" 159 + sd.get("gbeng") 160 + " gbsct=" 161 + sd.get("gbsct") 162 + " gbwls=" 163 + sd.get("gbwls")); 164 } 165 } 166 } 167