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 { "no", "nb" }, 275 { "ku", "ku_Arab" }, 276 }); 277 fixLocale(String locale)278 static private String fixLocale(String locale) { 279 locale = locale.replace('-', '_'); 280 String newLocale = fixLocaleMap.get(locale); 281 if (newLocale != null) { 282 locale = newLocale; 283 } 284 return locale; 285 } 286 287 /* 288 * Language 289 * -DXMLPATH=".*form of language.*" 290 * 291 * Country 292 * -DXMLPATH=".*the country or region.*" 293 * 294 * Currency 295 * -DXMLPATH=".*currency name.*" 296 * 297 * Month Long/Short 298 * -DXMLPATH=".*Name of the month of .*" 299 * -DXMLPATH=".*3 letter abbreviation for name of Month.*" 300 * 301 * Week Long/Short 302 * -DXMLPATH=".*day in week.*" 303 * -DXMLPATH=".*Short Version of .*" 304 * 305 * Timezone 306 * DXMLPATH=".*is a display name for a timezone.*" 307 */ 308 309 enum Type { 310 LANGUAGE, REGION, CURRENCY, MONTH, MONTHSHORT, DAY, DAYSHORT, TIMEZONE 311 } 312 313 static StandardCodes sc = StandardCodes.make(); 314 static DateFormatSymbols dfs = new DateFormatSymbols(ULocale.ENGLISH); 315 316 static DataHandler[] dataHandlers = { 317 new DataHandler(Type.LANGUAGE, ".*form of language.*"), 318 new DataHandler(Type.REGION, ".*the country or region.*"), 319 new DataHandler(Type.CURRENCY, ".*currency name.*"), 320 new DataHandler(Type.MONTH, ".*Name of the month of .*"), 321 new DataHandler(Type.MONTHSHORT, ".*3 letter abbreviation for name of Month.*"), 322 new DataHandler(Type.DAY, ".*day in week.*"), 323 new DataHandler(Type.DAYSHORT, ".*Short Version of .*"), 324 new DataHandler(Type.TIMEZONE, ".*is a display name for a timezone.*"), 325 }; 326 327 enum CasingAction { 328 NONE, FORCE_TITLE, FORCE_LOWER 329 } 330 331 static class DataHandler implements Comparable<DataHandler> { 332 // mostly stable 333 private Matcher matcher; 334 private Type type; 335 private Map<String, String> name_code = new TreeMap<>(); 336 // private Map<String,String> code_name = new TreeMap(); 337 private Set<String> missing = new TreeSet<>(); 338 339 // changes with each locale, must call reset 340 private Relation<String, String> id_to_value = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class); 341 private Map<String, String> id_to_cldrValue = new TreeMap<>(); 342 private CasingAction forceCasing = CasingAction.NONE; 343 reset(CLDRFile cldrFile)344 public void reset(CLDRFile cldrFile) { 345 id_to_value.clear(); 346 id_to_cldrValue.clear(); 347 forceCasing = CasingAction.NONE; 348 String key = null; 349 switch (type) { 350 case LANGUAGE: 351 key = "en"; 352 break; 353 case REGION: 354 key = "FR"; 355 break; 356 case CURRENCY: 357 key = "GBP"; 358 break; 359 case MONTH: 360 case MONTHSHORT: 361 key = "1"; 362 break; 363 case DAY: 364 case DAYSHORT: 365 key = "mon"; 366 break; 367 case TIMEZONE: 368 key = "America/New_York"; 369 break; 370 } 371 String sample = getCldrValue(cldrFile, key); 372 if (sample != null) { 373 if (UCharacter.isLowerCase(sample.charAt(0))) { 374 forceCasing = CasingAction.FORCE_LOWER; 375 } else if (UCharacter.isUpperCase(sample.charAt(0))) { 376 forceCasing = CasingAction.FORCE_TITLE; 377 } 378 } 379 } 380 fixValue(ULocale uLocale, String value)381 public String fixValue(ULocale uLocale, String value) { 382 value = TransliteratorUtilities.fromXML.transliterate(value); 383 384 if (forceCasing == CasingAction.FORCE_LOWER) { 385 if (!UCharacter.isLowerCase(value.charAt(0))) { 386 value = UCharacter.toLowerCase(value); 387 } 388 } else if (forceCasing == CasingAction.FORCE_TITLE) { 389 if (!UCharacter.isUpperCase(value.charAt(0))) { 390 value = UCharacter.toTitleCase(uLocale, value, null); 391 } 392 } 393 394 return value; 395 } 396 addValues(String id, String value, String cldrValue)397 public void addValues(String id, String value, String cldrValue) { 398 id_to_value.put(id, value); 399 if (cldrValue != null) { 400 id_to_cldrValue.put(id, cldrValue); 401 } 402 } 403 addName(String name, String code, boolean skipMessage)404 public void addName(String name, String code, boolean skipMessage) { 405 // String old = code_name.get(code); 406 // if (old != null) { 407 // if (!skipMessage) { 408 // System.out.println("Name collision:\t" + code + "\tnew: " + name + "\tkeeping: " + old); 409 // } 410 // } else { 411 // } 412 // code_name.put(code, name); 413 name_code.put(name, code); 414 } 415 DataHandler(Type type, String pattern)416 DataHandler(Type type, String pattern) { 417 this.type = type; 418 matcher = PatternCache.get(pattern).matcher(""); 419 switch (type) { 420 case LANGUAGE: 421 for (String code : sc.getAvailableCodes("language")) { 422 String name = english.getName("language", code); 423 if (name == null) { 424 // System.out.println("Missing name for: " + code); 425 continue; 426 } 427 addName(name, code.replace("-", "_"), false); 428 } 429 // add irregular names 430 addName("English (US)", "en_US", true); 431 addName("English (UK)", "en_GB", true); 432 // addName("English (AU)", "en_AU/short"); 433 // addName("Portuguese (PT)", "pt_PT/short"); 434 // addName("Portuguese (BR)", "pt_BR/short"); 435 addName("Chinese (Simplified)", "zh_Hans", true); 436 addName("Chinese (Traditional)", "zh_Hant", true); 437 addName("Norwegian (Nynorsk)", "nn", true); 438 addName("Portuguese (Portugal)", "pt_PT", true); 439 addName("Portuguese (Brazil)", "pt_BR", true); 440 addName("English (Australia)", "en_AU", true); 441 addName("Scots Gaelic", "gd", true); 442 addName("Frisian", "fy", true); 443 addName("Sesotho", "st", true); 444 addName("Kyrgyz", "ky", true); 445 addName("Laothian", "lo", true); 446 addName("Cambodian", "km", true); 447 addName("Greenlandic", "kl", true); 448 addName("Inupiak", "ik", true); 449 addName("Volapuk", "vo", true); 450 addName("Byelorussian", "be", true); 451 addName("Faeroese", "fo", true); 452 addName("Singhalese", "si", true); 453 addName("Gaelic", "ga", true); // IRISH 454 addName("Bhutani", "dz", true); 455 addName("Setswana", "tn", true); 456 addName("Siswati", "ss", true); 457 addName("Sangro", "sg", true); 458 // addName("Kirundi", "XXX"); // no ISO2 code 459 // addName("Sudanese", "XXX"); // ??? 460 break; 461 case REGION: 462 for (String code : sc.getAvailableCodes("territory")) { 463 String name = english.getName("territory", code); 464 if (name == null) { 465 // System.out.println("Missing name for: " + code); 466 continue; 467 } 468 addName(name, code, false); 469 } 470 // add irregular names 471 addName("Bosnia and Herzegowina", "BA", true); 472 addName("Congo", "CG", true); 473 addName("Congo, Democratic Republic of the", "CD", true); 474 addName("Congo, The Democratic Republic of the", "CD", true); 475 addName("Cote D'ivoire", "CI", true); 476 addName("Côte d'Ivoire", "CI", true); 477 addName("Equitorial Guinea", "GQ", true); 478 addName("French Quiana", "GF", true); 479 addName("Heard and Mc Donald Islands", "HM", true); 480 addName("Holy See (Vatican City State)", "VA", true); 481 addName("Iran (Islamic Republic of)", "IR", true); 482 addName("Korea, Democratic People's Republic of", "KP", true); 483 addName("Korea, Republic of", "KR", true); 484 addName("Libyan Arab Jamahiriya", "LY", true); 485 addName("Lichtenstein", "LI", true); 486 addName("Macao", "MO", true); 487 addName("Micronesia, Federated States of", "FM", true); 488 addName("Palestine", "PS", true); 489 addName("Serbia and Montenegro", "CS", true); 490 addName("Slovakia (Slovak Republic)", "SK", true); 491 addName("São Tomé and Príncipe", "ST", true); 492 addName("The Former Yugoslav Republic of Macedonia", "MK", true); 493 addName("United States minor outlying islands", "UM", true); 494 addName("Vatican City", "VA", true); 495 addName("Virgin Islands, British", "VG", true); 496 addName("Virgin Islands, U.S.", "VI", true); 497 addName("Zaire", "CD", true); 498 addName("Åland Islands", "AX", true); 499 break; 500 case CURRENCY: 501 for (String code : sc.getAvailableCodes("currency")) { 502 String name = english.getName("currency", code); 503 if (name == null) { 504 // System.out.println("Missing name for: " + code); 505 continue; 506 } 507 addName(name, code, false); 508 } 509 // add irregular names 510 addName("Australian Dollars", "AUD", true); 511 addName("Bolivian Boliviano", "BOB", true); 512 addName("British Pounds Sterling", "GBP", true); 513 addName("Bulgarian Lev", "BGN", true); 514 addName("Canadian Dollars", "CAD", true); 515 addName("Czech Koruna", "CZK", true); 516 addName("Danish Kroner", "DKK", true); 517 addName("Denmark Kroner", "DKK", true); 518 addName("Deutsche Marks", "DEM", true); 519 addName("Euros", "EUR", true); 520 addName("French Franks", "FRF", true); 521 addName("Hong Kong Dollars", "HKD", true); 522 addName("Israeli Shekel", "ILS", true); 523 addName("Lithuanian Litas", "LTL", true); 524 addName("Mexico Peso", "MXN", true); 525 addName("New Romanian Leu", "RON", true); 526 addName("New Taiwan Dollar", "TWD", true); 527 addName("New Zealand Dollars", "NZD", true); 528 addName("Norway Kroner", "NOK", true); 529 addName("Norwegian Kroner", "NOK", true); 530 addName("Peruvian Nuevo Sol", "PEN", true); 531 addName("Polish New Zloty", "PLN", true); 532 addName("Polish NewZloty", "PLN", true); 533 addName("Russian Rouble", "RUB", true); 534 addName("Singapore Dollars", "SGD", true); 535 addName("Slovenian Tolar", "SIT", true); 536 addName("Sweden Kronor", "SEK", true); 537 addName("Swedish Kronor", "SEK", true); 538 addName("Swiss Francs", "CHF", true); 539 addName("US Dollars", "USD", true); 540 addName("United Arab EmiratesD irham", "AED", true); 541 addName("Venezuela Bolivar", "VEB", true); 542 addName("Yuan Renminbi", "CNY", true); 543 break; 544 case TIMEZONE: 545 for (String code : sc.getAvailableCodes("tzid")) { 546 String[] parts = code.split("/"); 547 addName(parts[parts.length - 1].replace("_", " "), code, false); 548 } 549 // add irregular names 550 addName("Alaska Time", "America/Anchorage", true); 551 // addName("Atlantic Time", "XXX", true); 552 // addName("Atlantic Time - Halifax", "America/Halifax", true); 553 addName("Canary Islands", "Atlantic/Canary", true); 554 // addName("Central European Time", "XXX", true); 555 // addName("Central European Time - Madrid", "Europe/Madrid", true); 556 // addName("Central Time", "America/Chicago", true); 557 // addName("Central Time - Adelaide", "Australia/Adelaide", true); 558 // addName("Central Time - Darwin", "Australia/Darwin", true); 559 // addName("Central Time - Mexico City", "America/Mexico_City", true); 560 // addName("Central Time - Mexico City, Monterrey", "America/Monterrey", true); 561 // addName("Central Time - Regina", "America/Regina", true); 562 // addName("Central Time - Sasketchewan", "XXX", true); 563 // addName("Central Time - Winnipeg", "America/Winnipeg", true); 564 // addName("China Time - Beijing", "XXX", true); 565 addName("Dumont D'Urville", "Antarctica/DumontDUrville", true); 566 addName("Easter Island", "Pacific/Easter", true); 567 // addName("Eastern European Time", "XXX", true); 568 // addName("Eastern Standard Time", "XXX", true); 569 // addName("Eastern Time", "XXX", true); 570 // addName("Eastern Time - Brisbane", "Australia/Brisbane", true); 571 // addName("Eastern Time - Hobart", "Australia/Hobart", true); 572 // addName("Eastern Time - Iqaluit", "America/Iqaluit", true); 573 // addName("Eastern Time - Melbourne, Sydney", "XXX", true); 574 // addName("Eastern Time - Montreal", "XXX", true); 575 // addName("Eastern Time - Toronto", "XXX", true); 576 // addName("GMT (no daylight saving)", "XXX", true); 577 // addName("Greenwich Mean Time", "XXX", true); 578 // addName("Hanoi", "XXX", true); 579 // addName("Hawaii Time", "XXX", true); 580 // addName("India Standard Time", "XXX", true); 581 // addName("International Date Line West", "XXX", true); 582 // addName("Japan Time", "XXX", true); 583 // addName("Moscow+00", "XXX", true); 584 // addName("Moscow+01 - Samara", "XXX", true); 585 // addName("Moscow+02 - Yekaterinburg", "XXX", true); 586 // addName("Moscow+03 - Omsk, Novosibirsk", "XXX", true); 587 // addName("Moscow+04 - Krasnoyarsk", "XXX", true); 588 // addName("Moscow+05 - Irkutsk", "XXX", true); 589 // addName("Moscow+06 - Yakutsk", "XXX", true); 590 // addName("Moscow+07 - Vladivostok, Sakhalin", "XXX", true); 591 // addName("Moscow+07 - Yuzhno-Sakhalinsk", "XXX", true); 592 // addName("Moscow+08 - Magadan", "XXX", true); 593 // addName("Moscow+09 - Kamchatka, Anadyr", "XXX", true); 594 // addName("Moscow+09 - Petropavlovsk-Kamchatskiy", "XXX", true); 595 // addName("Moscow-01 - Kaliningrad", "XXX", true); 596 // addName("Mountain Time", "XXX", true); 597 // addName("Mountain Time - Arizona", "XXX", true); 598 // addName("Mountain Time - Chihuahua, Mazatlan", "XXX", true); 599 // addName("Mountain Time - Dawson Creek", "XXX", true); 600 // addName("Mountain Time - Edmonton", "XXX", true); 601 // addName("Mountain Time - Hermosillo", "XXX", true); 602 // addName("Mountain Time - Yellowknife", "XXX", true); 603 // addName("Newfoundland Time - St. Johns", "XXX", true); 604 // addName("Pacific Time", "XXX", true); 605 // addName("Pacific Time - Tijuana", "XXX", true); 606 // addName("Pacific Time - Vancouver", "XXX", true); 607 // addName("Pacific Time - Whitehorse", "XXX", true); 608 addName("Salvador", "America/El_Salvador", true); 609 addName("St. Kitts", "America/St_Kitts", true); 610 addName("St. Lucia", "America/St_Lucia", true); 611 addName("St. Thomas", "America/St_Thomas", true); 612 addName("St. Vincent", "America/St_Vincent", true); 613 // addName("Tel Aviv", "XXX", true); 614 // addName("Western European Time", "XXX", true); 615 // addName("Western European Time - Canary Islands", "XXX", true); 616 // addName("Western European Time - Ceuta", "XXX", true); 617 // addName("Western Time - Perth", "XXX", true); 618 break; 619 case MONTH: 620 case MONTHSHORT: 621 String[] names = type == Type.MONTH ? dfs.getMonths() : dfs.getShortMonths(); 622 for (int i = 0; i < names.length; ++i) { 623 addName(names[i], String.valueOf(i + 1), true); 624 } 625 break; 626 case DAY: 627 case DAYSHORT: 628 String[] names2 = type == Type.DAY ? dfs.getWeekdays() : dfs.getShortWeekdays(); 629 for (int i = 1; i < names2.length; ++i) { 630 addName(names2[i], names2[i].substring(0, 3).toLowerCase(Locale.ENGLISH), true); 631 } 632 break; 633 default: 634 // throw new IllegalArgumentException(); 635 break; 636 } 637 } 638 getCldrValue(CLDRFile cldrFile, String id)639 public String getCldrValue(CLDRFile cldrFile, String id) { 640 String result = cldrFile.getStringValue(getPath(id)); 641 // cldrFile.getName(CLDRFile.LANGUAGE_NAME, id, false); 642 if (result == null && type == Type.TIMEZONE) { 643 String[] parts = id.split("/"); 644 result = parts[parts.length - 1].replace("_", " "); 645 } 646 return result; 647 } 648 matches(String text)649 boolean matches(String text) { 650 return matcher.reset(text).matches(); 651 } 652 getCode(String value)653 String getCode(String value) { 654 return name_code.get(value); 655 } 656 657 @Override compareTo(DataHandler o)658 public int compareTo(DataHandler o) { 659 throw new IllegalArgumentException(); 660 } 661 getPath(String id, int count)662 String getPath(String id, int count) { 663 String result = getPath(id); 664 count += 650; 665 result += "[@alt=\"proposed-x" + count + "\"]"; 666 result += "[@draft=\"provisional\"]"; 667 return result; 668 } 669 getPath(String id)670 String getPath(String id) { 671 switch (type) { 672 case LANGUAGE: 673 return CLDRFile.getKey(CLDRFile.LANGUAGE_NAME, id); 674 case REGION: 675 return CLDRFile.getKey(CLDRFile.TERRITORY_NAME, id); 676 case CURRENCY: 677 return CLDRFile.getKey(CLDRFile.CURRENCY_NAME, id); 678 case TIMEZONE: 679 return "//ldml/dates/timeZoneNames/zone[@type=\"$1\"]/exemplarCity".replace("$1", id); 680 case MONTH: 681 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"$1\"]" 682 .replace("$1", id); 683 case MONTHSHORT: 684 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"abbreviated\"]/month[@type=\"$1\"]" 685 .replace("$1", id); 686 case DAY: 687 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"$1\"]" 688 .replace("$1", id); 689 case DAYSHORT: 690 return "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"abbreviated\"]/day[@type=\"$1\"]" 691 .replace("$1", id); 692 } 693 return null; 694 // 695 } 696 } 697 } 698