1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2016 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4/* 5 ******************************************************************************* 6 * Copyright (C) 1996-2014, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 * 10 */ 11 12package android.icu.dev.test.serializable; 13 14import java.io.ByteArrayInputStream; 15import java.io.ByteArrayOutputStream; 16import java.io.File; 17import java.io.FileInputStream; 18import java.io.FileOutputStream; 19import java.io.IOException; 20import java.io.InputStream; 21import java.io.ObjectInputStream; 22import java.io.ObjectOutputStream; 23import java.lang.reflect.Modifier; 24import java.net.URL; 25import java.util.ArrayList; 26import java.util.Date; 27import java.util.Enumeration; 28import java.util.HashMap; 29import java.util.List; 30import java.util.Locale; 31 32import android.icu.dev.test.format.MeasureUnitTest; 33import android.icu.dev.test.format.PluralRulesTest; 34import android.icu.impl.JavaTimeZone; 35import android.icu.impl.OlsonTimeZone; 36import android.icu.impl.TimeZoneAdapter; 37import android.icu.impl.URLHandler; 38import android.icu.impl.Utility; 39import android.icu.math.BigDecimal; 40import android.icu.math.MathContext; 41import android.icu.util.AnnualTimeZoneRule; 42import android.icu.util.Calendar; 43import android.icu.util.Currency; 44import android.icu.util.DateInterval; 45import android.icu.util.DateTimeRule; 46import android.icu.util.GregorianCalendar; 47import android.icu.util.ICUCloneNotSupportedException; 48import android.icu.util.ICUException; 49import android.icu.util.ICUUncheckedIOException; 50import android.icu.util.InitialTimeZoneRule; 51import android.icu.util.RuleBasedTimeZone; 52import android.icu.util.SimpleTimeZone; 53import android.icu.util.TimeArrayTimeZoneRule; 54import android.icu.util.TimeZone; 55import android.icu.util.TimeZoneRule; 56import android.icu.util.ULocale; 57import android.icu.util.VTimeZone; 58 59/** 60 * @author emader 61 * 62 * TODO To change the template for this generated type comment go to 63 * Window - Preferences - Java - Code Style - Code Templates 64 */ 65public class SerializableTestUtility { 66 private static Class serializable; 67 static { 68 try { 69 serializable = Class.forName("java.io.Serializable"); 70 } catch (ClassNotFoundException e) { 71 // TODO Auto-generated catch block 72 e.printStackTrace(); 73 } 74 } 75 76 public interface Handler 77 { 78 public Object[] getTestObjects(); 79 80 public boolean hasSameBehavior(Object a, Object b); 81 } 82 83 public static Handler getHandler(String className) 84 { 85 return (Handler) map.get(className); 86 } 87 88 private static class TimeZoneHandler implements Handler 89 { 90 String[] ZONES = { "GMT", "MET", "IST" }; 91 92 @Override 93 public Object[] getTestObjects() 94 { 95 TimeZone zones[] = new TimeZone[ZONES.length]; 96 97 for(int z = 0; z < ZONES.length; z += 1) { 98 zones[z] = TimeZone.getTimeZone(ZONES[z]); 99 } 100 101 return zones; 102 } 103 104 @Override 105 public boolean hasSameBehavior(Object a, Object b) 106 { 107 TimeZone zone_a = (TimeZone) a; 108 TimeZone zone_b = (TimeZone) b; 109 110 if (!(zone_a.getDisplayName().equals(zone_b.getDisplayName()))) { 111 return false; 112 } 113 114 int a_offsets[] = {0, 0}; 115 int b_offsets[] = {0, 0}; 116 117 boolean bSame = true; 118 for (int i = 0; i < sampleTimes.length; i++) { 119 zone_a.getOffset(sampleTimes[i], false, a_offsets); 120 zone_b.getOffset(sampleTimes[i], false, b_offsets); 121 if (a_offsets[0] != b_offsets[0] || a_offsets[1] != b_offsets[1]) { 122 bSame = false; 123 break; 124 } 125 } 126 return bSame; 127 } 128 } 129 130 private static Locale locales[] = { 131 Locale.CANADA, Locale.CANADA_FRENCH, Locale.CHINA, 132 Locale.CHINESE, Locale.ENGLISH, Locale.FRANCE, Locale.FRENCH, 133 Locale.GERMAN, Locale.GERMANY, Locale.ITALIAN, Locale.ITALY, 134 Locale.JAPAN, Locale.JAPANESE, Locale.KOREA, Locale.KOREAN, 135 Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, 136 Locale.TRADITIONAL_CHINESE, Locale.UK, Locale.US 137 }; 138 139 private static Locale places[] = { 140 Locale.CANADA, Locale.CANADA_FRENCH, Locale.CHINA, 141 Locale.FRANCE, Locale.GERMANY, Locale.ITALY, 142 Locale.JAPAN, Locale.KOREA, Locale.PRC, Locale.TAIWAN, 143 Locale.UK, Locale.US 144 }; 145 146 public static Locale[] getLocales() 147 { 148 return locales; 149 } 150 151 public static boolean compareStrings(String a[], String b[]) 152 { 153 if (a.length != b.length) { 154 return false; 155 } 156 157 for (int i = 0; i < a.length; i += 1) { 158 if (! a[i].equals(b[i])) { 159 return false; 160 } 161 } 162 163 return true; 164 } 165 166 public static boolean compareChars(char a[], char b[]) 167 { 168 if (a.length != b.length) { 169 return false; 170 } 171 172 for (int i = 0; i < a.length; i += 1) { 173 if (a[i] != b[i]) { 174 return false; 175 } 176 } 177 178 return true; 179 } 180 181 private static class SimpleTimeZoneHandler extends TimeZoneHandler 182 { 183 @Override 184 public Object[] getTestObjects() 185 { 186 SimpleTimeZone simpleTimeZones[] = new SimpleTimeZone[6]; 187 188 simpleTimeZones[0] = new SimpleTimeZone(32400000, "MyTimeZone"); 189 190 simpleTimeZones[1] = new SimpleTimeZone(32400000, "Asia/Tokyo"); 191 192 simpleTimeZones[2] = new SimpleTimeZone(32400000, "Asia/Tokyo"); 193 simpleTimeZones[2].setRawOffset(0); 194 195 simpleTimeZones[3] = new SimpleTimeZone(32400000, "Asia/Tokyo"); 196 simpleTimeZones[3].setStartYear(100); 197 198 simpleTimeZones[4] = new SimpleTimeZone(32400000, "Asia/Tokyo"); 199 simpleTimeZones[4].setStartYear(1000); 200 simpleTimeZones[4].setDSTSavings(1800000); 201 simpleTimeZones[4].setStartRule(3, 4, 180000); 202 simpleTimeZones[4].setEndRule(6, 3, 4, 360000); 203 204 simpleTimeZones[5] = new SimpleTimeZone(32400000, "Asia/Tokyo"); 205 simpleTimeZones[5].setStartRule(2, 3, 4, 360000); 206 simpleTimeZones[5].setEndRule(6, 3, 4, 360000); 207 208 return simpleTimeZones; 209 } 210 } 211 212 private static class VTimeZoneHandler extends TimeZoneHandler { 213 @Override 214 public Object[] getTestObjects() { 215 //TODO 216 VTimeZone[] vtzs = new VTimeZone[1]; 217 vtzs[0] = VTimeZone.create("America/New_York"); 218 return vtzs; 219 } 220 } 221 222 private static final int HOUR = 60*60*1000; 223 private static final AnnualTimeZoneRule[] TEST_US_EASTERN = { 224 new AnnualTimeZoneRule("EST", -5*HOUR, 0, 225 new DateTimeRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*HOUR, DateTimeRule.WALL_TIME), 226 1967, 2006), 227 228 new AnnualTimeZoneRule("EST", -5*HOUR, 0, 229 new DateTimeRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, true, 2*HOUR, DateTimeRule.WALL_TIME), 230 2007, AnnualTimeZoneRule.MAX_YEAR), 231 232 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 233 new DateTimeRule(Calendar.APRIL, -1, Calendar.SUNDAY, 2*HOUR, DateTimeRule.WALL_TIME), 234 1967, 1973), 235 236 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 237 new DateTimeRule(Calendar.JANUARY, 6, 2*HOUR, DateTimeRule.WALL_TIME), 238 1974, 1974), 239 240 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 241 new DateTimeRule(Calendar.FEBRUARY, 23, 2*HOUR, DateTimeRule.WALL_TIME), 242 1975, 1975), 243 244 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 245 new DateTimeRule(Calendar.APRIL, -1, Calendar.SUNDAY, 2*HOUR, DateTimeRule.WALL_TIME), 246 1976, 1986), 247 248 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 249 new DateTimeRule(Calendar.APRIL, 1, Calendar.SUNDAY, true, 2*HOUR, DateTimeRule.WALL_TIME), 250 1987, 2006), 251 252 new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, 253 new DateTimeRule(Calendar.MARCH, 8, Calendar.SUNDAY, true, 2*HOUR, DateTimeRule.WALL_TIME), 254 2007, AnnualTimeZoneRule.MAX_YEAR) 255 }; 256 257 private static class RuleBasedTimeZoneHandler extends TimeZoneHandler 258 { 259 @Override 260 public Object[] getTestObjects() 261 { 262 RuleBasedTimeZone ruleBasedTimeZones[] = new RuleBasedTimeZone[2]; 263 264 InitialTimeZoneRule ir = new InitialTimeZoneRule("GMT-5", -5*HOUR, 0); 265 266 // GMT-5, no transition 267 ruleBasedTimeZones[0] = new RuleBasedTimeZone("GMT-5", ir); 268 269 270 // US Eastern since 1967 271 ruleBasedTimeZones[1] = new RuleBasedTimeZone("US_East", ir); 272 for (int i = 0; i < TEST_US_EASTERN.length; i++) { 273 ruleBasedTimeZones[1].addTransitionRule(TEST_US_EASTERN[i]); 274 } 275 return ruleBasedTimeZones; 276 } 277 } 278 279 private static class DateTimeRuleHandler implements Handler { 280 @Override 281 public Object[] getTestObjects() { 282 DateTimeRule[] rules = new DateTimeRule[4]; 283 284 // DOM + UTC 285 rules[0] = new DateTimeRule(Calendar.OCTOBER, 10, 13*HOUR, DateTimeRule.UTC_TIME); 286 287 // DOW + WALL 288 rules[1] = new DateTimeRule(Calendar.MARCH, 2, Calendar.SUNDAY, 2*HOUR, DateTimeRule.WALL_TIME); 289 290 // DOW_GEQ_DOM + STD 291 rules[2] = new DateTimeRule(Calendar.MAY, 1, Calendar.MONDAY, true, 0*HOUR, DateTimeRule.STANDARD_TIME); 292 293 // DOW_LEQ_DOM + WALL 294 rules[3] = new DateTimeRule(Calendar.AUGUST, 31, Calendar.SATURDAY, false, 1*HOUR, DateTimeRule.WALL_TIME); 295 296 return rules; 297 } 298 299 @Override 300 public boolean hasSameBehavior(Object a, Object b) { 301 return hasSameRule((DateTimeRule)a, (DateTimeRule)b); 302 } 303 304 static boolean hasSameRule(DateTimeRule dtra, DateTimeRule dtrb) { 305 boolean bSame = false; 306 if (dtra.getDateRuleType() == dtrb.getDateRuleType() 307 && dtra.getRuleMonth() == dtrb.getRuleMonth() 308 && dtra.getTimeRuleType() == dtrb.getTimeRuleType() 309 && dtra.getRuleMillisInDay() == dtrb.getRuleMillisInDay()) { 310 switch (dtra.getDateRuleType()) { 311 case DateTimeRule.DOM: 312 bSame = (dtra.getRuleDayOfMonth() == dtrb.getRuleDayOfMonth()); 313 break; 314 case DateTimeRule.DOW: 315 bSame = (dtra.getRuleDayOfWeek() == dtrb.getRuleDayOfWeek() && 316 dtra.getRuleWeekInMonth() == dtrb.getRuleWeekInMonth()); 317 break; 318 case DateTimeRule.DOW_GEQ_DOM: 319 case DateTimeRule.DOW_LEQ_DOM: 320 bSame = (dtra.getRuleDayOfMonth() == dtrb.getRuleDayOfMonth() && 321 dtra.getRuleDayOfWeek() == dtrb.getRuleDayOfWeek()); 322 break; 323 } 324 } 325 return bSame; 326 } 327 } 328 329 private static boolean compareTimeZoneRules(TimeZoneRule ra, TimeZoneRule rb) { 330 if (ra.getName().equals(rb.getName()) && 331 ra.getRawOffset() == rb.getRawOffset() && 332 ra.getDSTSavings() == rb.getDSTSavings()) { 333 return true; 334 } 335 return false; 336 } 337 338 private static class AnnualTimeZoneRuleHandler implements Handler { 339 @Override 340 public Object[] getTestObjects() { 341 return TEST_US_EASTERN; 342 } 343 344 @Override 345 public boolean hasSameBehavior(Object a, Object b) { 346 AnnualTimeZoneRule ra = (AnnualTimeZoneRule)a; 347 AnnualTimeZoneRule rb = (AnnualTimeZoneRule)b; 348 if (DateTimeRuleHandler.hasSameRule(ra.getRule(), rb.getRule()) && 349 ra.getStartYear() == rb.getStartYear() && 350 ra.getEndYear() == rb.getEndYear()) { 351 return compareTimeZoneRules(ra, rb); 352 } 353 return false; 354 } 355 } 356 357 private static class InitialTimeZoneRuleHandler implements Handler { 358 @Override 359 public Object[] getTestObjects() { 360 TimeZoneRule[] rules = new TimeZoneRule[2]; 361 rules[0] = new InitialTimeZoneRule("EST", -5*HOUR, 0); 362 rules[1] = new InitialTimeZoneRule("PST", -8*HOUR, 0); 363 return rules; 364 } 365 366 @Override 367 public boolean hasSameBehavior(Object a, Object b) { 368 return compareTimeZoneRules((TimeZoneRule)a, (TimeZoneRule)b); 369 } 370 } 371 372 private static class TimeArrayTimeZoneRuleHandler implements Handler { 373 @Override 374 public Object[] getTestObjects() { 375 TimeArrayTimeZoneRule[] rules = new TimeArrayTimeZoneRule[1]; 376 long[] ttime = new long[] {-631152000000L, 0L, 946684800000L}; /* {1950-1-1, 1970-1-1, 2000-1-1} */ 377 rules[0] = new TimeArrayTimeZoneRule("Foo", 1*HOUR, 1*HOUR, ttime, DateTimeRule.UTC_TIME); 378 379 return rules; 380 } 381 @Override 382 public boolean hasSameBehavior(Object a, Object b) { 383 TimeArrayTimeZoneRule ra = (TimeArrayTimeZoneRule)a; 384 TimeArrayTimeZoneRule rb = (TimeArrayTimeZoneRule)b; 385 386 Date da = ra.getFirstStart(0, 0); 387 Date db = rb.getFirstStart(0, 0); 388 long t = da.getTime(); 389 if (da.equals(db)) { 390 da = ra.getFinalStart(0, 0); 391 db = rb.getFinalStart(0, 0); 392 long end = da.getTime(); 393 if (da.equals(db)) { 394 while (t < end) { 395 da = ra.getNextStart(t, 0, 0, false); 396 db = ra.getNextStart(t, 0, 0, false); 397 if (da == null || db == null || !da.equals(db)) { 398 break; 399 } 400 t = da.getTime(); 401 } 402 return compareTimeZoneRules(ra, rb); 403 } 404 } 405 return false; 406 } 407 } 408 409 private static class ULocaleHandler implements Handler 410 { 411 @Override 412 public Object[] getTestObjects() 413 { 414 ULocale uLocales[] = new ULocale[locales.length]; 415 416 for (int i = 0; i < locales.length; i += 1) { 417 uLocales[i] = ULocale.forLocale(locales[i]); 418 } 419 420 return uLocales; 421 } 422 423 @Override 424 public boolean hasSameBehavior(Object a, Object b) 425 { 426 ULocale uloc_a = (ULocale) a; 427 ULocale uloc_b = (ULocale) b; 428 429 return uloc_a.getName().equals(uloc_b.getName()); 430 } 431 } 432 433 public static class DateIntervalHandler implements Handler 434 { 435 private DateInterval dateInterval[] = { 436 new DateInterval(0L, 1164931200000L/*20061201T000000Z*/) 437 }; 438 @Override 439 public Object[] getTestObjects() 440 { 441 return dateInterval; 442 } 443 444 @Override 445 public boolean hasSameBehavior(Object a, Object b) 446 { 447 return a.equals(b); 448 } 449 } 450 451 private static class CurrencyHandler implements Handler 452 { 453 @Override 454 public Object[] getTestObjects() 455 { 456 Currency currencies[] = new Currency[places.length]; 457 458 for (int i = 0; i < places.length; i += 1) { 459 currencies[i] = Currency.getInstance(places[i]); 460 } 461 462 return currencies; 463 } 464 465 @Override 466 public boolean hasSameBehavior(Object a, Object b) 467 { 468 469 Currency curr_a = (Currency) a; 470 Currency curr_b = (Currency) b; 471 472 return a == b 473 || a != null && b != null 474 && curr_a.getCurrencyCode() != null 475 && curr_a.getCurrencyCode().equals(curr_b.getCurrencyCode()); 476 477 } 478 } 479 480 private static String zoneIDs[] = { 481 "Pacific/Honolulu", "America/Anchorage", "America/Los_Angeles", "America/Denver", 482 "America/Chicago", "America/New_York", "Africa/Cairo", "Africa/Addis_Ababa", "Africa/Dar_es_Salaam", 483 "Africa/Freetown", "Africa/Johannesburg", "Africa/Nairobi", "Asia/Bangkok", "Asia/Baghdad", 484 "Asia/Calcutta", "Asia/Hong_Kong", "Asia/Jakarta", "Asia/Jerusalem", "Asia/Manila", "Asia/Tokyo", 485 "Europe/Amsterdam", "Europe/Athens", "Europe/Berlin", "Europe/London", "Europe/Malta", "Europe/Moscow", 486 "Europe/Paris", "Europe/Rome" 487 }; 488 489 private static long sampleTimes[] = { 490 1136073600000L, // 20060101T000000Z 491 1138752000000L, // 20060201T000000Z 492 1141171200000L, // 20060301T000000Z 493 1143849600000L, // 20060401T000000Z 494 1146441600000L, // 20060501T000000Z 495 1149120000000L, // 20060601T000000Z 496 1151712000000L, // 20060701T000000Z 497 1154390400000L, // 20060801T000000Z 498 1157068800000L, // 20060901T000000Z 499 1159660800000L, // 20061001T000000Z 500 1162339200000L, // 20061101T000000Z 501 1164931200000L, // 20061201T000000Z 502 }; 503 504 private static class OlsonTimeZoneHandler implements Handler 505 { 506 @Override 507 public Object[] getTestObjects() 508 { 509 OlsonTimeZone timeZones[] = new OlsonTimeZone[zoneIDs.length]; 510 511 for (int i = 0; i < zoneIDs.length; i += 1) { 512 timeZones[i] = new OlsonTimeZone(zoneIDs[i]); 513 } 514 515 return timeZones; 516 517 } 518 519 @Override 520 public boolean hasSameBehavior(Object a, Object b) 521 { 522 OlsonTimeZone otz_a = (OlsonTimeZone) a; 523 OlsonTimeZone otz_b = (OlsonTimeZone) b; 524 int a_offsets[] = {0, 0}; 525 int b_offsets[] = {0, 0}; 526 527 boolean bSame = true; 528 for (int i = 0; i < sampleTimes.length; i++) { 529 otz_a.getOffset(sampleTimes[i], false, a_offsets); 530 otz_b.getOffset(sampleTimes[i], false, b_offsets); 531 if (a_offsets[0] != b_offsets[0] || a_offsets[1] != b_offsets[1]) { 532 bSame = false; 533 break; 534 } 535 } 536 return bSame; 537 } 538 } 539 540 private static class TimeZoneAdapterHandler implements Handler 541 { 542 @Override 543 public Object[] getTestObjects() 544 { 545 TimeZoneAdapter timeZones[] = new TimeZoneAdapter[zoneIDs.length]; 546 547 for (int i = 0; i < zoneIDs.length; i += 1) { 548 timeZones[i] = new TimeZoneAdapter(TimeZone.getTimeZone(zoneIDs[i])); 549 } 550 551 return timeZones; 552 553 } 554 555 @Override 556 public boolean hasSameBehavior(Object a, Object b) 557 { 558 GregorianCalendar cal = new GregorianCalendar(); 559 TimeZoneAdapter tza_a = (TimeZoneAdapter) a; 560 TimeZoneAdapter tza_b = (TimeZoneAdapter) b; 561 562 int a_offset, b_offset; 563 boolean a_dst, b_dst; 564 boolean bSame = true; 565 for (int i = 0; i < sampleTimes.length; i++) { 566 cal.setTimeInMillis(sampleTimes[i]); 567 int era = cal.get(Calendar.ERA); 568 int year = cal.get(Calendar.YEAR); 569 int month = cal.get(Calendar.MONTH); 570 int day = cal.get(Calendar.DAY_OF_MONTH); 571 int dow = cal.get(Calendar.DAY_OF_WEEK); 572 int mid = cal.get(Calendar.MILLISECONDS_IN_DAY); 573 a_offset = tza_a.getOffset(era, year, month, day, dow, mid); 574 b_offset = tza_b.getOffset(era, year, month, day, dow, mid); 575 Date d = new Date(sampleTimes[i]); 576 a_dst = tza_a.inDaylightTime(d); 577 b_dst = tza_b.inDaylightTime(d); 578 if (a_offset != b_offset || a_dst != b_dst) { 579 bSame = false; 580 break; 581 } 582 } 583 return bSame; 584 } 585 } 586 587 private static class JavaTimeZoneHandler implements Handler { 588 String[] ZONES = { "GMT", "America/New_York", "GMT+05:45" }; 589 590 @Override 591 public Object[] getTestObjects() { 592 JavaTimeZone zones[] = new JavaTimeZone[ZONES.length]; 593 for(int z = 0; z < ZONES.length; z += 1) { 594 java.util.TimeZone tz = java.util.TimeZone.getTimeZone(ZONES[z]); 595 zones[z] = new JavaTimeZone(tz, ZONES[z]); 596 } 597 return zones; 598 } 599 600 @Override 601 public boolean hasSameBehavior(Object a, Object b) 602 { 603 TimeZone zone_a = (TimeZone) a; 604 TimeZone zone_b = (TimeZone) b; 605 606 if (!(TimeZone.getCanonicalID(zone_a.getID()).equals(TimeZone.getCanonicalID(zone_b.getID())))) { 607 return false; 608 } 609 610 int a_offsets[] = {0, 0}; 611 int b_offsets[] = {0, 0}; 612 613 boolean bSame = true; 614 for (int i = 0; i < sampleTimes.length; i++) { 615 zone_a.getOffset(sampleTimes[i], false, a_offsets); 616 zone_b.getOffset(sampleTimes[i], false, b_offsets); 617 if (a_offsets[0] != b_offsets[0] || a_offsets[1] != b_offsets[1]) { 618 bSame = false; 619 break; 620 } 621 } 622 return bSame; 623 } 624 } 625 626 private static class BigDecimalHandler implements Handler 627 { 628 String values[] = { 629 "1234567890.", 630 "123456789.0", 631 "12345678.90", 632 "1234567.890", 633 "123456.7890", 634 "12345.67890", 635 "1234.567890", 636 "123.4567890", 637 "12.34567890", 638 "1.234567890", 639 ".1234567890"}; 640 641 @Override 642 public Object[] getTestObjects() 643 { 644 BigDecimal bds[] = new BigDecimal[values.length]; 645 646 for (int i = 0; i < values.length; i += 1) { 647 bds[i] = new BigDecimal(values[i]); 648 } 649 650 return bds; 651 } 652 653 @Override 654 public boolean hasSameBehavior(Object a, Object b) { 655 BigDecimal bda = (BigDecimal) a; 656 BigDecimal bdb = (BigDecimal) b; 657 658 return bda.toString().equals(bdb.toString()); 659 } 660 } 661 662 private static class MathContextHandler implements Handler 663 { 664 int forms[] = {MathContext.PLAIN, MathContext.ENGINEERING, MathContext.SCIENTIFIC}; 665 int rounds[] = { 666 MathContext.ROUND_CEILING, MathContext.ROUND_DOWN, MathContext.ROUND_FLOOR, 667 MathContext.ROUND_HALF_DOWN, MathContext.ROUND_HALF_EVEN, MathContext.ROUND_HALF_UP, 668 MathContext.ROUND_UNNECESSARY, MathContext.ROUND_UP}; 669 670 @Override 671 public Object[] getTestObjects() 672 { 673 int objectCount = forms.length * rounds.length; 674 MathContext contexts[] = new MathContext[objectCount]; 675 int i = 0; 676 677 for (int f = 0; f < forms.length; f += 1) { 678 for (int r = 0; r < rounds.length; r += 1) { 679 int digits = f * r; 680 boolean lostDigits = (r & 1) != 0; 681 682 contexts[i++] = new MathContext(digits, forms[f], lostDigits, rounds[r]); 683 } 684 } 685 686 return contexts; 687 } 688 689 @Override 690 public boolean hasSameBehavior(Object a, Object b) 691 { 692 MathContext mca = (MathContext) a; 693 MathContext mcb = (MathContext) b; 694 695 return mca.toString().equals(mcb.toString()); 696 } 697 } 698 699 private static abstract class ExceptionHandlerBase implements Handler { 700 @Override 701 public boolean hasSameBehavior(Object a, Object b) { 702 return sameThrowable((Exception) a, (Exception) b); 703 } 704 705 // Exception.equals() does not seem to work. 706 private static final boolean sameThrowable(Throwable a, Throwable b) { 707 return a == null ? b == null : 708 b == null ? false : 709 a.getClass().equals(b.getClass()) && 710 Utility.objectEquals(a.getMessage(), b.getMessage()) && 711 sameThrowable(a.getCause(), b.getCause()); 712 } 713 } 714 715 private static class ICUExceptionHandler extends ExceptionHandlerBase { 716 @Override 717 public Object[] getTestObjects() { 718 return new ICUException[] { 719 new ICUException(), 720 new ICUException("msg1"), 721 new ICUException(new RuntimeException("rte1")), 722 new ICUException("msg2", new RuntimeException("rte2")) 723 }; 724 } 725 } 726 727 private static class ICUUncheckedIOExceptionHandler extends ExceptionHandlerBase { 728 @Override 729 public Object[] getTestObjects() { 730 return new ICUUncheckedIOException[] { 731 new ICUUncheckedIOException(), 732 new ICUUncheckedIOException("msg1"), 733 new ICUUncheckedIOException(new RuntimeException("rte1")), 734 new ICUUncheckedIOException("msg2", new RuntimeException("rte2")) 735 }; 736 } 737 } 738 739 private static class ICUCloneNotSupportedExceptionHandler extends ExceptionHandlerBase { 740 @Override 741 public Object[] getTestObjects() { 742 return new ICUCloneNotSupportedException[] { 743 new ICUCloneNotSupportedException(), 744 new ICUCloneNotSupportedException("msg1"), 745 new ICUCloneNotSupportedException(new RuntimeException("rte1")), 746 new ICUCloneNotSupportedException("msg2", new RuntimeException("rte2")) 747 }; 748 } 749 } 750 751 private static HashMap map = new HashMap(); 752 753 static { 754 map.put("android.icu.util.TimeZone", new TimeZoneHandler()); 755 map.put("android.icu.util.SimpleTimeZone", new SimpleTimeZoneHandler()); 756 map.put("android.icu.util.RuleBasedTimeZone", new RuleBasedTimeZoneHandler()); 757 map.put("android.icu.util.VTimeZone", new VTimeZoneHandler()); 758 map.put("android.icu.util.DateTimeRule", new DateTimeRuleHandler()); 759 map.put("android.icu.util.AnnualTimeZoneRule", new AnnualTimeZoneRuleHandler()); 760 map.put("android.icu.util.InitialTimeZoneRule", new InitialTimeZoneRuleHandler()); 761 map.put("android.icu.util.TimeArrayTimeZoneRule", new TimeArrayTimeZoneRuleHandler()); 762 map.put("android.icu.util.ULocale", new ULocaleHandler()); 763 map.put("android.icu.util.Currency", new CurrencyHandler()); 764 map.put("android.icu.impl.JavaTimeZone", new JavaTimeZoneHandler()); 765 map.put("android.icu.impl.OlsonTimeZone", new OlsonTimeZoneHandler()); 766 map.put("android.icu.impl.TimeZoneAdapter", new TimeZoneAdapterHandler()); 767 map.put("android.icu.math.BigDecimal", new BigDecimalHandler()); 768 map.put("android.icu.math.MathContext", new MathContextHandler()); 769 770 map.put("android.icu.text.NumberFormat", new FormatHandler.NumberFormatHandler()); 771 map.put("android.icu.text.DecimalFormat", new FormatHandler.DecimalFormatHandler()); 772 map.put("android.icu.text.CompactDecimalFormat", new FormatHandler.CompactDecimalFormatHandler()); 773 map.put("android.icu.text.RuleBasedNumberFormat", new FormatHandler.RuleBasedNumberFormatHandler()); 774 map.put("android.icu.text.CurrencyPluralInfo", new FormatHandler.CurrencyPluralInfoHandler()); 775 map.put("android.icu.text.DecimalFormatSymbols", new FormatHandler.DecimalFormatSymbolsHandler()); 776 map.put("android.icu.text.MessageFormat", new FormatHandler.MessageFormatHandler()); 777 map.put("android.icu.text.DateFormat", new FormatHandler.DateFormatHandler()); 778 map.put("android.icu.text.DateFormatSymbols", new FormatHandler.DateFormatSymbolsHandler()); 779 map.put("android.icu.util.DateInterval", new DateIntervalHandler()); 780 map.put("android.icu.text.DateIntervalFormat", new FormatHandler.DateIntervalFormatHandler()); 781 map.put("android.icu.text.DateIntervalInfo", new FormatHandler.DateIntervalInfoHandler()); 782 map.put("android.icu.text.DateIntervalInfo$PatternInfo", new FormatHandler.PatternInfoHandler()); 783 map.put("android.icu.text.SimpleDateFormat", new FormatHandler.SimpleDateFormatHandler()); 784 map.put("android.icu.text.ChineseDateFormat", new FormatHandler.ChineseDateFormatHandler()); 785 map.put("android.icu.text.ChineseDateFormatSymbols", new FormatHandler.ChineseDateFormatSymbolsHandler()); 786 map.put("android.icu.impl.DateNumberFormat", new FormatHandler.DateNumberFormatHandler()); 787 map.put("android.icu.text.PluralFormat", new FormatHandler.PluralFormatHandler()); 788 map.put("android.icu.text.PluralRules", new FormatHandler.PluralRulesHandler()); 789 map.put("android.icu.text.PluralRulesSerialProxy", new FormatHandler.PluralRulesSerialProxyHandler()); 790 map.put("android.icu.text.TimeUnitFormat", new FormatHandler.TimeUnitFormatHandler()); 791 map.put("android.icu.text.SelectFormat", new FormatHandler.SelectFormatHandler()); 792 map.put("android.icu.impl.TimeZoneNamesImpl", new FormatHandler.TimeZoneNamesHandler()); 793 map.put("android.icu.text.TimeZoneFormat", new FormatHandler.TimeZoneFormatHandler()); 794 map.put("android.icu.impl.TimeZoneGenericNames", new FormatHandler.TimeZoneGenericNamesHandler()); 795 map.put("android.icu.impl.TZDBTimeZoneNames", new FormatHandler.TZDBTimeZoneNamesHandler()); 796 797 map.put("android.icu.util.Calendar", new CalendarHandler.BasicCalendarHandler()); 798 map.put("android.icu.util.BuddhistCalendar", new CalendarHandler.BuddhistCalendarHandler()); 799 map.put("android.icu.util.ChineseCalendar", new CalendarHandler.ChineseCalendarHandler()); 800 map.put("android.icu.util.CopticCalendar", new CalendarHandler.CopticCalendarHandler()); 801 map.put("android.icu.util.DangiCalendar", new CalendarHandler.DangiCalendarHandler()); 802 map.put("android.icu.util.EthiopicCalendar", new CalendarHandler.EthiopicCalendarHandler()); 803 map.put("android.icu.util.GregorianCalendar", new CalendarHandler.GregorianCalendarHandler()); 804 map.put("android.icu.util.HebrewCalendar", new CalendarHandler.HebrewCalendarHandler()); 805 map.put("android.icu.util.IndianCalendar", new CalendarHandler.IndianCalendarHandler()); 806 map.put("android.icu.util.IslamicCalendar", new CalendarHandler.IslamicCalendarHandler()); 807 map.put("android.icu.util.JapaneseCalendar", new CalendarHandler.JapaneseCalendarHandler()); 808 map.put("android.icu.util.PersianCalendar", new CalendarHandler.PersianCalendarHandler()); 809 map.put("android.icu.util.TaiwanCalendar", new CalendarHandler.TaiwanCalendarHandler()); 810 811 map.put("android.icu.text.ArabicShapingException", new ExceptionHandler.ArabicShapingExceptionHandler()); 812 map.put("android.icu.text.StringPrepParseException", new ExceptionHandler.StringPrepParseExceptionHandler()); 813 map.put("android.icu.util.UResourceTypeMismatchException", new ExceptionHandler.UResourceTypeMismatchExceptionHandler()); 814 map.put("android.icu.impl.InvalidFormatException", new ExceptionHandler.InvalidFormatExceptionHandler()); 815 816 map.put("android.icu.text.NumberFormat$Field", new FormatHandler.NumberFormatFieldHandler()); 817 map.put("android.icu.text.DateFormat$Field", new FormatHandler.DateFormatFieldHandler()); 818 map.put("android.icu.text.ChineseDateFormat$Field", new FormatHandler.ChineseDateFormatFieldHandler()); 819 map.put("android.icu.text.MessageFormat$Field", new FormatHandler.MessageFormatFieldHandler()); 820 821 map.put("android.icu.impl.duration.BasicDurationFormat", new FormatHandler.BasicDurationFormatHandler()); 822 map.put("android.icu.impl.RelativeDateFormat", new FormatHandler.RelativeDateFormatHandler()); 823 map.put("android.icu.util.IllformedLocaleException", new ExceptionHandler.IllformedLocaleExceptionHandler()); 824 map.put("android.icu.impl.locale.LocaleSyntaxException", new ExceptionHandler.LocaleSyntaxExceptionHandler()); 825 map.put("android.icu.impl.IllegalIcuArgumentException", new ExceptionHandler.IllegalIcuArgumentExceptionHandler()); 826 827 map.put("android.icu.text.PluralRules$FixedDecimal", new PluralRulesTest.FixedDecimalHandler()); 828 map.put("android.icu.util.MeasureUnit", new MeasureUnitTest.MeasureUnitHandler()); 829 map.put("android.icu.util.TimeUnit", new MeasureUnitTest.MeasureUnitHandler()); 830 map.put("android.icu.text.MeasureFormat", new MeasureUnitTest.MeasureFormatHandler()); 831 832 map.put("android.icu.util.ICUException", new ICUExceptionHandler()); 833 map.put("android.icu.util.ICUUncheckedIOException", new ICUUncheckedIOExceptionHandler()); 834 map.put("android.icu.util.ICUCloneNotSupportedException", new ICUCloneNotSupportedExceptionHandler()); 835 } 836 837 /* 838 * Serialization Helpers 839 */ 840 static Object[] getSerializedObjects(byte[] serializedBytes) throws ClassNotFoundException, IOException { 841 ByteArrayInputStream bis = new ByteArrayInputStream(serializedBytes); 842 ObjectInputStream ois = new ObjectInputStream(bis); 843 Object inputObjects[] = (Object[]) ois.readObject(); 844 845 ois.close(); 846 return inputObjects; 847 } 848 849 static byte[] getSerializedBytes(Object[] objectsOut) throws IOException { 850 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 851 ObjectOutputStream oos = new ObjectOutputStream(bos); 852 oos.writeObject(objectsOut); 853 854 byte[] serializedBytes = bos.toByteArray(); 855 oos.close(); 856 return serializedBytes; 857 } 858 859 static Object[] getSerializedObjects(File testFile) throws IOException, ClassNotFoundException { 860 FileInputStream fis = new FileInputStream(testFile); 861 ObjectInputStream ois = new ObjectInputStream(fis); 862 Object[] objects = (Object[]) ois.readObject(); 863 fis.close(); 864 return objects; 865 } 866 867 static byte[] copyStreamBytes(InputStream is) throws IOException { 868 byte[] buffer = new byte[1024]; 869 870 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 871 int len; 872 while((len = is.read(buffer, 0, buffer.length)) >= 0) { 873 bos.write(buffer, 0, len); 874 } 875 return bos.toByteArray(); 876 } 877 878 static List<String> getSerializationClassList(Object caller) throws IOException { 879 List<String> classList = new ArrayList(); 880 Enumeration<URL> urlEnum = caller.getClass().getClassLoader().getResources("android/icu"); 881 while (urlEnum.hasMoreElements()) { 882 URL url = urlEnum.nextElement(); 883 URLHandler handler = URLHandler.get(url); 884 if (handler == null) { 885 System.out.println("Unsupported URL: " + url); 886 continue; 887 } 888 CoverageClassVisitor visitor = new CoverageClassVisitor(classList); 889 handler.guide(visitor, true, false); 890 } 891 return classList; 892 } 893 894 private static class CoverageClassVisitor implements URLHandler.URLVisitor { 895 private List<String> classNames; 896 897 public CoverageClassVisitor(List<String> classNamesList) { 898 this.classNames = classNamesList; 899 } 900 901 /* (non-Javadoc) 902 * @see android.icu.impl.URLHandler.URLVisitor#visit(java.lang.String) 903 */ 904 @Override 905 public void visit(String classPath) { 906 int ix = classPath.lastIndexOf(".class"); 907 if (ix < 0) { 908 return; 909 } 910 String className = "android.icu" + classPath.substring(0, ix).replace('/', '.'); 911 912 // Skip things in android.icu.dev; they're not relevant. 913 if (className.startsWith("android.icu.dev.")) { 914 return; 915 } 916 Class c; 917 try { 918 c = Class.forName(className); 919 } catch (ClassNotFoundException e) { 920 return; 921 } 922 int m = c.getModifiers(); 923 924 if (className.equals("android.icu.text.PluralRules$FixedDecimal")) { 925 // Known Issue: "10268", "Serializable interface is not implemented in PluralRules$FixedDecimal" 926 return; 927 } 928 929 if (c.isEnum() || !serializable.isAssignableFrom(c)) { 930 //System.out.println("@@@ Skipping: " + className); 931 return; 932 } 933 if (!Modifier.isPublic(m) || Modifier.isInterface(m)) { 934 //System.out.println("@@@ Skipping: " + className); 935 return; 936 } 937 938 this.classNames.add(className); 939 } 940 } 941 942 public static void serializeObjects(File oof, Object[] objectsOut) throws IOException { 943 FileOutputStream fos = new FileOutputStream(oof); 944 ObjectOutputStream oos = new ObjectOutputStream(fos); 945 oos.writeObject(objectsOut); 946 947 oos.close(); 948 } 949} 950