1 7 8 package com.ibm.icu.util; 9 10 import java.io.Serializable ; 11 import java.lang.ref.SoftReference ; 12 import java.util.Collections ; 13 import java.util.Comparator ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.Locale ; 17 import java.util.Map ; 18 import java.util.MissingResourceException ; 19 import java.util.TreeMap ; 20 21 import com.ibm.icu.impl.SimpleCache; 22 import com.ibm.icu.impl.ICUResourceBundle; 23 import com.ibm.icu.impl.LocaleUtility; 24 import com.ibm.icu.lang.UCharacter; 25 88 public final class ULocale implements Serializable { 89 private static final long serialVersionUID = 3715177670352309217L; 91 92 96 public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH); 97 98 102 public static final ULocale FRENCH = new ULocale("fr", Locale.FRENCH); 103 104 108 public static final ULocale GERMAN = new ULocale("de", Locale.GERMAN); 109 110 114 public static final ULocale ITALIAN = new ULocale("it", Locale.ITALIAN); 115 116 120 public static final ULocale JAPANESE = new ULocale("ja", Locale.JAPANESE); 121 122 126 public static final ULocale KOREAN = new ULocale("ko", Locale.KOREAN); 127 128 132 public static final ULocale CHINESE = new ULocale("zh", Locale.CHINESE); 133 134 138 public static final ULocale SIMPLIFIED_CHINESE = new ULocale("zh_Hans", Locale.CHINESE); 139 140 144 public static final ULocale TRADITIONAL_CHINESE = new ULocale("zh_Hant", Locale.CHINESE); 145 146 150 public static final ULocale FRANCE = new ULocale("fr_FR", Locale.FRANCE); 151 152 156 public static final ULocale GERMANY = new ULocale("de_DE", Locale.GERMANY); 157 158 162 public static final ULocale ITALY = new ULocale("it_IT", Locale.ITALY); 163 164 168 public static final ULocale JAPAN = new ULocale("ja_JP", Locale.JAPAN); 169 170 174 public static final ULocale KOREA = new ULocale("ko_KR", Locale.KOREA); 175 176 180 public static final ULocale CHINA = new ULocale("zh_Hans_CN", Locale.CHINA); 181 182 186 public static final ULocale PRC = CHINA; 187 188 192 public static final ULocale TAIWAN = new ULocale("zh_Hant_TW", Locale.TAIWAN); 193 194 198 public static final ULocale UK = new ULocale("en_GB", Locale.UK); 199 200 204 public static final ULocale US = new ULocale("en_US", Locale.US); 205 206 210 public static final ULocale CANADA = new ULocale("en_CA", Locale.CANADA); 211 212 216 public static final ULocale CANADA_FRENCH = new ULocale("fr_CA", Locale.CANADA_FRENCH); 217 218 221 private static final String EMPTY_STRING = ""; 222 223 private static final char UNDERSCORE = '_'; 225 226 private static final Locale EMPTY_LOCALE = new Locale ("", ""); 228 229 233 public static final ULocale ROOT = new ULocale("root", EMPTY_LOCALE); 234 235 private static final SimpleCache CACHE = new SimpleCache(); 236 237 240 private transient Locale locale; 241 242 245 private String localeID; 246 247 250 252 254 258 259 260 private static String [] _languages; 261 private static String [] _replacementLanguages; 262 private static String [] _obsoleteLanguages; 263 private static String [] _languages3; 264 private static String [] _obsoleteLanguages3; 265 266 private static void initLanguageTables() { 268 if (_languages == null) { 269 270 272 String [] tempLanguages = { 273 "aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", "afa", 274 "afh", "ak", "akk", "ale", "alg", "am", "an", "ang", "apa", 275 "ar", "arc", "arn", "arp", "art", "arw", "as", "ast", 276 "ath", "aus", "av", "awa", "ay", "az", "ba", "bad", 277 "bai", "bal", "ban", "bas", "bat", "be", "bej", 278 "bem", "ber", "bg", "bh", "bho", "bi", "bik", "bin", 279 "bla", "bm", "bn", "bnt", "bo", "br", "bra", "bs", 280 "btk", "bua", "bug", "byn", "ca", "cad", "cai", "car", "cau", 281 "ce", "ceb", "cel", "ch", "chb", "chg", "chk", "chm", 282 "chn", "cho", "chp", "chr", "chy", "cmc", "co", "cop", 283 "cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", "csb", "cu", "cus", 284 "cv", "cy", "da", "dak", "dar", "day", "de", "del", "den", 285 "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv", "dyu", 286 "dz", "ee", "efi", "egy", "eka", "el", "elx", "en", 287 "enm", "eo", "es", "et", "eu", "ewo", "fa", 288 "fan", "fat", "ff", "fi", "fiu", "fj", "fo", "fon", 289 "fr", "frm", "fro", "fur", "fy", "ga", "gaa", "gay", 290 "gba", "gd", "gem", "gez", "gil", "gl", "gmh", "gn", 291 "goh", "gon", "gor", "got", "grb", "grc", "gu", "gv", 292 "gwi", "ha", "hai", "haw", "he", "hi", "hil", "him", 293 "hit", "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", "hz", 294 "ia", "iba", "id", "ie", "ig", "ii", "ijo", "ik", 295 "ilo", "inc", "ine", "inh", "io", "ira", "iro", "is", "it", 296 "iu", "ja", "jbo", "jpr", "jrb", "jv", "ka", "kaa", "kab", 297 "kac", "kam", "kar", "kaw", "kbd", "kg", "kha", "khi", 298 "kho", "ki", "kj", "kk", "kl", "km", "kmb", "kn", 299 "ko", "kok", "kos", "kpe", "kr", "krc", "kro", "kru", "ks", 300 "ku", "kum", "kut", "kv", "kw", "ky", "la", "lad", 301 "lah", "lam", "lb", "lez", "lg", "li", "ln", "lo", "lol", 302 "loz", "lt", "lu", "lua", "lui", "lun", "luo", "lus", 303 "lv", "mad", "mag", "mai", "mak", "man", "map", "mas", 304 "mdf", "mdr", "men", "mg", "mga", "mh", "mi", "mic", "min", 305 "mis", "mk", "mkh", "ml", "mn", "mnc", "mni", "mno", 306 "mo", "moh", "mos", "mr", "ms", "mt", "mul", "mun", 307 "mus", "mwr", "my", "myn", "myv", "na", "nah", "nai", "nap", 308 "nb", "nd", "nds", "ne", "new", "ng", "nia", "nic", 309 "niu", "nl", "nn", "no", "nog", "non", "nr", "nso", "nub", 310 "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oc", "oj", 311 "om", "or", "os", "osa", "ota", "oto", "pa", "paa", 312 "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", 313 "pi", "pl", "pon", "pra", "pro", "ps", "pt", "qu", 314 "raj", "rap", "rar", "rm", "rn", "ro", "roa", "rom", 315 "ru", "rup", "rw", "sa", "sad", "sah", "sai", "sal", "sam", 316 "sas", "sat", "sc", "sco", "sd", "se", "sel", "sem", 317 "sg", "sga", "sgn", "shn", "si", "sid", "sio", "sit", 318 "sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", 319 "sms", "sn", "snk", "so", "sog", "son", "sq", "sr", 320 "srr", "ss", "ssa", "st", "su", "suk", "sus", "sux", 321 "sv", "sw", "syr", "ta", "tai", "te", "tem", "ter", 322 "tet", "tg", "th", "ti", "tig", "tiv", "tk", "tkl", 323 "tl", "tlh", "tli", "tmh", "tn", "to", "tog", "tpi", "tr", 324 "ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", 325 "ty", "tyv", "udm", "ug", "uga", "uk", "umb", "und", "ur", 326 "uz", "vai", "ve", "vi", "vo", "vot", "wa", "wak", 327 "wal", "war", "was", "wen", "wo", "xal", "xh", "yao", "yap", 328 "yi", "yo", "ypk", "za", "zap", "zen", "zh", "znd", 329 "zu", "zun", 330 }; 331 332 String [] tempReplacementLanguages = { 333 "id", "he", "yi", "jv", "sr", "nb", 334 }; 335 336 String [] tempObsoleteLanguages = { 337 "in", "iw", "ji", "jw", "sh", "no", 338 }; 339 340 343 String [] tempLanguages3 = { 344 345 "aar", "abk", "ace", "ach", "ada", "ady", "ave", "afr", "afa", 346 347 "afh", "aka", "akk", "ale", "alg", "amh", "arg", "ang", "apa", 348 349 "ara", "arc", "arn", "arp", "art", "arw", "asm", "ast", 350 351 "ath", "aus", "ava", "awa", "aym", "aze", "bak", "bad", 352 353 "bai", "bal", "ban", "bas", "bat", "bel", "bej", 354 355 "bem", "ber", "bul", "bih", "bho", "bis", "bik", "bin", 356 357 "bla", "bam", "ben", "bnt", "bod", "bre", "bra", "bos", 358 359 "btk", "bua", "bug", "byn", "cat", "cad", "cai", "car", "cau", 360 361 "che", "ceb", "cel", "cha", "chb", "chg", "chk", "chm", 362 363 "chn", "cho", "chp", "chr", "chy", "cmc", "cos", "cop", 364 365 "cpe", "cpf", "cpp", "cre", "crh", "crp", "ces", "csb", "chu", "cus", 366 367 "chv", "cym", "dan", "dak", "dar", "day", "deu", "del", "den", 368 369 "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "div", "dyu", 370 371 "dzo", "ewe", "efi", "egy", "eka", "ell", "elx", "eng", 372 373 "enm", "epo", "spa", "est", "eus", "ewo", "fas", 374 375 "fan", "fat", "ful", "fin", "fiu", "fij", "fao", "fon", 376 377 "fra", "frm", "fro", "fur", "fry", "gle", "gaa", "gay", 378 379 "gba", "gla", "gem", "gez", "gil", "glg", "gmh", "grn", 380 381 "goh", "gon", "gor", "got", "grb", "grc", "guj", "glv", 382 383 "gwi", "hau", "hai", "haw", "heb", "hin", "hil", "him", 384 385 "hit", "hmn", "hmo", "hrv", "hsb", "hat", "hun", "hup", "hye", "her", 386 387 "ina", "iba", "ind", "ile", "ibo", "iii", "ijo", "ipk", 388 389 "ilo", "inc", "ine", "inh", "ido", "ira", "iro", "isl", "ita", 390 391 "iku", "jpn", "jbo", "jpr", "jrb", "jaw", "kat", "kaa", "kab", 392 393 "kac", "kam", "kar", "kaw", "kbd", "kon", "kha", "khi", 394 395 "kho", "kik", "kua", "kaz", "kal", "khm", "kmb", "kan", 396 397 "kor", "kok", "kos", "kpe", "kau", "krc", "kro", "kru", "kas", 398 399 "kur", "kum", "kut", "kom", "cor", "kir", "lat", "lad", 400 401 "lah", "lam", "ltz", "lez", "lug", "lim", "lin", "lao", "lol", 402 403 "loz", "lit", "lub", "lua", "lui", "lun", "luo", "lus", 404 405 "lav", "mad", "mag", "mai", "mak", "man", "map", "mas", 406 407 "mdf", "mdr", "men", "mlg", "mga", "mah", "mri", "mic", "min", 408 409 "mis", "mkd", "mkh", "mal", "mon", "mnc", "mni", "mno", 410 411 "mol", "moh", "mos", "mar", "msa", "mlt", "mul", "mun", 412 413 "mus", "mwr", "mya", "myn", "myv", "nau", "nah", "nai", "nap", 414 415 "nob", "nde", "nds", "nep", "new", "ndo", "nia", "nic", 416 417 "niu", "nld", "nno", "nor", "nog", "non", "nbl", "nso", "nub", 418 419 "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", "oci", "oji", 420 421 "orm", "ori", "oss", "osa", "ota", "oto", "pan", "paa", 422 423 "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", 424 425 "pli", "pol", "pon", "pra", "pro", "pus", "por", "que", 426 427 "raj", "rap", "rar", "roh", "run", "ron", "roa", "rom", 428 429 "rus", "rup", "kin", "san", "sad", "sah", "sai", "sal", "sam", 430 431 "sas", "sat", "srd", "sco", "snd", "sme", "sel", "sem", 432 433 "sag", "sga", "sgn", "shn", "sin", "sid", "sio", "sit", 434 435 "slk", "slv", "sla", "smo", "sma", "smi", "smj", "smn", 436 437 "sms", "sna", "snk", "som", "sog", "son", "sqi", "srp", 438 439 "srr", "ssw", "ssa", "sot", "sun", "suk", "sus", "sux", 440 441 "swe", "swa", "syr", "tam", "tai", "tel", "tem", "ter", 442 443 "tet", "tgk", "tha", "tir", "tig", "tiv", "tuk", "tkl", 444 445 "tgl", "tlh", "tli", "tmh", "tsn", "ton", "tog", "tpi", "tur", 446 447 "tso", "tsi", "tat", "tum", "tup", "tut", "tvl", "twi", 448 449 "tah", "tyv", "udm", "uig", "uga", "ukr", "umb", "und", "urd", 450 451 "uzb", "vai", "ven", "vie", "vol", "vot", "wln", "wak", 452 453 "wal", "war", "was", "wen", "wol", "xal", "xho", "yao", "yap", 454 455 "yid", "yor", "ypk", "zha", "zap", "zen", "zho", "znd", 456 457 "zul", "zun", 458 }; 459 460 String [] tempObsoleteLanguages3 = { 461 462 "ind", "heb", "yid", "jaw", "srp", 463 }; 464 465 synchronized (ULocale.class) { 466 if (_languages == null) { 467 _languages = tempLanguages; 468 _replacementLanguages = tempReplacementLanguages; 469 _obsoleteLanguages = tempObsoleteLanguages; 470 _languages3 = tempLanguages3; 471 _obsoleteLanguages3 = tempObsoleteLanguages3; 472 } 473 } 474 } 475 } 476 477 private static String [] _countries; 478 private static String [] _deprecatedCountries; 479 private static String [] _replacementCountries; 480 private static String [] _obsoleteCountries; 481 private static String [] _countries3; 482 private static String [] _obsoleteCountries3; 483 484 private static void initCountryTables() { 486 if (_countries == null) { 487 491 492 495 496 497 String [] tempCountries = { 498 "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", 499 "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", 500 "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", 501 "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", 502 "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", 503 "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", 504 "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", 505 "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", 506 "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", 507 "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", 508 "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", 509 "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", 510 "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", 511 "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", 512 "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", 513 "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", 514 "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", 515 "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", 516 "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", 517 "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", 518 "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", 519 "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", 520 "PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", 521 "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", 522 "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", 523 "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", 524 "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", 525 "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", 526 "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", 527 "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW", 528 }; 529 530 531 String [] tempObsoleteCountries = { 532 "FX", "RO", "TP", "ZR", 533 }; 534 535 String [] tempDeprecatedCountries = { 536 "BU", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" 537 }; 538 String [] tempReplacementCountries = { 539 540 "MM", "BJ", "FR", "BF", "VU", "ZW", "TL", "CS", "CD", 541 }; 542 543 545 String [] tempCountries3 = { 546 547 "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "ANT", 548 549 "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "AZE", 550 551 "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI", 552 553 "BEN", "BMU", "BRN", "BOL", "BRA", "BHS", "BTN", "BVT", 554 555 "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", 556 557 "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", 558 559 "CUB", "CPV", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK", 560 561 "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI", 562 563 "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", 564 565 "GAB", "GBR", "GRD", "GEO", "GUF", "GHA", "GIB", "GRL", 566 567 "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM", 568 569 "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN", 570 571 "IDN", "IRL", "ISR", "IND", "IOT", "IRQ", "IRN", "ISL", 572 573 "ITA", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", 574 575 "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO", 576 577 "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", 578 579 "LVA", "LBY", "MAR", "MCO", "MDA", "MDG", "MHL", "MKD", 580 581 "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR", 582 583 "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM", 584 585 "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", 586 587 "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", 588 589 "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT", 590 591 "PLW", "PRY", "QAT", "REU", "ROU", "RUS", "RWA", "SAU", 592 593 "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", 594 595 "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "STP", "SLV", 596 597 "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK", 598 599 "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV", 600 601 "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", 602 603 "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", 604 605 "WSM", "YEM", "MYT", "YUG", "ZAF", "ZMB", "ZWE", 606 }; 607 608 String [] tempObsoleteCountries3 = { 609 610 "FXX", "ROM", "TMP", "ZAR", 611 }; 612 613 synchronized (ULocale.class) { 614 if (_countries == null) { 615 _countries = tempCountries; 616 _deprecatedCountries = tempDeprecatedCountries; 617 _replacementCountries = tempReplacementCountries; 618 _obsoleteCountries = tempObsoleteCountries; 619 _countries3 = tempCountries3; 620 _obsoleteCountries3 = tempObsoleteCountries3; 621 } 622 } 623 } 624 } 625 626 private static String [][] _variantsToKeywords; 627 628 private static void initVariantsTable() { 629 if (_variantsToKeywords == null) { 630 635 String [][] tempVariantsToKeywords = { 636 { "C", "en_US_POSIX", null, null }, 638 { "art_LOJBAN", "jbo", null, null }, 639 { "az_AZ_CYRL", "az_Cyrl_AZ", null, null }, 640 { "az_AZ_LATN", "az_Latn_AZ", null, null }, 641 { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, 642 { "cel_GAULISH", "cel__GAULISH", null, null }, 643 { "de_1901", "de__1901", null, null }, 644 { "de_1906", "de__1906", null, null }, 645 { "de__PHONEBOOK", "de", "collation", "phonebook" }, 646 { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, 647 { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, 648 { "de_LU_PREEURO", "de_LU", "currency", "EUR" }, 649 { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, 650 { "en_BOONT", "en__BOONT", null, null }, 651 { "en_SCOUSE", "en__SCOUSE", null, null }, 652 { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, 653 { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, 654 { "es__TRADITIONAL", "es", "collation", "traditional" }, 655 { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, 656 { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, 657 { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, 658 { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, 659 { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, 660 { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, 661 { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, 662 { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, 663 { "hi__DIRECT", "hi", "collation", "direct" }, 664 { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, 665 { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, 666 { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, 668 { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, 669 { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, 670 { "sl_ROZAJ", "sl__ROZAJ", null, null }, 671 { "sr_SP_CYRL", "sr_Cyrl_CS", null, null }, 672 { "sr_SP_LATN", "sr_Latn_CS", null, null }, 673 { "sr_YU_CYRILLIC", "sr_Cyrl_CS", null, null }, 674 { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", null, null }, 675 { "uz_UZ_CYRL", "uz_Cyrl_UZ", null, null }, 676 { "uz_UZ_LATN", "uz_Latn_UZ", null, null }, 677 { "zh_CHS", "zh_Hans", null, null }, 678 { "zh_CHT", "zh_Hant", null, null }, 679 { "zh_GAN", "zh__GAN", null, null }, 680 { "zh_GUOYU", "zh", null, null }, 681 { "zh_HAKKA", "zh__HAKKA", null, null }, 682 { "zh_MIN", "zh__MIN", null, null }, 683 { "zh_MIN_NAN", "zh__MINNAN", null, null }, 684 { "zh_WUU", "zh__WUU", null, null }, 685 { "zh_XIANG", "zh__XIANG", null, null }, 686 { "zh_YUE", "zh__YUE", null, null }, 687 { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, 688 { "zh_TW_STROKE", "zh_TW", "collation", "stroke" }, 689 { "zh__PINYIN", "zh", "collation", "pinyin" } 690 }; 691 692 synchronized (ULocale.class) { 693 if (_variantsToKeywords == null) { 694 _variantsToKeywords = tempVariantsToKeywords; 695 } 696 } 697 } 698 } 699 700 703 private ULocale(String localeID, Locale locale) { 704 this.localeID = localeID; 705 this.locale = locale; 706 } 707 708 714 private ULocale(Locale loc) { 715 this.localeID = getName(loc.toString()); 716 this.locale = loc; 717 } 718 719 725 public static ULocale forLocale(Locale loc) { 726 if (loc == null) { 727 return null; 728 } 729 ULocale result = (ULocale)CACHE.get(loc); 730 if (result == null) { 731 if (defaultULocale != null && loc == defaultULocale.locale) { 732 result = defaultULocale; 733 } else { 734 String locStr = loc.toString(); 735 if (locStr.length() == 0) { 736 result = ROOT; 737 } else { 738 result = new ULocale(locStr, loc); 739 } 740 } 741 CACHE.put(loc, result); 742 } 743 return result; 744 } 745 746 762 public ULocale(String localeID) { 763 this.localeID = getName(localeID); 764 } 765 766 772 public ULocale(String a, String b) { 773 this(a, b, null); 774 } 775 776 796 public ULocale(String a, String b, String c) { 797 localeID = getName(lscvToID(a, b, c, EMPTY_STRING)); 798 } 799 800 806 public static ULocale createCanonical(String nonCanonicalID) { 807 return new ULocale(canonicalize(nonCanonicalID), (Locale )null); 808 } 809 810 private static String lscvToID(String lang, String script, String country, String variant) { 811 StringBuffer buf = new StringBuffer (); 812 813 if (lang != null && lang.length() > 0) { 814 buf.append(lang); 815 } 816 if (script != null && script.length() > 0) { 817 buf.append(UNDERSCORE); 818 buf.append(script); 819 } 820 if (country != null && country.length() > 0) { 821 buf.append(UNDERSCORE); 822 buf.append(country); 823 } 824 if (variant != null && variant.length() > 0) { 825 if (country == null || country.length() == 0) { 826 buf.append(UNDERSCORE); 827 } 828 buf.append(UNDERSCORE); 829 buf.append(variant); 830 } 831 return buf.toString(); 832 } 833 834 840 public Locale toLocale() { 841 if (locale == null) { 842 String [] names = new IDParser(localeID).getLanguageScriptCountryVariant(); 843 locale = new Locale (names[0], names[2], names[3]); 844 } 845 return locale; 846 } 847 848 private static SoftReference nameCacheRef = new SoftReference (Collections.synchronizedMap(new HashMap ())); 849 852 private static Locale defaultLocale = Locale.getDefault(); 853 private static ULocale defaultULocale = new ULocale(defaultLocale); 854 855 859 public static ULocale getDefault() { 860 synchronized (ULocale.class) { 861 Locale currentDefault = Locale.getDefault(); 862 if (defaultLocale != currentDefault) { 863 defaultLocale = currentDefault; 864 defaultULocale = new ULocale(defaultLocale); 865 } 866 return defaultULocale; 867 } 868 } 869 870 884 public static synchronized void setDefault(ULocale newLocale){ 885 Locale.setDefault(newLocale.toLocale()); 886 defaultULocale = newLocale; 887 } 888 889 894 public Object clone() { 895 return this; 896 } 897 898 902 public int hashCode() { 903 return localeID.hashCode(); 904 } 905 906 915 public boolean equals(Object obj) { 916 if (this == obj) { 917 return true; 918 } 919 if (obj instanceof String ) { 920 return localeID.equals((String )obj); 921 } 922 if (obj instanceof ULocale) { 923 return localeID.equals(((ULocale)obj).localeID); 924 } 925 return false; 926 } 927 928 932 public static ULocale[] getAvailableLocales() { 933 return ICUResourceBundle.getAvailableULocales(); 934 } 935 936 941 public static String [] getISOCountries() { 942 initCountryTables(); 943 return (String [])_countries.clone(); 944 } 945 946 954 public static String [] getISOLanguages() { 955 initLanguageTables(); 956 return (String [])_languages.clone(); 957 } 958 959 966 public String getLanguage() { 967 return getLanguage(localeID); 968 } 969 970 978 public static String getLanguage(String localeID) { 979 return new IDParser(localeID).getLanguage(); 980 } 981 982 988 public String getScript() { 989 return getScript(localeID); 990 } 991 992 998 public static String getScript(String localeID) { 999 return new IDParser(localeID).getScript(); 1000 } 1001 1002 1009 public String getCountry() { 1010 return getCountry(localeID); 1011 } 1012 1013 1021 public static String getCountry(String localeID) { 1022 return new IDParser(localeID).getCountry(); 1023 } 1024 1025 1031 public String getVariant() { 1032 return getVariant(localeID); 1033 } 1034 1035 1041 public static String getVariant(String localeID) { 1042 return new IDParser(localeID).getVariant(); 1043 } 1044 1045 1049 public static String getFallback(String localeID) { 1050 return getFallbackString(getName(localeID)); 1051 } 1052 1053 1057 public ULocale getFallback() { 1058 if (localeID.length() == 0 || localeID.charAt(0) == '@') { 1059 return null; 1060 } 1061 return new ULocale(getFallbackString(localeID), (Locale )null); 1062 } 1063 1064 1067 private static String getFallbackString(String fallback) { 1068 int limit = fallback.indexOf('@'); 1069 if (limit == -1) { 1070 limit = fallback.length(); 1071 } 1072 int start = fallback.lastIndexOf('_', limit); 1073 if (start == -1) { 1074 start = 0; 1075 } 1076 return fallback.substring(0, start) + fallback.substring(limit); 1077 } 1078 1079 1084 public String getBaseName() { 1085 return getBaseName(localeID); 1086 } 1087 1088 1094 public static String getBaseName(String localeID){ 1095 if (localeID.indexOf('@') == -1) { 1096 return localeID; 1097 } 1098 return new IDParser(localeID).getBaseName(); 1099 } 1100 1101 1107 public String getName() { 1108 return localeID; } 1110 1111 1118 public static String getName(String localeID){ 1119 Map cache = (Map )nameCacheRef.get(); 1120 if (cache == null) { 1121 cache = Collections.synchronizedMap(new HashMap ()); 1122 nameCacheRef = new SoftReference (cache); 1123 } 1124 String name = (String )cache.get(localeID); 1125 if (name == null) { 1126 name = new IDParser(localeID).getName(); 1127 cache.put(localeID, name); 1128 } 1129 return name; 1130 } 1131 1132 1136 public String toString() { 1137 return localeID; 1138 } 1139 1140 1146 public Iterator getKeywords() { 1147 return getKeywords(localeID); 1148 } 1149 1150 1157 public static Iterator getKeywords(String localeID){ 1158 return new IDParser(localeID).getKeywords(); 1159 } 1160 1161 1167 public String getKeywordValue(String keywordName){ 1168 return getKeywordValue(localeID, keywordName); 1169 } 1170 1171 1178 public static String getKeywordValue(String localeID, String keywordName) { 1179 return new IDParser(localeID).getKeywordValue(keywordName); 1180 } 1181 1182 1185 private static final class IDParser { 1186 private char[] id; 1187 private int index; 1188 private char[] buffer; 1189 private int blen; 1190 private boolean canonicalize; 1192 private boolean hadCountry; 1193 1194 Map keywords; 1196 String baseName; 1197 1198 1201 private static final char KEYWORD_SEPARATOR = '@'; 1202 private static final char HYPHEN = '-'; 1203 private static final char KEYWORD_ASSIGN = '='; 1204 private static final char COMMA = ','; 1205 private static final char ITEM_SEPARATOR = ';'; 1206 private static final char DOT = '.'; 1207 1208 private IDParser(String localeID) { 1209 this(localeID, false); 1210 } 1211 1212 private IDParser(String localeID, boolean canonicalize) { 1213 id = localeID.toCharArray(); 1214 index = 0; 1215 buffer = new char[id.length + 5]; 1216 blen = 0; 1217 this.canonicalize = canonicalize; 1218 } 1219 1220 private void reset() { 1221 index = blen = 0; 1222 } 1223 1224 1226 1229 private void append(char c) { 1230 try { 1231 buffer[blen] = c; 1232 } 1233 catch (IndexOutOfBoundsException e) { 1234 if (buffer.length > 512) { 1235 throw e; 1237 } 1238 char[] nbuffer = new char[buffer.length * 2]; 1239 System.arraycopy(buffer, 0, nbuffer, 0, buffer.length); 1240 nbuffer[blen] = c; 1241 buffer = nbuffer; 1242 } 1243 ++blen; 1244 } 1245 1246 private void addSeparator() { 1247 append(UNDERSCORE); 1248 } 1249 1250 1253 private String getString(int start) { 1254 if (start == blen) { 1255 return EMPTY_STRING; 1256 } 1257 return new String (buffer, start, blen-start); 1258 } 1259 1260 1263 private void set(int pos, String s) { 1264 this.blen = pos; append(s); 1266 } 1267 1268 1271 private void append(String s) { 1272 for (int i = 0; i < s.length(); ++i) { 1273 append(s.charAt(i)); 1274 } 1275 } 1276 1277 1279 1282 private static final char DONE = '\uffff'; 1283 1284 1289 private char next() { 1290 if (index == id.length) { 1291 index++; 1292 return DONE; 1293 } 1294 1295 return id[index++]; 1296 } 1297 1298 1301 private void skipUntilTerminatorOrIDSeparator() { 1302 while (!isTerminatorOrIDSeparator(next())) { 1303 } 1304 --index; 1305 } 1306 1307 1310 private boolean atTerminator() { 1311 return index >= id.length || isTerminator(id[index]); 1312 } 1313 1314 1317 1320 1321 1325 private boolean isTerminator(char c) { 1326 return c == KEYWORD_SEPARATOR || c == DONE || c == DOT; 1328 } 1329 1330 1333 private boolean isTerminatorOrIDSeparator(char c) { 1334 return c == KEYWORD_SEPARATOR || c == UNDERSCORE || c == HYPHEN || 1335 c == DONE || c == DOT; 1336 } 1337 1338 1342 private boolean haveExperimentalLanguagePrefix() { 1343 if (id.length > 2) { 1344 char c = id[1]; 1345 if (c == HYPHEN || c == UNDERSCORE) { 1346 c = id[0]; 1347 return c == 'x' || c == 'X' || c == 'i' || c == 'I'; 1348 } 1349 } 1350 return false; 1351 } 1352 1353 1356 private boolean haveKeywordAssign() { 1357 for (int i = index; i < id.length; ++i) { 1359 if (id[i] == KEYWORD_ASSIGN) { 1360 return true; 1361 } 1362 } 1363 return false; 1364 } 1365 1366 1371 private int parseLanguage() { 1372 if (haveExperimentalLanguagePrefix()) { 1373 append(Character.toLowerCase(id[0])); 1374 append(HYPHEN); 1375 index = 2; 1376 } 1377 1378 char c; 1379 while(!isTerminatorOrIDSeparator(c = next())) { 1380 append(Character.toLowerCase(c)); 1381 } 1382 --index; 1384 if (blen == 3) { 1385 initLanguageTables(); 1386 1387 1388 String lang = getString(0); 1389 int offset = findIndex(_languages3, lang); 1390 if (offset >= 0) { 1391 set(0, _languages[offset]); 1392 } else { 1393 offset = findIndex(_obsoleteLanguages3, lang); 1394 if (offset >= 0) { 1395 set(0, _obsoleteLanguages[offset]); 1396 } 1397 } 1398 } 1399 1400 return 0; 1401 } 1402 1403 1407 private void skipLanguage() { 1408 if (haveExperimentalLanguagePrefix()) { 1409 index = 2; 1410 } 1411 skipUntilTerminatorOrIDSeparator(); 1412 } 1413 1414 1423 private int parseScript() { 1424 if (!atTerminator()) { 1425 int oldIndex = index; ++index; 1427 1428 int oldBlen = blen; char c; 1430 while(!isTerminatorOrIDSeparator(c = next())) { 1431 if (blen == oldBlen) { addSeparator(); 1433 append(Character.toUpperCase(c)); 1434 } else { 1435 append(Character.toLowerCase(c)); 1436 } 1437 } 1438 --index; 1440 1441 if (index - oldIndex != 5) { index = oldIndex; 1443 blen = oldBlen; 1444 } else { 1445 oldBlen++; } 1447 1448 return oldBlen; 1449 } 1450 return blen; 1451 } 1452 1453 1460 private void skipScript() { 1461 if (!atTerminator()) { 1462 int oldIndex = index; 1463 ++index; 1464 1465 skipUntilTerminatorOrIDSeparator(); 1466 if (index - oldIndex != 5) { index = oldIndex; 1468 } 1469 } 1470 } 1471 1472 1477 private int parseCountry() { 1478 if (!atTerminator()) { 1479 ++index; 1480 1481 int oldBlen = blen; 1482 char c; 1483 while (!isTerminatorOrIDSeparator(c = next())) { 1484 if (oldBlen == blen) { hadCountry = true; addSeparator(); 1487 ++oldBlen; } 1489 append(Character.toUpperCase(c)); 1490 } 1491 --index; 1493 if (blen - oldBlen == 3) { 1494 initCountryTables(); 1495 1496 1497 int offset = findIndex(_countries3, getString(oldBlen)); 1498 if (offset >= 0) { 1499 set(oldBlen, _countries[offset]); 1500 } else { 1501 offset = findIndex(_obsoleteCountries3, getString(oldBlen)); 1502 if (offset >= 0) { 1503 set(oldBlen, _obsoleteCountries[offset]); 1504 } 1505 } 1506 } 1507 1508 return oldBlen; 1509 } 1510 1511 return blen; 1512 } 1513 1514 1519 private void skipCountry() { 1520 if (!atTerminator()) { 1521 ++index; 1522 skipUntilTerminatorOrIDSeparator(); 1523 } 1524 } 1525 1526 1550 private int parseVariant() { 1551 int oldBlen = blen; 1552 1553 boolean start = true; 1554 boolean needSeparator = true; 1555 boolean skipping = false; 1556 char c; 1557 while ((c = next()) != DONE) { 1558 if (c == DOT) { 1559 start = false; 1560 skipping = true; 1561 } else if (c == KEYWORD_SEPARATOR) { 1562 if (haveKeywordAssign()) { 1563 break; 1564 } 1565 skipping = false; 1566 start = false; 1567 needSeparator = true; } else if (start) { 1569 start = false; 1570 } else if (!skipping) { 1571 if (needSeparator) { 1572 boolean incOldBlen = blen == oldBlen; needSeparator = false; 1574 if (incOldBlen && !hadCountry) { addSeparator(); 1576 ++oldBlen; } 1578 addSeparator(); 1579 if (incOldBlen) { ++oldBlen; 1581 } 1582 } 1583 c = Character.toUpperCase(c); 1584 if (c == HYPHEN || c == COMMA) { 1585 c = UNDERSCORE; 1586 } 1587 append(c); 1588 } 1589 } 1590 --index; 1592 return oldBlen; 1593 } 1594 1595 1598 1601 public String getLanguage() { 1602 reset(); 1603 return getString(parseLanguage()); 1604 } 1605 1606 1609 public String getScript() { 1610 reset(); 1611 skipLanguage(); 1612 return getString(parseScript()); 1613 } 1614 1615 1618 public String getCountry() { 1619 reset(); 1620 skipLanguage(); 1621 skipScript(); 1622 return getString(parseCountry()); 1623 } 1624 1625 1628 public String getVariant() { 1629 reset(); 1630 skipLanguage(); 1631 skipScript(); 1632 skipCountry(); 1633 return getString(parseVariant()); 1634 } 1635 1636 1639 public String [] getLanguageScriptCountryVariant() { 1640 reset(); 1641 return new String [] { 1642 getString(parseLanguage()), 1643 getString(parseScript()), 1644 getString(parseCountry()), 1645 getString(parseVariant()) 1646 }; 1647 } 1648 1649 public void setBaseName(String baseName) { 1650 this.baseName = baseName; 1651 } 1652 1653 public void parseBaseName() { 1654 if (baseName != null) { 1655 set(0, baseName); 1656 } else { 1657 reset(); 1658 parseLanguage(); 1659 parseScript(); 1660 parseCountry(); 1661 parseVariant(); 1662 1663 if (blen > 1 && buffer[blen-1] == UNDERSCORE) { 1665 --blen; 1666 } 1667 } 1668 } 1669 1670 1674 public String getBaseName() { 1675 if (baseName != null) { 1676 return baseName; 1677 } 1678 parseBaseName(); 1679 return getString(0); 1680 } 1681 1682 1686 public String getName() { 1687 parseBaseName(); 1688 parseKeywords(); 1689 return getString(0); 1690 } 1691 1692 1694 1698 private boolean setToKeywordStart() { 1699 for (int i = index; i < id.length; ++i) { 1700 if (id[i] == KEYWORD_SEPARATOR) { 1701 if (canonicalize) { 1702 for (int j = ++i; j < id.length; ++j) { if (id[j] == KEYWORD_ASSIGN) { 1704 index = i; 1705 return true; 1706 } 1707 } 1708 } else { 1709 if (++i < id.length) { 1710 index = i; 1711 return true; 1712 } 1713 } 1714 break; 1715 } 1716 } 1717 return false; 1718 } 1719 1720 private static boolean isDoneOrKeywordAssign(char c) { 1721 return c == DONE || c == KEYWORD_ASSIGN; 1722 } 1723 1724 private static boolean isDoneOrItemSeparator(char c) { 1725 return c == DONE || c == ITEM_SEPARATOR; 1726 } 1727 1728 private String getKeyword() { 1729 int start = index; 1730 while (!isDoneOrKeywordAssign(next())) { 1731 } 1732 --index; 1733 return new String (id, start, index-start).trim().toLowerCase(); 1734 } 1735 1736 private String getValue() { 1737 int start = index; 1738 while (!isDoneOrItemSeparator(next())) { 1739 } 1740 --index; 1741 return new String (id, start, index-start).trim(); } 1743 1744 private Comparator getKeyComparator() { 1745 final Comparator comp = new Comparator () { 1746 public int compare(Object lhs, Object rhs) { 1747 return ((String )lhs).compareTo((String )rhs); 1748 } 1749 }; 1750 return comp; 1751 } 1752 1753 1756 private Map getKeywordMap() { 1757 if (keywords == null) { 1758 TreeMap m = null; 1759 if (setToKeywordStart()) { 1760 do { 1762 String key = getKeyword(); 1763 if (key.length() == 0) { 1764 break; 1765 } 1766 char c = next(); 1767 if (c != KEYWORD_ASSIGN) { 1768 if (c == DONE) { 1770 break; 1771 } else { 1772 continue; 1773 } 1774 } 1775 String value = getValue(); 1776 if (value.length() == 0) { 1777 continue; 1779 } 1780 if (m == null) { 1781 m = new TreeMap (getKeyComparator()); 1782 } else if (m.containsKey(key)) { 1783 continue; 1785 } 1786 m.put(key, value); 1787 } while (next() == ITEM_SEPARATOR); 1788 } 1789 keywords = m != null ? m : Collections.EMPTY_MAP; 1790 } 1791 1792 return keywords; 1793 } 1794 1795 1798 private int parseKeywords() { 1799 int oldBlen = blen; 1800 Map m = getKeywordMap(); 1801 if (!m.isEmpty()) { 1802 Iterator iter = m.entrySet().iterator(); 1803 boolean first = true; 1804 while (iter.hasNext()) { 1805 append(first ? KEYWORD_SEPARATOR : ITEM_SEPARATOR); 1806 first = false; 1807 Map.Entry e = (Map.Entry )iter.next(); 1808 append((String )e.getKey()); 1809 append(KEYWORD_ASSIGN); 1810 append((String )e.getValue()); 1811 } 1812 if (blen != oldBlen) { 1813 ++oldBlen; 1814 } 1815 } 1816 return oldBlen; 1817 } 1818 1819 1822 public Iterator getKeywords() { 1823 Map m = getKeywordMap(); 1824 return m.isEmpty() ? null : m.keySet().iterator(); 1825 } 1826 1827 1831 public String getKeywordValue(String keywordName) { 1832 Map m = getKeywordMap(); 1833 return m.isEmpty() ? null : (String )m.get(keywordName.trim().toLowerCase()); 1834 } 1835 1836 1839 public void defaultKeywordValue(String keywordName, String value) { 1840 setKeywordValue(keywordName, value, false); 1841 } 1842 1843 1848 public void setKeywordValue(String keywordName, String value) { 1849 setKeywordValue(keywordName, value, true); 1850 } 1851 1852 1859 private void setKeywordValue(String keywordName, String value, boolean reset) { 1860 if (keywordName == null) { 1861 if (reset) { 1862 keywords = Collections.EMPTY_MAP; 1864 } 1865 } else { 1866 keywordName = keywordName.trim().toLowerCase(); 1867 if (keywordName.length() == 0) { 1868 throw new IllegalArgumentException ("keyword must not be empty"); 1869 } 1870 if (value != null) { 1871 value = value.trim(); 1872 if (value.length() == 0) { 1873 throw new IllegalArgumentException ("value must not be empty"); 1874 } 1875 } 1876 Map m = getKeywordMap(); 1877 if (m.isEmpty()) { if (value != null) { 1879 keywords = new TreeMap (getKeyComparator()); 1881 keywords.put(keywordName, value.trim()); 1882 } 1883 } else { 1884 if (reset || !m.containsKey(keywordName)) { 1885 if (value != null) { 1886 m.put(keywordName, value); 1887 } else { 1888 m.remove(keywordName); 1889 if (m.isEmpty()) { 1890 keywords = Collections.EMPTY_MAP; 1892 } 1893 } 1894 } 1895 } 1896 } 1897 } 1898 } 1899 1900 1904 private static int findIndex(String [] array, String target){ 1905 for (int i = 0; i < array.length; i++) { 1906 if (target.equals(array[i])) { 1907 return i; 1908 } 1909 } 1910 return -1; 1911 } 1912 1913 1920 public static String canonicalize(String localeID){ 1921 IDParser parser = new IDParser(localeID, true); 1922 String baseName = parser.getBaseName(); 1923 boolean foundVariant = false; 1924 1925 if (localeID.equals("")) { 1930 return ""; 1931 } 1933 1934 1936 initVariantsTable(); 1937 1938 1939 for (int i = 0; i < _variantsToKeywords.length; i++) { 1940 if (_variantsToKeywords[i][0].equals(baseName)) { 1941 foundVariant = true; 1942 1943 String [] vals = _variantsToKeywords[i]; 1944 parser.setBaseName(vals[1]); 1945 if (vals[2] != null) { 1946 parser.defaultKeywordValue(vals[2], vals[3]); 1947 } 1948 break; 1949 } 1950 } 1951 1952 1953 if (!foundVariant) { 1954 int idx = baseName.indexOf("_EURO"); 1955 if (idx > -1) { 1956 parser.setBaseName(baseName.substring(0, idx)); 1957 parser.defaultKeywordValue("currency", "EUR"); 1958 } 1959 } 1960 1961 1962 if (!foundVariant) { 1963 if (parser.getLanguage().equals("nb") && parser.getVariant().equals("NY")) { 1964 parser.setBaseName(lscvToID("nn", parser.getScript(), parser.getCountry(), null)); 1965 } 1966 } 1967 1968 return parser.getName(); 1969 } 1970 1971 1982 public ULocale setKeywordValue(String keyword, String value) { 1983 return new ULocale(setKeywordValue(localeID, keyword, value), (Locale )null); 1984 } 1985 1986 1998 public static String setKeywordValue(String localeID, String keyword, String value) { 1999 IDParser parser = new IDParser(localeID); 2000 parser.setKeywordValue(keyword, value); 2001 return parser.getName(); 2002 } 2003 2004 2014 2019 2020 2030 public String getISO3Language(){ 2031 return getISO3Language(localeID); 2032 } 2033 2034 2044 public static String getISO3Language(String localeID){ 2045 initLanguageTables(); 2046 2047 String language = getLanguage(localeID); 2048 int offset = findIndex(_languages, language); 2049 if(offset>=0){ 2050 return _languages3[offset]; 2051 } else { 2052 offset = findIndex(_obsoleteLanguages, language); 2053 if (offset >= 0) { 2054 return _obsoleteLanguages3[offset]; 2055 } 2056 } 2057 return EMPTY_STRING; 2058 } 2059 2060 2068 public String getISO3Country(){ 2069 return getISO3Country(localeID); 2070 } 2071 2079 public static String getISO3Country(String localeID){ 2080 initCountryTables(); 2081 2082 String country = getCountry(localeID); 2083 int offset = findIndex(_countries, country); 2084 if(offset>=0){ 2085 return _countries3[offset]; 2086 }else{ 2087 offset = findIndex(_obsoleteCountries, country); 2088 if(offset>=0){ 2089 return _obsoleteCountries3[offset]; 2090 } 2091 } 2092 return EMPTY_STRING; 2093 } 2094 2095 2097 2100 private static String getTableString(String tableName, String subtableName, String item, String displayLocaleID) { 2101 if (item.length() > 0) { 2102 try { 2103 ICUResourceBundle bundle = (ICUResourceBundle)UResourceBundle. 2104 getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, displayLocaleID); 2105 return getTableString(tableName, subtableName, item, bundle); 2106 } catch (Exception e) { 2107 } 2109 } 2110 return item; 2111 } 2112 2113 2116 private static String getTableString(String tableName, String subtableName, String item, ICUResourceBundle bundle) { 2117 try { 2122 for (;;) { 2123 if ("currency".equals(subtableName)) { 2125 ICUResourceBundle table = bundle.getWithFallback("Currencies"); 2126 table = table.getWithFallback(item); 2127 return table.getString(1); 2128 } else { 2129 ICUResourceBundle table = bundle.getWithFallback(tableName); 2130 try { 2131 if (subtableName != null) { 2132 table = table.getWithFallback(subtableName); 2133 } 2134 return table.getStringWithFallback(item); 2135 } 2136 catch (MissingResourceException e) { 2137 2138 if(subtableName==null){ 2139 try{ 2140 String currentName = null; 2142 if(tableName.equals("Countries")){ 2143 currentName = getCurrentCountryID(item); 2144 }else if(tableName.equals("Languages")){ 2145 currentName = getCurrentLanguageID(item); 2146 } 2147 return table.getStringWithFallback(currentName); 2148 }catch (MissingResourceException ex){} 2149 } 2150 2151 String fallbackLocale = table.getWithFallback("Fallback").getString(); 2153 if (fallbackLocale.length() == 0) { 2154 fallbackLocale = "root"; 2155 } 2156 if(fallbackLocale.equals(table.getULocale().localeID)){ 2158 return item; 2159 } 2160 bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, 2161 fallbackLocale); 2162 } 2165 } 2166 } 2167 } 2168 catch (Exception e) { 2169 } 2171 return item; 2172 } 2173 2174 2179 public String getDisplayLanguage() { 2180 return getDisplayLanguageInternal(localeID, getDefault().localeID); 2181 } 2182 2183 2189 public String getDisplayLanguage(ULocale displayLocale) { 2190 return getDisplayLanguageInternal(localeID, displayLocale.localeID); 2191 } 2192 2193 2201 public static String getDisplayLanguage(String localeID, String displayLocaleID) { 2202 return getDisplayLanguageInternal(localeID, getName(displayLocaleID)); 2203 } 2204 2205 2213 public static String getDisplayLanguage(String localeID, ULocale displayLocale) { 2214 return getDisplayLanguageInternal(localeID, displayLocale.localeID); 2215 } 2216 2217 static String getCurrentCountryID(String oldID){ 2218 initCountryTables(); 2219 int offset = findIndex(_deprecatedCountries, oldID); 2220 if (offset >= 0) { 2221 return _replacementCountries[offset]; 2222 } 2223 return oldID; 2224 } 2225 static String getCurrentLanguageID(String oldID){ 2226 initLanguageTables(); 2227 int offset = findIndex(_obsoleteLanguages, oldID); 2228 if (offset >= 0) { 2229 return _replacementLanguages[offset]; 2230 } 2231 return oldID; 2232 } 2233 2234 2235 private static String getDisplayLanguageInternal(String localeID, String displayLocaleID) { 2237 return getTableString("Languages", null, new IDParser(localeID).getLanguage(), displayLocaleID); 2238 } 2239 2240 2245 public String getDisplayScript() { 2246 return getDisplayScriptInternal(localeID, getDefault().localeID); 2247 } 2248 2249 2255 public String getDisplayScript(ULocale displayLocale) { 2256 return getDisplayScriptInternal(localeID, displayLocale.localeID); 2257 } 2258 2259 2267 public static String getDisplayScript(String localeID, String displayLocaleID) { 2268 return getDisplayScriptInternal(localeID, getName(displayLocaleID)); 2269 } 2270 2271 2278 public static String getDisplayScript(String localeID, ULocale displayLocale) { 2279 return getDisplayScriptInternal(localeID, displayLocale.localeID); 2280 } 2281 2282 private static String getDisplayScriptInternal(String localeID, String displayLocaleID) { 2284 return getTableString("Scripts", null, new IDParser(localeID).getScript(), displayLocaleID); 2285 } 2286 2287 2292 public String getDisplayCountry() { 2293 return getDisplayCountryInternal(localeID, getDefault().localeID); 2294 } 2295 2296 2302 public String getDisplayCountry(ULocale displayLocale){ 2303 return getDisplayCountryInternal(localeID, displayLocale.localeID); 2304 } 2305 2306 2314 public static String getDisplayCountry(String localeID, String displayLocaleID) { 2315 return getDisplayCountryInternal(localeID, getName(displayLocaleID)); 2316 } 2317 2318 2326 public static String getDisplayCountry(String localeID, ULocale displayLocale) { 2327 return getDisplayCountryInternal(localeID, displayLocale.localeID); 2328 } 2329 2330 private static String getDisplayCountryInternal(String localeID, String displayLocaleID) { 2332 return getTableString("Countries", null, new IDParser(localeID).getCountry(), displayLocaleID); 2333 } 2334 2335 2340 public String getDisplayVariant() { 2341 return getDisplayVariantInternal(localeID, getDefault().localeID); 2342 } 2343 2344 2350 public String getDisplayVariant(ULocale displayLocale) { 2351 return getDisplayVariantInternal(localeID, displayLocale.localeID); 2352 } 2353 2354 2362 public static String getDisplayVariant(String localeID, String displayLocaleID){ 2363 return getDisplayVariantInternal(localeID, getName(displayLocaleID)); 2364 } 2365 2366 2374 public static String getDisplayVariant(String localeID, ULocale displayLocale) { 2375 return getDisplayVariantInternal(localeID, displayLocale.localeID); 2376 } 2377 2378 private static String getDisplayVariantInternal(String localeID, String displayLocaleID) { 2380 return getTableString("Variants", null, new IDParser(localeID).getVariant(), displayLocaleID); 2381 } 2382 2383 2390 public static String getDisplayKeyword(String keyword) { 2391 return getDisplayKeywordInternal(keyword, getDefault().localeID); 2392 } 2393 2394 2402 public static String getDisplayKeyword(String keyword, String displayLocaleID) { 2403 return getDisplayKeywordInternal(keyword, getName(displayLocaleID)); 2404 } 2405 2406 2414 public static String getDisplayKeyword(String keyword, ULocale displayLocale) { 2415 return getDisplayKeywordInternal(keyword, displayLocale.localeID); 2416 } 2417 2418 private static String getDisplayKeywordInternal(String keyword, String displayLocaleID) { 2420 return getTableString("Keys", null, keyword.trim().toLowerCase(), displayLocaleID); 2421 } 2422 2423 2429 public String getDisplayKeywordValue(String keyword) { 2430 return getDisplayKeywordValueInternal(localeID, keyword, getDefault().localeID); 2431 } 2432 2433 2440 public String getDisplayKeywordValue(String keyword, ULocale displayLocale) { 2441 return getDisplayKeywordValueInternal(localeID, keyword, displayLocale.localeID); 2442 } 2443 2444 2453 public static String getDisplayKeywordValue(String localeID, String keyword, String displayLocaleID) { 2454 return getDisplayKeywordValueInternal(localeID, keyword, getName(displayLocaleID)); 2455 } 2456 2457 2466 public static String getDisplayKeywordValue(String localeID, String keyword, ULocale displayLocale) { 2467 return getDisplayKeywordValueInternal(localeID, keyword, displayLocale.localeID); 2468 } 2469 2470 private static String getDisplayKeywordValueInternal(String localeID, String keyword, String displayLocaleID) { 2472 keyword = keyword.trim().toLowerCase(); 2473 String value = new IDParser(localeID).getKeywordValue(keyword); 2474 return getTableString("Types", keyword, value, displayLocaleID); 2475 } 2476 2477 2482 public String getDisplayName() { 2483 return getDisplayNameInternal(localeID, getDefault().localeID); 2484 } 2485 2486 2492 public String getDisplayName(ULocale displayLocale) { 2493 return getDisplayNameInternal(localeID, displayLocale.localeID); 2494 } 2495 2496 2504 public static String getDisplayName(String localeID, String displayLocaleID) { 2505 return getDisplayNameInternal(localeID, getName(displayLocaleID)); 2506 } 2507 2508 2516 public static String getDisplayName(String localeID, ULocale displayLocale) { 2517 return getDisplayNameInternal(localeID, displayLocale.localeID); 2518 } 2519 2520 private static String getDisplayNameInternal(String localeID, String displayLocaleID) { 2522 2526 final String [] tableNames = { "Languages", "Scripts", "Countries", "Variants" }; 2527 2528 ICUResourceBundle bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, displayLocaleID); 2529 2530 StringBuffer buf = new StringBuffer (); 2531 2532 IDParser parser = new IDParser(localeID); 2533 String [] names = parser.getLanguageScriptCountryVariant(); 2534 2535 boolean haveLanguage = names[0].length() > 0; 2536 boolean openParen = false; 2537 for (int i = 0; i < names.length; ++i) { 2538 String name = names[i]; 2539 if (name.length() > 0) { 2540 name = getTableString(tableNames[i], null, name, bundle); 2541 if (buf.length() > 0) { if (haveLanguage & !openParen) { 2543 buf.append(" ("); 2544 openParen = true; 2545 } else { 2546 buf.append(", "); 2547 } 2548 } 2549 buf.append(name); 2550 } 2551 } 2552 2553 Map m = parser.getKeywordMap(); 2554 if (!m.isEmpty()) { 2555 Iterator keys = m.entrySet().iterator(); 2556 while (keys.hasNext()) { 2557 if (buf.length() > 0) { 2558 if (haveLanguage & !openParen) { 2559 buf.append(" ("); 2560 openParen = true; 2561 } else { 2562 buf.append(", "); 2563 } 2564 } 2565 Map.Entry e = (Map.Entry )keys.next(); 2566 String key = (String )e.getKey(); 2567 String val = (String )e.getValue(); 2568 buf.append(getTableString("Keys", null, key, bundle)); 2569 buf.append("="); 2570 buf.append(getTableString("Types", key, val, bundle)); 2571 } 2572 } 2573 2574 if (openParen) { 2575 buf.append(")"); 2576 } 2577 2578 return buf.toString(); 2579 } 2580 2581 2592 public static Type ACTUAL_LOCALE = new Type(0); 2593 2594 2608 public static Type VALID_LOCALE = new Type(1); 2609 2610 2618 public static final class Type { 2619 private int localeType; 2620 private Type(int type) { localeType = type; } 2621 } 2622 2623 2624 2640 2641 public static ULocale acceptLanguage(String acceptLanguageList, ULocale[] availableLocales, 2642 boolean[] fallback) { 2643 2646 class ULocaleAcceptLanguageQ implements Comparable { 2647 private double q; 2648 private double serial; 2649 public ULocaleAcceptLanguageQ(double theq, int theserial) { 2650 q = theq; 2651 serial = theserial; 2652 } 2653 public int compareTo(Object o) { 2654 ULocaleAcceptLanguageQ other = (ULocaleAcceptLanguageQ) o; 2655 if(q > other.q) { return -1; 2657 } else if(q < other.q) { 2658 return 1; 2659 } 2660 if(serial < other.serial) { 2661 return -1; 2662 } else if(serial > other.serial) { 2663 return 1; 2664 } else { 2665 return 0; } 2667 } 2668 } 2669 2670 2672 TreeMap map = new TreeMap (); 2673 2674 final int l = acceptLanguageList.length(); 2675 int n; 2676 for(n=0;n<l;n++) { 2677 int itemEnd = acceptLanguageList.indexOf(',',n); 2678 if(itemEnd == -1) { 2679 itemEnd = l; 2680 } 2681 int paramEnd = acceptLanguageList.indexOf(';',n); 2682 double q = 1.0; 2683 2684 if((paramEnd != -1) && (paramEnd < itemEnd)) { 2685 2686 int t = paramEnd + 1; 2687 while(UCharacter.isWhitespace(acceptLanguageList.charAt(t))) { 2688 t++; 2689 } 2690 if(acceptLanguageList.charAt(t)=='q') { 2691 t++; 2692 } 2693 while(UCharacter.isWhitespace(acceptLanguageList.charAt(t))) { 2694 t++; 2695 } 2696 if(acceptLanguageList.charAt(t)=='=') { 2697 t++; 2698 } 2699 while(UCharacter.isWhitespace(acceptLanguageList.charAt(t))) { 2700 t++; 2701 } 2702 try { 2703 String val = acceptLanguageList.substring(t,itemEnd).trim(); 2704 q = Double.parseDouble(val); 2705 } catch (NumberFormatException nfe) { 2706 q = 1.0; 2707 } 2708 } else { 2709 q = 1.0; paramEnd = itemEnd; 2711 } 2712 2713 String loc = acceptLanguageList.substring(n,paramEnd).trim(); 2714 int serial = map.size(); 2715 ULocaleAcceptLanguageQ entry = new ULocaleAcceptLanguageQ(q,serial); 2716 map.put(entry, new ULocale(canonicalize(loc))); n = itemEnd; } 2719 2720 ULocale acceptList[] = (ULocale[])map.values().toArray(new ULocale[map.size()]); 2722 2723 return acceptLanguage(acceptList, availableLocales, fallback); 2725 } 2726 2727 2743 2744 public static ULocale acceptLanguage(ULocale[] acceptLanguageList, ULocale[] 2745 availableLocales, boolean[] fallback) { 2746 int i,j; 2748 if(fallback != null) { 2749 fallback[0]=true; 2750 } 2751 for(i=0;i<acceptLanguageList.length;i++) { 2752 ULocale aLocale = acceptLanguageList[i]; 2753 boolean[] setFallback = fallback; 2754 do { 2755 for(j=0;j<availableLocales.length;j++) { 2756 if(availableLocales[j].equals(aLocale)) { 2757 if(setFallback != null) { 2758 setFallback[0]=false; } 2760 return availableLocales[j]; 2761 } 2762 } 2763 Locale loc = aLocale.toLocale(); 2764 Locale parent = LocaleUtility.fallback(loc); 2765 if(parent != null) { 2766 aLocale = new ULocale(parent); 2767 } else { 2768 aLocale = null; 2769 } 2770 setFallback = null; } while (aLocale != null); 2772 } 2773 return null; 2774 } 2775 2776 2792 2793 public static ULocale acceptLanguage(String acceptLanguageList, boolean[] fallback) { 2794 return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(), 2795 fallback); 2796 } 2797 2798 2814 2815 public static ULocale acceptLanguage(ULocale[] acceptLanguageList, boolean[] 2816 fallback) { 2817 return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(), 2818 fallback); 2819 } 2820} 2821 | Popular Tags |