1 package org.unicode.cldr.tool; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.util.Locale; 7 import java.util.Map; 8 import java.util.Set; 9 import java.util.TreeMap; 10 import java.util.TreeSet; 11 import java.util.regex.Matcher; 12 13 import org.unicode.cldr.draft.FileUtilities; 14 import org.unicode.cldr.util.CLDRFile; 15 import org.unicode.cldr.util.CLDRFile.WinningChoice; 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.Pair; 20 import org.unicode.cldr.util.PathUtilities; 21 import org.unicode.cldr.util.PatternCache; 22 import org.unicode.cldr.util.SimpleFactory; 23 import org.unicode.cldr.util.StandardCodes; 24 import org.unicode.cldr.util.TransliteratorUtilities; 25 import org.unicode.cldr.util.XMLFileReader; 26 27 import com.ibm.icu.impl.Relation; 28 import com.ibm.icu.lang.UCharacter; 29 import com.ibm.icu.text.Collator; 30 import com.ibm.icu.text.DateFormatSymbols; 31 import com.ibm.icu.text.UnicodeSet; 32 import com.ibm.icu.util.ULocale; 33 34 class ExtractMessages { 35 public static final UnicodeSet LATIN_SCRIPT = new UnicodeSet("[:script=latin:]").freeze(); 36 37 private static Matcher fileMatcher; 38 39 public static PrintWriter output; 40 41 public static boolean SKIPEQUALS = true; 42 public static boolean SKIPIFCLDR = true; 43 public static String DIR = CLDRPaths.GEN_DIRECTORY + "/../additions/"; 44 main(String[] args)45 public static void main(String[] args) throws IOException { 46 double startTime = System.currentTimeMillis(); 47 output = FileUtilities.openUTF8Writer(DIR, "additions.txt"); 48 int totalCount = 0; 49 Set<String> skipped = new TreeSet<>(); 50 51 try { 52 String sourceDirectory = getProperty("SOURCE", null); 53 if (sourceDirectory == null) { 54 System.out.println("Need Source Directory! "); 55 return; 56 } 57 fileMatcher = PatternCache.get(getProperty("FILE", ".*")).matcher(""); 58 59 SKIPIFCLDR = getProperty("SKIPIFCLDR", null) != null; 60 61 boolean showMissing = true; 62 63 File src = new File(sourceDirectory); 64 65 XMLFileReader xfr = new XMLFileReader().setHandler(new EnglishHandler()); 66 xfr.read(src + "/en.xmb", XMLFileReader.CONTENT_HANDLER 67 | XMLFileReader.ERROR_HANDLER, false); 68 69 for (File file : src.listFiles()) { 70 if (file.isDirectory()) 71 continue; 72 if (file.length() == 0) 73 continue; 74 String canonicalFile = PathUtilities.getNormalizedPathString(file); 75 if (!canonicalFile.endsWith(".xtb")) { 76 continue; 77 } 78 79 String name = file.getName(); 80 name = name.substring(0, name.length() - 4); 81 82 if (!fileMatcher.reset(name).matches()) { 83 continue; 84 } 85 System.out.println("* " + canonicalFile); 86 87 try { 88 otherHandler.setLocale(name); 89 } catch (RuntimeException e1) { 90 System.out.println("Skipping, no CLDR locale file: " + name + "\t" + english.getName(name) + "\t" 91 + e1.getClass().getName() + "\t" + e1.getMessage()); 92 skipped.add(name); 93 continue; 94 } 95 96 xfr = new XMLFileReader().setHandler(otherHandler); 97 try { 98 xfr.read(canonicalFile, XMLFileReader.CONTENT_HANDLER 99 | XMLFileReader.ERROR_HANDLER, false); 100 } catch (RuntimeException e) { 101 System.out.println(e.getMessage()); 102 continue; 103 } 104 105 // now write it out 106 CLDRFile newFile = SimpleFactory.makeFile(otherHandler.getLocale()); 107 int itemCount = 0; 108 for (DataHandler dataHandler : dataHandlers) { 109 if (showMissing) { 110 System.out.println("case " + dataHandler.type + ":"); 111 for (String value : dataHandler.missing) { 112 System.out.println("addName(\"" + value + "\", \"XXX\", true);"); 113 } 114 } 115 116 for (String id : dataHandler.id_to_value.keySet()) { 117 Set<String> otherValue = dataHandler.id_to_value.getAll(id); 118 if (otherValue == null || otherValue.size() == 0) continue; 119 String cldrValue = dataHandler.id_to_cldrValue.get(id); 120 int count = 0; 121 for (String oValue : otherValue) { 122 itemCount++; 123 output.println(otherHandler.getLocale() 124 + "\t" + dataHandler.type 125 + "\t" + id 126 + "\t" + oValue 127 + (cldrValue == null ? "" : "\tcldr:\t" + cldrValue) 128 + (count == 0 ? "" : "\talt:\t" + String.valueOf(count))); 129 newFile.add(dataHandler.getPath(id, count), oValue); 130 } 131 } 132 } 133 PrintWriter cldrOut = FileUtilities.openUTF8Writer(DIR, otherHandler.getLocale() + ".xml"); 134 newFile.write(cldrOut); 135 cldrOut.close(); 136 137 output.println(); 138 showMissing = false; 139 output.flush(); 140 System.out.println("\titems: " + itemCount); 141 totalCount += itemCount; 142 } 143 144 for (String name : skipped) { 145 System.out.println("\tSkipping, no CLDR locale file: " + name + "\t" + english.getName(name)); 146 } 147 double deltaTime = System.currentTimeMillis() - startTime; 148 System.out.println("Elapsed: " + deltaTime / 1000.0 + " seconds"); 149 System.out.println("\ttotal items: " + totalCount); 150 } finally { 151 output.close(); 152 } 153 } 154 getProperty(String key, String defaultValue)155 private static String getProperty(String key, String defaultValue) { 156 String fileRegex = System.getProperty(key); 157 if (fileRegex == null) 158 fileRegex = defaultValue; 159 System.out.println("-D" + key + "=" + fileRegex); 160 return fileRegex; 161 } 162 163 private static Map<String, Pair<String, DataHandler>> numericId_Id = new TreeMap<>(); 164 private static Matcher numericIdMatcher = PatternCache.get("\\[@id=\"([^\"]+)\"\\]").matcher(""); 165 private static Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*"); 166 private static CLDRFile english = cldrFactory.make("en", true); 167 168 private static class EnglishHandler extends XMLFileReader.SimpleHandler { 169 170 @Override handlePathValue(String path, String value)171 public void handlePathValue(String path, String value) { 172 for (DataHandler handler : dataHandlers) { 173 if (handler.matches(path)) { 174 // //messagebundle/msg[@id="1907015897505457162"][@seq="71982"][@desc="Andorra is a display name for a timezone"][@xml:space="default"] 175 numericIdMatcher.reset(path).find(); 176 String id = numericIdMatcher.group(1); 177 value = value.trim(); 178 if (value.length() == 0) return; // skip empties 179 value = TransliteratorUtilities.fromXML.transliterate(value); 180 String realID = handler.getCode(value); 181 if (realID == null) { 182 handler.missing.add(value); 183 return; 184 } 185 numericId_Id.put(id, new Pair<>(realID, handler)); 186 // System.out.println(id + "\t" + path + "\t" + value); 187 } 188 } 189 } 190 } 191 192 public static Collator col = Collator.getInstance(ULocale.ENGLISH); 193 static { 194 col.setStrength(Collator.SECONDARY); 195 } 196 197 private static OtherHandler otherHandler = new OtherHandler(); 198 199 private static class OtherHandler extends XMLFileReader.SimpleHandler { 200 private String locale; 201 private ULocale uLocale; 202 CLDRFile cldrFile; 203 boolean usesLatin; 204 205 @Override handlePathValue(String path, String value)206 public void handlePathValue(String path, String value) { 207 // //messagebundle/msg[@id="1907015897505457162"][@seq="71982"][@desc="Andorra is a display name for a timezone"][@xml:space="default"] 208 value = value.trim(); 209 if (value.length() == 0) return; // skip empties 210 211 numericIdMatcher.reset(path).find(); 212 String numericId = numericIdMatcher.group(1); 213 Pair<String, DataHandler> id_handler = numericId_Id.get(numericId); 214 if (id_handler == null) return; 215 String id = id_handler.getFirst(); 216 DataHandler dataHandler = id_handler.getSecond(); 217 218 if (!usesLatin && LATIN_SCRIPT.containsSome(value)) { 219 // output.println(locale + "\tSkipping item with latin characters\t" + id + "\t" + value); 220 return; 221 } 222 223 // this should be reorganized to put more in the DataHandler, but for now... 224 225 value = dataHandler.fixValue(uLocale, value); 226 227 String cldrValue = dataHandler.getCldrValue(cldrFile, id); 228 if (cldrValue != null) { 229 if (col.compare(cldrValue, value) == 0) { 230 // System.out.println("Duplicate for " + id + "\t" + value); 231 if (SKIPEQUALS) return; 232 } else { 233 if (SKIPIFCLDR) return; 234 // output.println(locale + "\tDifferent value for\t" + id + "\t" + value + "\tcldr:\t" + cldrValue); 235 } 236 } 237 dataHandler.addValues(id, value, cldrValue); 238 } 239 setLocale(String locale)240 public void setLocale(String locale) { 241 242 // skip en, fr_CA 243 // as, sa bad 244 // ku cldr-latin, g-arabic 245 // ml, my, pa, te has mixed english 246 // TODO move this into datahandler eventually 247 locale = fixLocale(locale); 248 this.locale = locale; 249 this.uLocale = new ULocale(locale); 250 String lang = uLocale.getLanguage(); 251 if (locale.equals("fr_CA") || lang.equals("en")) { 252 throw new RuntimeException("Skipping " + locale); 253 } 254 cldrFile = cldrFactory.make(locale, false); 255 UnicodeSet exemplars = cldrFile.getExemplarSet("", WinningChoice.WINNING); 256 usesLatin = exemplars != null && exemplars.containsSome(LATIN_SCRIPT); 257 for (DataHandler dataHandler : dataHandlers) { 258 dataHandler.reset(cldrFile); 259 } 260 } 261 getLocale()262 public String getLocale() { 263 return locale; 264 } 265 } 266 267 static Map<String, String> fixLocaleMap = CldrUtility.asMap(new String[][] { 268 { "zh_CN", "zh" }, 269 { "zh_TW", "zh_Hant" }, 270 { "pt_BR", "pt" }, 271 { "in", "id" }, 272 { "iw", "he" }, 273 { "jw", "jv" }, 274 { "ku", "ku_Arab" }, 275 }); 276 fixLocale(String locale)277 static private String fixLocale(String locale) { 278 locale = locale.replace('-', '_'); 279 String newLocale = fixLocaleMap.get(locale); 280 if (newLocale != null) { 281 locale = newLocale; 282 } 283 return locale; 284 } 285 286 /* 287 * Language 288 * -DXMLPATH=".*form of language.*" 289 * 290 * Country 291 * -DXMLPATH=".*the country or region.*" 292 * 293 * Currency 294 * -DXMLPATH=".*currency name.*" 295 * 296 * Month Long/Short 297 * -DXMLPATH=".*Name of the month of .*" 298 * -DXMLPATH=".*3 letter abbreviation for name of Month.*" 299 * 300 * Week Long/Short 301 * -DXMLPATH=".*day in week.*" 302 * -DXMLPATH=".*Short Version of .*" 303 * 304 * Timezone 305 * DXMLPATH=".*is a display name for a timezone.*" 306 */ 307 308 enum Type { 309 LANGUAGE, REGION, CURRENCY, MONTH, MONTHSHORT, DAY, DAYSHORT, TIMEZONE 310 } 311 312 static StandardCodes sc = StandardCodes.make(); 313 static DateFormatSymbols dfs = new DateFormatSymbols(ULocale.ENGLISH); 314 315 static DataHandler[] dataHandlers = { 316 new DataHandler(Type.LANGUAGE, ".*form of language.*"), 317 new DataHandler(Type.REGION, ".*the country or region.*"), 318 new DataHandler(Type.CURRENCY, ".*currency name.*"), 319 new DataHandler(Type.MONTH, ".*Name of the month of .*"), 320 new DataHandler(Type.MONTHSHORT, ".*3 letter abbreviation for name of Month.*"), 321 new DataHandler(Type.DAY, ".*day in week.*"), 322 new DataHandler(Type.DAYSHORT, ".*Short Version of .*"), 323 new DataHandler(Type.TIMEZONE, ".*is a display name for a timezone.*"), 324 }; 325 326 enum CasingAction { 327 NONE, FORCE_TITLE, FORCE_LOWER 328 } 329 330 static class DataHandler implements Comparable<DataHandler> { 331 // mostly stable 332 private Matcher matcher; 333 private Type type; 334 private Map<String, String> name_code = new TreeMap<>(); 335 // private Map<String,String> code_name = new TreeMap(); 336 private Set<String> missing = new TreeSet<>(); 337 338 // changes with each locale, must call reset 339 private Relation<String, String> id_to_value = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class); 340 private Map<String, String> id_to_cldrValue = new TreeMap<>(); 341 private CasingAction forceCasing = CasingAction.NONE; 342 reset(CLDRFile cldrFile)343 public void reset(CLDRFile cldrFile) { 344 id_to_value.clear(); 345 id_to_cldrValue.clear(); 346 forceCasing = CasingAction.NONE; 347 String key = null; 348 switch (type) { 349 case LANGUAGE: 350 key = "en"; 351 break; 352 case REGION: 353 key = "FR"; 354 break; 355 case CURRENCY: 356 key = "GBP"; 357 break; 358 case MONTH: 359 case MONTHSHORT: 360 key = "1"; 361 break; 362 case DAY: 363 case DAYSHORT: 364 key = "mon"; 365 break; 366 case TIMEZONE: 367 key = "America/New_York"; 368 break; 369 } 370 String sample = getCldrValue(cldrFile, key); 371 if (sample != null) { 372 if (UCharacter.isLowerCase(sample.charAt(0))) { 373 forceCasing = CasingAction.FORCE_LOWER; 374 } else if (UCharacter.isUpperCase(sample.charAt(0))) { 375 forceCasing = CasingAction.FORCE_TITLE; 376 } 377 } 378 } 379 fixValue(ULocale uLocale, String value)380 public String fixValue(ULocale uLocale, String value) { 381 value = TransliteratorUtilities.fromXML.transliterate(value); 382 383 if (forceCasing == CasingAction.FORCE_LOWER) { 384 if (!UCharacter.isLowerCase(value.charAt(0))) { 385 value = UCharacter.toLowerCase(value); 386 } 387 } else if (forceCasing == CasingAction.FORCE_TITLE) { 388 if (!UCharacter.isUpperCase(value.charAt(0))) { 389 value = UCharacter.toTitleCase(uLocale, value, null); 390 } 391 } 392 393 return value; 394 } 395 addValues(String id, String value, String cldrValue)396 public void addValues(String id, String value, String cldrValue) { 397 id_to_value.put(id, value); 398 if (cldrValue != null) { 399 id_to_cldrValue.put(id, cldrValue); 400 } 401 } 402 addName(String name, String code, boolean skipMessage)403 public void addName(String name, String code, boolean skipMessage) { 404 // String old = code_name.get(code); 405 // if (old != null) { 406 // if (!skipMessage) { 407 // System.out.println("Name collision:\t" + code + "\tnew: " + name + "\tkeeping: " + old); 408 // } 409 // } else { 410 // } 411 // code_name.put(code, name); 412 name_code.put(name, code); 413 } 414 DataHandler(Type type, String pattern)415 DataHandler(Type type, String pattern) { 416 this.type = type; 417 matcher = PatternCache.get(pattern).matcher(""); 418 switch (type) { 419 case LANGUAGE: 420 for (String code : sc.getAvailableCodes("language")) { 421 String name = english.getName("language", code); 422 if (name == null) { 423 // System.out.println("Missing name for: " + code); 424 continue; 425 } 426 addName(name, code.replace("-", "_"), false); 427 } 428 // add irregular names 429 addName("English (US)", "en_US", true); 430 addName("English (UK)", "en_GB", true); 431 // addName("English (AU)", "en_AU/short"); 432 // addName("Portuguese (PT)", "pt_PT/short"); 433 // addName("Portuguese (BR)", "pt_BR/short"); 434 addName("Chinese (Simplified)", "zh_Hans", true); 435 addName("Chinese (Traditional)", "zh_Hant", true); 436 addName("Norwegian (Nynorsk)", "nn", true); 437 addName("Portuguese (Portugal)", "pt_PT", true); 438 addName("Portuguese (Brazil)", "pt_BR", true); 439 addName("English (Australia)", "en_AU", true); 440 addName("Scots Gaelic", "gd", true); 441 addName("Frisian", "fy", true); 442 addName("Sesotho", "st", true); 443 addName("Kyrgyz", "ky", true); 444 addName("Laothian", "lo", true); 445 addName("Cambodian", "km", true); 446 addName("Greenlandic", "kl", true); 447 addName("Inupiak", "ik", true); 448 addName("Volapuk", "vo", true); 449 addName("Byelorussian", "be", true); 450 addName("Faeroese", "fo", true); 451 addName("Singhalese", "si", true); 452 addName("Gaelic", "ga", true); // IRISH 453 addName("Bhutani", "dz", true); 454 addName("Setswana", "tn", true); 455 addName("Siswati", "ss", true); 456 addName("Sangro", "sg", true); 457 // addName("Kirundi", "XXX"); // no ISO2 code 458 // addName("Sudanese", "XXX"); // ??? 459 break; 460 case REGION: 461 for (String code : sc.getAvailableCodes("territory")) { 462 String name = english.getName("territory", code); 463 if (name == null) { 464 // System.out.println("Missing name for: " + code); 465 continue; 466 } 467 addName(name, code, false); 468 } 469 // add irregular names 470 addName("Bosnia and Herzegowina", "BA", true); 471 addName("Congo", "CG", true); 472 addName("Congo, Democratic Republic of the", "CD", true); 473 addName("Congo, The Democratic Republic of the", "CD", true); 474 addName("Cote D'ivoire", "CI", true); 475 addName("Côte d'Ivoire", "CI", true); 476 addName("Equitorial Guinea", "GQ", true); 477 addName("French Quiana", "GF", true); 478 addName("Heard and Mc Donald Islands", "HM", true); 479 addName("Holy See (Vatican City State)", "VA", true); 480 addName("Iran (Islamic Republic of)", "IR", true); 481 addName("Korea, Democratic People's Republic of", "KP", true); 482 addName("Korea, Republic of", "KR", true); 483 addName("Libyan Arab Jamahiriya", "LY", true); 484 addName("Lichtenstein", "LI", true); 485 addName("Macao", "MO", true); 486 addName("Micronesia, Federated States of", "FM", true); 487 addName("Palestine", "PS", true); 488 addName("Serbia and Montenegro", "CS", true); 489 addName("Slovakia (Slovak Republic)", "SK", true); 490 addName("São Tomé and Príncipe", "ST", true); 491 addName("The Former Yugoslav Republic of Macedonia", "MK", true); 492 addName("United States minor outlying islands", "UM", true); 493 addName("Vatican City", "VA", true); 494 addName("Virgin Islands, British", "VG", true); 495 addName("Virgin Islands, U.S.", "VI", true); 496 addName("Zaire", "CD", true); 497 addName("Åland Islands", "AX", true); 498 break; 499 case CURRENCY: 500 for (String code : sc.getAvailableCodes("currency")) { 501 String name = english.getName("currency", code); 502 if (name == null) { 503 // System.out.println("Missing name for: " + code); 504 continue; 505 } 506 addName(name, code, false); 507 } 508 // add irregular names 509 addName("Australian Dollars", "AUD", true); 510 addName("Bolivian Boliviano", "BOB", true); 511 addName("British Pounds Sterling", "GBP", true); 512 addName("Bulgarian Lev", "BGN", true); 513 addName("Canadian Dollars", "CAD", true); 514 addName("Czech Koruna", "CZK", true); 515 addName("Danish Kroner", "DKK", true); 516 addName("Denmark Kroner", "DKK", true); 517 addName("Deutsche Marks", "DEM", true); 518 addName("Euros", "EUR", true); 519 addName("French Franks", "FRF", true); 520 addName("Hong Kong Dollars", "HKD", true); 521 addName("Israeli Shekel", "ILS", true); 522 addName("Lithuanian Litas", "LTL", true); 523 addName("Mexico Peso", "MXN", true); 524 addName("New Romanian Leu", "RON", true); 525 addName("New Taiwan Dollar", "TWD", true); 526 addName("New Zealand Dollars", "NZD", true); 527 addName("Norway Kroner", "NOK", true); 528 addName("Norwegian Kroner", "NOK", true); 529 addName("Peruvian Nuevo Sol", "PEN", true); 530 addName("Polish New Zloty", "PLN", true); 531 addName("Polish NewZloty", "PLN", true); 532 addName("Russian Rouble", "RUB", true); 533 addName("Singapore Dollars", "SGD", true); 534 addName("Slovenian Tolar", "SIT", true); 535 addName("Sweden Kronor", "SEK", true); 536 addName("Swedish Kronor", "SEK", true); 537 addName("Swiss Francs", "CHF", true); 538 addName("US Dollars", "USD", true); 539 addName("United Arab EmiratesD irham", "AED", true); 540 addName("Venezuela Bolivar", "VEB", true); 541 addName("Yuan Renminbi", "CNY", true); 542 break; 543 case TIMEZONE: 544 for (String code : sc.getAvailableCodes("tzid")) { 545 String[] parts = code.split("/"); 546 addName(parts[parts.length - 1].replace("_", " "), code, false); 547 } 548 // add irregular names 549 addName("Alaska Time", "America/Anchorage", true); 550 // addName("Atlantic Time", "XXX", true); 551 // addName("Atlantic Time - Halifax", "America/Halifax", true); 552 addName("Canary Islands", "Atlantic/Canary", true); 553 // addName("Central European Time", "XXX", true); 554 // addName("Central European Time - Madrid", "Europe/Madrid", true); 555 // addName("Central Time", "America/Chicago", true); 556 // addName("Central Time - Adelaide", "Australia/Adelaide", true); 557 // addName("Central Time - Darwin", "Australia/Darwin", true); 558 // addName("Central Time - Mexico City", "America/Mexico_City", true); 559 // addName("Central Time - Mexico City, Monterrey", "America/Monterrey", true); 560 // addName("Central Time - Regina", "America/Regina", true); 561 // addName("Central Time - Sasketchewan", "XXX", true); 562 // addName("Central Time - Winnipeg", "America/Winnipeg", true); 563 // addName("China Time - Beijing", "XXX", true); 564 addName("Dumont D'Urville", "Antarctica/DumontDUrville", true); 565 addName("Easter Island", "Pacific/Easter", true); 566 // addName("Eastern European Time", "XXX", true); 567 // addName("Eastern Standard Time", "XXX", true); 568 // addName("Eastern Time", "XXX", true); 569 // addName("Eastern Time - Brisbane", "Australia/Brisbane", true); 570 // addName("Eastern Time - Hobart", "Australia/Hobart", true); 571 // addName("Eastern Time - Iqaluit", "America/Iqaluit", true); 572 // addName("Eastern Time - Melbourne, Sydney", "XXX", true); 573 // addName("Eastern Time - Montreal", "XXX", true); 574 // addName("Eastern Time - Toronto", "XXX", true); 575 // addName("GMT (no daylight saving)", "XXX", true); 576 // addName("Greenwich Mean Time", "XXX", true); 577 // addName("Hanoi", "XXX", true); 578 // addName("Hawaii Time", "XXX", true); 579 // addName("India Standard Time", "XXX", true); 580 // addName("International Date Line West", "XXX", true); 581 // addName("Japan Time", "XXX", true); 582 // addName("Moscow+00", "XXX", true); 583 // addName("Moscow+01 - Samara", "XXX", true); 584 // addName("Moscow+02 - Yekaterinburg", "XXX", true); 585 // addName("Moscow+03 - Omsk, Novosibirsk", "XXX", true); 586 // addName("Moscow+04 - Krasnoyarsk", "XXX", true); 587 // addName("Moscow+05 - Irkutsk", "XXX", true); 588 // addName("Moscow+06 - Yakutsk", "XXX", true); 589 // addName("Moscow+07 - Vladivostok, Sakhalin", "XXX", true); 590 // addName("Moscow+07 - Yuzhno-Sakhalinsk", "XXX", true); 591 // addName("Moscow+08 - Magadan", "XXX", true); 592 // addName("Moscow+09 - Kamchatka, Anadyr", "XXX", true); 593 // addName("Moscow+09 - Petropavlovsk-Kamchatskiy", "XXX", true); 594 // addName("Moscow-01 - Kaliningrad", "XXX", true); 595 // addName("Mountain Time", "XXX", true); 596 // addName("Mountain Time - Arizona", "XXX", true); 597 // addName("Mountain Time - Chihuahua, Mazatlan", "XXX", true); 598 // addName("Mountain Time - Dawson Creek", "XXX", true); 599 // addName("Mountain Time - Edmonton", "XXX", true); 600 // addName("Mountain Time - Hermosillo", "XXX", true); 601 // addName("Mountain Time - Yellowknife", "XXX", true); 602 // addName("Newfoundland Time - St. Johns", "XXX", true); 603 // addName("Pacific Time", "XXX", true); 604 // addName("Pacific Time - Tijuana", "XXX", true); 605 // addName("Pacific Time - Vancouver", "XXX", true); 606 // addName("Pacific Time - Whitehorse", "XXX", true); 607 addName("Salvador", "America/El_Salvador", true); 608 addName("St. Kitts", "America/St_Kitts", true); 609 addName("St. Lucia", "America/St_Lucia", true); 610 addName("St. Thomas", "America/St_Thomas", true); 611 addName("St. Vincent", "America/St_Vincent", true); 612 // addName("Tel Aviv", "XXX", true); 613 // addName("Western European Time", "XXX", true); 614 // addName("Western European Time - Canary Islands", "XXX", true); 615 // addName("Western European Time - Ceuta", "XXX", true); 616 // addName("Western Time - Perth", "XXX", true); 617 break; 618 case MONTH: 619 case MONTHSHORT: 620 String[] names = type == Type.MONTH ? dfs.getMonths() : dfs.getShortMonths(); 621 for (int i = 0; i < names.length; ++i) { 622 addName(names[i], String.valueOf(i + 1), true); 623 } 624 break; 625 case DAY: 626 case DAYSHORT: 627 String[] names2 = type == Type.DAY ? dfs.getWeekdays() : dfs.getShortWeekdays(); 628 for (int i = 1; i < names2.length; ++i) { 629 addName(names2[i], names2[i].substring(0, 3).toLowerCase(Locale.ENGLISH), true); 630 } 631 break; 632 default: 633 // throw new IllegalArgumentException(); 634 break; 635 } 636 } 637 getCldrValue(CLDRFile cldrFile, String id)638 public String getCldrValue(CLDRFile cldrFile, String id) { 639 String result = cldrFile.getStringValue(getPath(id)); 640 // cldrFile.getName(CLDRFile.LANGUAGE_NAME, id, false); 641 if (result == null && type == Type.TIMEZONE) { 642 String[] parts = id.split("/"); 643 result = parts[parts.length - 1].replace("_", " "); 644 } 645 return result; 646 } 647 matches(String text)648 boolean matches(String text) { 649 return matcher.reset(text).matches(); 650 } 651 getCode(String value)652 String getCode(String value) { 653 return name_code.get(value); 654 } 655 656 @Override compareTo(DataHandler o)657 public int compareTo(DataHandler o) { 658 throw new IllegalArgumentException(); 659 } 660 getPath(String id, int count)661 String getPath(String id, int count) { 662 String result = getPath(id); 663 count += 650; 664 result += "[@alt=\"proposed-x" + count + "\"]"; 665 result += "[@draft=\"provisional\"]"; 666 return result; 667 } 668 getPath(String id)669 String getPath(String id) { 670 switch (type) { 671 case LANGUAGE: 672 return CLDRFile.getKey(CLDRFile.LANGUAGE_NAME, id); 673 case REGION: 674 return CLDRFile.getKey(CLDRFile.TERRITORY_NAME, id); 675 case CURRENCY: 676 return CLDRFile.getKey(CLDRFile.CURRENCY_NAME, id); 677 case TIMEZONE: 678 return "//ldml/dates/timeZoneNames/zone[@type=\"$1\"]/exemplarCity".replace("$1", id); 679 case MONTH: 680 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"$1\"]" 681 .replace("$1", id); 682 case MONTHSHORT: 683 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"abbreviated\"]/month[@type=\"$1\"]" 684 .replace("$1", id); 685 case DAY: 686 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"$1\"]" 687 .replace("$1", id); 688 case DAYSHORT: 689 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"abbreviated\"]/day[@type=\"$1\"]" 690 .replace("$1", id); 691 } 692 return null; 693 // 694 } 695 } 696 } 697