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