1 /* 2 ******************************************************************************* 3 * Copyright (C) 2003-2014, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 package com.ibm.icu.dev.test.collator; 9 10 import java.util.Arrays; 11 import java.util.Collections; 12 import java.util.HashMap; 13 import java.util.HashSet; 14 import java.util.Iterator; 15 import java.util.Locale; 16 import java.util.Map; 17 import java.util.MissingResourceException; 18 import java.util.Set; 19 20 import com.ibm.icu.dev.test.TestFmwk; 21 import com.ibm.icu.text.Collator; 22 import com.ibm.icu.text.Collator.CollatorFactory; 23 import com.ibm.icu.util.ULocale; 24 25 public class CollationServiceTest extends TestFmwk { main(String[] args)26 public static void main(String[] args) { 27 new CollationServiceTest().run(args); 28 } 29 TestRegister()30 public void TestRegister() { 31 // register a singleton 32 Collator frcol = Collator.getInstance(ULocale.FRANCE); 33 Collator uscol = Collator.getInstance(ULocale.US); 34 35 { // try override en_US collator 36 Object key = Collator.registerInstance(frcol, ULocale.US); 37 Collator ncol = Collator.getInstance(ULocale.US); 38 if (!frcol.equals(ncol)) { 39 errln("register of french collator for en_US failed"); 40 } 41 42 // coverage 43 Collator test = Collator.getInstance(ULocale.GERMANY); // CollatorFactory.handleCreate 44 if (!test.getLocale(ULocale.VALID_LOCALE).equals(ULocale.GERMAN)) { 45 errln("Collation from Germany is really " + test.getLocale(ULocale.VALID_LOCALE)); 46 } 47 48 if (!Collator.unregister(key)) { 49 errln("failed to unregister french collator"); 50 } 51 ncol = Collator.getInstance(ULocale.US); 52 if (!uscol.equals(ncol)) { 53 errln("collator after unregister does not match original"); 54 } 55 } 56 57 ULocale fu_FU = new ULocale("fu_FU_FOO"); 58 59 { // try create collator for new locale 60 Collator fucol = Collator.getInstance(fu_FU); 61 Object key = Collator.registerInstance(frcol, fu_FU); 62 Collator ncol = Collator.getInstance(fu_FU); 63 if (!frcol.equals(ncol)) { 64 errln("register of fr collator for fu_FU failed"); 65 } 66 67 ULocale[] locales = Collator.getAvailableULocales(); 68 boolean found = false; 69 for (int i = 0; i < locales.length; ++i) { 70 if (locales[i].equals(fu_FU)) { 71 found = true; 72 break; 73 } 74 } 75 if (!found) { 76 errln("new locale fu_FU not reported as supported locale"); 77 } 78 try{ 79 String name = Collator.getDisplayName(fu_FU); 80 if (!"fu (FU, FOO)".equals(name) 81 && !"fu_FU_FOO".equals(name) /* no LocaleDisplayNamesImpl */) { 82 errln("found " + name + " for fu_FU"); 83 } 84 }catch(MissingResourceException ex){ 85 warnln("Could not load locale data."); 86 } 87 try{ 88 String name = Collator.getDisplayName(fu_FU, fu_FU); 89 if (!"fu (FU, FOO)".equals(name) 90 && !"fu_FU_FOO".equals(name) /* no LocaleDisplayNamesImpl */) { 91 errln("found " + name + " for fu_FU"); 92 } 93 }catch(MissingResourceException ex){ 94 warnln("Could not load locale data."); 95 } 96 97 if (!Collator.unregister(key)) { 98 errln("failed to unregister french collator"); 99 } 100 ncol = Collator.getInstance(fu_FU); 101 if (!fucol.equals(ncol)) { 102 errln("collator after unregister does not match original fu_FU"); 103 } 104 } 105 106 { 107 // coverage after return to default 108 ULocale[] locales = Collator.getAvailableULocales(); 109 110 for (int i = 0; i < locales.length; ++i) { 111 if (locales[i].equals(fu_FU)) { 112 errln("new locale fu_FU not reported as supported locale"); 113 break; 114 } 115 } 116 117 Collator ncol = Collator.getInstance(ULocale.US); 118 if (!ncol.getLocale(ULocale.VALID_LOCALE).equals(ULocale.US)) { 119 errln("Collation from US is really " + ncol.getLocale(ULocale.VALID_LOCALE)); 120 } 121 } 122 } 123 TestRegisterFactory()124 public void TestRegisterFactory() { 125 126 class CollatorInfo { 127 ULocale locale; 128 Collator collator; 129 Map displayNames; // locale -> string 130 131 CollatorInfo(ULocale locale, Collator collator, Map displayNames) { 132 this.locale = locale; 133 this.collator = collator; 134 this.displayNames = displayNames; 135 } 136 137 String getDisplayName(ULocale displayLocale) { 138 String name = null; 139 if (displayNames != null) { 140 name = (String)displayNames.get(displayLocale); 141 } 142 if (name == null) { 143 name = locale.getDisplayName(displayLocale); 144 } 145 return name; 146 } 147 } 148 149 class TestFactory extends CollatorFactory { 150 private Map map; 151 private Set ids; 152 153 TestFactory(CollatorInfo[] info) { 154 map = new HashMap(); 155 for (int i = 0; i < info.length; ++i) { 156 CollatorInfo ci = info[i]; 157 map.put(ci.locale, ci); 158 } 159 } 160 161 public Collator createCollator(ULocale loc) { 162 CollatorInfo ci = (CollatorInfo)map.get(loc); 163 if (ci != null) { 164 return ci.collator; 165 } 166 return null; 167 } 168 169 public String getDisplayName(ULocale objectLocale, ULocale displayLocale) { 170 CollatorInfo ci = (CollatorInfo)map.get(objectLocale); 171 if (ci != null) { 172 return ci.getDisplayName(displayLocale); 173 } 174 return null; 175 } 176 177 public Set getSupportedLocaleIDs() { 178 if (ids == null) { 179 HashSet set = new HashSet(); 180 Iterator iter = map.keySet().iterator(); 181 while (iter.hasNext()) { 182 ULocale locale = (ULocale)iter.next(); 183 String id = locale.toString(); 184 set.add(id); 185 } 186 ids = Collections.unmodifiableSet(set); 187 } 188 return ids; 189 } 190 } 191 192 class TestFactoryWrapper extends CollatorFactory { 193 CollatorFactory delegate; 194 195 TestFactoryWrapper(CollatorFactory delegate) { 196 this.delegate = delegate; 197 } 198 199 public Collator createCollator(ULocale loc) { 200 return delegate.createCollator(loc); 201 } 202 203 // use CollatorFactory getDisplayName(ULocale, ULocale) for coverage 204 205 public Set getSupportedLocaleIDs() { 206 return delegate.getSupportedLocaleIDs(); 207 } 208 } 209 210 ULocale fu_FU = new ULocale("fu_FU"); 211 ULocale fu_FU_FOO = new ULocale("fu_FU_FOO"); 212 213 Map fuFUNames = new HashMap(); 214 fuFUNames.put(fu_FU, "ze leetle bunny Fu-Fu"); 215 fuFUNames.put(fu_FU_FOO, "zee leetel bunny Foo-Foo"); 216 fuFUNames.put(ULocale.US, "little bunny Foo Foo"); 217 218 Collator frcol = Collator.getInstance(ULocale.FRANCE); 219 /* Collator uscol = */Collator.getInstance(ULocale.US); 220 Collator gecol = Collator.getInstance(ULocale.GERMANY); 221 Collator jpcol = Collator.getInstance(ULocale.JAPAN); 222 Collator fucol = Collator.getInstance(fu_FU); 223 224 CollatorInfo[] info = { 225 new CollatorInfo(ULocale.US, frcol, null), 226 new CollatorInfo(ULocale.FRANCE, gecol, null), 227 new CollatorInfo(fu_FU, jpcol, fuFUNames), 228 }; 229 TestFactory factory = null; 230 try{ 231 factory = new TestFactory(info); 232 }catch(MissingResourceException ex){ 233 warnln("Could not load locale data."); 234 } 235 // coverage 236 { 237 TestFactoryWrapper wrapper = new TestFactoryWrapper(factory); // in java, gc lets us easily multiply reference! 238 Object key = Collator.registerFactory(wrapper); 239 String name = null; 240 try{ 241 name = Collator.getDisplayName(fu_FU, fu_FU_FOO); 242 }catch(MissingResourceException ex){ 243 warnln("Could not load locale data."); 244 } 245 logln("*** default name: " + name); 246 Collator.unregister(key); 247 248 ULocale bar_BAR = new ULocale("bar_BAR"); 249 Collator col = Collator.getInstance(bar_BAR); 250 ULocale valid = col.getLocale(ULocale.VALID_LOCALE); 251 String validName = valid.getName(); 252 if(validName.length() != 0 && !validName.equals("root")) { 253 errln("Collation from bar_BAR is really \"" + validName + "\" but should be root"); 254 } 255 } 256 257 int n1 = checkAvailable("before registerFactory"); 258 259 { 260 Object key = Collator.registerFactory(factory); 261 262 int n2 = checkAvailable("after registerFactory"); 263 264 Collator ncol = Collator.getInstance(ULocale.US); 265 if (!frcol.equals(ncol)) { 266 errln("frcoll for en_US failed"); 267 } 268 269 ncol = Collator.getInstance(fu_FU_FOO); 270 if (!jpcol.equals(ncol)) { 271 errln("jpcol for fu_FU_FOO failed, got: " + ncol); 272 } 273 274 ULocale[] locales = Collator.getAvailableULocales(); 275 boolean found = false; 276 for (int i = 0; i < locales.length; ++i) { 277 if (locales[i].equals(fu_FU)) { 278 found = true; 279 break; 280 } 281 } 282 if (!found) { 283 errln("new locale fu_FU not reported as supported locale"); 284 } 285 286 String name = Collator.getDisplayName(fu_FU); 287 if (!"little bunny Foo Foo".equals(name)) { 288 errln("found " + name + " for fu_FU"); 289 } 290 291 name = Collator.getDisplayName(fu_FU, fu_FU_FOO); 292 if (!"zee leetel bunny Foo-Foo".equals(name)) { 293 errln("found " + name + " for fu_FU in fu_FU_FOO"); 294 } 295 296 if (!Collator.unregister(key)) { 297 errln("failed to unregister factory"); 298 } 299 300 int n3 = checkAvailable("after unregister"); 301 assertTrue("register increases count", n2>n1); 302 assertTrue("unregister restores count", n3==n1); 303 304 ncol = Collator.getInstance(fu_FU); 305 if (!fucol.equals(ncol)) { 306 errln("collator after unregister does not match original fu_FU"); 307 } 308 } 309 } 310 311 /** 312 * Check the integrity of the results of Collator.getAvailableULocales(). 313 * Return the number of items returned. 314 */ checkAvailable(String msg)315 int checkAvailable(String msg) { 316 Locale locs[] = Collator.getAvailableLocales(); 317 if (!assertTrue("getAvailableLocales != null", locs!=null)) return -1; 318 checkArray(msg, locs, null); 319 ULocale ulocs[] = Collator.getAvailableULocales(); 320 if (!assertTrue("getAvailableULocales != null", ulocs!=null)) return -1; 321 checkArray(msg, ulocs, null); 322 // This is not true because since ULocale objects with script code cannot be 323 // converted to Locale objects 324 //assertTrue("getAvailableLocales().length == getAvailableULocales().length", locs.length == ulocs.length); 325 return locs.length; 326 } 327 328 private static final String KW[] = { 329 "collation" 330 }; 331 332 private static final String KWVAL[] = { 333 "phonebook", 334 "stroke" 335 }; 336 TestSeparateTrees()337 public void TestSeparateTrees() { 338 String kw[] = Collator.getKeywords(); 339 if (!assertTrue("getKeywords != null", kw!=null)) return; 340 checkArray("getKeywords", kw, KW); 341 342 String kwval[] = Collator.getKeywordValues(KW[0]); 343 if (!assertTrue("getKeywordValues != null", kwval!=null)) return; 344 checkArray("getKeywordValues", kwval, KWVAL); 345 346 boolean isAvailable[] = new boolean[1]; 347 ULocale equiv = Collator.getFunctionalEquivalent(KW[0], 348 new ULocale("de"), 349 isAvailable); 350 if (assertTrue("getFunctionalEquivalent(de)!=null", equiv!=null)) { 351 assertEquals("getFunctionalEquivalent(de)", "root", equiv.toString()); 352 } 353 assertTrue("getFunctionalEquivalent(de).isAvailable==true", 354 isAvailable[0] == true); 355 356 equiv = Collator.getFunctionalEquivalent(KW[0], 357 new ULocale("de_DE"), 358 isAvailable); 359 if (assertTrue("getFunctionalEquivalent(de_DE)!=null", equiv!=null)) { 360 assertEquals("getFunctionalEquivalent(de_DE)", "root", equiv.toString()); 361 } 362 assertTrue("getFunctionalEquivalent(de_DE).isAvailable==false", 363 isAvailable[0] == false); 364 365 equiv = Collator.getFunctionalEquivalent(KW[0], new ULocale("zh_Hans")); 366 if (assertTrue("getFunctionalEquivalent(zh_Hans)!=null", equiv!=null)) { 367 assertEquals("getFunctionalEquivalent(zh_Hans)", "zh", equiv.toString()); 368 } 369 } 370 TestGetFunctionalEquivalent()371 public void TestGetFunctionalEquivalent() { 372 String kw[] = Collator.getKeywords(); 373 final String DATA[] = { 374 "sv", "sv", "t", 375 "sv@collation=direct", "sv", "t", 376 "sv@collation=traditional", "sv", "t", 377 "sv@collation=gb2312han", "sv", "t", 378 "sv@collation=stroke", "sv", "t", 379 "sv@collation=pinyin", "sv", "t", 380 "sv@collation=standard", "sv@collation=standard", "t", 381 "sv@collation=reformed", "sv", "t", 382 "sv@collation=big5han", "sv", "t", 383 "sv_FI", "sv", "f", 384 "sv_FI@collation=direct", "sv", "f", 385 "sv_FI@collation=traditional", "sv", "f", 386 "sv_FI@collation=gb2312han", "sv", "f", 387 "sv_FI@collation=stroke", "sv", "f", 388 "sv_FI@collation=pinyin", "sv", "f", 389 "sv_FI@collation=standard", "sv@collation=standard", "f", 390 "sv_FI@collation=reformed", "sv", "f", 391 "sv_FI@collation=big5han", "sv", "f", 392 "nl", "root", "t", 393 "nl@collation=direct", "root", "t", 394 "nl_BE", "root", "f", 395 "nl_BE@collation=direct", "root", "f", 396 "nl_BE@collation=traditional", "root", "f", 397 "nl_BE@collation=gb2312han", "root", "f", 398 "nl_BE@collation=stroke", "root", "f", 399 "nl_BE@collation=pinyin", "root", "f", 400 "nl_BE@collation=big5han", "root", "f", 401 "nl_BE@collation=phonebook", "root", "f", 402 "en_US_VALLEYGIRL","root","f" 403 }; 404 final int DATA_COUNT=(DATA.length/3); 405 406 for(int i=0;i<DATA_COUNT;i++) { 407 boolean isAvailable[] = new boolean[1]; 408 ULocale input = new ULocale(DATA[(i*3)+0]); 409 ULocale expect = new ULocale(DATA[(i*3)+1]); 410 boolean expectAvailable = DATA[(i*3)+2].equals("t"); 411 ULocale actual = Collator.getFunctionalEquivalent(kw[0],input,isAvailable); 412 if(!actual.equals(expect) || (expectAvailable!=isAvailable[0])) { 413 errln("#" + i + ": Collator.getFunctionalEquivalent(" + input + ")=" + actual + ", avail " + new Boolean(isAvailable[0]) + ", " + 414 "expected " + expect + " avail " + new Boolean(expectAvailable)); 415 } else { 416 logln("#" + i + ": Collator.getFunctionalEquivalent(" + input + ")=" + actual + ", avail " + new Boolean(isAvailable[0])); 417 } 418 } 419 } 420 421 // public void PrintFunctionalEquivalentList() { 422 // ULocale[] locales = Collator.getAvailableULocales(); 423 // String[] keywords = Collator.getKeywords(); 424 // logln("Collation"); 425 // logln("Possible keyword=values pairs:"); 426 // for (int i = 0; i < Collator.getKeywords().length; ++i) { 427 // String[] values = Collator.getKeywordValues(keywords[i]); 428 // for (int j = 0; j < values.length; ++j) { 429 // System.out.println(keywords[i] + "=" + values[j]); 430 // } 431 // } 432 // logln("Differing Collators:"); 433 // boolean[] isAvailable = {true}; 434 // for (int k = 0; k < locales.length; ++k) { 435 // logln(locales[k].getDisplayName(ULocale.ENGLISH) + " [" +locales[k] + "]"); 436 // for (int i = 0; i < Collator.getKeywords().length; ++i) { 437 // ULocale base = Collator.getFunctionalEquivalent(keywords[i],locales[k]); 438 // String[] values = Collator.getKeywordValues(keywords[i]); 439 // for (int j = 0; j < Collator.getKeywordValues(keywords[i]).length;++j) { 440 // ULocale other = Collator.getFunctionalEquivalent(keywords[i], 441 // new ULocale(locales[k] + "@" + keywords[i] + "=" + values[j]), 442 // isAvailable); 443 // if (isAvailable[0] && !other.equals(base)) { 444 // logln("\t" + keywords[i] + "=" + values[j] + ";\t" + base + ";\t" + other); 445 // } 446 // } 447 // } 448 // } 449 // } 450 arrayContains(String[] array, String s)451 private static boolean arrayContains(String[] array, String s) { 452 for (int i = 0; i < array.length; ++i) { 453 if (s.equals(array[i])) { 454 return true; 455 } 456 } 457 return false; 458 } 459 TestGetKeywordValues()460 public void TestGetKeywordValues(){ 461 final String[][] PREFERRED = { 462 {"und", "standard", "eor", "search"}, 463 {"en_US", "standard", "eor", "search"}, 464 {"en_029", "standard", "eor", "search"}, 465 {"de_DE", "standard", "phonebook", "search", "eor"}, 466 {"de_Latn_DE", "standard", "phonebook", "search", "eor"}, 467 {"zh", "pinyin", "stroke", "eor", "search", "standard"}, 468 {"zh_Hans", "pinyin", "stroke", "eor", "search", "standard"}, 469 {"zh_CN", "pinyin", "stroke", "eor", "search", "standard"}, 470 {"zh_Hant", "stroke", "pinyin", "eor", "search", "standard"}, 471 {"zh_TW", "stroke", "pinyin", "eor", "search", "standard"}, 472 {"zh__PINYIN", "pinyin", "stroke", "eor", "search", "standard"}, 473 {"es_ES", "standard", "search", "traditional", "eor"}, 474 {"es__TRADITIONAL", "traditional", "search", "standard", "eor"}, 475 {"und@collation=phonebook", "standard", "eor", "search"}, 476 {"de_DE@collation=big5han", "standard", "phonebook", "search", "eor"}, 477 {"zzz@collation=xxx", "standard", "eor", "search"}, 478 }; 479 480 for (int i = 0; i < PREFERRED.length; i++) { 481 String locale = PREFERRED[i][0]; 482 ULocale loc = new ULocale(locale); 483 String[] expected = PREFERRED[i]; 484 String[] pref = Collator.getKeywordValuesForLocale("collation", loc, true); 485 for (int j = 1; j < expected.length; ++j) { 486 if (!arrayContains(pref, expected[j])) { 487 errln("Keyword value " + expected[j] + " missing for locale: " + locale); 488 } 489 } 490 491 // Collator.getKeywordValues return the same contents for both commonlyUsed 492 // true and false. 493 String[] all = Collator.getKeywordValuesForLocale("collation", loc, false); 494 boolean matchAll = false; 495 if (pref.length == all.length) { 496 matchAll = true; 497 for (int j = 0; j < pref.length; j++) { 498 boolean foundMatch = false; 499 for (int k = 0; k < all.length; k++) { 500 if (pref[j].equals(all[k])) { 501 foundMatch = true; 502 break; 503 } 504 } 505 if (!foundMatch) { 506 matchAll = false; 507 break; 508 } 509 } 510 } 511 if (!matchAll) { 512 errln("FAIL: All values for locale " + loc 513 + " got:" + Arrays.toString(all) + " expected:" + Arrays.toString(pref)); 514 } 515 } 516 } 517 } 518