1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ****************************************************************************** 5 * Copyright (C) 2007-2015, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ****************************************************************************** 8 */ 9 10 // Copyright 2006 Google Inc. All Rights Reserved. 11 12 package com.ibm.icu.dev.test.duration; 13 14 import java.io.BufferedReader; 15 import java.io.InputStream; 16 import java.io.InputStreamReader; 17 import java.io.PrintWriter; 18 import java.util.ArrayList; 19 import java.util.HashMap; 20 import java.util.List; 21 import java.util.Map; 22 23 import org.junit.Test; 24 import org.junit.runner.RunWith; 25 import org.junit.runners.JUnit4; 26 27 import com.ibm.icu.dev.test.TestFmwk; 28 import com.ibm.icu.impl.duration.BasicPeriodFormatterService; 29 import com.ibm.icu.impl.duration.Period; 30 import com.ibm.icu.impl.duration.PeriodBuilder; 31 import com.ibm.icu.impl.duration.PeriodBuilderFactory; 32 import com.ibm.icu.impl.duration.PeriodFormatter; 33 import com.ibm.icu.impl.duration.PeriodFormatterFactory; 34 import com.ibm.icu.impl.duration.TimeUnit; 35 import com.ibm.icu.impl.duration.TimeUnitConstants; 36 import com.ibm.icu.impl.duration.impl.DataRecord.ECountVariant; 37 import com.ibm.icu.impl.duration.impl.DataRecord.EUnitVariant; 38 39 /** 40 * Test cases for en 41 */ 42 @RunWith(JUnit4.class) 43 public abstract class LanguageTestFmwk extends TestFmwk implements TimeUnitConstants { 44 45 private static final TimeUnit[] units = { 46 TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.WEEK, TimeUnit.DAY, TimeUnit.HOUR, 47 TimeUnit.MINUTE, TimeUnit.SECOND, TimeUnit.MILLISECOND 48 }; 49 50 protected boolean inheritTargets() { 51 return true; 52 } 53 54 private static final BasicPeriodFormatterService pfs = BasicPeriodFormatterService 55 .getInstance(); 56 57 private TestData data; 58 private String locale; 59 60 //private DurationFormatterFactory dfFactory; 61 private PeriodFormatterFactory pfFactory; 62 private PeriodBuilderFactory pbFactory; 63 64 private PrintWriter pw; 65 66 private static final Map datacache = new HashMap(); // String->TestData 67 68 private static final long[] approxDurations = { 69 36525L*24*60*60*10, 3045*24*60*60*10L, 7*24*60*60*1000L, 24*60*60*1000L, 70 60*60*1000L, 60*1000L, 1000L, 1L 71 }; 72 73 private static long approximateDuration(TimeUnit unit) { 74 return approxDurations[unit.ordinal()]; 75 } 76 77 private static TestData getTestData(String locale) { 78 // debug 79 if (locale.equals("testFullPluralizedForms")) { 80 Thread.dumpStack(); 81 } 82 TestData data = (TestData) datacache.get(locale); 83 if (data == null) { 84 try { 85 InputStream is = LanguageTestFmwk.class 86 .getResourceAsStream("testdata/testdata_" + locale 87 + ".txt"); 88 // debug 89 if (is == null) { 90 System.out.println("test data for locale '" + locale 91 + "' is null"); 92 } 93 InputStreamReader isr = new InputStreamReader(is, "UTF-8"); 94 try { 95 data = new FileTestData(isr); 96 } finally { 97 isr.close(); 98 } 99 } catch (Exception e) { 100 System.err.println(e.getMessage()); 101 // swallow any exception 102 } 103 } 104 return data; 105 } 106 107 public LanguageTestFmwk(String locale, boolean ignore) { 108 this(getTestData(locale), locale); 109 } 110 111 private LanguageTestFmwk(TestData data, String locale) { 112 if (data == null) { 113 data = DefaultData.getInstance(); 114 } 115 this.data = data; 116 this.locale = locale; 117 } 118 119 // public static void writeData(PrintWriter pw, String locale) 120 // throws Exception { 121 // LanguageTestRoot test = new LanguageTestRoot(DefaultData.getInstance(), 122 // locale); 123 // test.writeData(pw); 124 // } 125 126 // private void writeData(PrintWriter writer) throws Exception { 127 ///* 128 // pw = writer; 129 // setUp(); 130 // testFullPluralizedForms(); 131 // tearDown(); 132 // setUp(); 133 // testMediumForms(); 134 // tearDown(); 135 // setUp(); 136 // testShortForms(); 137 // tearDown(); 138 // setUp(); 139 // testCustomMinutes(); 140 // tearDown(); 141 // setUp(); 142 // testLimitedUnits(); 143 // tearDown(); 144 // setUp(); 145 // testHalfUnits(); 146 // tearDown(); 147 // setUp(); 148 // testFractionalUnits(); 149 // tearDown(); 150 // setUp(); 151 // testMultipleUnits(); 152 // tearDown(); 153 // pw = null; 154 // writer.flush(); 155 //*/ 156 // } 157 158 protected void xAssertEquals(String msg, String[] expected, int n, 159 String actual) { 160 if (pw != null) { 161 pw.println(actual); 162 } else { 163 // java doesn't dump enough context to be useful, so do it myself 164 if (actual == null) { 165 assertEquals(msg, expected[n], actual); 166 } else { 167 if (!actual.equals(expected[n])) { 168 fail("\n(!!" 169 + msg 170 + ") " 171 + asciify("expected '" + expected[n] 172 + "' but got '" + actual + "'")); 173 } 174 } 175 } 176 } 177 178 protected static String timestring(Period ts) { 179 StringBuffer buf = new StringBuffer(); 180 if (ts.isMoreThan()) { 181 buf.append("mt"); 182 } else if (ts.isLessThan()) { 183 buf.append("lt"); 184 } 185 for (int i = 0; i < units.length; ++i) { 186 TimeUnit p = units[i]; 187 if (ts.isSet(p)) { 188 buf.append(Float.toString(ts.getCount(p))); 189 buf.append(p.toString().charAt(0)); 190 } 191 } 192 buf.append(ts.isInPast() ? "p" : "f"); 193 return buf.toString(); 194 } 195 196 protected static String asciify(String s) { 197 StringBuffer sb = null; 198 for (int i = 0, e = s.length(); i < e; ++i) { 199 char c = s.charAt(i); 200 if (c < 0x20 || c > 0x7e) { 201 if (sb == null) { 202 sb = new StringBuffer(); 203 sb.append(s.substring(0, i)); 204 } 205 sb.append("\\u"); 206 if (c < 0x10) { 207 sb.append("000"); 208 } else if (c < 0x100) { 209 sb.append("00"); 210 } else if (c < 0x1000) { 211 sb.append("0"); 212 } 213 sb.append(Integer.toHexString(c)); 214 } else { 215 if (sb != null) { 216 sb.append(c); 217 } 218 } 219 } 220 if (sb != null) { 221 System.out.println("asciify '" + s + "' --> '" + sb.toString() 222 + "'"); 223 } 224 return sb == null ? s : sb.toString(); 225 } 226 227 private void xAssertEquals(String[] expected, int n, String actual) { 228 xAssertEquals(null, expected, n, actual); 229 } 230 231 private void setUp() throws Exception { 232 pfFactory = pfs.newPeriodFormatterFactory().setLocale(locale); 233 pbFactory = pfs.newPeriodBuilderFactory().setLocale(locale); 234 } 235 236 @Test 237 public void testFullPluralizedForms() throws Exception { 238 setUp(); 239 int[] counts = data.getFullPluralizedFormCounts(); 240 String[] targets = data.getFullPluralizedFormTargets(); 241 if (pw != null) { 242 pw.println("=fullPluralizedFormCounts"); 243 for (int i = 0; i < counts.length; ++i) { 244 int c = counts[i]; 245 pw.println(String.valueOf(c)); 246 } 247 pw.println("=fullPluralizedFormTargets"); 248 } 249 250 int n = 0; 251 PeriodFormatter pf = pfFactory.getFormatter(); 252 for (int i = 0; i < units.length; ++i) { 253 TimeUnit u = units[i]; 254 // System.err.print("\nunit: " + u); 255 PeriodBuilder pb = pbFactory.getFixedUnitBuilder(u); 256 for (int j = 0; j < counts.length; ++j) { 257 int c = counts[j]; 258 // System.err.println("\ncount[" + j + "]: " + c); 259 Period p = pb.create(approximateDuration(u) * c); 260 String string = pf.format(p); 261 xAssertEquals(u.toString() + c, targets, n++, string); 262 } 263 } 264 } 265 266 @Test 267 public void testMediumForms() throws Exception { 268 setUp(); 269 String[] targets = data.getMediumFormTargets(); 270 271 if (pw != null) { 272 pw.println("=mediumFormTargets"); 273 } 274 275 pfFactory.setUnitVariant(EUnitVariant.MEDIUM); 276 pfFactory.setDisplayPastFuture(false); 277 PeriodFormatter pf = pfFactory.getFormatter(); 278 int n = 0; 279 for (int i = 0; i < units.length; ++i) { 280 TimeUnit u = units[i]; 281 PeriodBuilder pb = pbFactory.getFixedUnitBuilder(u); 282 Period p = pb.create(approximateDuration(u) * 3); 283 String string = pf.format(p); 284 xAssertEquals(u.toString(), targets, n++, string); 285 } 286 } 287 288 @Test 289 public void testShortForms() throws Exception { 290 setUp(); 291 String[] targets = data.getShortFormTargets(); 292 293 if (pw != null) { 294 pw.println("=shortFormTargets"); 295 } 296 297 pfFactory.setUnitVariant(EUnitVariant.SHORT); 298 pfFactory.setDisplayPastFuture(false); 299 PeriodFormatter pf = pfFactory.getFormatter(); 300 int n = 0; 301 for (int i = 0; i < units.length; ++i) { 302 TimeUnit u = units[i]; 303 PeriodBuilder pb = pbFactory.getFixedUnitBuilder(u); 304 Period p = pb.create(approximateDuration(u) * 3); 305 String string = pf.format(p); 306 xAssertEquals(u.toString(), targets, n++, string); 307 } 308 } 309 310 @Test 311 public void testCustomMinutes() throws Exception { 312 setUp(); 313 String[] targets = data.getCustomMinuteTargets(); 314 315 if (pw != null) { 316 pw.println("=customMinuteTargets"); 317 } 318 319 pfFactory.setCountVariant(ECountVariant.INTEGER_CUSTOM); 320 pfFactory.setDisplayPastFuture(false); 321 PeriodFormatter pf = pfFactory.getFormatter(); 322 323 Period p = Period.at(1, HOUR); 324 int n = 0; 325 for (int i = 1; i < 12; ++i) { 326 p = p.and(i * 5, MINUTE).omit(HOUR); 327 xAssertEquals(targets, n++, pf.format(p)); 328 p = p.and(1, HOUR); 329 xAssertEquals(targets, n++, pf.format(p)); 330 } 331 } 332 333 @Test 334 public void testLimitedUnits() throws Exception { 335 setUp(); 336 String[] targets = data.getLimitedUnitTargets(); 337 338 if (pw != null) { 339 pw.println("=limitedPeriodTargets"); 340 } 341 342 Period p = Period.at(1, MONTH); 343 int n = 0; 344 for (int i = 0; i < 3; ++i) { 345 switch (i) { 346 case 0: 347 p = p.at(); 348 break; 349 case 1: 350 p = p.lessThan(); 351 break; 352 case 2: 353 p = p.moreThan(); 354 break; 355 } 356 for (int j = 0; j < 3; ++j) { 357 pfFactory.setDisplayPastFuture(true); 358 switch (j) { 359 case 0: 360 pfFactory.setDisplayPastFuture(false); 361 break; 362 case 1: 363 p = p.inPast(); 364 break; 365 case 2: 366 p = p.inFuture(); 367 break; 368 } 369 370 PeriodFormatter pf = pfFactory.getFormatter(); 371 372 p = p.omit(WEEK).omit(DAY); 373 xAssertEquals(targets, n++, pf.format(p)); 374 375 p = p.and(2, WEEK); 376 xAssertEquals(targets, n++, pf.format(p)); 377 378 p = p.and(3, DAY); 379 xAssertEquals(targets, n++, pf.format(p)); 380 } 381 } 382 383 p = p.omit(MONTH).omit(WEEK).omit(DAY).and(1, HOUR); 384 for (int i = 0; i < 3; ++i) { 385 switch (i) { 386 case 0: 387 p = p.at(); 388 break; 389 case 1: 390 p = p.lessThan(); 391 break; 392 case 2: 393 p = p.moreThan(); 394 break; 395 } 396 for (int j = 0; j < 3; ++j) { 397 pfFactory.setDisplayPastFuture(true); 398 switch (j) { 399 case 0: 400 pfFactory.setDisplayPastFuture(false); 401 break; 402 case 1: 403 p = p.inPast(); 404 break; 405 case 2: 406 p = p.inFuture(); 407 break; 408 } 409 410 PeriodFormatter pf = pfFactory.getFormatter(); 411 412 p = p.omit(MINUTE).omit(SECOND); 413 xAssertEquals(targets, n++, pf.format(p)); 414 415 p = p.and(2, MINUTE); 416 xAssertEquals(targets, n++, pf.format(p)); 417 418 p = p.and(3, SECOND); 419 xAssertEquals(targets, n++, pf.format(p)); 420 } 421 } 422 } 423 424 @Test 425 public void testHalfUnits() throws Exception { 426 setUp(); 427 int[] counts = data.getHalfUnitCounts(); 428 String[] targets = data.getHalfUnitTargets(); 429 430 if (pw != null) { 431 pw.println("=halfPeriodCounts"); 432 for (int i = 0; i < counts.length; ++i) { 433 int c = counts[i]; 434 pw.println(String.valueOf(c)); 435 } 436 pw.println("=halfPeriodTargets"); 437 } 438 439 pfFactory.setCountVariant(ECountVariant.HALF_FRACTION); 440 pfFactory.setDisplayPastFuture(false); 441 PeriodFormatter pf = pfFactory.getFormatter(); 442 443 int n = 0; 444 for (int i = 0; i < units.length; ++i) { 445 TimeUnit u = units[i]; 446 for (int j = 0; j < counts.length; ++j) { 447 int c = counts[j]; 448 Period p = Period.at(c + .5f, u); 449 String string = pf.format(p); 450 xAssertEquals(u.toString(), targets, n++, string); 451 } 452 } 453 } 454 455 @Test 456 public void testFractionalUnits() throws Exception { 457 setUp(); 458 float[] counts = data.getFractionalUnitCounts(); 459 String[] targets = data.getFractionalUnitTargets(); 460 461 if (pw != null) { 462 pw.println("=fractionalPeriodCounts"); 463 for (int i = 0; i < counts.length; ++i) { 464 float c = counts[i]; 465 pw.println(String.valueOf(c)); 466 } 467 pw.println("=fractionalPeriodTargets"); 468 } 469 470 pfFactory.setCountVariant(ECountVariant.DECIMAL2); 471 pfFactory.setDisplayPastFuture(false); 472 PeriodFormatter pf = pfFactory.getFormatter(); 473 474 int n = 0; 475 for (int i = 0; i < units.length; ++i) { 476 TimeUnit u = units[i]; 477 for (int j = 0; j < counts.length; ++j) { 478 float c = counts[j]; 479 Period p = Period.at(c, u); 480 String string = pf.format(p); 481 xAssertEquals(u.toString(), targets, n++, string); 482 } 483 } 484 } 485 486 @Test 487 public void testMultipleUnits() throws Exception { 488 setUp(); 489 String[] targets = data.getMultipleUnitTargets(); 490 491 if (pw != null) { 492 pw.println("=multiplePeriodTargets"); 493 } 494 495 pfFactory.setCountVariant(ECountVariant.INTEGER); 496 pfFactory.setDisplayPastFuture(false); 497 PeriodFormatter pf = pfFactory.getFormatter(); 498 499 int n = 0; 500 for (int i = 0; i < units.length - 1; ++i) { 501 Period p = Period.at(1, units[i]).and(2, units[i + 1]); 502 xAssertEquals(targets, n++, pf.format(p)); 503 if (i < units.length - 2) { 504 p = Period.at(1, units[i]).and(3, units[i + 2]); 505 xAssertEquals(targets, n++, pf.format(p)); 506 p = Period.at(1, units[i]).and(2, units[i + 1]).and(3, 507 units[i + 2]); 508 xAssertEquals(targets, n++, pf.format(p)); 509 } 510 } 511 } 512 513 public static abstract class TestData { 514 abstract int[] getFullPluralizedFormCounts(); 515 abstract String[] getFullPluralizedFormTargets(); 516 abstract String[] getMediumFormTargets(); 517 abstract String[] getShortFormTargets(); 518 abstract String[] getCustomMinuteTargets(); 519 abstract String[] getLimitedUnitTargets(); 520 abstract int[] getHalfUnitCounts(); 521 abstract String[] getHalfUnitTargets(); 522 abstract float[] getFractionalUnitCounts(); 523 abstract String[] getFractionalUnitTargets(); 524 abstract String[] getMultipleUnitTargets(); 525 } 526 527 } 528 529 class FileTestData extends LanguageTestFmwk.TestData { 530 private int[] fullPluralizedFormCounts; 531 private String[] fullPluralizedFormTargets; 532 private String[] mediumFormTargets; 533 private String[] shortFormTargets; 534 private String[] customMinuteTargets; 535 private String[] limitedUnitTargets; 536 private int[] halfUnitCounts; 537 private String[] halfUnitTargets; 538 private float[] fractionalUnitCounts; 539 private String[] fractionalUnitTargets; 540 private String[] multipleUnitTargets; 541 542 @Override 543 int[] getFullPluralizedFormCounts() { 544 return fullPluralizedFormCounts; 545 } 546 547 @Override 548 String[] getFullPluralizedFormTargets() { 549 return fullPluralizedFormTargets; 550 } 551 552 @Override 553 String[] getMediumFormTargets() { 554 return mediumFormTargets; 555 } 556 557 @Override 558 String[] getShortFormTargets() { 559 return shortFormTargets; 560 } 561 562 @Override 563 String[] getCustomMinuteTargets() { 564 return customMinuteTargets; 565 } 566 567 @Override 568 String[] getLimitedUnitTargets() { 569 return limitedUnitTargets; 570 } 571 572 @Override 573 int[] getHalfUnitCounts() { 574 return halfUnitCounts; 575 } 576 577 @Override 578 String[] getHalfUnitTargets() { 579 return halfUnitTargets; 580 } 581 582 @Override 583 float[] getFractionalUnitCounts() { 584 return fractionalUnitCounts; 585 } 586 587 @Override 588 String[] getFractionalUnitTargets() { 589 return fractionalUnitTargets; 590 } 591 592 @Override 593 String[] getMultipleUnitTargets() { 594 return multipleUnitTargets; 595 } 596 597 public FileTestData(InputStreamReader isr) throws Exception { 598 BufferedReader br = new BufferedReader(isr); 599 600 class Wrapup { 601 int[] intArray; 602 603 float[] floatArray; 604 605 String[] stringArray; 606 607 void wrapup(List /* of String */list, Element element) { 608 if (list == null) 609 return; 610 611 switch (element.mode) { 612 case EMode.mString: 613 stringArray = (String[]) list.toArray(new String[list 614 .size()]); 615 break; 616 617 case EMode.mInt: 618 intArray = new int[list.size()]; 619 for (int i = 0, e = intArray.length; i < e; ++i) { 620 intArray[i] = Integer.parseInt((String) list.get(i)); 621 } 622 break; 623 624 case EMode.mFloat: 625 floatArray = new float[list.size()]; 626 for (int i = 0, e = floatArray.length; i < e; ++i) { 627 floatArray[i] = Float.parseFloat((String) list.get(i)); 628 } 629 break; 630 } 631 632 switch (element.which) { 633 case Element.XfullPluralizedFormCounts: 634 FileTestData.this.fullPluralizedFormCounts = intArray; 635 break; 636 case Element.XfullPluralizedFormTargets: 637 FileTestData.this.fullPluralizedFormTargets = stringArray; 638 break; 639 case Element.XmediumFormTargets: 640 FileTestData.this.mediumFormTargets = stringArray; 641 break; 642 case Element.XshortFormTargets: 643 FileTestData.this.shortFormTargets = stringArray; 644 break; 645 case Element.XcustomMinuteTargets: 646 FileTestData.this.customMinuteTargets = stringArray; 647 break; 648 case Element.XlimitedUnitTargets: 649 FileTestData.this.limitedUnitTargets = stringArray; 650 break; 651 case Element.XhalfUnitCounts: 652 FileTestData.this.halfUnitCounts = intArray; 653 break; 654 case Element.XhalfUnitTargets: 655 FileTestData.this.halfUnitTargets = stringArray; 656 break; 657 case Element.XfractionalUnitCounts: 658 FileTestData.this.fractionalUnitCounts = floatArray; 659 break; 660 case Element.XfractionalUnitTargets: 661 FileTestData.this.fractionalUnitTargets = stringArray; 662 break; 663 case Element.XmultipleUnitTargets: 664 FileTestData.this.multipleUnitTargets = stringArray; 665 break; 666 } 667 } 668 } 669 Wrapup w = new Wrapup(); 670 671 List /* of String */list = null; 672 Element element = null; 673 String line = null; 674 while (null != (line = br.readLine())) { 675 line = line.trim(); 676 if (line.length() == 0 || line.charAt(0) == '#') 677 continue; 678 if (line.charAt(0) == '=') { 679 w.wrapup(list, element); 680 681 list = new ArrayList(); 682 element = Element.forString(line.substring(1)); 683 } else if (line.equals("null")) { 684 list.add(null); 685 } else { 686 list.add(line); 687 } 688 } 689 w.wrapup(list, element); 690 } 691 } 692 693 class DefaultData extends LanguageTestFmwk.TestData { 694 private static final int[] fullPluralizedFormCounts = { -3, -2, -1, 0, 1, 695 2, 3, 5, 10, 11, 12, 20, 21, 22, 23, 25 }; 696 697 private static final int[] halfUnitCounts = { 0, 1, 2, 5, 10, 11, 12, 20, 698 21, 22 }; 699 700 private static final float[] fractionalUnitCounts = { 0.025f, 1.0f, 1.205f, 701 2.125f, 12.05f }; 702 703 private static final DefaultData instance = new DefaultData(); 704 705 private DefaultData() { 706 } 707 708 public static DefaultData getInstance() { 709 return instance; 710 } 711 712 @Override 713 int[] getFullPluralizedFormCounts() { 714 return fullPluralizedFormCounts; 715 } 716 717 @Override 718 String[] getFullPluralizedFormTargets() { 719 return null; 720 } 721 722 @Override 723 String[] getMediumFormTargets() { 724 return null; 725 } 726 727 @Override 728 String[] getShortFormTargets() { 729 return null; 730 } 731 732 @Override 733 String[] getCustomMinuteTargets() { 734 return null; 735 } 736 737 @Override 738 String[] getLimitedUnitTargets() { 739 return null; 740 } 741 742 @Override 743 int[] getHalfUnitCounts() { 744 return halfUnitCounts; 745 } 746 747 @Override 748 String[] getHalfUnitTargets() { 749 return null; 750 } 751 752 @Override 753 float[] getFractionalUnitCounts() { 754 return fractionalUnitCounts; 755 } 756 757 @Override 758 String[] getFractionalUnitTargets() { 759 return null; 760 } 761 762 @Override 763 String[] getMultipleUnitTargets() { 764 return null; 765 } 766 } 767 768 class EMode { 769 static final int mString = 0; 770 static final int mInt = 1; 771 static final int mFloat = 2; 772 } 773 774 class Element { 775 final String name; 776 final int mode; 777 final int which; 778 779 static int counter = 0; 780 static Element[] list = new Element[11]; 781 782 Element(String name) { 783 this.name = name; 784 mode = EMode.mString; 785 this.which = counter++; 786 list[this.which] = this; 787 } 788 789 Element(String name, int mode) { 790 this.name = name; 791 this.mode = mode; 792 this.which = counter++; 793 list[this.which] = this; 794 } 795 796 static final int XfullPluralizedFormCounts = 0; 797 static final int XfullPluralizedFormTargets = 1; 798 static final int XmediumFormTargets = 2; 799 static final int XshortFormTargets = 3; 800 static final int XcustomMinuteTargets = 4; 801 static final int XlimitedUnitTargets = 5; 802 static final int XhalfUnitCounts = 6; 803 static final int XhalfUnitTargets = 7; 804 static final int XfractionalUnitCounts = 8; 805 static final int XfractionalUnitTargets = 9; 806 static final int XmultipleUnitTargets = 10; 807 808 static final Element fullPluralizedFormCounts = new Element( 809 "fullPluralizedFormCounts", EMode.mInt); 810 811 static final Element fullPluralizedFormTargets = new Element( 812 "fullPluralizedFormTargets"); 813 814 static final Element mediumFormTargets = new Element("mediumFormTargets"); 815 816 static final Element shortFormTargets = new Element("shortFormTargets"); 817 818 static final Element customMinuteTargets = new Element( 819 "customMinuteTargets"); 820 821 static final Element limitedUnitTargets = new Element("limitedUnitTargets"); 822 823 static final Element halfUnitCounts = new Element("halfUnitCounts", 824 EMode.mInt); 825 826 static final Element halfUnitTargets = new Element("halfUnitTargets"); 827 828 static final Element fractionalUnitCounts = new Element( 829 "fractionalUnitCounts", EMode.mFloat); 830 831 static final Element fractionalUnitTargets = new Element( 832 "fractionalUnitTargets"); 833 834 static final Element multipleUnitTargets = new Element( 835 "multipleUnitTargets"); 836 837 static Element forString(String s) { 838 for (int i = 0; i < list.length; ++i) { 839 if (list[i].name.equals(s)) { 840 return list[i]; 841 } 842 } 843 return null; 844 } 845 } 846