1 package org.unicode.cldr.tool; 2 3 import java.io.File; 4 import java.util.ArrayList; 5 import java.util.List; 6 import java.util.Locale; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.Set; 10 import java.util.TreeMap; 11 import java.util.TreeSet; 12 import java.util.regex.Pattern; 13 14 import org.unicode.cldr.util.CLDRConfig; 15 import org.unicode.cldr.util.CLDRPaths; 16 import org.unicode.cldr.util.CldrUtility; 17 import org.unicode.cldr.util.Factory; 18 import org.unicode.cldr.util.LocaleIDParser; 19 import org.unicode.cldr.util.Pair; 20 import org.unicode.cldr.util.XMLFileReader; 21 import org.unicode.cldr.util.XPathParts; 22 23 import com.google.common.collect.ImmutableMap; 24 import com.google.common.collect.ImmutableSortedSet; 25 26 public class SubdivisionNames { 27 28 public static final String SUBDIVISION_PATH_PREFIX = "//ldml/localeDisplayNames/subdivisions/subdivision"; 29 30 private final Map<String, String> subdivisionToName; 31 SubdivisionNames(String locale)32 public SubdivisionNames(String locale) { 33 this(locale, "subdivisions"); 34 } 35 36 /** 37 * Get the subdivision names for the locale in all the directories 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(CLDRPaths.COMMON_DIRECTORY + dir + "/" 63 + locale 64 + ".xml", data, true); 65 for (Pair<String, String> pair : data) { 66 String name = pair.getSecond(); 67 if (CldrUtility.INHERITANCE_MARKER.contentEquals(name)) { 68 continue; 69 } 70 // <subdivision type="AD-02">Canillo</subdivision> 71 String rawPath = pair.getFirst(); 72 XPathParts path = XPathParts.getFrozenInstance(rawPath); 73 if (!"subdivision".equals(path.getElement(-1))) { 74 continue; 75 } 76 String type = path.getAttributeValue(-1, "type"); 77 if (!builder.containsKey(type)) { // only add if not there already 78 builder.put(type, name); 79 } 80 } 81 } catch (Exception e) {} // 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 117 + "[@type=\"" + code + "\"]"; 118 } 119 getRegionFromSubdivision(String sdCode)120 public static String getRegionFromSubdivision(String sdCode) { 121 return sdCode.compareTo("A") < 0 ? sdCode.substring(0, 3) : sdCode.substring(0, 2).toUpperCase(Locale.ENGLISH); 122 } 123 getSubregion(String sdCode)124 public static String getSubregion(String sdCode) { 125 return sdCode.compareTo("A") < 0 ? sdCode.substring(3) : sdCode.substring(2).toUpperCase(Locale.ENGLISH); 126 } 127 isRegionCode(String regionOrSubdivision)128 public static boolean isRegionCode(String regionOrSubdivision) { 129 return regionOrSubdivision.length() == 2 130 || (regionOrSubdivision.length() == 3 && regionOrSubdivision.compareTo("A") < 0); 131 } 132 toIsoFormat(String sdCode)133 public static String toIsoFormat(String sdCode) { 134 sdCode = sdCode.toUpperCase(Locale.ENGLISH); 135 int insertion = sdCode.compareTo("A") < 0 ? 3 : 2; 136 return sdCode.substring(0, insertion) + "-" + sdCode.substring(insertion); 137 } 138 139 static final Pattern OLD_SUBDIVISION = Pattern.compile("[a-zA-Z]{2}[-_][a-zA-Z0-9]{1,4}"); 140 141 public static boolean isOldSubdivisionCode(String item) { 142 return item.length() > 4 && item.length() < 7 && OLD_SUBDIVISION.matcher(item).matches(); 143 } 144 145 public static void main(String[] args) { 146 Factory annotations = CLDRConfig.getInstance().getAnnotationsFactory(); 147 for (String locale : annotations.getAvailable()) { 148 SubdivisionNames sd = new SubdivisionNames(locale, "main", "subdivisions"); 149 /** 150 * <subdivision type="gbeng">England</subdivision> 151 <subdivision type="gbsct">Scotland</subdivision> 152 <subdivision type="gbwls">Wales</subdivision> 153 154 */ 155 System.out.println(locale 156 + " gbeng=" + sd.get("gbeng") 157 + " gbsct=" + sd.get("gbsct") 158 + " gbwls=" + sd.get("gbwls") 159 ); 160 } 161 } 162 } 163