From 7dcc85ac131ca20a7d0563814df59942f8363a2c Mon Sep 17 00:00:00 2001 From: Andy Heninger Date: Thu, 3 Mar 2011 18:45:22 +0000 Subject: [PATCH] ICU-8400 fixes for DOS line endings and missing svn properties. (BRS) X-SVN-Rev: 29528 --- .gitattributes | 53 - icu4j/eclipse-build/eclipse_mod_classes.txt | 10 +- .../eclipse_mod_test_classes.txt | 14 +- .../com.ibm.icu.base/feature.xml | 66 +- .../com/ibm/icu/tests/BreakIteratorTest.java | 718 +- .../src/com/ibm/icu/tests/CalendarTest.java | 1130 +-- .../com/ibm/icu/tests/CollationKeyTest.java | 204 +- .../src/com/ibm/icu/tests/CollatorTest.java | 410 +- .../ibm/icu/tests/DateFormatSymbolsTest.java | 514 +- .../src/com/ibm/icu/tests/DateFormatTest.java | 908 +- .../icu/tests/DecimalFormatSymbolsTest.java | 688 +- .../com/ibm/icu/tests/DecimalFormatTest.java | 484 +- .../src/com/ibm/icu/tests/ICUTestCase.java | 572 +- .../com/ibm/icu/tests/MessageFormatTest.java | 614 +- .../com/ibm/icu/tests/NumberFormatTest.java | 894 +- .../ibm/icu/tests/SimpleDateFormatTest.java | 404 +- .../src/com/ibm/icu/tests/TimeZoneTest.java | 470 +- .../src/com/ibm/icu/tests/ULocaleTest.java | 1496 ++-- .../src/com/ibm/icu/impl/ICUCache.java | 42 +- .../src/com/ibm/icu/impl/LocaleIDParser.java | 1480 ++-- .../src/com/ibm/icu/impl/LocaleIDs.java | 1072 +-- .../src/com/ibm/icu/impl/LocaleUtility.java | 264 +- .../src/com/ibm/icu/impl/SimpleCache.java | 146 +- .../com/ibm/icu/impl/locale/AsciiUtil.java | 360 +- .../src/com/ibm/icu/math/BigDecimal.java | 7760 ++++++++--------- .../src/com/ibm/icu/math/MathContext.java | 1202 +-- .../src/com/ibm/icu/text/Bidi.java | 5172 +++++------ .../src/com/ibm/icu/text/BidiClassifier.java | 28 +- .../src/com/ibm/icu/text/BidiRun.java | 28 +- .../src/com/ibm/icu/text/BreakIterator.java | 1666 ++-- .../src/com/ibm/icu/text/CollationKey.java | 830 +- .../src/com/ibm/icu/text/Collator.java | 1864 ++-- .../com/ibm/icu/text/CurrencyPluralInfo.java | 28 +- .../src/com/ibm/icu/text/DateFormat.java | 3898 ++++----- .../com/ibm/icu/text/DateFormatSymbols.java | 1680 ++-- .../src/com/ibm/icu/text/DecimalFormat.java | 3524 ++++---- .../ibm/icu/text/DecimalFormatSymbols.java | 700 +- .../src/com/ibm/icu/text/MessageFormat.java | 2830 +++--- .../src/com/ibm/icu/text/NumberFormat.java | 2624 +++--- .../src/com/ibm/icu/text/RawCollationKey.java | 28 +- .../com/ibm/icu/text/SimpleDateFormat.java | 1028 +-- .../src/com/ibm/icu/text/UFormat.java | 160 +- .../src/com/ibm/icu/text/UnicodeSet.java | 28 +- .../src/com/ibm/icu/util/Calendar.java | 4690 +++++----- .../src/com/ibm/icu/util/Currency.java | 840 +- .../src/com/ibm/icu/util/CurrencyAmount.java | 28 +- .../src/com/ibm/icu/util/TimeZone.java | 1420 +-- .../src/com/ibm/icu/util/ULocale.java | 4986 +++++------ .../src/com/ibm/icu/util/VersionInfo.java | 28 +- 49 files changed, 30015 insertions(+), 30068 deletions(-) diff --git a/.gitattributes b/.gitattributes index 600c859b712..fbc0dcb59c4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -209,11 +209,8 @@ icu4c/source/tools/toolutil/toolutil.vcxproj -text icu4j/build.properties -text icu4j/demos/.settings/org.eclipse.core.resources.prefs -text icu4j/demos/manifest.stub -text -icu4j/eclipse-build/eclipse_mod_classes.txt -text -icu4j/eclipse-build/eclipse_mod_test_classes.txt -text icu4j/eclipse-build/features.template/com.ibm.icu.base/.project -text icu4j/eclipse-build/features.template/com.ibm.icu.base/build.properties -text -icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.classpath -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.project -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.core.prefs -text @@ -221,20 +218,6 @@ icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclips icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/META-INF/MANIFEST.MF -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/build.properties -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/plugin.properties -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.classpath -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.project -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.core.prefs -text @@ -242,37 +225,6 @@ icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt. icu4j/eclipse-build/plugins.template/com.ibm.icu.base/META-INF/MANIFEST.MF -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base/build.properties -text icu4j/eclipse-build/plugins.template/com.ibm.icu.base/plugin.properties -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiClassifier.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiRun.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CurrencyPluralInfo.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/RawCollationKey.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UnicodeSet.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/CurrencyAmount.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java -text -icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/VersionInfo.java -text icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/META-INF/MANIFEST.MF -text icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/plugin.properties -text icu4j/eclipse-build/plugins.template/com.ibm.icu/META-INF/MANIFEST.MF -text @@ -292,7 +244,6 @@ icu4j/main/classes/core/.project -text icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text icu4j/main/classes/core/manifest.stub -text -icu4j/main/classes/core/src/com/ibm/icu/lang/CharSequences.java -text icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text @@ -327,7 +278,6 @@ icu4j/main/classes/translit/.externalToolBuilders/copy-data-translit.launch -tex icu4j/main/classes/translit/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/translit/.settings/org.eclipse.jdt.core.prefs -text icu4j/main/classes/translit/.settings/org.eclipse.jdt.ui.prefs -text -icu4j/main/classes/translit/src/com/ibm/icu/text/SourceTargetUtility.java -text icu4j/main/classes/translit/translit-build.launch -text icu4j/main/shared/.project -text icu4j/main/shared/.settings/org.eclipse.core.resources.prefs -text @@ -601,7 +551,6 @@ icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.4/com.ibm icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.4/com.ibm.icu.util.ULocale.dat -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.4/com.ibm.icu.util.UResourceTypeMismatchException.dat -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.4/com.ibm.icu.util.VTimeZone.dat -text -icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Timer.java -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.16.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.32.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges2.16.tri2 -text @@ -612,8 +561,6 @@ icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesEmpty.16. icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesEmpty.32.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesSingleValue.16.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesSingleValue.32.tri2 -text -icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMap.java -text -icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TrieMapTest.java -text icu4j/main/tests/framework/.classpath -text icu4j/main/tests/framework/.project -text icu4j/main/tests/framework/.settings/org.eclipse.core.resources.prefs -text diff --git a/icu4j/eclipse-build/eclipse_mod_classes.txt b/icu4j/eclipse-build/eclipse_mod_classes.txt index dc2f9c68ef4..d279e2e7897 100644 --- a/icu4j/eclipse-build/eclipse_mod_classes.txt +++ b/icu4j/eclipse-build/eclipse_mod_classes.txt @@ -1,5 +1,5 @@ -# Copyright (C) 2011, International Business Machines Corporation and -# others. All Rights Reserved. - -com/ibm/icu/lang/UCharacter.java -com/ibm/icu/text/DecimalFormat.java +# Copyright (C) 2011, International Business Machines Corporation and +# others. All Rights Reserved. + +com/ibm/icu/lang/UCharacter.java +com/ibm/icu/text/DecimalFormat.java diff --git a/icu4j/eclipse-build/eclipse_mod_test_classes.txt b/icu4j/eclipse-build/eclipse_mod_test_classes.txt index 20b52928f3d..7059aeb914a 100644 --- a/icu4j/eclipse-build/eclipse_mod_test_classes.txt +++ b/icu4j/eclipse-build/eclipse_mod_test_classes.txt @@ -1,7 +1,7 @@ -# Copyright (C) 2011, International Business Machines Corporation and -# others. All Rights Reserved. - -com/ibm/icu/dev/test/format/IntlTestDecimalFormatAPI.java -com/ibm/icu/dev/test/format/NumberFormatTest.java -com/ibm/icu/dev/test/serializable/CompatibilityTest.java -com/ibm/icu/dev/test/serializable/CoverageTest.java +# Copyright (C) 2011, International Business Machines Corporation and +# others. All Rights Reserved. + +com/ibm/icu/dev/test/format/IntlTestDecimalFormatAPI.java +com/ibm/icu/dev/test/format/NumberFormatTest.java +com/ibm/icu/dev/test/serializable/CompatibilityTest.java +com/ibm/icu/dev/test/serializable/CoverageTest.java diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml b/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml index 367bcd27097..5102e29769f 100644 --- a/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml +++ b/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml @@ -1,33 +1,33 @@ - - - - - [Enter Feature Description here.] - - - - [Enter Copyright Description here.] - - - - [Enter License Description here.] - - - - - - - + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java index 6b26f3b2f30..3db154648c4 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java @@ -1,359 +1,359 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.Locale; - -import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.util.ULocale; - -public class BreakIteratorTest extends ICUTestCase { - // ICU behaves a bit differently with this text, but the tested values aren't - // affected. If Java changes behavior they might need to change. - private static final String text = "Mr. and Mrs. Mumblety-Peg paid $35.97 for a new 12\" cockatoo. " + - "When they got home they both cooed \"Isn't it lovely?\" and sighed softly. " + - "\"Let's name it u\u0308\u5098!\" they said with glee."; - private static int pos = text.indexOf("sn't"); - private static BreakIterator cbr; - private static BreakIterator wbr; - private static BreakIterator lbr; - private static BreakIterator sbr; - - static { - cbr = BreakIterator.getCharacterInstance(); - cbr.setText(text); - wbr = BreakIterator.getWordInstance(); - wbr.setText(text); - lbr = BreakIterator.getLineInstance(); - lbr.setText(text); - sbr = BreakIterator.getSentenceInstance(); - sbr.setText(text); - - // diagnostic - // dump(cbr); - // dump(wbr); - // dump(lbr); - // dump(sbr); - } - - // private static void dump(BreakIterator bi) { - // for (int ix = bi.first(), lim = text.length(); ix != lim;) { - // int nx = bi.next(); - // if (nx < 0) nx = lim; - // System.out.println(Integer.toString(ix) + ": " + text.substring(ix, nx)); - // ix = nx; - // } - // } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.hashCode()' - */ - public void testHashCode() { - BreakIterator br = BreakIterator.getWordInstance(); - br.setText(text); - BreakIterator brne = BreakIterator.getWordInstance(); - brne.setText(text + "X"); - wbr.first(); - testEHCS(br, wbr, brne); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.BreakIterator(BreakIterator)' - */ - public void testBreakIterator() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.first()' - */ - public void testFirst() { - assertEquals(0, cbr.first()); - assertEquals(0, wbr.first()); - assertEquals(0, lbr.first()); - assertEquals(0, sbr.first()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.last()' - */ - public void testLast() { - assertEquals(text.length(), cbr.last()); - assertEquals(text.length(), wbr.last()); - assertEquals(text.length(), lbr.last()); - assertEquals(text.length(), sbr.last()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.next(int)' - */ - public void testNextInt() { - cbr.first(); - wbr.first(); - lbr.first(); - sbr.first(); - assertEquals(2, cbr.next(2)); - assertEquals(3, wbr.next(2)); - assertEquals(8, lbr.next(2)); - assertEquals(62, sbr.next(2)); - - cbr.last(); - wbr.last(); - lbr.last(); - sbr.last(); - assertEquals(174, cbr.next(-2)); - assertEquals(171, wbr.next(-2)); - assertEquals(166, lbr.next(-2)); - assertEquals(135, sbr.next(-2)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.next()' - */ - public void testNext() { - cbr.first(); - wbr.first(); - lbr.first(); - sbr.first(); - assertEquals(1, cbr.next()); - assertEquals(2, wbr.next()); - assertEquals(4, lbr.next()); - assertEquals(13, sbr.next()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.previous()' - */ - public void testPrevious() { - cbr.last(); - wbr.last(); - lbr.last(); - sbr.last(); - assertEquals(175, cbr.previous()); - assertEquals(175, wbr.previous()); - assertEquals(171, lbr.previous()); - assertEquals(156, sbr.previous()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.following(int)' - */ - public void testFollowing() { - assertEquals(100, cbr.following(pos)); - assertEquals(103, wbr.following(pos)); - assertEquals(104, lbr.following(pos)); - assertEquals(116, sbr.following(pos)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.preceding(int)' - */ - public void testPreceding() { - assertEquals(98, cbr.preceding(pos)); - assertEquals(98, wbr.preceding(pos)); - assertEquals(97, lbr.preceding(pos)); - assertEquals(62, sbr.preceding(pos)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.isBoundary(int)' - */ - public void testIsBoundary() { - assertTrue(cbr.isBoundary(pos)); - assertFalse(wbr.isBoundary(pos)); - assertFalse(lbr.isBoundary(pos)); - assertFalse(sbr.isBoundary(pos)); - - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.current()' - */ - public void testCurrent() { - cbr.following(pos); - wbr.following(pos); - lbr.following(pos); - sbr.following(pos); - assertEquals(100, cbr.current()); - assertEquals(103, wbr.current()); - assertEquals(104, lbr.current()); - assertEquals(116, sbr.current()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getText()' - */ - public void testGetText() { - CharacterIterator ci = cbr.getText(); - StringBuffer buf = new StringBuffer(ci.getEndIndex() - ci.getBeginIndex()); - for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) { - buf.append(c); - } - String result = buf.toString(); - assertEquals(text, result); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.setText(String)' - */ - public void testSetTextString() { - // implicitly tested - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.setText(CharacterIterator)' - */ - public void testSetTextCharacterIterator() { - CharacterIterator ci = new StringCharacterIterator(text, pos); - BreakIterator bi = BreakIterator.getWordInstance(); - bi.setText(ci); - assertEquals(2, bi.next()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance()' - */ - public void testGetWordInstance() { - // implicitly tested - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(Locale)' - */ - public void testGetWordInstanceLocale() { - assertNotNull(BreakIterator.getWordInstance(Locale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(ULocale)' - */ - public void testGetWordInstanceULocale() { - assertNotNull(BreakIterator.getWordInstance(ULocale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance()' - */ - public void testGetLineInstance() { - // implicitly tested - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(Locale)' - */ - public void testGetLineInstanceLocale() { - assertNotNull(BreakIterator.getLineInstance(Locale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(ULocale)' - */ - public void testGetLineInstanceULocale() { - assertNotNull(BreakIterator.getLineInstance(ULocale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance()' - */ - public void testGetCharacterInstance() { - // implicitly tested - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(Locale)' - */ - public void testGetCharacterInstanceLocale() { - assertNotNull(BreakIterator.getCharacterInstance(Locale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(ULocale)' - */ - public void testGetCharacterInstanceULocale() { - assertNotNull(BreakIterator.getCharacterInstance(ULocale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance()' - */ - public void testGetSentenceInstance() { - // implicitly tested - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(Locale)' - */ - public void testGetSentenceInstanceLocale() { - assertNotNull(BreakIterator.getSentenceInstance(Locale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(ULocale)' - */ - public void testGetSentenceInstanceULocale() { - assertNotNull(BreakIterator.getSentenceInstance(ULocale.JAPAN)); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance()' - */ - public void testGetTitleInstance() { - // not implemented - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(Locale)' - */ - public void testGetTitleInstanceLocale() { - // not implemented - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(ULocale)' - */ - public void testGetTitleInstanceULocale() { - // not implemented - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableLocales()' - */ - public void testGetAvailableLocales() { - assertNotNull(BreakIterator.getAvailableLocales()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableULocales()' - */ - public void testGetAvailableULocales() { - assertNotNull(BreakIterator.getAvailableULocales()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.toString()' - */ - public void testToString() { - assertNotNull(cbr.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.clone()' - */ - public void testClone() { - // see testHashCode - } - - /* - * Test method for 'com.ibm.icu.text.BreakIterator.equals(Object)' - */ - public void testEqualsObject() { - // see testHashCode - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.Locale; + +import com.ibm.icu.text.BreakIterator; +import com.ibm.icu.util.ULocale; + +public class BreakIteratorTest extends ICUTestCase { + // ICU behaves a bit differently with this text, but the tested values aren't + // affected. If Java changes behavior they might need to change. + private static final String text = "Mr. and Mrs. Mumblety-Peg paid $35.97 for a new 12\" cockatoo. " + + "When they got home they both cooed \"Isn't it lovely?\" and sighed softly. " + + "\"Let's name it u\u0308\u5098!\" they said with glee."; + private static int pos = text.indexOf("sn't"); + private static BreakIterator cbr; + private static BreakIterator wbr; + private static BreakIterator lbr; + private static BreakIterator sbr; + + static { + cbr = BreakIterator.getCharacterInstance(); + cbr.setText(text); + wbr = BreakIterator.getWordInstance(); + wbr.setText(text); + lbr = BreakIterator.getLineInstance(); + lbr.setText(text); + sbr = BreakIterator.getSentenceInstance(); + sbr.setText(text); + + // diagnostic + // dump(cbr); + // dump(wbr); + // dump(lbr); + // dump(sbr); + } + + // private static void dump(BreakIterator bi) { + // for (int ix = bi.first(), lim = text.length(); ix != lim;) { + // int nx = bi.next(); + // if (nx < 0) nx = lim; + // System.out.println(Integer.toString(ix) + ": " + text.substring(ix, nx)); + // ix = nx; + // } + // } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.hashCode()' + */ + public void testHashCode() { + BreakIterator br = BreakIterator.getWordInstance(); + br.setText(text); + BreakIterator brne = BreakIterator.getWordInstance(); + brne.setText(text + "X"); + wbr.first(); + testEHCS(br, wbr, brne); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.BreakIterator(BreakIterator)' + */ + public void testBreakIterator() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.first()' + */ + public void testFirst() { + assertEquals(0, cbr.first()); + assertEquals(0, wbr.first()); + assertEquals(0, lbr.first()); + assertEquals(0, sbr.first()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.last()' + */ + public void testLast() { + assertEquals(text.length(), cbr.last()); + assertEquals(text.length(), wbr.last()); + assertEquals(text.length(), lbr.last()); + assertEquals(text.length(), sbr.last()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.next(int)' + */ + public void testNextInt() { + cbr.first(); + wbr.first(); + lbr.first(); + sbr.first(); + assertEquals(2, cbr.next(2)); + assertEquals(3, wbr.next(2)); + assertEquals(8, lbr.next(2)); + assertEquals(62, sbr.next(2)); + + cbr.last(); + wbr.last(); + lbr.last(); + sbr.last(); + assertEquals(174, cbr.next(-2)); + assertEquals(171, wbr.next(-2)); + assertEquals(166, lbr.next(-2)); + assertEquals(135, sbr.next(-2)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.next()' + */ + public void testNext() { + cbr.first(); + wbr.first(); + lbr.first(); + sbr.first(); + assertEquals(1, cbr.next()); + assertEquals(2, wbr.next()); + assertEquals(4, lbr.next()); + assertEquals(13, sbr.next()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.previous()' + */ + public void testPrevious() { + cbr.last(); + wbr.last(); + lbr.last(); + sbr.last(); + assertEquals(175, cbr.previous()); + assertEquals(175, wbr.previous()); + assertEquals(171, lbr.previous()); + assertEquals(156, sbr.previous()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.following(int)' + */ + public void testFollowing() { + assertEquals(100, cbr.following(pos)); + assertEquals(103, wbr.following(pos)); + assertEquals(104, lbr.following(pos)); + assertEquals(116, sbr.following(pos)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.preceding(int)' + */ + public void testPreceding() { + assertEquals(98, cbr.preceding(pos)); + assertEquals(98, wbr.preceding(pos)); + assertEquals(97, lbr.preceding(pos)); + assertEquals(62, sbr.preceding(pos)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.isBoundary(int)' + */ + public void testIsBoundary() { + assertTrue(cbr.isBoundary(pos)); + assertFalse(wbr.isBoundary(pos)); + assertFalse(lbr.isBoundary(pos)); + assertFalse(sbr.isBoundary(pos)); + + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.current()' + */ + public void testCurrent() { + cbr.following(pos); + wbr.following(pos); + lbr.following(pos); + sbr.following(pos); + assertEquals(100, cbr.current()); + assertEquals(103, wbr.current()); + assertEquals(104, lbr.current()); + assertEquals(116, sbr.current()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getText()' + */ + public void testGetText() { + CharacterIterator ci = cbr.getText(); + StringBuffer buf = new StringBuffer(ci.getEndIndex() - ci.getBeginIndex()); + for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) { + buf.append(c); + } + String result = buf.toString(); + assertEquals(text, result); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.setText(String)' + */ + public void testSetTextString() { + // implicitly tested + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.setText(CharacterIterator)' + */ + public void testSetTextCharacterIterator() { + CharacterIterator ci = new StringCharacterIterator(text, pos); + BreakIterator bi = BreakIterator.getWordInstance(); + bi.setText(ci); + assertEquals(2, bi.next()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance()' + */ + public void testGetWordInstance() { + // implicitly tested + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(Locale)' + */ + public void testGetWordInstanceLocale() { + assertNotNull(BreakIterator.getWordInstance(Locale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(ULocale)' + */ + public void testGetWordInstanceULocale() { + assertNotNull(BreakIterator.getWordInstance(ULocale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance()' + */ + public void testGetLineInstance() { + // implicitly tested + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(Locale)' + */ + public void testGetLineInstanceLocale() { + assertNotNull(BreakIterator.getLineInstance(Locale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(ULocale)' + */ + public void testGetLineInstanceULocale() { + assertNotNull(BreakIterator.getLineInstance(ULocale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance()' + */ + public void testGetCharacterInstance() { + // implicitly tested + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(Locale)' + */ + public void testGetCharacterInstanceLocale() { + assertNotNull(BreakIterator.getCharacterInstance(Locale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(ULocale)' + */ + public void testGetCharacterInstanceULocale() { + assertNotNull(BreakIterator.getCharacterInstance(ULocale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance()' + */ + public void testGetSentenceInstance() { + // implicitly tested + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(Locale)' + */ + public void testGetSentenceInstanceLocale() { + assertNotNull(BreakIterator.getSentenceInstance(Locale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(ULocale)' + */ + public void testGetSentenceInstanceULocale() { + assertNotNull(BreakIterator.getSentenceInstance(ULocale.JAPAN)); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance()' + */ + public void testGetTitleInstance() { + // not implemented + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(Locale)' + */ + public void testGetTitleInstanceLocale() { + // not implemented + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(ULocale)' + */ + public void testGetTitleInstanceULocale() { + // not implemented + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableLocales()' + */ + public void testGetAvailableLocales() { + assertNotNull(BreakIterator.getAvailableLocales()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableULocales()' + */ + public void testGetAvailableULocales() { + assertNotNull(BreakIterator.getAvailableULocales()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.toString()' + */ + public void testToString() { + assertNotNull(cbr.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.clone()' + */ + public void testClone() { + // see testHashCode + } + + /* + * Test method for 'com.ibm.icu.text.BreakIterator.equals(Object)' + */ + public void testEqualsObject() { + // see testHashCode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java index 69195a2a4e9..3237a940363 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java @@ -1,565 +1,565 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Date; -import java.util.Locale; - -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -public class CalendarTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.util.Calendar.hashCode()' - */ - public void testHashCode() { - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - Calendar cal3 = Calendar.getInstance(); - - long t = System.currentTimeMillis(); - cal1.setTimeInMillis(t); - cal2.setTimeInMillis(t); - cal3.setTimeInMillis(t); - - cal3.setMinimalDaysInFirstWeek(cal3.getMinimalDaysInFirstWeek()+1); - testEHCS(cal1, cal2, cal3); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.Calendar(Calendar)' - */ - public void testCalendar() { - // tested implicitly everywhere - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance()' - */ - public void testGetInstance() { - // tested by testEHCS - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone)' - */ - public void testGetInstanceTimeZone() { - TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - Calendar cal = Calendar.getInstance(tz); - assertNotNull(cal); - assertNotNull(cal.getTime()); - assertEquals(tz, cal.getTimeZone()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance(Locale)' - */ - public void testGetInstanceLocale() { - Calendar cal = Calendar.getInstance(Locale.US); - assertNotNull(cal); - assertNotNull(cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance(ULocale)' - */ - public void testGetInstanceULocale() { - Calendar cal = Calendar.getInstance(ULocale.US); - assertNotNull(cal); - assertNotNull(cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, Locale)' - */ - public void testGetInstanceTimeZoneLocale() { - TimeZone tz = TimeZone.getTimeZone("America/New_York"); - Calendar cal = Calendar.getInstance(tz, Locale.US); - assertNotNull(cal); - assertNotNull(cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, ULocale)' - */ - public void testGetInstanceTimeZoneULocale() { - TimeZone tz = TimeZone.getTimeZone("America/New_York"); - Calendar cal = Calendar.getInstance(tz, ULocale.US); - assertNotNull(cal); - assertNotNull(cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getAvailableLocales()' - */ - public void testGetAvailableLocales() { - assertNotNull(Calendar.getAvailableLocales()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getAvailableULocales()' - */ - public void testGetAvailableULocales() { - assertNotNull(Calendar.getAvailableULocales()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getTime()' - */ - public void testGetTime() { - Calendar cal = Calendar.getInstance(); - assertNotNull(cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setTime(Date)' - */ - public void testSetTime() { - Calendar cal = Calendar.getInstance(); - cal.clear(); - cal.set(2006, 0, 20, 9, 30, 0); - Date date = cal.getTime(); - cal = Calendar.getInstance(); - cal.setTime(date); - assertEquals(date, cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getTimeInMillis()' - */ - public void testGetTimeInMillis() { - Calendar cal = Calendar.getInstance(); - assertTrue(0 != cal.getTimeInMillis()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setTimeInMillis(long)' - */ - public void testSetTimeInMillis() { - Calendar cal = Calendar.getInstance(); - cal.clear(); - cal.set(2006, 0, 20, 9, 30, 0); - long millis = cal.getTimeInMillis(); - Date date = cal.getTime(); - - cal = Calendar.getInstance(); - cal.setTimeInMillis(millis); - - assertEquals(date, cal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.get(int)' - */ - public void testGet() { - Calendar cal = Calendar.getInstance(); - cal.clear(); - cal.set(2006, 0, 20, 9, 30, 0); - assertEquals(0, cal.get(Calendar.MONTH)); - assertEquals(20, cal.get(Calendar.DAY_OF_MONTH)); - assertEquals(30, cal.get(Calendar.MINUTE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.set(int, int)' - */ - public void testSetIntInt() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, 1977); - assertEquals(1977, cal.get(Calendar.YEAR)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int)' - */ - public void testSetIntIntInt() { - Calendar cal = Calendar.getInstance(); - cal.set(1997, 9, 15); - assertEquals(15, cal.get(Calendar.DATE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int)' - */ - public void testSetIntIntIntIntInt() { - Calendar cal = Calendar.getInstance(); - cal.set(1997, 9, 15, 14, 25); - assertEquals(25, cal.get(Calendar.MINUTE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int, int)' - */ - public void testSetIntIntIntIntIntInt() { - Calendar cal = Calendar.getInstance(); - cal.set(1997, 9, 15, 14, 25, 51); - assertEquals(51, cal.get(Calendar.SECOND)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.clear()' - */ - public void testClear() { - Calendar cal = Calendar.getInstance(); - cal.set(1997, 9, 15, 14, 25, 51); - cal.clear(); - assertEquals(0, cal.get(Calendar.MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.clear(int)' - */ - public void testClearInt() { - Calendar cal = Calendar.getInstance(); - cal.set(1997, 9, 15, 14, 25, 51); - assertTrue(cal.isSet(Calendar.DAY_OF_MONTH)); - cal.clear(Calendar.DAY_OF_MONTH); - assertFalse(cal.isSet(Calendar.DAY_OF_MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.isSet(int)' - */ - public void testIsSet() { - // see testClearInt - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.equals(Object)' - */ - public void testEqualsObject() { - // tested by testHashCode - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.isEquivalentTo(Calendar)' - */ - public void testIsEquivalentTo() { - Calendar cal = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - cal2.set(1994, 6, 21, 8, 7); - assertTrue(cal.isEquivalentTo(cal2)); - cal.setTimeZone(TimeZone.getTimeZone("CST")); - cal2.setTimeZone(TimeZone.getTimeZone("PDT")); - assertFalse(cal.isEquivalentTo(cal2)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.before(Object)' - */ - public void testBefore() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, 1990); - assertTrue(cal.before(new Date())); - assertTrue(cal.before(Calendar.getInstance())); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.after(Object)' - */ - public void testAfter() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, 3058); - assertTrue(cal.after(new Date())); - assertTrue(cal.after(Calendar.getInstance())); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getActualMaximum(int)' - */ - public void testGetActualMaximum() { - Calendar cal = Calendar.getInstance(Locale.US); - assertEquals(11, cal.getActualMaximum(Calendar.MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getActualMinimum(int)' - */ - public void testGetActualMinimum() { - Calendar cal = Calendar.getInstance(Locale.US); - assertEquals(0, cal.getActualMinimum(Calendar.MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.roll(int, boolean)' - */ - public void testRollIntBoolean() { - Calendar cal = Calendar.getInstance(Locale.US); - cal.set(1997, 1, 27); - cal.roll(Calendar.DATE, true); - assertEquals(28, cal.get(Calendar.DATE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.roll(int, int)' - */ - public void testRollIntInt() { - Calendar cal = Calendar.getInstance(Locale.US); - cal.set(1997, 1, 27); - cal.roll(Calendar.DATE, 3); - assertEquals(2, cal.get(Calendar.DATE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.add(int, int)' - */ - public void testAdd() { - Calendar cal = Calendar.getInstance(Locale.US); - cal.set(1997, 1, 27); - cal.add(Calendar.DATE, 3); - assertEquals(2, cal.get(Calendar.DATE)); - assertEquals(2, cal.get(Calendar.MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(Locale)' - */ - public void testGetDisplayNameLocale() { - Calendar cal = Calendar.getInstance(); - assertEquals("Gregorian Calendar", cal.getDisplayName(Locale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(ULocale)' - */ - public void testGetDisplayNameULocale() { - Calendar cal = Calendar.getInstance(); - assertEquals("Gregorian Calendar", cal.getDisplayName(ULocale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.compareTo(Calendar)' - */ - public void testCompareToCalendar() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, 1990); - assertTrue(0 > cal.compareTo(Calendar.getInstance())); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.compareTo(Object)' - */ - public void testCompareToObject() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, 1990); - assertTrue(0 > cal.compareTo(Calendar.getInstance())); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, Locale)' - */ - public void testGetDateTimeFormatIntIntLocale() { - Calendar cal = Calendar.getInstance(); - cal.set(1990, 8, 16, 20, 3); - DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, Locale.US); - assertEquals("September 16, 1990 8:03 PM", df.format(cal)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, ULocale)' - */ - public void testGetDateTimeFormatIntIntULocale() { - Calendar cal = Calendar.getInstance(); - cal.set(1990, 8, 16, 20, 3); - DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, ULocale.US); - assertEquals("September 16, 1990 8:03 PM", df.format(cal)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.fieldDifference(Date, int)' - */ - public void testFieldDifference() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.DAY_OF_MONTH, 0); - Date date = cal.getTime(); - cal.add(Calendar.DAY_OF_MONTH, 5); - assertEquals(-5, cal.fieldDifference(date, Calendar.DAY_OF_MONTH)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getTimeZone()' - */ - public void testGetTimeZone() { - Calendar cal = Calendar.getInstance(); - assertNotNull(cal.getTimeZone()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setTimeZone(TimeZone)' - */ - public void testSetTimeZone() { - Calendar cal = Calendar.getInstance(); - TimeZone value1 = cal.getTimeZone(); - String tzn = "PDT".equals(value1.getID()) ? "CST" : "PDT"; - TimeZone value2 = TimeZone.getTimeZone(tzn); - cal.setTimeZone(value2); - TimeZone result = cal.getTimeZone(); - assertNotEqual(value1, result); - assertEquals(value2, result); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setLenient(boolean)' - */ - public void testSetLenient() { - Calendar cal = Calendar.getInstance(); - boolean lenient = cal.isLenient(); - cal.setLenient(!lenient); - assertFalse(lenient == cal.isLenient()); - - // not testing if it has the expected effect - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.isLenient()' - */ - public void testIsLenient() { - // tested by testSetLenient - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setFirstDayOfWeek(int)' - */ - public void testSetFirstDayOfWeek() { - Calendar cal = Calendar.getInstance(); - int firstDay = cal.getFirstDayOfWeek(); - cal.setFirstDayOfWeek(firstDay+1); - assertEquals(firstDay+1, cal.getFirstDayOfWeek()); - - // don't test functionality - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getFirstDayOfWeek()' - */ - public void testGetFirstDayOfWeek() { - // tested by testSetFirstDayOfWeek - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.setMinimalDaysInFirstWeek(int)' - */ - public void testSetMinimalDaysInFirstWeek() { - Calendar cal = Calendar.getInstance(); - int firstDay = cal.getMinimalDaysInFirstWeek(); - cal.setMinimalDaysInFirstWeek(firstDay+1); - assertEquals(firstDay+1, cal.getMinimalDaysInFirstWeek()); - - // don't test functionality - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getMinimalDaysInFirstWeek()' - */ - public void testGetMinimalDaysInFirstWeek() { - // tested by testSetMinimalDaysInFirstWeek - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getMinimum(int)' - */ - public void testGetMinimum() { - Calendar cal = Calendar.getInstance(); - assertEquals(1, cal.getMinimum(Calendar.DAY_OF_WEEK)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getMaximum(int)' - */ - public void testGetMaximum() { - Calendar cal = Calendar.getInstance(); - assertEquals(7, cal.getMaximum(Calendar.DAY_OF_WEEK)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getGreatestMinimum(int)' - */ - public void testGetGreatestMinimum() { - Calendar cal = Calendar.getInstance(); - assertEquals(1, cal.getGreatestMinimum(Calendar.DATE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getLeastMaximum(int)' - */ - public void testGetLeastMaximum() { - Calendar cal = Calendar.getInstance(); - assertEquals(28, cal.getLeastMaximum(Calendar.DATE)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getDayOfWeekType(int)' - */ - public void testGetDayOfWeekType() { - Calendar cal = Calendar.getInstance(Locale.US); - assertEquals(Calendar.WEEKDAY, cal.getDayOfWeekType(Calendar.FRIDAY)); - assertEquals(Calendar.WEEKEND, cal.getDayOfWeekType(Calendar.SATURDAY)); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getWeekendTransition(int)' - */ - public void testGetWeekendTransition() { - Calendar cal = Calendar.getInstance(Locale.US); - try { - cal.getWeekendTransition(Calendar.WEEKEND_ONSET); - fail("expected IllegalArgumentException from getWeekendTransition"); - } - catch (UnsupportedOperationException e) { - // ok - } - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.isWeekend(Date)' - */ - public void testIsWeekendDate() { - Calendar cal = Calendar.getInstance(Locale.US); - cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY); - assertTrue(cal.isWeekend(cal.getTime())); - cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); - assertFalse(cal.isWeekend(cal.getTime())); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.isWeekend()' - */ - public void testIsWeekend() { - Calendar cal = Calendar.getInstance(Locale.US); - cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY); - assertTrue(cal.isWeekend()); - cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); - assertFalse(cal.isWeekend()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.clone()' - */ - public void testClone() { - // tested by testHashCode - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.toString()' - */ - public void testToString() { - Calendar cal = Calendar.getInstance(); - assertNotNull(cal.toString()); - } - - /* - * Test method for 'com.ibm.icu.util.Calendar.getType()' - */ - public void testGetType() { - Calendar cal = Calendar.getInstance(Locale.US); - assertEquals("gregorian", cal.getType()); - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Date; +import java.util.Locale; + +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +public class CalendarTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.util.Calendar.hashCode()' + */ + public void testHashCode() { + Calendar cal1 = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); + Calendar cal3 = Calendar.getInstance(); + + long t = System.currentTimeMillis(); + cal1.setTimeInMillis(t); + cal2.setTimeInMillis(t); + cal3.setTimeInMillis(t); + + cal3.setMinimalDaysInFirstWeek(cal3.getMinimalDaysInFirstWeek()+1); + testEHCS(cal1, cal2, cal3); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.Calendar(Calendar)' + */ + public void testCalendar() { + // tested implicitly everywhere + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance()' + */ + public void testGetInstance() { + // tested by testEHCS + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone)' + */ + public void testGetInstanceTimeZone() { + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar cal = Calendar.getInstance(tz); + assertNotNull(cal); + assertNotNull(cal.getTime()); + assertEquals(tz, cal.getTimeZone()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance(Locale)' + */ + public void testGetInstanceLocale() { + Calendar cal = Calendar.getInstance(Locale.US); + assertNotNull(cal); + assertNotNull(cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance(ULocale)' + */ + public void testGetInstanceULocale() { + Calendar cal = Calendar.getInstance(ULocale.US); + assertNotNull(cal); + assertNotNull(cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, Locale)' + */ + public void testGetInstanceTimeZoneLocale() { + TimeZone tz = TimeZone.getTimeZone("America/New_York"); + Calendar cal = Calendar.getInstance(tz, Locale.US); + assertNotNull(cal); + assertNotNull(cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, ULocale)' + */ + public void testGetInstanceTimeZoneULocale() { + TimeZone tz = TimeZone.getTimeZone("America/New_York"); + Calendar cal = Calendar.getInstance(tz, ULocale.US); + assertNotNull(cal); + assertNotNull(cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getAvailableLocales()' + */ + public void testGetAvailableLocales() { + assertNotNull(Calendar.getAvailableLocales()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getAvailableULocales()' + */ + public void testGetAvailableULocales() { + assertNotNull(Calendar.getAvailableULocales()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getTime()' + */ + public void testGetTime() { + Calendar cal = Calendar.getInstance(); + assertNotNull(cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setTime(Date)' + */ + public void testSetTime() { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(2006, 0, 20, 9, 30, 0); + Date date = cal.getTime(); + cal = Calendar.getInstance(); + cal.setTime(date); + assertEquals(date, cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getTimeInMillis()' + */ + public void testGetTimeInMillis() { + Calendar cal = Calendar.getInstance(); + assertTrue(0 != cal.getTimeInMillis()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setTimeInMillis(long)' + */ + public void testSetTimeInMillis() { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(2006, 0, 20, 9, 30, 0); + long millis = cal.getTimeInMillis(); + Date date = cal.getTime(); + + cal = Calendar.getInstance(); + cal.setTimeInMillis(millis); + + assertEquals(date, cal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.get(int)' + */ + public void testGet() { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(2006, 0, 20, 9, 30, 0); + assertEquals(0, cal.get(Calendar.MONTH)); + assertEquals(20, cal.get(Calendar.DAY_OF_MONTH)); + assertEquals(30, cal.get(Calendar.MINUTE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.set(int, int)' + */ + public void testSetIntInt() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, 1977); + assertEquals(1977, cal.get(Calendar.YEAR)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int)' + */ + public void testSetIntIntInt() { + Calendar cal = Calendar.getInstance(); + cal.set(1997, 9, 15); + assertEquals(15, cal.get(Calendar.DATE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int)' + */ + public void testSetIntIntIntIntInt() { + Calendar cal = Calendar.getInstance(); + cal.set(1997, 9, 15, 14, 25); + assertEquals(25, cal.get(Calendar.MINUTE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int, int)' + */ + public void testSetIntIntIntIntIntInt() { + Calendar cal = Calendar.getInstance(); + cal.set(1997, 9, 15, 14, 25, 51); + assertEquals(51, cal.get(Calendar.SECOND)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.clear()' + */ + public void testClear() { + Calendar cal = Calendar.getInstance(); + cal.set(1997, 9, 15, 14, 25, 51); + cal.clear(); + assertEquals(0, cal.get(Calendar.MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.clear(int)' + */ + public void testClearInt() { + Calendar cal = Calendar.getInstance(); + cal.set(1997, 9, 15, 14, 25, 51); + assertTrue(cal.isSet(Calendar.DAY_OF_MONTH)); + cal.clear(Calendar.DAY_OF_MONTH); + assertFalse(cal.isSet(Calendar.DAY_OF_MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.isSet(int)' + */ + public void testIsSet() { + // see testClearInt + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.equals(Object)' + */ + public void testEqualsObject() { + // tested by testHashCode + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.isEquivalentTo(Calendar)' + */ + public void testIsEquivalentTo() { + Calendar cal = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); + cal2.set(1994, 6, 21, 8, 7); + assertTrue(cal.isEquivalentTo(cal2)); + cal.setTimeZone(TimeZone.getTimeZone("CST")); + cal2.setTimeZone(TimeZone.getTimeZone("PDT")); + assertFalse(cal.isEquivalentTo(cal2)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.before(Object)' + */ + public void testBefore() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, 1990); + assertTrue(cal.before(new Date())); + assertTrue(cal.before(Calendar.getInstance())); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.after(Object)' + */ + public void testAfter() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, 3058); + assertTrue(cal.after(new Date())); + assertTrue(cal.after(Calendar.getInstance())); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getActualMaximum(int)' + */ + public void testGetActualMaximum() { + Calendar cal = Calendar.getInstance(Locale.US); + assertEquals(11, cal.getActualMaximum(Calendar.MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getActualMinimum(int)' + */ + public void testGetActualMinimum() { + Calendar cal = Calendar.getInstance(Locale.US); + assertEquals(0, cal.getActualMinimum(Calendar.MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.roll(int, boolean)' + */ + public void testRollIntBoolean() { + Calendar cal = Calendar.getInstance(Locale.US); + cal.set(1997, 1, 27); + cal.roll(Calendar.DATE, true); + assertEquals(28, cal.get(Calendar.DATE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.roll(int, int)' + */ + public void testRollIntInt() { + Calendar cal = Calendar.getInstance(Locale.US); + cal.set(1997, 1, 27); + cal.roll(Calendar.DATE, 3); + assertEquals(2, cal.get(Calendar.DATE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.add(int, int)' + */ + public void testAdd() { + Calendar cal = Calendar.getInstance(Locale.US); + cal.set(1997, 1, 27); + cal.add(Calendar.DATE, 3); + assertEquals(2, cal.get(Calendar.DATE)); + assertEquals(2, cal.get(Calendar.MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(Locale)' + */ + public void testGetDisplayNameLocale() { + Calendar cal = Calendar.getInstance(); + assertEquals("Gregorian Calendar", cal.getDisplayName(Locale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(ULocale)' + */ + public void testGetDisplayNameULocale() { + Calendar cal = Calendar.getInstance(); + assertEquals("Gregorian Calendar", cal.getDisplayName(ULocale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.compareTo(Calendar)' + */ + public void testCompareToCalendar() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, 1990); + assertTrue(0 > cal.compareTo(Calendar.getInstance())); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.compareTo(Object)' + */ + public void testCompareToObject() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, 1990); + assertTrue(0 > cal.compareTo(Calendar.getInstance())); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, Locale)' + */ + public void testGetDateTimeFormatIntIntLocale() { + Calendar cal = Calendar.getInstance(); + cal.set(1990, 8, 16, 20, 3); + DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, Locale.US); + assertEquals("September 16, 1990 8:03 PM", df.format(cal)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, ULocale)' + */ + public void testGetDateTimeFormatIntIntULocale() { + Calendar cal = Calendar.getInstance(); + cal.set(1990, 8, 16, 20, 3); + DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, ULocale.US); + assertEquals("September 16, 1990 8:03 PM", df.format(cal)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.fieldDifference(Date, int)' + */ + public void testFieldDifference() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_MONTH, 0); + Date date = cal.getTime(); + cal.add(Calendar.DAY_OF_MONTH, 5); + assertEquals(-5, cal.fieldDifference(date, Calendar.DAY_OF_MONTH)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getTimeZone()' + */ + public void testGetTimeZone() { + Calendar cal = Calendar.getInstance(); + assertNotNull(cal.getTimeZone()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setTimeZone(TimeZone)' + */ + public void testSetTimeZone() { + Calendar cal = Calendar.getInstance(); + TimeZone value1 = cal.getTimeZone(); + String tzn = "PDT".equals(value1.getID()) ? "CST" : "PDT"; + TimeZone value2 = TimeZone.getTimeZone(tzn); + cal.setTimeZone(value2); + TimeZone result = cal.getTimeZone(); + assertNotEqual(value1, result); + assertEquals(value2, result); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setLenient(boolean)' + */ + public void testSetLenient() { + Calendar cal = Calendar.getInstance(); + boolean lenient = cal.isLenient(); + cal.setLenient(!lenient); + assertFalse(lenient == cal.isLenient()); + + // not testing if it has the expected effect + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.isLenient()' + */ + public void testIsLenient() { + // tested by testSetLenient + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setFirstDayOfWeek(int)' + */ + public void testSetFirstDayOfWeek() { + Calendar cal = Calendar.getInstance(); + int firstDay = cal.getFirstDayOfWeek(); + cal.setFirstDayOfWeek(firstDay+1); + assertEquals(firstDay+1, cal.getFirstDayOfWeek()); + + // don't test functionality + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getFirstDayOfWeek()' + */ + public void testGetFirstDayOfWeek() { + // tested by testSetFirstDayOfWeek + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.setMinimalDaysInFirstWeek(int)' + */ + public void testSetMinimalDaysInFirstWeek() { + Calendar cal = Calendar.getInstance(); + int firstDay = cal.getMinimalDaysInFirstWeek(); + cal.setMinimalDaysInFirstWeek(firstDay+1); + assertEquals(firstDay+1, cal.getMinimalDaysInFirstWeek()); + + // don't test functionality + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getMinimalDaysInFirstWeek()' + */ + public void testGetMinimalDaysInFirstWeek() { + // tested by testSetMinimalDaysInFirstWeek + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getMinimum(int)' + */ + public void testGetMinimum() { + Calendar cal = Calendar.getInstance(); + assertEquals(1, cal.getMinimum(Calendar.DAY_OF_WEEK)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getMaximum(int)' + */ + public void testGetMaximum() { + Calendar cal = Calendar.getInstance(); + assertEquals(7, cal.getMaximum(Calendar.DAY_OF_WEEK)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getGreatestMinimum(int)' + */ + public void testGetGreatestMinimum() { + Calendar cal = Calendar.getInstance(); + assertEquals(1, cal.getGreatestMinimum(Calendar.DATE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getLeastMaximum(int)' + */ + public void testGetLeastMaximum() { + Calendar cal = Calendar.getInstance(); + assertEquals(28, cal.getLeastMaximum(Calendar.DATE)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getDayOfWeekType(int)' + */ + public void testGetDayOfWeekType() { + Calendar cal = Calendar.getInstance(Locale.US); + assertEquals(Calendar.WEEKDAY, cal.getDayOfWeekType(Calendar.FRIDAY)); + assertEquals(Calendar.WEEKEND, cal.getDayOfWeekType(Calendar.SATURDAY)); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getWeekendTransition(int)' + */ + public void testGetWeekendTransition() { + Calendar cal = Calendar.getInstance(Locale.US); + try { + cal.getWeekendTransition(Calendar.WEEKEND_ONSET); + fail("expected IllegalArgumentException from getWeekendTransition"); + } + catch (UnsupportedOperationException e) { + // ok + } + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.isWeekend(Date)' + */ + public void testIsWeekendDate() { + Calendar cal = Calendar.getInstance(Locale.US); + cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY); + assertTrue(cal.isWeekend(cal.getTime())); + cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); + assertFalse(cal.isWeekend(cal.getTime())); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.isWeekend()' + */ + public void testIsWeekend() { + Calendar cal = Calendar.getInstance(Locale.US); + cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY); + assertTrue(cal.isWeekend()); + cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); + assertFalse(cal.isWeekend()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.clone()' + */ + public void testClone() { + // tested by testHashCode + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.toString()' + */ + public void testToString() { + Calendar cal = Calendar.getInstance(); + assertNotNull(cal.toString()); + } + + /* + * Test method for 'com.ibm.icu.util.Calendar.getType()' + */ + public void testGetType() { + Calendar cal = Calendar.getInstance(Locale.US); + assertEquals("gregorian", cal.getType()); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java index 45725be90c2..a1afd34a424 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java @@ -1,102 +1,102 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import com.ibm.icu.text.CollationKey; -import com.ibm.icu.text.Collator; - -public class CollationKeyTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.text.CollationKey.hashCode()' - */ - public void testHashCode() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - CollationKey k2 = c.getCollationKey("this"); - c.setStrength(Collator.TERTIARY); - CollationKey kn = c.getCollationKey("this"); - testEHCS(k1, k2, kn); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.CollationKey(CollationKey)' - */ - public void testCollationKey() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.compareTo(CollationKey)' - */ - public void testCompareToCollationKey() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - CollationKey k2 = c.getCollationKey("this"); - c.setStrength(Collator.TERTIARY); - CollationKey k3 = c.getCollationKey("this"); - assertTrue(0 == k1.compareTo(k2)); - assertFalse(0 == k1.compareTo(k3)); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.compareTo(Object)' - */ - public void testCompareToObject() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - CollationKey k2 = c.getCollationKey("this"); - assertTrue(0 == k1.compareTo(k2)); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.equals(Object)' - */ - public void testEqualsObject() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - CollationKey k2 = c.getCollationKey("this"); - assertTrue(k1.equals((Object)k2)); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.toString()' - */ - public void testToString() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - assertNotNull(k1.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.getSourceString()' - */ - public void testGetSourceString() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - assertEquals("This", k1.getSourceString()); - } - - /* - * Test method for 'com.ibm.icu.text.CollationKey.toByteArray()' - */ - public void testToByteArray() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey("This"); - byte[] key = k1.toByteArray(); - assertNotNull(key); - assertTrue(0 < key.length); - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import com.ibm.icu.text.CollationKey; +import com.ibm.icu.text.Collator; + +public class CollationKeyTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.text.CollationKey.hashCode()' + */ + public void testHashCode() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + CollationKey k2 = c.getCollationKey("this"); + c.setStrength(Collator.TERTIARY); + CollationKey kn = c.getCollationKey("this"); + testEHCS(k1, k2, kn); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.CollationKey(CollationKey)' + */ + public void testCollationKey() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.compareTo(CollationKey)' + */ + public void testCompareToCollationKey() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + CollationKey k2 = c.getCollationKey("this"); + c.setStrength(Collator.TERTIARY); + CollationKey k3 = c.getCollationKey("this"); + assertTrue(0 == k1.compareTo(k2)); + assertFalse(0 == k1.compareTo(k3)); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.compareTo(Object)' + */ + public void testCompareToObject() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + CollationKey k2 = c.getCollationKey("this"); + assertTrue(0 == k1.compareTo(k2)); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.equals(Object)' + */ + public void testEqualsObject() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + CollationKey k2 = c.getCollationKey("this"); + assertTrue(k1.equals((Object)k2)); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.toString()' + */ + public void testToString() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + assertNotNull(k1.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.getSourceString()' + */ + public void testGetSourceString() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + assertEquals("This", k1.getSourceString()); + } + + /* + * Test method for 'com.ibm.icu.text.CollationKey.toByteArray()' + */ + public void testToByteArray() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey("This"); + byte[] key = k1.toByteArray(); + assertNotNull(key); + assertTrue(0 < key.length); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java index 08349f18cbb..28f003d7cc6 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java @@ -1,205 +1,205 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Locale; - -import com.ibm.icu.text.CollationKey; -import com.ibm.icu.text.Collator; -import com.ibm.icu.util.ULocale; - -public class CollatorTest extends ICUTestCase { - private static final String s1 = "Fu\u0308nf"; // capital F + u + diaresis - private static final String s2 = "fu\u0308nf"; // u + diaresis - private static final String s3 = "f\u00fcnf"; // u-umlaut - private static final String s4 = "fu\u0308\u0316nf"; // u + diaresis above + grave below - private static final String s5 = "fu\u0316\u0308nf"; // u + grave below + diaresis above - - /* - * Test method for 'com.ibm.icu.text.Collator.hashCode()' - */ - public void testHashCode() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.SECONDARY); - Collator c2 = Collator.getInstance(); - c2.setStrength(Collator.SECONDARY); - Collator cn = Collator.getInstance(); - cn.setStrength(Collator.TERTIARY); - testEHCS(c, c2, cn); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.Collator(Collator)' - */ - public void testCollator() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.Collator.setStrength(int)' - */ - public void testSetStrength() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - assertTrue(0 == c.compare(s1, s2)); - c.setStrength(Collator.SECONDARY); - assertTrue(0 == c.compare(s1, s2)); - c.setStrength(Collator.TERTIARY); - assertTrue(0 < c.compare(s1, s2)); - assertTrue(0 == c.compare(s2, s3)); - c.setStrength(Collator.QUATERNARY); - assertTrue(0 > c.compare(s2, s3)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.setDecomposition(int)' - */ - public void testSetDecomposition() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.TERTIARY); - assertTrue(0 != c.compare(s4, s5)); - c.setDecomposition(Collator.IDENTICAL); - assertTrue(0 == c.compare(s4, s5)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getInstance()' - */ - public void testGetInstance() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getInstance(ULocale)' - */ - public void testGetInstanceULocale() { - Collator c = Collator.getInstance(ULocale.GERMANY); - assertNotNull(c); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getInstance(Locale)' - */ - public void testGetInstanceLocale() { - Collator c = Collator.getInstance(Locale.GERMANY); - assertNotNull(c); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getAvailableLocales()' - */ - public void testGetAvailableLocales() { - assertNotNull(Collator.getAvailableLocales()); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getAvailableULocales()' - */ - public void testGetAvailableULocales() { - assertNotNull(Collator.getAvailableULocales()); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getKeywords()' - */ - public void testGetKeywords() { - assertEquals(0, Collator.getKeywords().length); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getKeywordValues(String)' - */ - public void testGetKeywordValues() { - assertEquals(0, Collator.getKeywordValues("").length); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getStrength()' - */ - public void testGetStrength() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - assertEquals(Collator.PRIMARY, c.getStrength()); - c.setStrength(Collator.SECONDARY); - assertEquals(Collator.SECONDARY, c.getStrength()); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getDecomposition()' - */ - public void testGetDecomposition() { - Collator c = Collator.getInstance(); - c.setDecomposition(Collator.CANONICAL_DECOMPOSITION); - assertEquals(Collator.CANONICAL_DECOMPOSITION, c.getDecomposition()); - c.setDecomposition(Collator.NO_DECOMPOSITION); - assertEquals(Collator.NO_DECOMPOSITION, c.getDecomposition()); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.compare(Object, Object)' - */ - public void testCompareObjectObject() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - assertTrue(0 == c.compare((Object)s1, (Object)s2)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.equals(String, String)' - */ - public void testEqualsStringString() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - assertTrue(c.equals(s1, s2)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.compare(String, String)' - */ - public void testCompareStringString() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - assertTrue(0 == c.compare(s1, s2)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.getCollationKey(String)' - */ - public void testGetCollationKey() { - Collator c = Collator.getInstance(); - c.setStrength(Collator.PRIMARY); - CollationKey k1 = c.getCollationKey(s1); - CollationKey k2 = c.getCollationKey(s2); - assertTrue(k1.equals(k2)); - c.setStrength(Collator.TERTIARY); - k1 = c.getCollationKey(s1); - k2 = c.getCollationKey(s2); - assertFalse(k1.equals(k2)); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.toString()' - */ - public void testToString() { - assertNotNull(Collator.getInstance().toString()); - } - - /* - * Test method for 'com.ibm.icu.text.Collator.clone()' - */ - public void testClone() { - // tested above - } - - /* - * Test method for 'com.ibm.icu.text.Collator.equals(Object)' - */ - public void testEqualsObject() { - // tested above - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Locale; + +import com.ibm.icu.text.CollationKey; +import com.ibm.icu.text.Collator; +import com.ibm.icu.util.ULocale; + +public class CollatorTest extends ICUTestCase { + private static final String s1 = "Fu\u0308nf"; // capital F + u + diaresis + private static final String s2 = "fu\u0308nf"; // u + diaresis + private static final String s3 = "f\u00fcnf"; // u-umlaut + private static final String s4 = "fu\u0308\u0316nf"; // u + diaresis above + grave below + private static final String s5 = "fu\u0316\u0308nf"; // u + grave below + diaresis above + + /* + * Test method for 'com.ibm.icu.text.Collator.hashCode()' + */ + public void testHashCode() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.SECONDARY); + Collator c2 = Collator.getInstance(); + c2.setStrength(Collator.SECONDARY); + Collator cn = Collator.getInstance(); + cn.setStrength(Collator.TERTIARY); + testEHCS(c, c2, cn); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.Collator(Collator)' + */ + public void testCollator() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.Collator.setStrength(int)' + */ + public void testSetStrength() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + assertTrue(0 == c.compare(s1, s2)); + c.setStrength(Collator.SECONDARY); + assertTrue(0 == c.compare(s1, s2)); + c.setStrength(Collator.TERTIARY); + assertTrue(0 < c.compare(s1, s2)); + assertTrue(0 == c.compare(s2, s3)); + c.setStrength(Collator.QUATERNARY); + assertTrue(0 > c.compare(s2, s3)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.setDecomposition(int)' + */ + public void testSetDecomposition() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.TERTIARY); + assertTrue(0 != c.compare(s4, s5)); + c.setDecomposition(Collator.IDENTICAL); + assertTrue(0 == c.compare(s4, s5)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getInstance()' + */ + public void testGetInstance() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getInstance(ULocale)' + */ + public void testGetInstanceULocale() { + Collator c = Collator.getInstance(ULocale.GERMANY); + assertNotNull(c); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getInstance(Locale)' + */ + public void testGetInstanceLocale() { + Collator c = Collator.getInstance(Locale.GERMANY); + assertNotNull(c); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getAvailableLocales()' + */ + public void testGetAvailableLocales() { + assertNotNull(Collator.getAvailableLocales()); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getAvailableULocales()' + */ + public void testGetAvailableULocales() { + assertNotNull(Collator.getAvailableULocales()); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getKeywords()' + */ + public void testGetKeywords() { + assertEquals(0, Collator.getKeywords().length); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getKeywordValues(String)' + */ + public void testGetKeywordValues() { + assertEquals(0, Collator.getKeywordValues("").length); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getStrength()' + */ + public void testGetStrength() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + assertEquals(Collator.PRIMARY, c.getStrength()); + c.setStrength(Collator.SECONDARY); + assertEquals(Collator.SECONDARY, c.getStrength()); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getDecomposition()' + */ + public void testGetDecomposition() { + Collator c = Collator.getInstance(); + c.setDecomposition(Collator.CANONICAL_DECOMPOSITION); + assertEquals(Collator.CANONICAL_DECOMPOSITION, c.getDecomposition()); + c.setDecomposition(Collator.NO_DECOMPOSITION); + assertEquals(Collator.NO_DECOMPOSITION, c.getDecomposition()); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.compare(Object, Object)' + */ + public void testCompareObjectObject() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + assertTrue(0 == c.compare((Object)s1, (Object)s2)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.equals(String, String)' + */ + public void testEqualsStringString() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + assertTrue(c.equals(s1, s2)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.compare(String, String)' + */ + public void testCompareStringString() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + assertTrue(0 == c.compare(s1, s2)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.getCollationKey(String)' + */ + public void testGetCollationKey() { + Collator c = Collator.getInstance(); + c.setStrength(Collator.PRIMARY); + CollationKey k1 = c.getCollationKey(s1); + CollationKey k2 = c.getCollationKey(s2); + assertTrue(k1.equals(k2)); + c.setStrength(Collator.TERTIARY); + k1 = c.getCollationKey(s1); + k2 = c.getCollationKey(s2); + assertFalse(k1.equals(k2)); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.toString()' + */ + public void testToString() { + assertNotNull(Collator.getInstance().toString()); + } + + /* + * Test method for 'com.ibm.icu.text.Collator.clone()' + */ + public void testClone() { + // tested above + } + + /* + * Test method for 'com.ibm.icu.text.Collator.equals(Object)' + */ + public void testEqualsObject() { + // tested above + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java index 2021969e0f1..4636e696dcb 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java @@ -1,257 +1,257 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Locale; - -import com.ibm.icu.text.DateFormatSymbols; -import com.ibm.icu.util.ULocale; - -public class DateFormatSymbolsTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.hashCode()' - */ - public void testHashCode() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - DateFormatSymbols dfs2 = new DateFormatSymbols(ULocale.US); - DateFormatSymbols dfsn = new DateFormatSymbols(Locale.US); - dfsn.setAmPmStrings(new String[] { "sw", "xw" }); - testEHCS(dfs, dfs2, dfsn); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(DateFormatSymbols)' - */ - public void testDateFormatSymbolsDateFormatSymbols() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols()' - */ - public void testDateFormatSymbols() { - DateFormatSymbols dfs = new DateFormatSymbols(); - assertNotNull(dfs.getWeekdays()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(Locale)' - */ - public void testDateFormatSymbolsLocale() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getWeekdays()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(ULocale)' - */ - public void testDateFormatSymbolsULocale() { - DateFormatSymbols dfs = new DateFormatSymbols(ULocale.US); - assertNotNull(dfs.getWeekdays()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getEras()' - */ - public void testGetEras() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getEras()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setEras(String[])' - */ - public void testSetEras() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getEras(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setEras(newvalue); - String[] result = dfs.getEras(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getMonths()' - */ - public void testGetMonths() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getMonths()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setMonths(String[])' - */ - public void testSetMonths() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getMonths(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setMonths(newvalue); - String[] result = dfs.getMonths(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortMonths()' - */ - public void testGetShortMonths() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getShortMonths()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortMonths(String[])' - */ - public void testSetShortMonths() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getShortMonths(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setShortMonths(newvalue); - String[] result = dfs.getShortMonths(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getWeekdays()' - */ - public void testGetWeekdays() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getShortMonths()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setWeekdays(String[])' - */ - public void testSetWeekdays() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getWeekdays(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setWeekdays(newvalue); - String[] result = dfs.getWeekdays(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortWeekdays()' - */ - public void testGetShortWeekdays() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getShortWeekdays()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortWeekdays(String[])' - */ - public void testSetShortWeekdays() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getShortWeekdays(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setShortWeekdays(newvalue); - String[] result = dfs.getShortWeekdays(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getAmPmStrings()' - */ - public void testGetAmPmStrings() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getAmPmStrings()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setAmPmStrings(String[])' - */ - public void testSetAmPmStrings() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[] oldvalue = dfs.getAmPmStrings(); - String[] newvalue = (String[])oldvalue.clone(); - newvalue[0] = newvalue[0] + "!"; - dfs.setAmPmStrings(newvalue); - String[] result = dfs.getAmPmStrings(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getZoneStrings()' - */ - public void testGetZoneStrings() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getZoneStrings()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setZoneStrings(String[][])' - */ - public void testSetZoneStrings() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String[][] oldvalue = dfs.getZoneStrings(); - String[][] newvalue = (String[][])cloneComplex(oldvalue); - newvalue[0][0] = newvalue[0][0] + "!"; - dfs.setZoneStrings(newvalue); - String[][] result = dfs.getZoneStrings(); - assertArraysNotEqual(oldvalue, result); - assertArraysEqual(newvalue, result); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.getLocalPatternChars()' - */ - public void testGetLocalPatternChars() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.getLocalPatternChars()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.setLocalPatternChars(String)' - */ - public void testSetLocalPatternChars() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - String pat = dfs.getLocalPatternChars(); - StringBuffer buf = new StringBuffer(pat); - buf.setCharAt(0, (char)(pat.charAt(0) + 1)); - String pat2 = buf.toString(); - dfs.setLocalPatternChars(pat2); - String pat3 = dfs.getLocalPatternChars(); - assertNotEqual(pat, pat2); - assertEquals(pat2, pat3); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.toString()' - */ - public void testToString() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - assertNotNull(dfs.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.clone()' - */ - public void testClone() { - // tested by testHashCode - } - - /* - * Test method for 'com.ibm.icu.text.DateFormatSymbols.equals(Object)' - */ - public void testEqualsObject() { - // tested by testHashCode - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Locale; + +import com.ibm.icu.text.DateFormatSymbols; +import com.ibm.icu.util.ULocale; + +public class DateFormatSymbolsTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.hashCode()' + */ + public void testHashCode() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + DateFormatSymbols dfs2 = new DateFormatSymbols(ULocale.US); + DateFormatSymbols dfsn = new DateFormatSymbols(Locale.US); + dfsn.setAmPmStrings(new String[] { "sw", "xw" }); + testEHCS(dfs, dfs2, dfsn); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(DateFormatSymbols)' + */ + public void testDateFormatSymbolsDateFormatSymbols() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols()' + */ + public void testDateFormatSymbols() { + DateFormatSymbols dfs = new DateFormatSymbols(); + assertNotNull(dfs.getWeekdays()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(Locale)' + */ + public void testDateFormatSymbolsLocale() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getWeekdays()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(ULocale)' + */ + public void testDateFormatSymbolsULocale() { + DateFormatSymbols dfs = new DateFormatSymbols(ULocale.US); + assertNotNull(dfs.getWeekdays()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getEras()' + */ + public void testGetEras() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getEras()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setEras(String[])' + */ + public void testSetEras() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getEras(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setEras(newvalue); + String[] result = dfs.getEras(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getMonths()' + */ + public void testGetMonths() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getMonths()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setMonths(String[])' + */ + public void testSetMonths() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getMonths(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setMonths(newvalue); + String[] result = dfs.getMonths(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortMonths()' + */ + public void testGetShortMonths() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getShortMonths()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortMonths(String[])' + */ + public void testSetShortMonths() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getShortMonths(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setShortMonths(newvalue); + String[] result = dfs.getShortMonths(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getWeekdays()' + */ + public void testGetWeekdays() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getShortMonths()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setWeekdays(String[])' + */ + public void testSetWeekdays() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getWeekdays(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setWeekdays(newvalue); + String[] result = dfs.getWeekdays(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortWeekdays()' + */ + public void testGetShortWeekdays() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getShortWeekdays()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortWeekdays(String[])' + */ + public void testSetShortWeekdays() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getShortWeekdays(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setShortWeekdays(newvalue); + String[] result = dfs.getShortWeekdays(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getAmPmStrings()' + */ + public void testGetAmPmStrings() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getAmPmStrings()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setAmPmStrings(String[])' + */ + public void testSetAmPmStrings() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[] oldvalue = dfs.getAmPmStrings(); + String[] newvalue = (String[])oldvalue.clone(); + newvalue[0] = newvalue[0] + "!"; + dfs.setAmPmStrings(newvalue); + String[] result = dfs.getAmPmStrings(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getZoneStrings()' + */ + public void testGetZoneStrings() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getZoneStrings()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setZoneStrings(String[][])' + */ + public void testSetZoneStrings() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String[][] oldvalue = dfs.getZoneStrings(); + String[][] newvalue = (String[][])cloneComplex(oldvalue); + newvalue[0][0] = newvalue[0][0] + "!"; + dfs.setZoneStrings(newvalue); + String[][] result = dfs.getZoneStrings(); + assertArraysNotEqual(oldvalue, result); + assertArraysEqual(newvalue, result); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.getLocalPatternChars()' + */ + public void testGetLocalPatternChars() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.getLocalPatternChars()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.setLocalPatternChars(String)' + */ + public void testSetLocalPatternChars() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + String pat = dfs.getLocalPatternChars(); + StringBuffer buf = new StringBuffer(pat); + buf.setCharAt(0, (char)(pat.charAt(0) + 1)); + String pat2 = buf.toString(); + dfs.setLocalPatternChars(pat2); + String pat3 = dfs.getLocalPatternChars(); + assertNotEqual(pat, pat2); + assertEquals(pat2, pat3); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.toString()' + */ + public void testToString() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + assertNotNull(dfs.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.clone()' + */ + public void testClone() { + // tested by testHashCode + } + + /* + * Test method for 'com.ibm.icu.text.DateFormatSymbols.equals(Object)' + */ + public void testEqualsObject() { + // tested by testHashCode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java index 37f5559f0aa..1e1e7e9815b 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java @@ -1,454 +1,454 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.text.FieldPosition; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; - -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.text.NumberFormat; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -public class DateFormatTest extends ICUTestCase { - private Calendar aCal; - private Calendar anESTCal; - private Date aDate; - private String aDateString; - private String aTimeString; - private String anESTTimeString; - private String aDateTimeString; - private String aShortDateTimeString; - private String aDefaultESTDateTimeString; - private DateFormat aDF; - private StringBuffer aBuf; - private FieldPosition anFP; - private FieldPosition anFPField; - - private static int YEAR_POS_START = 8; - private static int YEAR_POS_END = 12; - - protected void setUp() throws Exception { - super.setUp(); - - java.util.GregorianCalendar gcal = new java.util.GregorianCalendar(); - gcal.clear(); - gcal.set(java.util.GregorianCalendar.YEAR, 1990); - gcal.set(java.util.GregorianCalendar.MONTH, java.util.GregorianCalendar.DECEMBER); - gcal.set(java.util.GregorianCalendar.DATE, 17); - gcal.set(java.util.GregorianCalendar.HOUR, 5); - gcal.set(java.util.GregorianCalendar.MINUTE, 17); - aCal = new Calendar(gcal); - anESTCal = Calendar.getInstance(); - anESTCal.setTimeZone(TimeZone.getTimeZone("EST")); - aDate = gcal.getTime(); - aDateString = "Dec 17, 1990"; // medium -- the default - aTimeString = "5:17:00 AM"; // medium - anESTTimeString = "8:17:00 AM"; - aDateTimeString = "Dec 17, 1990 5:17:00 AM"; // medium, medium - aDefaultESTDateTimeString = "Dec 17, 1990 8:17 AM"; // medium, short -- the default - aShortDateTimeString = "12/17/90 5:17 AM"; // short, short - aDF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US); - aBuf = new StringBuffer(); - anFP = new FieldPosition(DateFormat.YEAR_FIELD); - anFPField = new FieldPosition(DateFormat.Field.YEAR); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.hashCode()' - */ - public final void testHashCode() { - DateFormat df = DateFormat.getInstance(); - DateFormat eq = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); - testEHCS(df, eq, aDF); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.DateFormat(DateFormat)' - */ - public final void testDateFormat() { - DateFormat df = new DateFormat(java.text.DateFormat.getInstance()); - assertEquals(DateFormat.getInstance(), df); - } - - private void assertEqualDateString(StringBuffer buf) { - assertEquals(aDateTimeString, buf.toString()); - } - - private void assertEqualDateString(String str) { - assertEquals(aDateTimeString, str); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.format(Object, StringBuffer, FieldPosition)' - */ - public final void testFormatObjectStringBufferFieldPosition() { - assertEqualDateString(aDF.format(aDate, aBuf, anFP)); - assertEquals(YEAR_POS_START, anFP.getBeginIndex()); - assertEquals(YEAR_POS_END, anFP.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.format(Calendar, StringBuffer, FieldPosition)' - */ - public final void testFormatCalendarStringBufferFieldPosition() { - assertEqualDateString(aDF.format(aCal, aBuf, anFP)); - assertEquals(YEAR_POS_START, anFP.getBeginIndex()); - assertEquals(YEAR_POS_END, anFP.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.format(Date, StringBuffer, FieldPosition)' - */ - public final void testFormatDateStringBufferFieldPosition() { - assertEqualDateString(aDF.format(aDate, aBuf, anFPField)); - assertEquals(YEAR_POS_START, anFPField.getBeginIndex()); - assertEquals(YEAR_POS_END, anFPField.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.format(Date)' - */ - public final void testFormatDate() { - assertEqualDateString(aDF.format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.parse(String)' - */ - public final void testParseString() throws Exception { - assertEquals(aDate, aDF.parse(aDateTimeString)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.parse(String, Calendar, ParsePosition)' - */ - public final void testParseStringCalendarParsePosition() { - aDF.parse(aDateTimeString, aCal, new ParsePosition(0)); - assertEquals(aDate, aCal.getTime()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.parse(String, ParsePosition)' - */ - public final void testParseStringParsePosition() { - assertEquals(aDate, aDF.parse(aDateTimeString, new ParsePosition(0))); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.parseObject(String, ParsePosition)' - */ - public final void testParseObjectStringParsePosition() { - assertEquals(aDate, aDF.parseObject(aDateTimeString, new ParsePosition(0))); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance()' - */ - public final void testGetTimeInstance() { - assertEquals(aTimeString, DateFormat.getTimeInstance().format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int)' - */ - public final void testGetTimeInstanceInt() { - assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, Locale)' - */ - public final void testGetTimeInstanceIntLocale() { - assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, ULocale)' - */ - public final void testGetTimeInstanceIntULocale() { - assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance()' - */ - public final void testGetDateInstance() { - assertEquals(aDateString, DateFormat.getDateInstance().format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int)' - */ - public final void testGetDateInstanceInt() { - assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, Locale)' - */ - public final void testGetDateInstanceIntLocale() { - assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, ULocale)' - */ - public final void testGetDateInstanceIntULocale() { - assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance()' - */ - public final void testGetDateTimeInstance() { - assertEquals(aDateTimeString, DateFormat.getDateTimeInstance().format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int)' - */ - public final void testGetDateTimeInstanceIntInt() { - assertEquals(aDateTimeString, - DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, Locale)' - */ - public final void testGetDateTimeInstanceIntIntLocale() { - assertEquals(aDateTimeString, - DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, ULocale)' - */ - public final void testGetDateTimeInstanceIntIntULocale() { - assertEquals(aDateTimeString, - DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getInstance()' - */ - public final void testGetInstance() { - assertEquals(aShortDateTimeString, DateFormat.getInstance().format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getAvailableLocales()' - */ - public final void testGetAvailableLocales() { - Locale[] locales = DateFormat.getAvailableLocales(); - if (ICUTestCase.testingWrapper) { - ICUTestCase.assertArraysEqual(java.text.DateFormat.getAvailableLocales(), locales); - } else { - assertNotNull(locales); - } - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.setCalendar(Calendar)' - */ - public final void testSetCalendar() { - Calendar cal = Calendar.getInstance(); - cal.setTimeZone(TimeZone.getTimeZone("EST")); - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); - df.setCalendar(cal); - assertEquals("8:17 AM", df.format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getCalendar()' - */ - public final void testGetCalendar() { - Calendar cal = Calendar.getInstance(); - cal.setTimeZone(TimeZone.getTimeZone("EST")); - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); - df.setCalendar(cal); - assertEquals(cal, df.getCalendar()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.setNumberFormat(NumberFormat)' - */ - public final void testSetNumberFormat() { - // no easy way to test effect of setting the number format - NumberFormat nf = NumberFormat.getInstance(); - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); - df.setNumberFormat(nf); - // note, can't actually USE the dateformat since it changes the calendar - assertEquals(nf, df.getNumberFormat()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getNumberFormat()' - */ - public final void testGetNumberFormat() { - // see testSetNumberFormat - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.setTimeZone(TimeZone)' - */ - public final void testSetTimeZone() { - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); - TimeZone tz = TimeZone.getTimeZone("EST"); - df.setTimeZone(tz); - assertEquals("8:17 AM", df.format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeZone()' - */ - public final void testGetTimeZone() { - DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); - TimeZone tz = TimeZone.getTimeZone("EST"); - df.setTimeZone(tz); - assertEquals(tz, df.getTimeZone()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.setLenient(boolean)' - */ - public final void testSetLenient() throws Exception { - DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); - df.parse("2/31/90"); // succeeds, default is lenient - df.setLenient(false); - try { - df.parse("2/31/90"); - throw new Exception("strict parse should have failed"); - } - catch (ParseException e) { - // ok, this is what we expect - } - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.isLenient()' - */ - public final void testIsLenient() { - DateFormat df = DateFormat.getInstance(); - assertTrue(df.isLenient()); - df.setLenient(false); - assertFalse(df.isLenient()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, Locale)' - */ - public final void testGetDateInstanceCalendarIntLocale() { - assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, ULocale)' - */ - public final void testGetDateInstanceCalendarIntULocale() { - assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, Locale)' - */ - public final void testGetTimeInstanceCalendarIntLocale() { - assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, ULocale)' - */ - public final void testGetTimeInstanceCalendarIntULocale() { - assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, Locale)' - */ - public final void testGetDateTimeInstanceCalendarIntIntLocale() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, ULocale)' - */ - public final void testGetDateTimeInstanceCalendarIntIntULocale() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, Locale)' - */ - public final void testGetInstanceCalendarLocale() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, Locale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, ULocale)' - */ - public final void testGetInstanceCalendarULocale() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, ULocale.US).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar)' - */ - public final void testGetInstanceCalendar() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int)' - */ - public final void testGetDateInstanceCalendarInt() { - assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int)' - */ - public final void testGetTimeInstanceCalendarInt() { - assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int)' - */ - public final void testGetDateTimeInstanceCalendarIntInt() { - assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT).format(aDate)); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.toString()' - */ - public final void testToString() { - assertNotNull(aDF.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.clone()' - */ - public final void testClone() { - // see testHashCode - } - - /* - * Test method for 'com.ibm.icu.text.DateFormat.equals(Object)' - */ - public final void testEqualsObject() { - // see testHashCode - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.text.FieldPosition; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +public class DateFormatTest extends ICUTestCase { + private Calendar aCal; + private Calendar anESTCal; + private Date aDate; + private String aDateString; + private String aTimeString; + private String anESTTimeString; + private String aDateTimeString; + private String aShortDateTimeString; + private String aDefaultESTDateTimeString; + private DateFormat aDF; + private StringBuffer aBuf; + private FieldPosition anFP; + private FieldPosition anFPField; + + private static int YEAR_POS_START = 8; + private static int YEAR_POS_END = 12; + + protected void setUp() throws Exception { + super.setUp(); + + java.util.GregorianCalendar gcal = new java.util.GregorianCalendar(); + gcal.clear(); + gcal.set(java.util.GregorianCalendar.YEAR, 1990); + gcal.set(java.util.GregorianCalendar.MONTH, java.util.GregorianCalendar.DECEMBER); + gcal.set(java.util.GregorianCalendar.DATE, 17); + gcal.set(java.util.GregorianCalendar.HOUR, 5); + gcal.set(java.util.GregorianCalendar.MINUTE, 17); + aCal = new Calendar(gcal); + anESTCal = Calendar.getInstance(); + anESTCal.setTimeZone(TimeZone.getTimeZone("EST")); + aDate = gcal.getTime(); + aDateString = "Dec 17, 1990"; // medium -- the default + aTimeString = "5:17:00 AM"; // medium + anESTTimeString = "8:17:00 AM"; + aDateTimeString = "Dec 17, 1990 5:17:00 AM"; // medium, medium + aDefaultESTDateTimeString = "Dec 17, 1990 8:17 AM"; // medium, short -- the default + aShortDateTimeString = "12/17/90 5:17 AM"; // short, short + aDF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US); + aBuf = new StringBuffer(); + anFP = new FieldPosition(DateFormat.YEAR_FIELD); + anFPField = new FieldPosition(DateFormat.Field.YEAR); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.hashCode()' + */ + public final void testHashCode() { + DateFormat df = DateFormat.getInstance(); + DateFormat eq = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); + testEHCS(df, eq, aDF); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.DateFormat(DateFormat)' + */ + public final void testDateFormat() { + DateFormat df = new DateFormat(java.text.DateFormat.getInstance()); + assertEquals(DateFormat.getInstance(), df); + } + + private void assertEqualDateString(StringBuffer buf) { + assertEquals(aDateTimeString, buf.toString()); + } + + private void assertEqualDateString(String str) { + assertEquals(aDateTimeString, str); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.format(Object, StringBuffer, FieldPosition)' + */ + public final void testFormatObjectStringBufferFieldPosition() { + assertEqualDateString(aDF.format(aDate, aBuf, anFP)); + assertEquals(YEAR_POS_START, anFP.getBeginIndex()); + assertEquals(YEAR_POS_END, anFP.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.format(Calendar, StringBuffer, FieldPosition)' + */ + public final void testFormatCalendarStringBufferFieldPosition() { + assertEqualDateString(aDF.format(aCal, aBuf, anFP)); + assertEquals(YEAR_POS_START, anFP.getBeginIndex()); + assertEquals(YEAR_POS_END, anFP.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.format(Date, StringBuffer, FieldPosition)' + */ + public final void testFormatDateStringBufferFieldPosition() { + assertEqualDateString(aDF.format(aDate, aBuf, anFPField)); + assertEquals(YEAR_POS_START, anFPField.getBeginIndex()); + assertEquals(YEAR_POS_END, anFPField.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.format(Date)' + */ + public final void testFormatDate() { + assertEqualDateString(aDF.format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.parse(String)' + */ + public final void testParseString() throws Exception { + assertEquals(aDate, aDF.parse(aDateTimeString)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.parse(String, Calendar, ParsePosition)' + */ + public final void testParseStringCalendarParsePosition() { + aDF.parse(aDateTimeString, aCal, new ParsePosition(0)); + assertEquals(aDate, aCal.getTime()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.parse(String, ParsePosition)' + */ + public final void testParseStringParsePosition() { + assertEquals(aDate, aDF.parse(aDateTimeString, new ParsePosition(0))); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.parseObject(String, ParsePosition)' + */ + public final void testParseObjectStringParsePosition() { + assertEquals(aDate, aDF.parseObject(aDateTimeString, new ParsePosition(0))); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance()' + */ + public final void testGetTimeInstance() { + assertEquals(aTimeString, DateFormat.getTimeInstance().format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int)' + */ + public final void testGetTimeInstanceInt() { + assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, Locale)' + */ + public final void testGetTimeInstanceIntLocale() { + assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, ULocale)' + */ + public final void testGetTimeInstanceIntULocale() { + assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance()' + */ + public final void testGetDateInstance() { + assertEquals(aDateString, DateFormat.getDateInstance().format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int)' + */ + public final void testGetDateInstanceInt() { + assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, Locale)' + */ + public final void testGetDateInstanceIntLocale() { + assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, ULocale)' + */ + public final void testGetDateInstanceIntULocale() { + assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance()' + */ + public final void testGetDateTimeInstance() { + assertEquals(aDateTimeString, DateFormat.getDateTimeInstance().format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int)' + */ + public final void testGetDateTimeInstanceIntInt() { + assertEquals(aDateTimeString, + DateFormat.getDateTimeInstance( + DateFormat.MEDIUM, DateFormat.MEDIUM).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, Locale)' + */ + public final void testGetDateTimeInstanceIntIntLocale() { + assertEquals(aDateTimeString, + DateFormat.getDateTimeInstance( + DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, ULocale)' + */ + public final void testGetDateTimeInstanceIntIntULocale() { + assertEquals(aDateTimeString, + DateFormat.getDateTimeInstance( + DateFormat.MEDIUM, DateFormat.MEDIUM, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getInstance()' + */ + public final void testGetInstance() { + assertEquals(aShortDateTimeString, DateFormat.getInstance().format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getAvailableLocales()' + */ + public final void testGetAvailableLocales() { + Locale[] locales = DateFormat.getAvailableLocales(); + if (ICUTestCase.testingWrapper) { + ICUTestCase.assertArraysEqual(java.text.DateFormat.getAvailableLocales(), locales); + } else { + assertNotNull(locales); + } + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.setCalendar(Calendar)' + */ + public final void testSetCalendar() { + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("EST")); + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + df.setCalendar(cal); + assertEquals("8:17 AM", df.format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getCalendar()' + */ + public final void testGetCalendar() { + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("EST")); + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + df.setCalendar(cal); + assertEquals(cal, df.getCalendar()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.setNumberFormat(NumberFormat)' + */ + public final void testSetNumberFormat() { + // no easy way to test effect of setting the number format + NumberFormat nf = NumberFormat.getInstance(); + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + df.setNumberFormat(nf); + // note, can't actually USE the dateformat since it changes the calendar + assertEquals(nf, df.getNumberFormat()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getNumberFormat()' + */ + public final void testGetNumberFormat() { + // see testSetNumberFormat + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.setTimeZone(TimeZone)' + */ + public final void testSetTimeZone() { + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + TimeZone tz = TimeZone.getTimeZone("EST"); + df.setTimeZone(tz); + assertEquals("8:17 AM", df.format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeZone()' + */ + public final void testGetTimeZone() { + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + TimeZone tz = TimeZone.getTimeZone("EST"); + df.setTimeZone(tz); + assertEquals(tz, df.getTimeZone()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.setLenient(boolean)' + */ + public final void testSetLenient() throws Exception { + DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); + df.parse("2/31/90"); // succeeds, default is lenient + df.setLenient(false); + try { + df.parse("2/31/90"); + throw new Exception("strict parse should have failed"); + } + catch (ParseException e) { + // ok, this is what we expect + } + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.isLenient()' + */ + public final void testIsLenient() { + DateFormat df = DateFormat.getInstance(); + assertTrue(df.isLenient()); + df.setLenient(false); + assertFalse(df.isLenient()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, Locale)' + */ + public final void testGetDateInstanceCalendarIntLocale() { + assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, ULocale)' + */ + public final void testGetDateInstanceCalendarIntULocale() { + assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, Locale)' + */ + public final void testGetTimeInstanceCalendarIntLocale() { + assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, ULocale)' + */ + public final void testGetTimeInstanceCalendarIntULocale() { + assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, Locale)' + */ + public final void testGetDateTimeInstanceCalendarIntIntLocale() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, ULocale)' + */ + public final void testGetDateTimeInstanceCalendarIntIntULocale() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, Locale)' + */ + public final void testGetInstanceCalendarLocale() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, Locale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, ULocale)' + */ + public final void testGetInstanceCalendarULocale() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, ULocale.US).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar)' + */ + public final void testGetInstanceCalendar() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int)' + */ + public final void testGetDateInstanceCalendarInt() { + assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int)' + */ + public final void testGetTimeInstanceCalendarInt() { + assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int)' + */ + public final void testGetDateTimeInstanceCalendarIntInt() { + assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT).format(aDate)); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.toString()' + */ + public final void testToString() { + assertNotNull(aDF.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.clone()' + */ + public final void testClone() { + // see testHashCode + } + + /* + * Test method for 'com.ibm.icu.text.DateFormat.equals(Object)' + */ + public final void testEqualsObject() { + // see testHashCode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java index 9cc7ce6837d..22779a5b2b0 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java @@ -1,344 +1,344 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Locale; - -import com.ibm.icu.text.DecimalFormatSymbols; -import com.ibm.icu.util.ULocale; - -public class DecimalFormatSymbolsTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.hashCode()' - */ - public void testHashCode() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); - DecimalFormatSymbols dfs2 = new DecimalFormatSymbols(ULocale.US); - DecimalFormatSymbols dfsn = new DecimalFormatSymbols(Locale.FRANCE); - testEHCS(dfs, dfs2, dfsn); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(DecimalFormatSymbols)' - */ - public void testDecimalFormatSymbolsDecimalFormatSymbols() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols()' - */ - public void testDecimalFormatSymbols() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(); - assertTrue(-1 != dfs.getDecimalSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(Locale)' - */ - public void testDecimalFormatSymbolsLocale() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); - assertTrue(-1 != dfs.getDecimalSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(ULocale)' - */ - public void testDecimalFormatSymbolsULocale() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertTrue(-1 != dfs.getDecimalSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getZeroDigit()' - */ - public void testGetZeroDigit() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('0', dfs.getZeroDigit()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setZeroDigit(char)' - */ - public void testSetZeroDigit() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getZeroDigit(); - char value1 = (char)(value + 1); - dfs.setZeroDigit(value1); - char result = dfs.getZeroDigit(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getGroupingSeparator()' - */ - public void testGetGroupingSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals(',', dfs.getGroupingSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setGroupingSeparator(char)' - */ - public void testSetGroupingSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getGroupingSeparator(); - char value1 = (char)(value + 1); - dfs.setGroupingSeparator(value1); - char result = dfs.getGroupingSeparator(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDecimalSeparator()' - */ - public void testGetDecimalSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('.', dfs.getDecimalSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDecimalSeparator(char)' - */ - public void testSetDecimalSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getDecimalSeparator(); - char value1 = (char)(value + 1); - dfs.setDecimalSeparator(value1); - char result = dfs.getDecimalSeparator(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPerMill()' - */ - public void testGetPerMill() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('\u2030', dfs.getPerMill()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPerMill(char)' - */ - public void testSetPerMill() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getPerMill(); - char value1 = (char)(value + 1); - dfs.setPerMill(value1); - char result = dfs.getPerMill(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPercent()' - */ - public void testGetPercent() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('%', dfs.getPercent()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPercent(char)' - */ - public void testSetPercent() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getPercent(); - char value1 = (char)(value + 1); - dfs.setPercent(value1); - char result = dfs.getPercent(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDigit()' - */ - public void testGetDigit() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('#', dfs.getDigit()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDigit(char)' - */ - public void testSetDigit() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getDigit(); - char value1 = (char)(value + 1); - dfs.setDigit(value1); - char result = dfs.getDigit(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPatternSeparator()' - */ - public void testGetPatternSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals(';', dfs.getPatternSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPatternSeparator(char)' - */ - public void testSetPatternSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getPatternSeparator(); - char value1 = (char)(value + 1); - dfs.setPatternSeparator(value1); - char result = dfs.getPatternSeparator(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInfinity()' - */ - public void testGetInfinity() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals("\u221e", dfs.getInfinity()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInfinity(String)' - */ - public void testSetInfinity() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - String value = dfs.getInfinity(); - String value1 = value + "!"; - dfs.setInfinity(value1); - String result = dfs.getInfinity(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getNaN()' - */ - public void testGetNaN() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertNotNull(dfs.getNaN()); // java returns missing character??? - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setNaN(String)' - */ - public void testSetNaN() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - String value = dfs.getNaN(); - String value1 = value + "!"; - dfs.setNaN(value1); - String result = dfs.getNaN(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMinusSign()' - */ - public void testGetMinusSign() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('-', dfs.getMinusSign()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMinusSign(char)' - */ - public void testSetMinusSign() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getMinusSign(); - char value1 = (char)(value + 1); - dfs.setMinusSign(value1); - char result = dfs.getMinusSign(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getCurrencySymbol()' - */ - public void testGetCurrencySymbol() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals("$", dfs.getCurrencySymbol()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setCurrencySymbol(String)' - */ - public void testSetCurrencySymbol() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - String value = dfs.getCurrencySymbol(); - String value1 = value + "!"; - dfs.setCurrencySymbol(value1); - String result = dfs.getCurrencySymbol(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInternationalCurrencySymbol()' - */ - public void testGetInternationalCurrencySymbol() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals("USD", dfs.getInternationalCurrencySymbol()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInternationalCurrencySymbol(String)' - */ - public void testSetInternationalCurrencySymbol() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - String value = dfs.getInternationalCurrencySymbol(); - String value1 = value + "!"; - dfs.setInternationalCurrencySymbol(value1); - String result = dfs.getInternationalCurrencySymbol(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMonetaryDecimalSeparator()' - */ - public void testGetMonetaryDecimalSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - assertEquals('.', dfs.getMonetaryDecimalSeparator()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMonetaryDecimalSeparator(char)' - */ - public void testSetMonetaryDecimalSeparator() { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); - char value = dfs.getMonetaryDecimalSeparator(); - char value1 = (char)(value + 1); - dfs.setMonetaryDecimalSeparator(value1); - char result = dfs.getMonetaryDecimalSeparator(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.clone()' - */ - public void testClone() { - // tested in testHashcode - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.equals(Object)' - */ - public void testEqualsObject() { - // tested in testHashcode - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Locale; + +import com.ibm.icu.text.DecimalFormatSymbols; +import com.ibm.icu.util.ULocale; + +public class DecimalFormatSymbolsTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.hashCode()' + */ + public void testHashCode() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); + DecimalFormatSymbols dfs2 = new DecimalFormatSymbols(ULocale.US); + DecimalFormatSymbols dfsn = new DecimalFormatSymbols(Locale.FRANCE); + testEHCS(dfs, dfs2, dfsn); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(DecimalFormatSymbols)' + */ + public void testDecimalFormatSymbolsDecimalFormatSymbols() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols()' + */ + public void testDecimalFormatSymbols() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(); + assertTrue(-1 != dfs.getDecimalSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(Locale)' + */ + public void testDecimalFormatSymbolsLocale() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); + assertTrue(-1 != dfs.getDecimalSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(ULocale)' + */ + public void testDecimalFormatSymbolsULocale() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertTrue(-1 != dfs.getDecimalSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getZeroDigit()' + */ + public void testGetZeroDigit() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('0', dfs.getZeroDigit()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setZeroDigit(char)' + */ + public void testSetZeroDigit() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getZeroDigit(); + char value1 = (char)(value + 1); + dfs.setZeroDigit(value1); + char result = dfs.getZeroDigit(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getGroupingSeparator()' + */ + public void testGetGroupingSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals(',', dfs.getGroupingSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setGroupingSeparator(char)' + */ + public void testSetGroupingSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getGroupingSeparator(); + char value1 = (char)(value + 1); + dfs.setGroupingSeparator(value1); + char result = dfs.getGroupingSeparator(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDecimalSeparator()' + */ + public void testGetDecimalSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('.', dfs.getDecimalSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDecimalSeparator(char)' + */ + public void testSetDecimalSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getDecimalSeparator(); + char value1 = (char)(value + 1); + dfs.setDecimalSeparator(value1); + char result = dfs.getDecimalSeparator(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPerMill()' + */ + public void testGetPerMill() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('\u2030', dfs.getPerMill()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPerMill(char)' + */ + public void testSetPerMill() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getPerMill(); + char value1 = (char)(value + 1); + dfs.setPerMill(value1); + char result = dfs.getPerMill(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPercent()' + */ + public void testGetPercent() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('%', dfs.getPercent()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPercent(char)' + */ + public void testSetPercent() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getPercent(); + char value1 = (char)(value + 1); + dfs.setPercent(value1); + char result = dfs.getPercent(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDigit()' + */ + public void testGetDigit() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('#', dfs.getDigit()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDigit(char)' + */ + public void testSetDigit() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getDigit(); + char value1 = (char)(value + 1); + dfs.setDigit(value1); + char result = dfs.getDigit(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPatternSeparator()' + */ + public void testGetPatternSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals(';', dfs.getPatternSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPatternSeparator(char)' + */ + public void testSetPatternSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getPatternSeparator(); + char value1 = (char)(value + 1); + dfs.setPatternSeparator(value1); + char result = dfs.getPatternSeparator(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInfinity()' + */ + public void testGetInfinity() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals("\u221e", dfs.getInfinity()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInfinity(String)' + */ + public void testSetInfinity() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + String value = dfs.getInfinity(); + String value1 = value + "!"; + dfs.setInfinity(value1); + String result = dfs.getInfinity(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getNaN()' + */ + public void testGetNaN() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertNotNull(dfs.getNaN()); // java returns missing character??? + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setNaN(String)' + */ + public void testSetNaN() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + String value = dfs.getNaN(); + String value1 = value + "!"; + dfs.setNaN(value1); + String result = dfs.getNaN(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMinusSign()' + */ + public void testGetMinusSign() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('-', dfs.getMinusSign()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMinusSign(char)' + */ + public void testSetMinusSign() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getMinusSign(); + char value1 = (char)(value + 1); + dfs.setMinusSign(value1); + char result = dfs.getMinusSign(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getCurrencySymbol()' + */ + public void testGetCurrencySymbol() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals("$", dfs.getCurrencySymbol()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setCurrencySymbol(String)' + */ + public void testSetCurrencySymbol() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + String value = dfs.getCurrencySymbol(); + String value1 = value + "!"; + dfs.setCurrencySymbol(value1); + String result = dfs.getCurrencySymbol(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInternationalCurrencySymbol()' + */ + public void testGetInternationalCurrencySymbol() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals("USD", dfs.getInternationalCurrencySymbol()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInternationalCurrencySymbol(String)' + */ + public void testSetInternationalCurrencySymbol() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + String value = dfs.getInternationalCurrencySymbol(); + String value1 = value + "!"; + dfs.setInternationalCurrencySymbol(value1); + String result = dfs.getInternationalCurrencySymbol(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMonetaryDecimalSeparator()' + */ + public void testGetMonetaryDecimalSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + assertEquals('.', dfs.getMonetaryDecimalSeparator()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMonetaryDecimalSeparator(char)' + */ + public void testSetMonetaryDecimalSeparator() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US); + char value = dfs.getMonetaryDecimalSeparator(); + char value1 = (char)(value + 1); + dfs.setMonetaryDecimalSeparator(value1); + char result = dfs.getMonetaryDecimalSeparator(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.clone()' + */ + public void testClone() { + // tested in testHashcode + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.equals(Object)' + */ + public void testEqualsObject() { + // tested in testHashcode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java index 23cc40d6f52..b438e2fb95f 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java @@ -1,242 +1,242 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Locale; - -import com.ibm.icu.text.DecimalFormat; -import com.ibm.icu.text.DecimalFormatSymbols; - -public class DecimalFormatTest extends ICUTestCase { - private static final long lmax = Long.MAX_VALUE; - private static final double dsmall = 23.33; - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.clone()' - */ - public void testClone() { - DecimalFormat df = new DecimalFormat("#,#0.00"); - DecimalFormat df2 = new DecimalFormat("#,#0.00"); - DecimalFormat dfn = new DecimalFormat("#,#0.00"); - dfn.setNegativePrefix(dfn.getNegativePrefix() + '!'); - testEHCS(df, df2, dfn); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(DecimalFormat)' - */ - public void testDecimalFormatDecimalFormat() { - // tested implicitly - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat()' - */ - public void testDecimalFormat() { - DecimalFormat df = new DecimalFormat(); - assertEquals("9,223,372,036,854,775,807", df.format(lmax)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String)' - */ - public void testDecimalFormatString() { - DecimalFormat df = new DecimalFormat("#,##0.000"); - assertEquals("23.330", df.format(dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String, DecimalFormatSymbols)' - */ - public void testDecimalFormatStringDecimalFormatSymbols() { - DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE); - DecimalFormat df = new DecimalFormat("#,##0.000", sym); - assertEquals("23,330", df.format(dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getDecimalFormatSymbols()' - */ - public void testGetDecimalFormatSymbols() { - DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE); - DecimalFormat df = new DecimalFormat("#,##0.000", sym); - assertEquals(sym, df.getDecimalFormatSymbols()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols)' - */ - public void testSetDecimalFormatSymbols() { - DecimalFormat df = new DecimalFormat(); - df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.FRANCE)); - assertEquals("23,33", df.format(dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getPositivePrefix()' - */ - public void testGetPositivePrefix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - assertEquals("+", df.getPositivePrefix()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setPositivePrefix(String)' - */ - public void testSetPositivePrefix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - df.setPositivePrefix("?"); - assertEquals("?23.3", df.format(dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativePrefix()' - */ - public void testGetNegativePrefix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - assertEquals("-", df.getNegativePrefix()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativePrefix(String)' - */ - public void testSetNegativePrefix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - df.setNegativePrefix("~"); - assertEquals("~23.3", df.format(-dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getPositiveSuffix()' - */ - public void testGetPositiveSuffix() { - DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~"); - assertEquals("**", df.getPositiveSuffix()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setPositiveSuffix(String)' - */ - public void testSetPositiveSuffix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - df.setPositiveSuffix("**"); - assertEquals("+23.3**", df.format(dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativeSuffix()' - */ - public void testGetNegativeSuffix() { - DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~"); - assertEquals("~~", df.getNegativeSuffix()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativeSuffix(String)' - */ - public void testSetNegativeSuffix() { - DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); - df.setNegativeSuffix("~~"); - assertEquals("-23.3~~", df.format(-dsmall)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getMultiplier()' - */ - public void testGetMultiplier() { - DecimalFormat df = new DecimalFormat("%000"); - df.setMultiplier(1000); - assertEquals(1000, df.getMultiplier()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setMultiplier(int)' - */ - public void testSetMultiplier() { - DecimalFormat df = new DecimalFormat("%000"); - assertEquals("%012", df.format(.123)); - df.setMultiplier(1000); - assertEquals("%123", df.format(.123)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.getGroupingSize()' - */ - public void testGetGroupingSize() { - DecimalFormat df = new DecimalFormat("#,#0.#"); - assertEquals(2, df.getGroupingSize()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setGroupingSize(int)' - */ - public void testSetGroupingSize() { - DecimalFormat df = new DecimalFormat("#,##0.##"); - assertEquals("1,234,567.89", df.format(1234567.89)); - df.setGroupingSize(2); - assertEquals("1,23,45,67.89", df.format(1234567.89)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.isDecimalSeparatorAlwaysShown()' - */ - public void testIsDecimalSeparatorAlwaysShown() { - DecimalFormat df = new DecimalFormat("#.#"); - df.setDecimalSeparatorAlwaysShown(false); - assertEquals("1", df.format(1)); - assertEquals("1.2", df.format(1.2)); - df.setDecimalSeparatorAlwaysShown(true); - assertEquals("1.", df.format(1)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalSeparatorAlwaysShown(boolean)' - */ - public void testSetDecimalSeparatorAlwaysShown() { - DecimalFormat df = new DecimalFormat("#.#"); - df.setDecimalSeparatorAlwaysShown(false); - assertFalse(df.isDecimalSeparatorAlwaysShown()); - df.setDecimalSeparatorAlwaysShown(true); - assertTrue(df.isDecimalSeparatorAlwaysShown()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.toPattern()' - */ - public void testToPattern() { - DecimalFormat df = new DecimalFormat("#,##0.##"); - assertEquals("#,##0.##", df.toPattern()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.toLocalizedPattern()' - */ - public void testToLocalizedPattern() { - DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE)); - assertEquals("#,##0.##", df.toPattern()); - assertEquals("#\u00a0##0,##", df.toLocalizedPattern()); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.applyPattern(String)' - */ - public void testApplyPattern() { - DecimalFormat df = new DecimalFormat("#,##0.##"); - df.applyPattern("#,0.#"); - assertEquals("1,2,3.4", df.format(123.4)); - } - - /* - * Test method for 'com.ibm.icu.text.DecimalFormat.applyLocalizedPattern(String)' - */ - public void testApplyLocalizedPattern() { - DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE)); - df.applyLocalizedPattern("#\u00a00,#"); - assertEquals("1\u00a02\u00a03,4", df.format(123.4)); - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Locale; + +import com.ibm.icu.text.DecimalFormat; +import com.ibm.icu.text.DecimalFormatSymbols; + +public class DecimalFormatTest extends ICUTestCase { + private static final long lmax = Long.MAX_VALUE; + private static final double dsmall = 23.33; + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.clone()' + */ + public void testClone() { + DecimalFormat df = new DecimalFormat("#,#0.00"); + DecimalFormat df2 = new DecimalFormat("#,#0.00"); + DecimalFormat dfn = new DecimalFormat("#,#0.00"); + dfn.setNegativePrefix(dfn.getNegativePrefix() + '!'); + testEHCS(df, df2, dfn); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(DecimalFormat)' + */ + public void testDecimalFormatDecimalFormat() { + // tested implicitly + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat()' + */ + public void testDecimalFormat() { + DecimalFormat df = new DecimalFormat(); + assertEquals("9,223,372,036,854,775,807", df.format(lmax)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String)' + */ + public void testDecimalFormatString() { + DecimalFormat df = new DecimalFormat("#,##0.000"); + assertEquals("23.330", df.format(dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String, DecimalFormatSymbols)' + */ + public void testDecimalFormatStringDecimalFormatSymbols() { + DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE); + DecimalFormat df = new DecimalFormat("#,##0.000", sym); + assertEquals("23,330", df.format(dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getDecimalFormatSymbols()' + */ + public void testGetDecimalFormatSymbols() { + DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE); + DecimalFormat df = new DecimalFormat("#,##0.000", sym); + assertEquals(sym, df.getDecimalFormatSymbols()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols)' + */ + public void testSetDecimalFormatSymbols() { + DecimalFormat df = new DecimalFormat(); + df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.FRANCE)); + assertEquals("23,33", df.format(dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getPositivePrefix()' + */ + public void testGetPositivePrefix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + assertEquals("+", df.getPositivePrefix()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setPositivePrefix(String)' + */ + public void testSetPositivePrefix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + df.setPositivePrefix("?"); + assertEquals("?23.3", df.format(dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativePrefix()' + */ + public void testGetNegativePrefix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + assertEquals("-", df.getNegativePrefix()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativePrefix(String)' + */ + public void testSetNegativePrefix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + df.setNegativePrefix("~"); + assertEquals("~23.3", df.format(-dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getPositiveSuffix()' + */ + public void testGetPositiveSuffix() { + DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~"); + assertEquals("**", df.getPositiveSuffix()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setPositiveSuffix(String)' + */ + public void testSetPositiveSuffix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + df.setPositiveSuffix("**"); + assertEquals("+23.3**", df.format(dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativeSuffix()' + */ + public void testGetNegativeSuffix() { + DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~"); + assertEquals("~~", df.getNegativeSuffix()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativeSuffix(String)' + */ + public void testSetNegativeSuffix() { + DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#"); + df.setNegativeSuffix("~~"); + assertEquals("-23.3~~", df.format(-dsmall)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getMultiplier()' + */ + public void testGetMultiplier() { + DecimalFormat df = new DecimalFormat("%000"); + df.setMultiplier(1000); + assertEquals(1000, df.getMultiplier()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setMultiplier(int)' + */ + public void testSetMultiplier() { + DecimalFormat df = new DecimalFormat("%000"); + assertEquals("%012", df.format(.123)); + df.setMultiplier(1000); + assertEquals("%123", df.format(.123)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.getGroupingSize()' + */ + public void testGetGroupingSize() { + DecimalFormat df = new DecimalFormat("#,#0.#"); + assertEquals(2, df.getGroupingSize()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setGroupingSize(int)' + */ + public void testSetGroupingSize() { + DecimalFormat df = new DecimalFormat("#,##0.##"); + assertEquals("1,234,567.89", df.format(1234567.89)); + df.setGroupingSize(2); + assertEquals("1,23,45,67.89", df.format(1234567.89)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.isDecimalSeparatorAlwaysShown()' + */ + public void testIsDecimalSeparatorAlwaysShown() { + DecimalFormat df = new DecimalFormat("#.#"); + df.setDecimalSeparatorAlwaysShown(false); + assertEquals("1", df.format(1)); + assertEquals("1.2", df.format(1.2)); + df.setDecimalSeparatorAlwaysShown(true); + assertEquals("1.", df.format(1)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalSeparatorAlwaysShown(boolean)' + */ + public void testSetDecimalSeparatorAlwaysShown() { + DecimalFormat df = new DecimalFormat("#.#"); + df.setDecimalSeparatorAlwaysShown(false); + assertFalse(df.isDecimalSeparatorAlwaysShown()); + df.setDecimalSeparatorAlwaysShown(true); + assertTrue(df.isDecimalSeparatorAlwaysShown()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.toPattern()' + */ + public void testToPattern() { + DecimalFormat df = new DecimalFormat("#,##0.##"); + assertEquals("#,##0.##", df.toPattern()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.toLocalizedPattern()' + */ + public void testToLocalizedPattern() { + DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE)); + assertEquals("#,##0.##", df.toPattern()); + assertEquals("#\u00a0##0,##", df.toLocalizedPattern()); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.applyPattern(String)' + */ + public void testApplyPattern() { + DecimalFormat df = new DecimalFormat("#,##0.##"); + df.applyPattern("#,0.#"); + assertEquals("1,2,3.4", df.format(123.4)); + } + + /* + * Test method for 'com.ibm.icu.text.DecimalFormat.applyLocalizedPattern(String)' + */ + public void testApplyLocalizedPattern() { + DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE)); + df.applyLocalizedPattern("#\u00a00,#"); + assertEquals("1\u00a02\u00a03,4", df.format(123.4)); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java index 2e3de90a441..617fc14709c 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java @@ -1,286 +1,286 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Externalizable; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Locale; - -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -import junit.framework.TestCase; - -/** - * Implement boilerplate tests. - * Currently there is only one method, testEHCS, which tests equals, hashCode, - * clone, and serialization. - */ -public abstract class ICUTestCase extends TestCase { - private static final Object[] EMPTY_ARGS = {}; - private static final Class[] EMPTY_CLASSES = {}; - - private static final Locale oldLocale = Locale.getDefault(); - private static final ULocale oldULocale = ULocale.getDefault(); - private static final java.util.TimeZone oldJTimeZone = java.util.TimeZone.getDefault(); - private static final TimeZone oldITimeZone = TimeZone.getDefault(); - - // TODO: what's the best way to check this? - public static final boolean testingWrapper = true; - - protected void setUp() throws Exception { - super.setUp(); - Locale.setDefault(Locale.US); - ULocale.setDefault(ULocale.US); - java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("PST")); - TimeZone.setDefault(TimeZone.getTimeZone("PST")); - } - - protected void tearDown() throws Exception { - ULocale.setDefault(oldULocale); - Locale.setDefault(oldLocale); - TimeZone.setDefault(oldITimeZone); - java.util.TimeZone.setDefault(oldJTimeZone); - super.tearDown(); - } - - private static final Object test = new Object(); - - /** - * Assert that two objects are _not_ equal. Curiously missing from Assert. - * @param lhs an object to test, may be null - * @param rhs an object to test, may be null - */ - public static void assertNotEqual(Object lhs, Object rhs) { - if (lhs == null) { - if (rhs == null) fail("null equals null"); - } else { - if (lhs.equals(rhs)) { - fail(lhs.toString() + " equals " + rhs); - } - } - } - - public static void assertNotEqual(long lhs, long rhs) { - if (lhs == rhs) { - fail("values are equal: " + lhs); - } - } - - /** - * Test whether equality, hashCode, clone, and serialization work as expected. - * Equals(Object) is assumed to return false (not throw an exception) if passed - * null or an object of an incompatible class. - * Hashcodes must be equal iff the two objects compare equal. No attempt is made to - * evaluate the quality of the hashcode distribution, so (in particular) degenerate - * hashcode implementations will pass this test. - * Clone will be tested if the method "clone" is public on the class of obj. - * It is assumed to return an object that compares equal to obj. - * Serialization will be tested if object implements Serializable or Externalizable. - * It is assumed the serialized/deserialized object compares equal to obj. - * @param obj the object to test - * @param eq an object that should compare equal to, but is not the same as, obj. - * it should be assignable to the class of obj. - * @param neq a non-null object that should not compare equal to obj. - * it should be assignable to the class of obj. - */ - public static void testEHCS(Object obj, Object eq, Object neq) { - if (obj == null || eq == null || neq == null) { - throw new NullPointerException(); - } - Class cls = obj.getClass(); - if (!(cls.isAssignableFrom(eq.getClass()) && cls.isAssignableFrom(neq.getClass()))) { - throw new IllegalArgumentException("unassignable classes"); - } - - // reflexive - assertEquals(obj, obj); - - // should return false, not throw exception - assertNotEqual(obj, test); - assertNotEqual(obj, null); - - // commutative - assertEquals(obj, eq); - assertEquals(eq, obj); - - assertNotEqual(obj, neq); - assertNotEqual(neq, obj); - - // equal objects MUST have equal hashes, unequal objects MAY have equal hashes - assertEquals(obj.hashCode(), eq.hashCode()); - - Object clone = null; - try { - // look for public clone method and call it if available - Method method_clone = cls.getMethod("clone", EMPTY_CLASSES); - clone = method_clone.invoke(obj, EMPTY_ARGS); - assertNotNull(clone); - } - catch(NoSuchMethodException e) { - // ok - } - catch(InvocationTargetException e) { - // ok - } - catch(IllegalAccessException e) { - // ok - } - - if (clone != null) { - assertEquals(obj, clone); - assertEquals(clone, obj); - } - - if (obj instanceof Serializable || obj instanceof Externalizable) { - Object ser = null; - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(clone); - oos.close(); - - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bis); - ser = ois.readObject(); - ois.close(); - } - catch(IOException e) { - System.err.println(e.getMessage()); - throw new RuntimeException(e); - } - catch(ClassNotFoundException e) { - System.err.println(e.getMessage()); - throw new RuntimeException(e); - } - - if (ser != null) { - assertEquals(obj, ser); - assertEquals(ser, obj); - assertEquals(obj.hashCode(), ser.hashCode()); - } - } - } - - /** - * Fail if the arrays are not equal. To be equal, the arrays must - * be the same length, and each element in the left array must compare - * equal to the corresponding element of the right array. - * Also fails if one of the objects is not an array. - * @param lhs the left array - * @param rhs the right array - */ - public static void assertArraysEqual(Object lhs, Object rhs) { - Class lcls = lhs.getClass(); - Class rcls = rhs.getClass(); - if (!(lcls.isArray() && rcls.isArray())) { - fail("objects are not arrays"); - } - String result = arraysAreEqual(lhs, rhs); - if (result != null) { - fail(result); - } - } - - /** - * Fail if the arrays are equal. Also fails if one or the other - * argument is not an array. - * @param lhs the left array - * @param rhs the right array - */ - public static void assertArraysNotEqual(Object lhs, Object rhs) { - Class lcls = lhs.getClass(); - Class rcls = rhs.getClass(); - if (!(lcls.isArray() && rcls.isArray())) { - fail("objects are not arrays"); - } - String result = arraysAreEqual(lhs, rhs); - if (result == null) { - fail("arrays are equal"); - } - } - - // slow but general - private static String arraysAreEqual(Object lhsa, Object rhsa) { - int lhsl = Array.getLength(lhsa); - int rhsl = Array.getLength(rhsa); - if (lhsl != rhsl) { - return "length " + lhsl + " != " + rhsl; - } - boolean lhsaA = lhsa.getClass().getComponentType().isArray(); - boolean rhsaA = rhsa.getClass().getComponentType().isArray(); - if (lhsaA != rhsaA) { - return (lhsaA ? "" : "non-") + "array != " + (rhsaA ? "" : "non-") + "array"; - } - for (int i = 0; i < lhsl; ++i) { - Object lhse = Array.get(lhsa, i); - Object rhse = Array.get(rhsa, i); - if (lhse == null) { - if (rhse != null) { - return "null != " + rhse; - } - } else { - if (lhsaA) { - String result = arraysAreEqual(lhse, rhse); - if (result != null) { - if (result.charAt(0) != '[') { - result = " " + result; - } - return "[" + i + "]" + result; - } - } else { - if (!lhse.equals(rhse)) { - return lhse.toString() + " != " + rhse; - } - } - } - } - return null; - } - - // much more painful and slow than it should be... partly because of the - // oddness of clone, partly because arrays don't provide a Method for - // 'clone' despite the fact that they implement it and make it public. - public static Object cloneComplex(Object obj) { - Object result = null; - if (obj != null) { - Class cls = obj.getClass(); - if (cls.isArray()) { - int len = Array.getLength(obj); - Class typ = cls.getComponentType(); - result = Array.newInstance(typ, len); - boolean prim = typ.isPrimitive(); - for (int i = 0; i < len; ++i) { - Object elem = Array.get(obj, i); - Array.set(result, i, prim ? elem : cloneComplex(elem)); - } - } else { - result = obj; // default - try { - Method cloneM = cls.getMethod("clone", EMPTY_CLASSES); - result = cloneM.invoke(obj, EMPTY_ARGS); - } - catch (NoSuchMethodException e) { - } - catch (IllegalAccessException e) { - } - catch (InvocationTargetException e) { - } - } - } - return result; - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Locale; + +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +import junit.framework.TestCase; + +/** + * Implement boilerplate tests. + * Currently there is only one method, testEHCS, which tests equals, hashCode, + * clone, and serialization. + */ +public abstract class ICUTestCase extends TestCase { + private static final Object[] EMPTY_ARGS = {}; + private static final Class[] EMPTY_CLASSES = {}; + + private static final Locale oldLocale = Locale.getDefault(); + private static final ULocale oldULocale = ULocale.getDefault(); + private static final java.util.TimeZone oldJTimeZone = java.util.TimeZone.getDefault(); + private static final TimeZone oldITimeZone = TimeZone.getDefault(); + + // TODO: what's the best way to check this? + public static final boolean testingWrapper = true; + + protected void setUp() throws Exception { + super.setUp(); + Locale.setDefault(Locale.US); + ULocale.setDefault(ULocale.US); + java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("PST")); + } + + protected void tearDown() throws Exception { + ULocale.setDefault(oldULocale); + Locale.setDefault(oldLocale); + TimeZone.setDefault(oldITimeZone); + java.util.TimeZone.setDefault(oldJTimeZone); + super.tearDown(); + } + + private static final Object test = new Object(); + + /** + * Assert that two objects are _not_ equal. Curiously missing from Assert. + * @param lhs an object to test, may be null + * @param rhs an object to test, may be null + */ + public static void assertNotEqual(Object lhs, Object rhs) { + if (lhs == null) { + if (rhs == null) fail("null equals null"); + } else { + if (lhs.equals(rhs)) { + fail(lhs.toString() + " equals " + rhs); + } + } + } + + public static void assertNotEqual(long lhs, long rhs) { + if (lhs == rhs) { + fail("values are equal: " + lhs); + } + } + + /** + * Test whether equality, hashCode, clone, and serialization work as expected. + * Equals(Object) is assumed to return false (not throw an exception) if passed + * null or an object of an incompatible class. + * Hashcodes must be equal iff the two objects compare equal. No attempt is made to + * evaluate the quality of the hashcode distribution, so (in particular) degenerate + * hashcode implementations will pass this test. + * Clone will be tested if the method "clone" is public on the class of obj. + * It is assumed to return an object that compares equal to obj. + * Serialization will be tested if object implements Serializable or Externalizable. + * It is assumed the serialized/deserialized object compares equal to obj. + * @param obj the object to test + * @param eq an object that should compare equal to, but is not the same as, obj. + * it should be assignable to the class of obj. + * @param neq a non-null object that should not compare equal to obj. + * it should be assignable to the class of obj. + */ + public static void testEHCS(Object obj, Object eq, Object neq) { + if (obj == null || eq == null || neq == null) { + throw new NullPointerException(); + } + Class cls = obj.getClass(); + if (!(cls.isAssignableFrom(eq.getClass()) && cls.isAssignableFrom(neq.getClass()))) { + throw new IllegalArgumentException("unassignable classes"); + } + + // reflexive + assertEquals(obj, obj); + + // should return false, not throw exception + assertNotEqual(obj, test); + assertNotEqual(obj, null); + + // commutative + assertEquals(obj, eq); + assertEquals(eq, obj); + + assertNotEqual(obj, neq); + assertNotEqual(neq, obj); + + // equal objects MUST have equal hashes, unequal objects MAY have equal hashes + assertEquals(obj.hashCode(), eq.hashCode()); + + Object clone = null; + try { + // look for public clone method and call it if available + Method method_clone = cls.getMethod("clone", EMPTY_CLASSES); + clone = method_clone.invoke(obj, EMPTY_ARGS); + assertNotNull(clone); + } + catch(NoSuchMethodException e) { + // ok + } + catch(InvocationTargetException e) { + // ok + } + catch(IllegalAccessException e) { + // ok + } + + if (clone != null) { + assertEquals(obj, clone); + assertEquals(clone, obj); + } + + if (obj instanceof Serializable || obj instanceof Externalizable) { + Object ser = null; + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(clone); + oos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + ser = ois.readObject(); + ois.close(); + } + catch(IOException e) { + System.err.println(e.getMessage()); + throw new RuntimeException(e); + } + catch(ClassNotFoundException e) { + System.err.println(e.getMessage()); + throw new RuntimeException(e); + } + + if (ser != null) { + assertEquals(obj, ser); + assertEquals(ser, obj); + assertEquals(obj.hashCode(), ser.hashCode()); + } + } + } + + /** + * Fail if the arrays are not equal. To be equal, the arrays must + * be the same length, and each element in the left array must compare + * equal to the corresponding element of the right array. + * Also fails if one of the objects is not an array. + * @param lhs the left array + * @param rhs the right array + */ + public static void assertArraysEqual(Object lhs, Object rhs) { + Class lcls = lhs.getClass(); + Class rcls = rhs.getClass(); + if (!(lcls.isArray() && rcls.isArray())) { + fail("objects are not arrays"); + } + String result = arraysAreEqual(lhs, rhs); + if (result != null) { + fail(result); + } + } + + /** + * Fail if the arrays are equal. Also fails if one or the other + * argument is not an array. + * @param lhs the left array + * @param rhs the right array + */ + public static void assertArraysNotEqual(Object lhs, Object rhs) { + Class lcls = lhs.getClass(); + Class rcls = rhs.getClass(); + if (!(lcls.isArray() && rcls.isArray())) { + fail("objects are not arrays"); + } + String result = arraysAreEqual(lhs, rhs); + if (result == null) { + fail("arrays are equal"); + } + } + + // slow but general + private static String arraysAreEqual(Object lhsa, Object rhsa) { + int lhsl = Array.getLength(lhsa); + int rhsl = Array.getLength(rhsa); + if (lhsl != rhsl) { + return "length " + lhsl + " != " + rhsl; + } + boolean lhsaA = lhsa.getClass().getComponentType().isArray(); + boolean rhsaA = rhsa.getClass().getComponentType().isArray(); + if (lhsaA != rhsaA) { + return (lhsaA ? "" : "non-") + "array != " + (rhsaA ? "" : "non-") + "array"; + } + for (int i = 0; i < lhsl; ++i) { + Object lhse = Array.get(lhsa, i); + Object rhse = Array.get(rhsa, i); + if (lhse == null) { + if (rhse != null) { + return "null != " + rhse; + } + } else { + if (lhsaA) { + String result = arraysAreEqual(lhse, rhse); + if (result != null) { + if (result.charAt(0) != '[') { + result = " " + result; + } + return "[" + i + "]" + result; + } + } else { + if (!lhse.equals(rhse)) { + return lhse.toString() + " != " + rhse; + } + } + } + } + return null; + } + + // much more painful and slow than it should be... partly because of the + // oddness of clone, partly because arrays don't provide a Method for + // 'clone' despite the fact that they implement it and make it public. + public static Object cloneComplex(Object obj) { + Object result = null; + if (obj != null) { + Class cls = obj.getClass(); + if (cls.isArray()) { + int len = Array.getLength(obj); + Class typ = cls.getComponentType(); + result = Array.newInstance(typ, len); + boolean prim = typ.isPrimitive(); + for (int i = 0; i < len; ++i) { + Object elem = Array.get(obj, i); + Array.set(result, i, prim ? elem : cloneComplex(elem)); + } + } else { + result = obj; // default + try { + Method cloneM = cls.getMethod("clone", EMPTY_CLASSES); + result = cloneM.invoke(obj, EMPTY_ARGS); + } + catch (NoSuchMethodException e) { + } + catch (IllegalAccessException e) { + } + catch (InvocationTargetException e) { + } + } + } + return result; + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java index 7f269fae9aa..9947214313e 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java @@ -1,307 +1,307 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.tests; - -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; - -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.text.MessageFormat; -import com.ibm.icu.text.NumberFormat; -import com.ibm.icu.util.ULocale; - -public class MessageFormatTest extends ICUTestCase { - private final String pattern = "Deleted {0,number} files at {1,time,short} on {1,date}."; - private final String altPattern = "Deleted {0, number } files at {1, time, short} on {1, date}."; - private final Date date = new Date(716698890835L); - private final Number num = new Long(3456); - private final Object[] args = { num, date }; - private final Date dateOnly = new Date(716626800000L); - private final String englishTarget = "Deleted 3,456 files at 8:01 PM on Sep 16, 1992."; - private final String germanTarget = "Deleted 3.456 files at 20:01 on 16.09.1992."; - private final String modifiedTarget = "Deleted 3,456 files at 8:01:30 PM PDT on Sep 16, 1992."; - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.hashCode()' - */ - public void testHashCode() { - MessageFormat mf = new MessageFormat(pattern); - MessageFormat eq = new MessageFormat(altPattern); - MessageFormat ne = new MessageFormat("Deleted (0, number, currency} files at {1, time} on {1, date}."); - testEHCS(mf, eq, ne); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(MessageFormat)' - */ - public void testMessageFormatMessageFormat() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String)' - */ - public void testMessageFormatString() { - MessageFormat mf = new MessageFormat(pattern); - assertEquals(englishTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, Locale)' - */ - public void testMessageFormatStringLocale() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - assertEquals(englishTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, ULocale)' - */ - public void testMessageFormatStringULocale() { - MessageFormat mf = new MessageFormat(pattern, ULocale.US); - assertEquals(englishTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(Locale)' - */ - public void testSetLocaleLocale() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setLocale(Locale.GERMANY); - mf.applyPattern(pattern); - assertEquals(germanTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(ULocale)' - */ - public void testSetLocaleULocale() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setLocale(ULocale.GERMANY); - mf.applyPattern(pattern); - assertEquals(germanTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.getLocale()' - */ - public void testGetLocale() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setLocale(Locale.GERMANY); - assertEquals(Locale.GERMANY, mf.getLocale()); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.getULocale()' - */ - public void testGetULocale() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setLocale(ULocale.GERMANY); - assertEquals(ULocale.GERMANY, mf.getULocale()); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.applyPattern(String)' - */ - public void testApplyPattern() { - MessageFormat mf = new MessageFormat("foo"); - mf.applyPattern(pattern); - assertEquals(englishTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.toPattern()' - */ - public void testToPattern() { - MessageFormat mf = new MessageFormat(altPattern); - assertEquals(pattern, mf.toPattern()); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setFormatsByArgumentIndex(Format[])' - public void testSetFormatsByArgumentIndex() { - // this api is broken. if the same argument is used twice with two different - // formats, this can't be used, since it sets only one format per argument. - MessageFormat mf = new MessageFormat(pattern, Locale.US); - Format[] formats = { - NumberFormat.getIntegerInstance(), - DateFormat.getTimeInstance(DateFormat.SHORT), - DateFormat.getDateInstance(), - }; - mf.setFormatsByArgumentIndex(formats); - assertEquals(brokenButConformantTarget, mf.format(args)); - } - */ - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setFormats(Format[])' - */ - public void testSetFormats() { - // this api, while it has the problem that the order of formats depends - // on the order in the string, at least lets you set all the formats. - - MessageFormat mf = new MessageFormat(pattern, Locale.US); - Format[] formats = { - NumberFormat.getIntegerInstance(), - DateFormat.getTimeInstance(DateFormat.SHORT), - DateFormat.getDateInstance(), - }; - mf.setFormats(formats); - assertEquals(englishTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setFormatByArgumentIndex(int, Format)' - public void testSetFormatByArgumentIndex() { - // same problem, once you set a format for an argument, you've set all of them - - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setFormatByArgumentIndex(1, DateFormat.getTimeInstance(DateFormat.SHORT)); - assertEquals(brokenButConformantTarget, mf.format(args)); - - } - */ - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.setFormat(int, Format)' - */ - public void testSetFormat() { - // and ok again - MessageFormat mf = new MessageFormat(pattern, Locale.US); - mf.setFormat(1, DateFormat.getTimeInstance(DateFormat.LONG)); - assertEquals(modifiedTarget, mf.format(args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.getFormatsByArgumentIndex()' - public void testGetFormatsByArgumentIndex() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - Format[] formats = mf.getFormatsByArgumentIndex(); - NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); - assertEquals(formats[0], nf); - DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US); - assertEquals(formats[1], df); - } - */ - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.getFormats()' - */ - public void testGetFormats() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - Format[] formats = mf.getFormats(); - NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); - assertEquals(formats[0], nf); - DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US); - assertEquals(formats[1], tf); - DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US); - assertEquals(formats[2], df); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.format(Object[], StringBuffer, FieldPosition)' - */ - public void testFormatObjectArrayStringBufferFieldPosition() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(0); - mf.format(args, buf, fp); - assertEquals(englishTarget, buf.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.format(String, Object[])' - */ - public void testFormatStringObjectArray() { - assertEquals(englishTarget, MessageFormat.format(pattern, args)); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.format(Object, StringBuffer, FieldPosition)' - */ - public void testFormatObjectStringBufferFieldPosition() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(0); - mf.format((Object)args, buf, fp); - assertEquals(englishTarget, buf.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.parse(String, ParsePosition)' - */ - public void testParseStringParsePosition() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - ParsePosition pp = new ParsePosition(1); - Object[] result = mf.parse("!" + englishTarget, pp); - assertEquals(num, result[0]); - assertEquals(dateOnly, result[1]); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.parse(String)' - */ - public void testParseString() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - try { - Object[] result = mf.parse(englishTarget); - assertEquals(num, result[0]); - assertEquals(dateOnly, result[1]); - } - catch (ParseException e) { - fail(e.getMessage()); - } - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.parseObject(String, ParsePosition)' - */ - public void testParseObjectStringParsePosition() { - MessageFormat mf = new MessageFormat(pattern, Locale.US); - ParsePosition pp = new ParsePosition(0); - Object result = mf.parseObject(englishTarget, pp); - assertEquals(num, ((Object[])result)[0]); - assertEquals(dateOnly, ((Object[])result)[1]); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.autoQuoteApostrophe(String)' - */ - public void testAutoQuoteApostrophe() { - String str = "Let's meet at {1,time,h 'o'' clock'} at l'Orange Bleue"; - String pat = MessageFormat.autoQuoteApostrophe(str); - MessageFormat mf = new MessageFormat(pat, Locale.US); - String result = mf.format(args); - assertEquals("Let's meet at 8 o' clock at l'Orange Bleue", result); - assertEquals("Let''s meet at {1,time,h 'o'' clock'} at l''Orange Bleue", pat); - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.clone()' - */ - public void testClone() { - // tested already in testHashcode - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.equals(Object)' - */ - public void testEqualsObject() { - // tested already in testHashcode - } - - /* - * Test method for 'com.ibm.icu.text.MessageFormat.toString()' - */ - public void testToString() { - // no need to test - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.tests; + +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.text.MessageFormat; +import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.util.ULocale; + +public class MessageFormatTest extends ICUTestCase { + private final String pattern = "Deleted {0,number} files at {1,time,short} on {1,date}."; + private final String altPattern = "Deleted {0, number } files at {1, time, short} on {1, date}."; + private final Date date = new Date(716698890835L); + private final Number num = new Long(3456); + private final Object[] args = { num, date }; + private final Date dateOnly = new Date(716626800000L); + private final String englishTarget = "Deleted 3,456 files at 8:01 PM on Sep 16, 1992."; + private final String germanTarget = "Deleted 3.456 files at 20:01 on 16.09.1992."; + private final String modifiedTarget = "Deleted 3,456 files at 8:01:30 PM PDT on Sep 16, 1992."; + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.hashCode()' + */ + public void testHashCode() { + MessageFormat mf = new MessageFormat(pattern); + MessageFormat eq = new MessageFormat(altPattern); + MessageFormat ne = new MessageFormat("Deleted (0, number, currency} files at {1, time} on {1, date}."); + testEHCS(mf, eq, ne); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(MessageFormat)' + */ + public void testMessageFormatMessageFormat() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String)' + */ + public void testMessageFormatString() { + MessageFormat mf = new MessageFormat(pattern); + assertEquals(englishTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, Locale)' + */ + public void testMessageFormatStringLocale() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + assertEquals(englishTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, ULocale)' + */ + public void testMessageFormatStringULocale() { + MessageFormat mf = new MessageFormat(pattern, ULocale.US); + assertEquals(englishTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(Locale)' + */ + public void testSetLocaleLocale() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setLocale(Locale.GERMANY); + mf.applyPattern(pattern); + assertEquals(germanTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(ULocale)' + */ + public void testSetLocaleULocale() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setLocale(ULocale.GERMANY); + mf.applyPattern(pattern); + assertEquals(germanTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.getLocale()' + */ + public void testGetLocale() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setLocale(Locale.GERMANY); + assertEquals(Locale.GERMANY, mf.getLocale()); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.getULocale()' + */ + public void testGetULocale() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setLocale(ULocale.GERMANY); + assertEquals(ULocale.GERMANY, mf.getULocale()); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.applyPattern(String)' + */ + public void testApplyPattern() { + MessageFormat mf = new MessageFormat("foo"); + mf.applyPattern(pattern); + assertEquals(englishTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.toPattern()' + */ + public void testToPattern() { + MessageFormat mf = new MessageFormat(altPattern); + assertEquals(pattern, mf.toPattern()); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setFormatsByArgumentIndex(Format[])' + public void testSetFormatsByArgumentIndex() { + // this api is broken. if the same argument is used twice with two different + // formats, this can't be used, since it sets only one format per argument. + MessageFormat mf = new MessageFormat(pattern, Locale.US); + Format[] formats = { + NumberFormat.getIntegerInstance(), + DateFormat.getTimeInstance(DateFormat.SHORT), + DateFormat.getDateInstance(), + }; + mf.setFormatsByArgumentIndex(formats); + assertEquals(brokenButConformantTarget, mf.format(args)); + } + */ + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setFormats(Format[])' + */ + public void testSetFormats() { + // this api, while it has the problem that the order of formats depends + // on the order in the string, at least lets you set all the formats. + + MessageFormat mf = new MessageFormat(pattern, Locale.US); + Format[] formats = { + NumberFormat.getIntegerInstance(), + DateFormat.getTimeInstance(DateFormat.SHORT), + DateFormat.getDateInstance(), + }; + mf.setFormats(formats); + assertEquals(englishTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setFormatByArgumentIndex(int, Format)' + public void testSetFormatByArgumentIndex() { + // same problem, once you set a format for an argument, you've set all of them + + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setFormatByArgumentIndex(1, DateFormat.getTimeInstance(DateFormat.SHORT)); + assertEquals(brokenButConformantTarget, mf.format(args)); + + } + */ + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.setFormat(int, Format)' + */ + public void testSetFormat() { + // and ok again + MessageFormat mf = new MessageFormat(pattern, Locale.US); + mf.setFormat(1, DateFormat.getTimeInstance(DateFormat.LONG)); + assertEquals(modifiedTarget, mf.format(args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.getFormatsByArgumentIndex()' + public void testGetFormatsByArgumentIndex() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + Format[] formats = mf.getFormatsByArgumentIndex(); + NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); + assertEquals(formats[0], nf); + DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US); + assertEquals(formats[1], df); + } + */ + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.getFormats()' + */ + public void testGetFormats() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + Format[] formats = mf.getFormats(); + NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); + assertEquals(formats[0], nf); + DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US); + assertEquals(formats[1], tf); + DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US); + assertEquals(formats[2], df); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.format(Object[], StringBuffer, FieldPosition)' + */ + public void testFormatObjectArrayStringBufferFieldPosition() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(0); + mf.format(args, buf, fp); + assertEquals(englishTarget, buf.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.format(String, Object[])' + */ + public void testFormatStringObjectArray() { + assertEquals(englishTarget, MessageFormat.format(pattern, args)); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.format(Object, StringBuffer, FieldPosition)' + */ + public void testFormatObjectStringBufferFieldPosition() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(0); + mf.format((Object)args, buf, fp); + assertEquals(englishTarget, buf.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.parse(String, ParsePosition)' + */ + public void testParseStringParsePosition() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + ParsePosition pp = new ParsePosition(1); + Object[] result = mf.parse("!" + englishTarget, pp); + assertEquals(num, result[0]); + assertEquals(dateOnly, result[1]); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.parse(String)' + */ + public void testParseString() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + try { + Object[] result = mf.parse(englishTarget); + assertEquals(num, result[0]); + assertEquals(dateOnly, result[1]); + } + catch (ParseException e) { + fail(e.getMessage()); + } + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.parseObject(String, ParsePosition)' + */ + public void testParseObjectStringParsePosition() { + MessageFormat mf = new MessageFormat(pattern, Locale.US); + ParsePosition pp = new ParsePosition(0); + Object result = mf.parseObject(englishTarget, pp); + assertEquals(num, ((Object[])result)[0]); + assertEquals(dateOnly, ((Object[])result)[1]); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.autoQuoteApostrophe(String)' + */ + public void testAutoQuoteApostrophe() { + String str = "Let's meet at {1,time,h 'o'' clock'} at l'Orange Bleue"; + String pat = MessageFormat.autoQuoteApostrophe(str); + MessageFormat mf = new MessageFormat(pat, Locale.US); + String result = mf.format(args); + assertEquals("Let's meet at 8 o' clock at l'Orange Bleue", result); + assertEquals("Let''s meet at {1,time,h 'o'' clock'} at l''Orange Bleue", pat); + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.clone()' + */ + public void testClone() { + // tested already in testHashcode + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.equals(Object)' + */ + public void testEqualsObject() { + // tested already in testHashcode + } + + /* + * Test method for 'com.ibm.icu.text.MessageFormat.toString()' + */ + public void testToString() { + // no need to test + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java index 3c7b7dd9dca..ec7188ff5b0 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java @@ -1,447 +1,447 @@ -/* - ******************************************************************************* - * Copyright (C) 2007-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.math.BigInteger; -import java.text.FieldPosition; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Locale; - -import com.ibm.icu.text.NumberFormat; -import com.ibm.icu.util.ULocale; - -public class NumberFormatTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.NumberFormat(NumberFormat)' - */ - public void testNumberFormat() { - NumberFormat nf = new NumberFormat(java.text.NumberFormat.getInstance()); - assertEquals(nf, NumberFormat.getInstance()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(Object, StringBuffer, FieldPosition)' - */ - public void testFormatObjectStringBufferFieldPosition() { - Number num = new Long(1234L); - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(NumberFormat.INTEGER_FIELD); - NumberFormat.getInstance().format(num, buf, fp); - assertEquals("1,234", buf.toString()); - assertEquals(0, fp.getBeginIndex()); - assertEquals(5, fp.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.parseObject(String, ParsePosition)' - */ - public void testParseObjectStringParsePosition() { - ParsePosition pp = new ParsePosition(0); - Object result = NumberFormat.getInstance().parse("1,234", pp); - assertEquals(result, new Long(1234)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double)' - */ - public void testFormatDouble() { - assertEquals("1,234.567", NumberFormat.getInstance().format(1234.567)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long)' - */ - public void testFormatLong() { - assertEquals("1,234", NumberFormat.getInstance().format(1234L)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger)' - */ - public void testFormatBigInteger() { - // note, java doesn't handle biginteger with full precision. - BigInteger bi = new BigInteger("123456"); - assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double, StringBuffer, FieldPosition)' - */ - public void testFormatDoubleStringBufferFieldPosition() { - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD); - assertEquals("123,456.789", NumberFormat.getInstance().format(123456.789, buf, fp).toString()); - assertEquals(8, fp.getBeginIndex()); - assertEquals(11, fp.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long, StringBuffer, FieldPosition)' - */ - public void testFormatLongStringBufferFieldPosition() { - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR); - assertEquals("123,456", NumberFormat.getInstance().format(123456L, buf, fp).toString()); - assertEquals(3, fp.getBeginIndex()); - assertEquals(4, fp.getEndIndex()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger, StringBuffer, FieldPosition)' - */ - public void testFormatBigIntegerStringBufferFieldPosition() { - // note, java doesn't handle biginteger with full precision. - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(0); - BigInteger bi = new BigInteger("123456"); - assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi, buf, fp).toString()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String, ParsePosition)' - */ - public void testParseStringParsePosition() { - ParsePosition pp = new ParsePosition(3); - assertEquals(new Long(123456), NumberFormat.getInstance().parse("xxx123,456yyy", pp)); - assertEquals(10, pp.getIndex()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String)' - */ - public void testParseString() throws ParseException { - Number result = NumberFormat.getInstance().parse("123,456,yyy"); - assertEquals(new Long(123456), result); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.isParseIntegerOnly()' - */ - public void testIsParseIntegerOnly() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setParseIntegerOnly(true); - assertTrue(nf.isParseIntegerOnly()); - nf.setParseIntegerOnly(false); - assertFalse(nf.isParseIntegerOnly()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setParseIntegerOnly(boolean)' - */ - public void testSetParseIntegerOnly() throws ParseException { - String str = "123.456,yyy"; - NumberFormat nf = NumberFormat.getInstance(); - assertEquals(new Double(123.456), nf.parse(str)); - nf.setParseIntegerOnly(true); - assertEquals(new Long(123), nf.parse(str)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance()' - */ - public void testGetInstance() { - // used everywhere, no need to test - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(Locale)' - */ - public void testGetInstanceLocale() { - NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY); - assertEquals("123,456", nf.format(123.456)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(ULocale)' - */ - public void testGetInstanceULocale() { - NumberFormat nf = NumberFormat.getInstance(ULocale.GERMANY); - assertEquals("123,456", nf.format(123.456)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance()' - */ - public void testGetNumberInstance() { - NumberFormat nf = NumberFormat.getNumberInstance(); - assertEquals("123,456.789", nf.format(123456.789)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(Locale)' - */ - public void testGetNumberInstanceLocale() { - NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY); - assertEquals("123.456,789", nf.format(123456.789)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(ULocale)' - */ - public void testGetNumberInstanceULocale() { - NumberFormat nf = NumberFormat.getNumberInstance(ULocale.GERMANY); - assertEquals("123.456,789", nf.format(123456.789)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance()' - */ - public void testGetIntegerInstance() { - NumberFormat nf = NumberFormat.getIntegerInstance(); - assertEquals("123,457", nf.format(123456.789)); // rounds - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(Locale)' - */ - public void testGetIntegerInstanceLocale() { - NumberFormat nf = NumberFormat.getIntegerInstance(Locale.GERMANY); - assertEquals("123.457", nf.format(123456.789)); // rounds - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(ULocale)' - */ - public void testGetIntegerInstanceULocale() { - NumberFormat nf = NumberFormat.getIntegerInstance(ULocale.GERMANY); - assertEquals("123.457", nf.format(123456.789)); // rounds - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance()' - */ - public void testGetCurrencyInstance() { - NumberFormat nf = NumberFormat.getCurrencyInstance(); - assertEquals("$123,456.99", nf.format(123456.99)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(Locale)' - */ - public void testGetCurrencyInstanceLocale() { - NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY); - assertEquals("123.456,99 \u20AC", nf.format(123456.99)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(ULocale)' - */ - public void testGetCurrencyInstanceULocale() { - NumberFormat nf = NumberFormat.getCurrencyInstance(ULocale.GERMANY); - assertEquals("123.456,99 \u20AC", nf.format(123456.99)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance()' - */ - public void testGetPercentInstance() { - NumberFormat nf = NumberFormat.getPercentInstance(); - assertEquals("123,456%", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(Locale)' - */ - public void testGetPercentInstanceLocale() { - NumberFormat nf = NumberFormat.getPercentInstance(Locale.GERMANY); - assertEquals("123.456%", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(ULocale)' - */ - public void testGetPercentInstanceULocale() { - NumberFormat nf = NumberFormat.getPercentInstance(ULocale.GERMANY); - assertEquals("123.456%", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance()' - */ - public void testGetScientificInstance() { - NumberFormat nf = NumberFormat.getScientificInstance(); - assertEquals(".123456E4", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(Locale)' - */ - public void testGetScientificInstanceLocale() { - NumberFormat nf = NumberFormat.getScientificInstance(Locale.GERMANY); - assertEquals(",123456E4", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(ULocale)' - */ - public void testGetScientificInstanceULocale() { - NumberFormat nf = NumberFormat.getScientificInstance(ULocale.GERMANY); - assertEquals(",123456E4", nf.format(1234.56)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableLocales()' - */ - public void testGetAvailableLocales() { - Locale[] ilocales = NumberFormat.getAvailableLocales(); - if (ICUTestCase.testingWrapper) { - Locale[] jlocales = java.text.NumberFormat.getAvailableLocales(); - for (int i = 0; i < ilocales.length; ++i) { - assertEquals(jlocales[i], ilocales[i]); - } - } - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableULocales()' - */ - public void testGetAvailableULocales() { - ULocale[] ulocales = NumberFormat.getAvailableULocales(); - if (ICUTestCase.testingWrapper) { - Locale[] jlocales = java.text.NumberFormat.getAvailableLocales(); - for (int i = 0; i < ulocales.length; ++i) { - assertEquals(jlocales[i], ulocales[i].toLocale()); - } - } - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.isGroupingUsed()' - */ - public void testIsGroupingUsed() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setGroupingUsed(true); - assertTrue(nf.isGroupingUsed()); - nf.setGroupingUsed(false); - assertFalse(nf.isGroupingUsed()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setGroupingUsed(boolean)' - */ - public void testSetGroupingUsed() { - NumberFormat nf = NumberFormat.getInstance(); - assertEquals("123,456,789", nf.format(123456789)); - nf.setGroupingUsed(false); - assertEquals("123456789", nf.format(123456789)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumIntegerDigits()' - */ - public void testGetMaximumIntegerDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMaximumIntegerDigits(4); - assertEquals(4, nf.getMaximumIntegerDigits()); - nf.setMaximumIntegerDigits(6); - assertEquals(6, nf.getMaximumIntegerDigits()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumIntegerDigits(int)' - */ - public void testSetMaximumIntegerDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMaximumIntegerDigits(4); - assertEquals("3,456", nf.format(123456)); // high digits truncated - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumIntegerDigits()' - */ - public void testGetMinimumIntegerDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMinimumIntegerDigits(4); - assertEquals(4, nf.getMinimumIntegerDigits()); - nf.setMinimumIntegerDigits(6); - assertEquals(6, nf.getMinimumIntegerDigits()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumIntegerDigits(int)' - */ - public void testSetMinimumIntegerDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMinimumIntegerDigits(4); - assertEquals("0,012", nf.format(12)); // pad out with zero, grouping still used - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumFractionDigits()' - */ - public void testGetMaximumFractionDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMaximumFractionDigits(4); - assertEquals(4, nf.getMaximumFractionDigits()); - nf.setMaximumFractionDigits(6); - assertEquals(6, nf.getMaximumFractionDigits()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumFractionDigits(int)' - */ - public void testSetMaximumFractionDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMaximumFractionDigits(4); - assertEquals("1.2346", nf.format(1.2345678)); // low digits rounded - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumFractionDigits()' - */ - public void testGetMinimumFractionDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMinimumFractionDigits(4); - assertEquals(4, nf.getMinimumFractionDigits()); - nf.setMinimumFractionDigits(6); - assertEquals(6, nf.getMinimumFractionDigits()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumFractionDigits(int)' - */ - public void testSetMinimumFractionDigits() { - NumberFormat nf = NumberFormat.getInstance(); - nf.setMinimumFractionDigits(4); - assertEquals("1.2000", nf.format(1.2)); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.toString()' - */ - public void testToString() { - assertNotNull(NumberFormat.getInstance().toString()); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.hashCode()' - */ - public void testHashCode() { - NumberFormat nf = NumberFormat.getInstance(); - NumberFormat eq = NumberFormat.getInstance(Locale.US); - NumberFormat neq = NumberFormat.getInstance(Locale.GERMANY); - - ICUTestCase.testEHCS(nf, eq, neq); - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.clone()' - */ - public void testClone() { - // see testHashCode - } - - /* - * Test method for 'com.ibm.icu.x.text.NumberFormat.equals(Object)' - */ - public void testEqualsObject() { - // see testHashCode - } -} +/* + ******************************************************************************* + * Copyright (C) 2007-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.math.BigInteger; +import java.text.FieldPosition; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Locale; + +import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.util.ULocale; + +public class NumberFormatTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.NumberFormat(NumberFormat)' + */ + public void testNumberFormat() { + NumberFormat nf = new NumberFormat(java.text.NumberFormat.getInstance()); + assertEquals(nf, NumberFormat.getInstance()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(Object, StringBuffer, FieldPosition)' + */ + public void testFormatObjectStringBufferFieldPosition() { + Number num = new Long(1234L); + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(NumberFormat.INTEGER_FIELD); + NumberFormat.getInstance().format(num, buf, fp); + assertEquals("1,234", buf.toString()); + assertEquals(0, fp.getBeginIndex()); + assertEquals(5, fp.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.parseObject(String, ParsePosition)' + */ + public void testParseObjectStringParsePosition() { + ParsePosition pp = new ParsePosition(0); + Object result = NumberFormat.getInstance().parse("1,234", pp); + assertEquals(result, new Long(1234)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double)' + */ + public void testFormatDouble() { + assertEquals("1,234.567", NumberFormat.getInstance().format(1234.567)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long)' + */ + public void testFormatLong() { + assertEquals("1,234", NumberFormat.getInstance().format(1234L)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger)' + */ + public void testFormatBigInteger() { + // note, java doesn't handle biginteger with full precision. + BigInteger bi = new BigInteger("123456"); + assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double, StringBuffer, FieldPosition)' + */ + public void testFormatDoubleStringBufferFieldPosition() { + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD); + assertEquals("123,456.789", NumberFormat.getInstance().format(123456.789, buf, fp).toString()); + assertEquals(8, fp.getBeginIndex()); + assertEquals(11, fp.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long, StringBuffer, FieldPosition)' + */ + public void testFormatLongStringBufferFieldPosition() { + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR); + assertEquals("123,456", NumberFormat.getInstance().format(123456L, buf, fp).toString()); + assertEquals(3, fp.getBeginIndex()); + assertEquals(4, fp.getEndIndex()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger, StringBuffer, FieldPosition)' + */ + public void testFormatBigIntegerStringBufferFieldPosition() { + // note, java doesn't handle biginteger with full precision. + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(0); + BigInteger bi = new BigInteger("123456"); + assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi, buf, fp).toString()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String, ParsePosition)' + */ + public void testParseStringParsePosition() { + ParsePosition pp = new ParsePosition(3); + assertEquals(new Long(123456), NumberFormat.getInstance().parse("xxx123,456yyy", pp)); + assertEquals(10, pp.getIndex()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String)' + */ + public void testParseString() throws ParseException { + Number result = NumberFormat.getInstance().parse("123,456,yyy"); + assertEquals(new Long(123456), result); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.isParseIntegerOnly()' + */ + public void testIsParseIntegerOnly() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setParseIntegerOnly(true); + assertTrue(nf.isParseIntegerOnly()); + nf.setParseIntegerOnly(false); + assertFalse(nf.isParseIntegerOnly()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setParseIntegerOnly(boolean)' + */ + public void testSetParseIntegerOnly() throws ParseException { + String str = "123.456,yyy"; + NumberFormat nf = NumberFormat.getInstance(); + assertEquals(new Double(123.456), nf.parse(str)); + nf.setParseIntegerOnly(true); + assertEquals(new Long(123), nf.parse(str)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance()' + */ + public void testGetInstance() { + // used everywhere, no need to test + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(Locale)' + */ + public void testGetInstanceLocale() { + NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY); + assertEquals("123,456", nf.format(123.456)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(ULocale)' + */ + public void testGetInstanceULocale() { + NumberFormat nf = NumberFormat.getInstance(ULocale.GERMANY); + assertEquals("123,456", nf.format(123.456)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance()' + */ + public void testGetNumberInstance() { + NumberFormat nf = NumberFormat.getNumberInstance(); + assertEquals("123,456.789", nf.format(123456.789)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(Locale)' + */ + public void testGetNumberInstanceLocale() { + NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY); + assertEquals("123.456,789", nf.format(123456.789)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(ULocale)' + */ + public void testGetNumberInstanceULocale() { + NumberFormat nf = NumberFormat.getNumberInstance(ULocale.GERMANY); + assertEquals("123.456,789", nf.format(123456.789)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance()' + */ + public void testGetIntegerInstance() { + NumberFormat nf = NumberFormat.getIntegerInstance(); + assertEquals("123,457", nf.format(123456.789)); // rounds + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(Locale)' + */ + public void testGetIntegerInstanceLocale() { + NumberFormat nf = NumberFormat.getIntegerInstance(Locale.GERMANY); + assertEquals("123.457", nf.format(123456.789)); // rounds + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(ULocale)' + */ + public void testGetIntegerInstanceULocale() { + NumberFormat nf = NumberFormat.getIntegerInstance(ULocale.GERMANY); + assertEquals("123.457", nf.format(123456.789)); // rounds + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance()' + */ + public void testGetCurrencyInstance() { + NumberFormat nf = NumberFormat.getCurrencyInstance(); + assertEquals("$123,456.99", nf.format(123456.99)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(Locale)' + */ + public void testGetCurrencyInstanceLocale() { + NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY); + assertEquals("123.456,99 \u20AC", nf.format(123456.99)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(ULocale)' + */ + public void testGetCurrencyInstanceULocale() { + NumberFormat nf = NumberFormat.getCurrencyInstance(ULocale.GERMANY); + assertEquals("123.456,99 \u20AC", nf.format(123456.99)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance()' + */ + public void testGetPercentInstance() { + NumberFormat nf = NumberFormat.getPercentInstance(); + assertEquals("123,456%", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(Locale)' + */ + public void testGetPercentInstanceLocale() { + NumberFormat nf = NumberFormat.getPercentInstance(Locale.GERMANY); + assertEquals("123.456%", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(ULocale)' + */ + public void testGetPercentInstanceULocale() { + NumberFormat nf = NumberFormat.getPercentInstance(ULocale.GERMANY); + assertEquals("123.456%", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance()' + */ + public void testGetScientificInstance() { + NumberFormat nf = NumberFormat.getScientificInstance(); + assertEquals(".123456E4", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(Locale)' + */ + public void testGetScientificInstanceLocale() { + NumberFormat nf = NumberFormat.getScientificInstance(Locale.GERMANY); + assertEquals(",123456E4", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(ULocale)' + */ + public void testGetScientificInstanceULocale() { + NumberFormat nf = NumberFormat.getScientificInstance(ULocale.GERMANY); + assertEquals(",123456E4", nf.format(1234.56)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableLocales()' + */ + public void testGetAvailableLocales() { + Locale[] ilocales = NumberFormat.getAvailableLocales(); + if (ICUTestCase.testingWrapper) { + Locale[] jlocales = java.text.NumberFormat.getAvailableLocales(); + for (int i = 0; i < ilocales.length; ++i) { + assertEquals(jlocales[i], ilocales[i]); + } + } + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableULocales()' + */ + public void testGetAvailableULocales() { + ULocale[] ulocales = NumberFormat.getAvailableULocales(); + if (ICUTestCase.testingWrapper) { + Locale[] jlocales = java.text.NumberFormat.getAvailableLocales(); + for (int i = 0; i < ulocales.length; ++i) { + assertEquals(jlocales[i], ulocales[i].toLocale()); + } + } + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.isGroupingUsed()' + */ + public void testIsGroupingUsed() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setGroupingUsed(true); + assertTrue(nf.isGroupingUsed()); + nf.setGroupingUsed(false); + assertFalse(nf.isGroupingUsed()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setGroupingUsed(boolean)' + */ + public void testSetGroupingUsed() { + NumberFormat nf = NumberFormat.getInstance(); + assertEquals("123,456,789", nf.format(123456789)); + nf.setGroupingUsed(false); + assertEquals("123456789", nf.format(123456789)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumIntegerDigits()' + */ + public void testGetMaximumIntegerDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumIntegerDigits(4); + assertEquals(4, nf.getMaximumIntegerDigits()); + nf.setMaximumIntegerDigits(6); + assertEquals(6, nf.getMaximumIntegerDigits()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumIntegerDigits(int)' + */ + public void testSetMaximumIntegerDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumIntegerDigits(4); + assertEquals("3,456", nf.format(123456)); // high digits truncated + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumIntegerDigits()' + */ + public void testGetMinimumIntegerDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumIntegerDigits(4); + assertEquals(4, nf.getMinimumIntegerDigits()); + nf.setMinimumIntegerDigits(6); + assertEquals(6, nf.getMinimumIntegerDigits()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumIntegerDigits(int)' + */ + public void testSetMinimumIntegerDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumIntegerDigits(4); + assertEquals("0,012", nf.format(12)); // pad out with zero, grouping still used + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumFractionDigits()' + */ + public void testGetMaximumFractionDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(4); + assertEquals(4, nf.getMaximumFractionDigits()); + nf.setMaximumFractionDigits(6); + assertEquals(6, nf.getMaximumFractionDigits()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumFractionDigits(int)' + */ + public void testSetMaximumFractionDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(4); + assertEquals("1.2346", nf.format(1.2345678)); // low digits rounded + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumFractionDigits()' + */ + public void testGetMinimumFractionDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumFractionDigits(4); + assertEquals(4, nf.getMinimumFractionDigits()); + nf.setMinimumFractionDigits(6); + assertEquals(6, nf.getMinimumFractionDigits()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumFractionDigits(int)' + */ + public void testSetMinimumFractionDigits() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumFractionDigits(4); + assertEquals("1.2000", nf.format(1.2)); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.toString()' + */ + public void testToString() { + assertNotNull(NumberFormat.getInstance().toString()); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.hashCode()' + */ + public void testHashCode() { + NumberFormat nf = NumberFormat.getInstance(); + NumberFormat eq = NumberFormat.getInstance(Locale.US); + NumberFormat neq = NumberFormat.getInstance(Locale.GERMANY); + + ICUTestCase.testEHCS(nf, eq, neq); + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.clone()' + */ + public void testClone() { + // see testHashCode + } + + /* + * Test method for 'com.ibm.icu.x.text.NumberFormat.equals(Object)' + */ + public void testEqualsObject() { + // see testHashCode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java index 2bf36232777..0136a82ab9e 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java @@ -1,202 +1,202 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.text.FieldPosition; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; - -import com.ibm.icu.text.DateFormatSymbols; -import com.ibm.icu.text.SimpleDateFormat; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -public class SimpleDateFormatTest extends ICUTestCase { - private static final String mdy = "MMM dd yyyy"; - private static final String md2 = "MMM dd yy"; - private static final String hmz = "'The time is' HH:mm:ss zzz"; - private static final String hmzmdy = hmz + " 'on' " + mdy; - private static final String hmzmdyStr = "The time is 15:05:20 CST on Jan 10 2006"; - - private static final TimeZone tzc = TimeZone.getTimeZone("CST"); - private static final TimeZone tzp = TimeZone.getTimeZone("PST"); - private static final Calendar cal = Calendar.getInstance(tzc); - private static final Date date; - static { - cal.clear(); - cal.set(2006, 0, 10, 15, 5, 20); // arrgh, doesn't clear millis - date = cal.getTime(); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.format(Calendar, StringBuffer, FieldPosition)' - */ - public void testFormatCalendarStringBufferFieldPosition() { - StringBuffer buf = new StringBuffer(); - FieldPosition fp = new FieldPosition(0); - SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); - sdf.format(cal, buf, fp); - assertEquals(hmzmdyStr, buf.toString()); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.parse(String, Calendar, ParsePosition)' - */ - public void testParseStringCalendarParsePosition() { - Calendar cal = Calendar.getInstance(tzp); - cal.clear(); - ParsePosition pp = new ParsePosition(0); - SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); - sdf.parse(hmzmdyStr, cal, pp); - assertEquals(date, cal.getTime()); - // note: java doesn't return the parsed time zone - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.clone()' - */ - public void testClone() { - - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat()' - */ - public void testSimpleDateFormat() { - SimpleDateFormat sdf = new SimpleDateFormat(); - java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(); - assertEquals(jsdf.format(date), sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String)' - */ - public void testSimpleDateFormatString() { - SimpleDateFormat sdf = new SimpleDateFormat(mdy); - java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy); - assertEquals(jsdf.format(date), sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, Locale)' - */ - public void testSimpleDateFormatStringLocale() { - Locale l = Locale.JAPAN; - SimpleDateFormat sdf = new SimpleDateFormat(mdy, l); - java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l); - assertEquals(jsdf.format(date), sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, ULocale)' - */ - public void testSimpleDateFormatStringULocale() { - ULocale l = ULocale.JAPAN; - SimpleDateFormat sdf = new SimpleDateFormat(mdy, l); - java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l.toLocale()); - assertEquals(jsdf.format(date), sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, DateFormatSymbols)' - */ - public void testSimpleDateFormatStringDateFormatSymbols() { - Locale l = Locale.US; - DateFormatSymbols dfs = new DateFormatSymbols(l); - java.text.DateFormatSymbols jdfs = new java.text.DateFormatSymbols(l); - SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs); - java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, jdfs); - assertEquals(jsdf.format(date), sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.set2DigitYearStart(Date)' - */ - public void testSet2DigitYearStart() { - SimpleDateFormat sdf = new SimpleDateFormat(md2); - sdf.set2DigitYearStart(date); - try { - Date d = sdf.parse("Jan 15 04"); - assertNotEqual(-1, d.toString().indexOf("2104")); - } - catch (ParseException pe) { - fail(pe.getMessage()); - } - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.get2DigitYearStart()' - */ - public void testGet2DigitYearStart() { - SimpleDateFormat sdf = new SimpleDateFormat(md2); - sdf.set2DigitYearStart(date); - assertEquals(date, sdf.get2DigitYearStart()); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.toPattern()' - */ - public void testToPattern() { - SimpleDateFormat sdf = new SimpleDateFormat(mdy); - assertEquals(mdy, sdf.toPattern()); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.toLocalizedPattern()' - */ - public void testToLocalizedPattern() { - Locale l = Locale.getDefault(); - Locale.setDefault(Locale.US); - SimpleDateFormat sdf = new SimpleDateFormat(mdy); - assertEquals(mdy, sdf.toLocalizedPattern()); - Locale.setDefault(l); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyPattern(String)' - */ - public void testApplyPattern() { - SimpleDateFormat sdf = new SimpleDateFormat(); - sdf.setTimeZone(tzc); - sdf.applyPattern(hmzmdy); - assertEquals(hmzmdyStr, sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyLocalizedPattern(String)' - */ - public void testApplyLocalizedPattern() { - SimpleDateFormat sdf = new SimpleDateFormat(); - sdf.setTimeZone(tzc); - sdf.applyLocalizedPattern(hmzmdy); - assertEquals(hmzmdyStr, sdf.format(date)); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.getDateFormatSymbols()' - */ - public void testGetDateFormatSymbols() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); - SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs); - assertEquals(dfs, sdf.getDateFormatSymbols()); - } - - /* - * Test method for 'com.ibm.icu.text.SimpleDateFormat.setDateFormatSymbols(DateFormatSymbols)' - */ - public void testSetDateFormatSymbols() { - DateFormatSymbols dfs = new DateFormatSymbols(Locale.JAPAN); - SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); - sdf.setDateFormatSymbols(dfs); - // assumes Japanese symbols do not have gregorian month names - assertEquals(-1, sdf.format(date).indexOf("Jan")); - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.text.FieldPosition; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +import com.ibm.icu.text.DateFormatSymbols; +import com.ibm.icu.text.SimpleDateFormat; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +public class SimpleDateFormatTest extends ICUTestCase { + private static final String mdy = "MMM dd yyyy"; + private static final String md2 = "MMM dd yy"; + private static final String hmz = "'The time is' HH:mm:ss zzz"; + private static final String hmzmdy = hmz + " 'on' " + mdy; + private static final String hmzmdyStr = "The time is 15:05:20 CST on Jan 10 2006"; + + private static final TimeZone tzc = TimeZone.getTimeZone("CST"); + private static final TimeZone tzp = TimeZone.getTimeZone("PST"); + private static final Calendar cal = Calendar.getInstance(tzc); + private static final Date date; + static { + cal.clear(); + cal.set(2006, 0, 10, 15, 5, 20); // arrgh, doesn't clear millis + date = cal.getTime(); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.format(Calendar, StringBuffer, FieldPosition)' + */ + public void testFormatCalendarStringBufferFieldPosition() { + StringBuffer buf = new StringBuffer(); + FieldPosition fp = new FieldPosition(0); + SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); + sdf.format(cal, buf, fp); + assertEquals(hmzmdyStr, buf.toString()); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.parse(String, Calendar, ParsePosition)' + */ + public void testParseStringCalendarParsePosition() { + Calendar cal = Calendar.getInstance(tzp); + cal.clear(); + ParsePosition pp = new ParsePosition(0); + SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); + sdf.parse(hmzmdyStr, cal, pp); + assertEquals(date, cal.getTime()); + // note: java doesn't return the parsed time zone + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.clone()' + */ + public void testClone() { + + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat()' + */ + public void testSimpleDateFormat() { + SimpleDateFormat sdf = new SimpleDateFormat(); + java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(); + assertEquals(jsdf.format(date), sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String)' + */ + public void testSimpleDateFormatString() { + SimpleDateFormat sdf = new SimpleDateFormat(mdy); + java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy); + assertEquals(jsdf.format(date), sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, Locale)' + */ + public void testSimpleDateFormatStringLocale() { + Locale l = Locale.JAPAN; + SimpleDateFormat sdf = new SimpleDateFormat(mdy, l); + java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l); + assertEquals(jsdf.format(date), sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, ULocale)' + */ + public void testSimpleDateFormatStringULocale() { + ULocale l = ULocale.JAPAN; + SimpleDateFormat sdf = new SimpleDateFormat(mdy, l); + java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l.toLocale()); + assertEquals(jsdf.format(date), sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, DateFormatSymbols)' + */ + public void testSimpleDateFormatStringDateFormatSymbols() { + Locale l = Locale.US; + DateFormatSymbols dfs = new DateFormatSymbols(l); + java.text.DateFormatSymbols jdfs = new java.text.DateFormatSymbols(l); + SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs); + java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, jdfs); + assertEquals(jsdf.format(date), sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.set2DigitYearStart(Date)' + */ + public void testSet2DigitYearStart() { + SimpleDateFormat sdf = new SimpleDateFormat(md2); + sdf.set2DigitYearStart(date); + try { + Date d = sdf.parse("Jan 15 04"); + assertNotEqual(-1, d.toString().indexOf("2104")); + } + catch (ParseException pe) { + fail(pe.getMessage()); + } + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.get2DigitYearStart()' + */ + public void testGet2DigitYearStart() { + SimpleDateFormat sdf = new SimpleDateFormat(md2); + sdf.set2DigitYearStart(date); + assertEquals(date, sdf.get2DigitYearStart()); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.toPattern()' + */ + public void testToPattern() { + SimpleDateFormat sdf = new SimpleDateFormat(mdy); + assertEquals(mdy, sdf.toPattern()); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.toLocalizedPattern()' + */ + public void testToLocalizedPattern() { + Locale l = Locale.getDefault(); + Locale.setDefault(Locale.US); + SimpleDateFormat sdf = new SimpleDateFormat(mdy); + assertEquals(mdy, sdf.toLocalizedPattern()); + Locale.setDefault(l); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyPattern(String)' + */ + public void testApplyPattern() { + SimpleDateFormat sdf = new SimpleDateFormat(); + sdf.setTimeZone(tzc); + sdf.applyPattern(hmzmdy); + assertEquals(hmzmdyStr, sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyLocalizedPattern(String)' + */ + public void testApplyLocalizedPattern() { + SimpleDateFormat sdf = new SimpleDateFormat(); + sdf.setTimeZone(tzc); + sdf.applyLocalizedPattern(hmzmdy); + assertEquals(hmzmdyStr, sdf.format(date)); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.getDateFormatSymbols()' + */ + public void testGetDateFormatSymbols() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.US); + SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs); + assertEquals(dfs, sdf.getDateFormatSymbols()); + } + + /* + * Test method for 'com.ibm.icu.text.SimpleDateFormat.setDateFormatSymbols(DateFormatSymbols)' + */ + public void testSetDateFormatSymbols() { + DateFormatSymbols dfs = new DateFormatSymbols(Locale.JAPAN); + SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy); + sdf.setDateFormatSymbols(dfs); + // assumes Japanese symbols do not have gregorian month names + assertEquals(-1, sdf.format(date).indexOf("Jan")); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java index d85d0a24ddc..f8a2fe16ce1 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java @@ -1,235 +1,235 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Date; -import java.util.Locale; - -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -public class TimeZoneTest extends ICUTestCase { - - /* - * Test method for 'com.ibm.icu.util.TimeZone.hashCode()' - */ - public void testHashCode() { - TimeZone tz1 = TimeZone.getTimeZone("PST"); - TimeZone tz2 = TimeZone.getTimeZone("PST"); - TimeZone tzn = TimeZone.getTimeZone("CST"); - testEHCS(tz1, tz2, tzn); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.TimeZone(TimeZone)' - */ - public void testTimeZone() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getOffset(int, int, int, int, int, int)' - */ - public void testGetOffset() { - TimeZone tz = TimeZone.getTimeZone("PST"); - int offset = tz.getOffset(1, 2004, 0, 01, 1, 0); - assertEquals(-28800000, offset); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.setRawOffset(int)' - */ - public void testSetRawOffset() { - TimeZone tz = TimeZone.getTimeZone("PST"); - int value = tz.getRawOffset(); - int value1 = value + 100000; - tz.setRawOffset(value1); - int result = tz.getRawOffset(); - assertNotEqual(value, result); - assertEquals(value1, result); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getRawOffset()' - */ - public void testGetRawOffset() { - TimeZone tz = TimeZone.getTimeZone("PST"); - int offset = tz.getRawOffset(); - assertEquals(-28800000, offset); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getID()' - */ - public void testGetID() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("PST", tz.getID()); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.setID(String)' - */ - public void testSetID() { - TimeZone tz = TimeZone.getTimeZone("PST"); - String value1 = tz.getID(); - String value2 = value1 + "!"; - tz.setID(value2); - String result = tz.getID(); - assertNotEqual(value1, result); - assertEquals(value2, result); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName()' - */ - public void testGetDisplayName() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("Pacific Standard Time", tz.getDisplayName()); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(Locale)' - */ - public void testGetDisplayNameLocale() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("Pacific Standard Time", tz.getDisplayName(Locale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(ULocale)' - */ - public void testGetDisplayNameULocale() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("Pacific Standard Time", tz.getDisplayName(ULocale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int)' - */ - public void testGetDisplayNameBooleanInt() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT)); - assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, Locale)' - */ - public void testGetDisplayNameBooleanIntLocale() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, Locale.US)); - assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, ULocale)' - */ - public void testGetDisplayNameBooleanIntULocale() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, ULocale.US)); - assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, ULocale.US)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDSTSavings()' - */ - public void testGetDSTSavings() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertEquals(3600000, tz.getDSTSavings()); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.useDaylightTime()' - */ - public void testUseDaylightTime() { - TimeZone tz = TimeZone.getTimeZone("PST"); - assertTrue(tz.useDaylightTime()); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.inDaylightTime(Date)' - */ - public void testInDaylightTime() { - TimeZone tz = TimeZone.getTimeZone("PST"); - Calendar cal = Calendar.getInstance(); - cal.set(2005, 0, 17); - Date date = cal.getTime(); - assertFalse(tz.inDaylightTime(date)); - cal.set(2005, 6, 17); - date = cal.getTime(); - assertTrue(tz.inDaylightTime(date)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getTimeZone(String)' - */ - public void testGetTimeZone() { - // implicitly tested everywhere - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs(int)' - */ - public void testGetAvailableIDsInt() { - String[] ids = TimeZone.getAvailableIDs(-28800000); - assertNotNull(ids); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs()' - */ - public void testGetAvailableIDs() { - String[] ids = TimeZone.getAvailableIDs(); - assertNotNull(ids); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.getDefault()' - */ - public void testGetDefault() { - TimeZone tz = TimeZone.getDefault(); - assertNotNull(tz); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.setDefault(TimeZone)' - */ - public void testSetDefault() { - TimeZone tz1 = TimeZone.getDefault(); - String newCode = "PDT".equals(tz1.getID()) ? "CST" : "PDT"; - TimeZone tz2 = TimeZone.getTimeZone(newCode); - TimeZone.setDefault(tz2); - TimeZone result = TimeZone.getDefault(); - assertNotEqual(tz1, result); - assertEquals(tz2, result); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.hasSameRules(TimeZone)' - */ - public void testHasSameRules() { - TimeZone tz1 = TimeZone.getTimeZone("PST"); - TimeZone tz2 = TimeZone.getTimeZone("America/Los_Angeles"); - assertTrue(tz1.hasSameRules(tz2)); - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.clone()' - */ - public void testClone() { - // tested by testHashCode - } - - /* - * Test method for 'com.ibm.icu.util.TimeZone.equals(Object)' - */ - public void testEqualsObject() { - // tested by testHashCode - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Date; +import java.util.Locale; + +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +public class TimeZoneTest extends ICUTestCase { + + /* + * Test method for 'com.ibm.icu.util.TimeZone.hashCode()' + */ + public void testHashCode() { + TimeZone tz1 = TimeZone.getTimeZone("PST"); + TimeZone tz2 = TimeZone.getTimeZone("PST"); + TimeZone tzn = TimeZone.getTimeZone("CST"); + testEHCS(tz1, tz2, tzn); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.TimeZone(TimeZone)' + */ + public void testTimeZone() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getOffset(int, int, int, int, int, int)' + */ + public void testGetOffset() { + TimeZone tz = TimeZone.getTimeZone("PST"); + int offset = tz.getOffset(1, 2004, 0, 01, 1, 0); + assertEquals(-28800000, offset); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.setRawOffset(int)' + */ + public void testSetRawOffset() { + TimeZone tz = TimeZone.getTimeZone("PST"); + int value = tz.getRawOffset(); + int value1 = value + 100000; + tz.setRawOffset(value1); + int result = tz.getRawOffset(); + assertNotEqual(value, result); + assertEquals(value1, result); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getRawOffset()' + */ + public void testGetRawOffset() { + TimeZone tz = TimeZone.getTimeZone("PST"); + int offset = tz.getRawOffset(); + assertEquals(-28800000, offset); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getID()' + */ + public void testGetID() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("PST", tz.getID()); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.setID(String)' + */ + public void testSetID() { + TimeZone tz = TimeZone.getTimeZone("PST"); + String value1 = tz.getID(); + String value2 = value1 + "!"; + tz.setID(value2); + String result = tz.getID(); + assertNotEqual(value1, result); + assertEquals(value2, result); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName()' + */ + public void testGetDisplayName() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("Pacific Standard Time", tz.getDisplayName()); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(Locale)' + */ + public void testGetDisplayNameLocale() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("Pacific Standard Time", tz.getDisplayName(Locale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(ULocale)' + */ + public void testGetDisplayNameULocale() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("Pacific Standard Time", tz.getDisplayName(ULocale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int)' + */ + public void testGetDisplayNameBooleanInt() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT)); + assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, Locale)' + */ + public void testGetDisplayNameBooleanIntLocale() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, Locale.US)); + assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, ULocale)' + */ + public void testGetDisplayNameBooleanIntULocale() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, ULocale.US)); + assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, ULocale.US)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDSTSavings()' + */ + public void testGetDSTSavings() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertEquals(3600000, tz.getDSTSavings()); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.useDaylightTime()' + */ + public void testUseDaylightTime() { + TimeZone tz = TimeZone.getTimeZone("PST"); + assertTrue(tz.useDaylightTime()); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.inDaylightTime(Date)' + */ + public void testInDaylightTime() { + TimeZone tz = TimeZone.getTimeZone("PST"); + Calendar cal = Calendar.getInstance(); + cal.set(2005, 0, 17); + Date date = cal.getTime(); + assertFalse(tz.inDaylightTime(date)); + cal.set(2005, 6, 17); + date = cal.getTime(); + assertTrue(tz.inDaylightTime(date)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getTimeZone(String)' + */ + public void testGetTimeZone() { + // implicitly tested everywhere + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs(int)' + */ + public void testGetAvailableIDsInt() { + String[] ids = TimeZone.getAvailableIDs(-28800000); + assertNotNull(ids); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs()' + */ + public void testGetAvailableIDs() { + String[] ids = TimeZone.getAvailableIDs(); + assertNotNull(ids); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.getDefault()' + */ + public void testGetDefault() { + TimeZone tz = TimeZone.getDefault(); + assertNotNull(tz); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.setDefault(TimeZone)' + */ + public void testSetDefault() { + TimeZone tz1 = TimeZone.getDefault(); + String newCode = "PDT".equals(tz1.getID()) ? "CST" : "PDT"; + TimeZone tz2 = TimeZone.getTimeZone(newCode); + TimeZone.setDefault(tz2); + TimeZone result = TimeZone.getDefault(); + assertNotEqual(tz1, result); + assertEquals(tz2, result); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.hasSameRules(TimeZone)' + */ + public void testHasSameRules() { + TimeZone tz1 = TimeZone.getTimeZone("PST"); + TimeZone tz2 = TimeZone.getTimeZone("America/Los_Angeles"); + assertTrue(tz1.hasSameRules(tz2)); + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.clone()' + */ + public void testClone() { + // tested by testHashCode + } + + /* + * Test method for 'com.ibm.icu.util.TimeZone.equals(Object)' + */ + public void testEqualsObject() { + // tested by testHashCode + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java index 21cf50bfc54..d8a2b85d80d 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java @@ -1,748 +1,748 @@ -/* - ******************************************************************************* - * Copyright (C) 2006-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.tests; - -import java.util.Iterator; -import java.util.Locale; - -import com.ibm.icu.util.ULocale; - -public class ULocaleTest extends ICUTestCase { - private String sampleName; - private String longULocaleName; - private String longULocaleBasename; - private String nonNormalizedName; - private ULocale longULocale; - private Locale sampleLocale; - - /** - * @Override - */ - protected void setUp() throws Exception { - super.setUp(); - - sampleName = "ll_CC_VVVV"; - longULocaleName = "ll_Ssss_CC_VVVV@collation=phonebook;key=value"; - longULocaleBasename = longULocaleName.substring(0, longULocaleName.indexOf('@')); - nonNormalizedName = "LL_ssss_cc_VVVV@ Key = value ; Collation = phonebook ; "; - longULocale = new ULocale(longULocaleName); - sampleLocale = new ULocale(sampleName).toLocale(); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.hashCode()' - */ - public void testHashCode() { - ULocale obj = ULocale.GERMANY; - ULocale eq = new ULocale("de_DE"); - ULocale neq = new ULocale("de_DE_FRENCH"); - - ICUTestCase.testEHCS(obj, eq, neq); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.forLocale(Locale)' - */ - public void testForLocale() { - assertEquals(ULocale.GERMANY, ULocale.forLocale(Locale.GERMANY)); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String)' - */ - public void testULocaleString() { - assertEquals(ULocale.GERMAN, new ULocale("de")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String)' - */ - public void testULocaleStringString() { - assertEquals(ULocale.GERMANY, new ULocale("de", "DE")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String, String)' - */ - public void testULocaleStringStringString() { - assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.createCanonical(String)' - */ - public void testCreateCanonical() { - ULocale result = ULocale.createCanonical("de__PHONEBOOK"); - assertEquals(new ULocale("de@collation=phonebook"), result); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.toLocale()' - */ - public void testToLocale() { - assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDefault()' - */ - public void testGetDefault() { - assertEquals(Locale.getDefault(), ULocale.getDefault().toLocale()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.setDefault(ULocale)' - */ - public void testSetDefault() { - Locale oldLocale = Locale.getDefault(); - ULocale oldULocale = ULocale.getDefault(); - try { - ULocale.setDefault(longULocale); - ICUTestCase.assertNotEqual(Locale.getDefault(), oldLocale); - ICUTestCase.assertNotEqual(ULocale.getDefault(), oldULocale); - assertEquals(longULocale, ULocale.getDefault()); - assertEquals(sampleLocale, Locale.getDefault()); - } - finally { - ULocale.setDefault(oldULocale); - Locale.setDefault(oldLocale); // in case of some error - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.clone()' - */ - public void testClone() { - // see testHashcode - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.equals(Object)' - */ - public void testEqualsObject() { - // see testHashcode - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getAvailableLocales()' - */ - public void testGetAvailableLocales() { - ULocale[] ulocales = ULocale.getAvailableLocales(); - if (ICUTestCase.testingWrapper) { - Locale[] locales = Locale.getAvailableLocales(); - for (int i = 0; i < ulocales.length; ++i) { - assertEquals(ulocales[i].toLocale(), locales[i]); - } - } - // else nothing to test except that the function returned. - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISOCountries()' - */ - public void testGetISOCountries() { - String[] ucountries = ULocale.getISOCountries(); - assertNotNull(ucountries); - if (ICUTestCase.testingWrapper) { - // keep our own data for now - // our data doesn't match java's so this test would fail - // TODO: enable if we decide to use java's data - // String[] countries = Locale.getISOCountries(); - // TestBoilerplate.assertArraysEqual(ucountries, countries); - } - // else nothing to test except that the function returned. - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISOLanguages()' - */ - public void testGetISOLanguages() { - String[] ulanguages = ULocale.getISOLanguages(); - assertNotNull(ulanguages); - if (ICUTestCase.testingWrapper) { - // keep our own data for now - // our data doesn't match java's so this test would fail - // TODO: enable if we decide to use java's data - // String[] languages = Locale.getISOLanguages(); - // TestBoilerplate.assertArraysEqual(ulanguages, languages); - } - // else nothing to test except that the function returned. - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage()' - */ - public void testGetLanguage() { - assertEquals("ll", longULocale.getLanguage()); - assertEquals("ll", longULocale.toLocale().getLanguage()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage(String)' - */ - public void testGetLanguageString() { - assertEquals("ll", ULocale.getLanguage(longULocale.getName())); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getScript()' - */ - public void testGetScript() { - assertEquals("Ssss", longULocale.getScript()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getScript(String)' - */ - public void testGetScriptString() { - assertEquals("Ssss", ULocale.getScript(longULocale.getName())); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getCountry()' - */ - public void testGetCountry() { - assertEquals("CC", longULocale.getCountry()); - assertEquals("CC", longULocale.toLocale().getCountry()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getCountry(String)' - */ - public void testGetCountryString() { - assertEquals("CC", ULocale.getCountry(longULocale.getName())); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getVariant()' - */ - public void testGetVariant() { - assertEquals("VVVV", longULocale.getVariant()); - assertEquals("VVVV", longULocale.toLocale().getVariant()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getVariant(String)' - */ - public void testGetVariantString() { - assertEquals("VVVV", ULocale.getVariant(longULocale.getName())); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getFallback(String)' - */ - public void testGetFallbackString() { - assertEquals(ULocale.GERMAN, ULocale.getFallback(ULocale.GERMANY.getName())); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getFallback()' - */ - public void testGetFallback() { - assertEquals(ULocale.GERMAN, ULocale.GERMANY.getFallback()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName()' - */ - public void testGetBaseName() { - assertEquals(longULocaleBasename, longULocale.getBaseName()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName(String)' - */ - public void testGetBaseNameString() { - assertEquals(longULocaleBasename, longULocale.getBaseName()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getName()' - */ - public void testGetName() { - assertEquals(longULocaleName, longULocale.getName()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getName(String)' - */ - public void testGetNameString() { - assertEquals(longULocaleName, ULocale.getName(nonNormalizedName)); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.toString()' - */ - public void testToString() { - assertEquals(longULocaleName, longULocale.toString()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords()' - */ - public void testGetKeywords() { - Iterator iter = longULocale.getKeywords(); - assertEquals(iter.next(), "collation"); - assertEquals(iter.next(), "key"); - assertFalse(iter.hasNext()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords(String)' - */ - public void testGetKeywordsString() { - Iterator iter = ULocale.getKeywords(nonNormalizedName); - assertEquals(iter.next(), "collation"); - assertEquals(iter.next(), "key"); - assertFalse(iter.hasNext()); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String)' - */ - public void testGetKeywordValueString() { - assertEquals("value", longULocale.getKeywordValue("key")); - assertEquals("phonebook", longULocale.getKeywordValue("collation")); - assertNull(longULocale.getKeywordValue("zzyzx")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String, String)' - */ - public void testGetKeywordValueStringString() { - assertEquals("value", ULocale.getKeywordValue(longULocaleName, "key")); - assertEquals("phonebook", ULocale.getKeywordValue(longULocaleName, "collation")); - assertNull(ULocale.getKeywordValue(longULocaleName, "zzyzx")); - - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.canonicalize(String)' - */ - public void testCanonicalize() { - assertEquals("de@collation=phonebook", ULocale.canonicalize("de__PHONEBOOK")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String)' - */ - public void testSetKeywordValueStringString() { - ULocale munged = longULocale.setKeywordValue("key", "C#"); - assertEquals("C#", munged.getKeywordValue("key")); - munged = munged.setKeywordValue("zzyzx", "grue"); - assertEquals("grue", munged.getKeywordValue("zzyzx")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String, String)' - */ - public void testSetKeywordValueStringStringString() { - String munged = ULocale.setKeywordValue(longULocaleName, "key", "C#"); - assertEquals("C#", ULocale.getKeywordValue(munged, "key")); - munged = ULocale.setKeywordValue(munged, "zzyzx", "grue"); - assertEquals("grue", ULocale.getKeywordValue(munged, "zzyzx")); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language()' - */ - public void testGetISO3Language() { - String il = ULocale.GERMANY.getISO3Language(); - String jl = Locale.GERMANY.getISO3Language(); - assertEquals(il, jl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language(String)' - */ - public void testGetISO3LanguageString() { - String il = ULocale.getISO3Language(ULocale.GERMANY.getName()); - String jl = Locale.GERMANY.getISO3Language(); - assertEquals(il, jl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country()' - */ - public void testGetISO3Country() { - String ic = ULocale.GERMANY.getISO3Country(); - String jc = Locale.GERMANY.getISO3Country(); - assertEquals(ic, jc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country(String)' - */ - public void testGetISO3CountryString() { - String ic = ULocale.getISO3Country(ULocale.GERMANY.getName()); - String jc = Locale.GERMANY.getISO3Country(); - assertEquals(ic, jc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage()' - */ - public void testGetDisplayLanguage() { - String idl = ULocale.GERMANY.getDisplayLanguage(); - String jdl = Locale.GERMANY.getDisplayLanguage(); - assertEquals(idl, jdl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(ULocale)' - */ - public void testGetDisplayLanguageULocale() { - String idl = ULocale.GERMANY.getDisplayLanguage(ULocale.GERMANY); - String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); - assertEquals(idl, jdl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, String)' - */ - public void testGetDisplayLanguageStringString() { - String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), "de_DE"); - String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); - assertEquals(idl, jdl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, ULocale)' - */ - public void testGetDisplayLanguageStringULocale() { - String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), ULocale.GERMANY); - String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); - assertEquals(idl, jdl); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript()' - */ - public void testGetDisplayScript() { - String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript(); - if (ICUTestCase.testingWrapper) { - assertEquals("Hant", is); - } else { - assertEquals("Traditional Chinese", is); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(ULocale)' - */ - public void testGetDisplayScriptULocale() { - String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript(ULocale.GERMANY); - if (ICUTestCase.testingWrapper) { - assertEquals("Hant", is); - } else { - // TODO: look up expected value - assertEquals("Hant", is); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, String)' - */ - public void testGetDisplayScriptStringString() { - String is = ULocale.getDisplayScript("zh_Hant", "de_DE"); - if (ICUTestCase.testingWrapper) { - assertEquals("Hant", is); - } else { - // TODO: look up expected value - assertEquals("Hant", is); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, ULocale)' - */ - public void testGetDisplayScriptStringULocale() { - String is = ULocale.getDisplayScript("zh_Hant", ULocale.GERMANY); - if (ICUTestCase.testingWrapper) { - assertEquals("Hant", is); - } else { - // TODO: look up expected value - assertEquals("Hant", is); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry()' - */ - public void testGetDisplayCountry() { - String idc = ULocale.GERMANY.getDisplayCountry(); - String jdc = Locale.GERMANY.getDisplayCountry(); - assertEquals(idc, jdc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(ULocale)' - */ - public void testGetDisplayCountryULocale() { - String idc = ULocale.GERMANY.getDisplayCountry(ULocale.GERMANY); - String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); - assertEquals(idc, jdc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, String)' - */ - public void testGetDisplayCountryStringString() { - String idc = ULocale.getDisplayCountry("de_DE", "de_DE"); - String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); - assertEquals(idc, jdc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, ULocale)' - */ - public void testGetDisplayCountryStringULocale() { - String idc = ULocale.getDisplayCountry("de_DE", ULocale.GERMANY); - String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); - assertEquals(idc, jdc); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant()' - */ - public void testGetDisplayVariant() { - String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant(); - String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(); - assertEquals(jdv, idv); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(ULocale)' - */ - public void testGetDisplayVariantULocale() { - String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant(ULocale.GERMANY); - String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); - assertEquals(jdv, idv); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, String)' - */ - public void testGetDisplayVariantStringString() { - String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", "de_DE"); - String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); - assertEquals(jdv, idv); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, ULocale)' - */ - public void testGetDisplayVariantStringULocale() { - String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", ULocale.GERMANY); - String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); - assertEquals(jdv, idv); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String)' - */ - public void testGetDisplayKeywordString() { - String idk = ULocale.getDisplayKeyword("collation"); - assertEquals("collation", idk); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, String)' - */ - public void testGetDisplayKeywordStringString() { - String idk = ULocale.getDisplayKeyword("collation", "de_DE"); - if (ICUTestCase.testingWrapper) { - assertEquals("collation", idk); - } else { - // TODO: find real value - assertEquals("collation", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, ULocale)' - */ - public void testGetDisplayKeywordStringULocale() { - String idk = ULocale.getDisplayKeyword("collation", ULocale.GERMANY); - if (ICUTestCase.testingWrapper) { - assertEquals("collation", idk); - } else { - // TODO: find real value - assertEquals("collation", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String)' - */ - public void testGetDisplayKeywordValueString() { - ULocale ul = new ULocale("de_DE@collation=phonebook"); - String idk = ul.getDisplayKeywordValue("collation"); - if (ICUTestCase.testingWrapper) { - assertEquals("phonebook", idk); - } else { - // TODO: find real value - assertEquals("phonebook", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, ULocale)' - */ - public void testGetDisplayKeywordValueStringULocale() { - ULocale ul = new ULocale("de_DE@collation=phonebook"); - String idk = ul.getDisplayKeywordValue("collation", ULocale.GERMANY); - if (ICUTestCase.testingWrapper) { - assertEquals("phonebook", idk); - } else { - // TODO: find real value - assertEquals("phonebook", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, String)' - */ - public void testGetDisplayKeywordValueStringStringString() { - String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", "de_DE"); - if (ICUTestCase.testingWrapper) { - assertEquals("phonebook", idk); - } else { - // TODO: find real value - assertEquals("phonebook", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, ULocale)' - */ - public void testGetDisplayKeywordValueStringStringULocale() { - String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", ULocale.GERMANY); - if (ICUTestCase.testingWrapper) { - assertEquals("phonebook", idk); - } else { - // TODO: find real value - assertEquals("phonebook", idk); - } - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName()' - */ - public void testGetDisplayName() { - String idn = ULocale.GERMANY.getDisplayName(); - String jdn = Locale.GERMANY.getDisplayName(); - assertEquals(idn, jdn); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(ULocale)' - */ - public void testGetDisplayNameULocale() { - String idn = ULocale.GERMANY.getDisplayName(ULocale.GERMANY); - String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); - assertEquals(idn, jdn); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, String)' - */ - public void testGetDisplayNameStringString() { - String idn = ULocale.getDisplayName("de_DE", "de_DE"); - String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); - assertEquals(idn, jdn); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, ULocale)' - */ - public void testGetDisplayNameStringULocale() { - String idn = ULocale.getDisplayName("de_DE", ULocale.GERMANY); - String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); - assertEquals(idn, jdn); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, ULocale[], boolean[])' - */ - public void testAcceptLanguageStringULocaleArrayBooleanArray() { - boolean[] fallback = new boolean[1]; - ULocale[] locales = { - new ULocale("en_CA"), - new ULocale("es_US"), - }; - ULocale result = ULocale.acceptLanguage("en-US, en-GB, en-CA, es-US", locales, fallback); - assertEquals(new ULocale("en_CA"), result); - assertFalse(fallback[0]); - result = ULocale.acceptLanguage("en-US, en-GB, es-US-NEWMEXICO", locales, fallback); - assertEquals(new ULocale("es_US"), result); - assertTrue(fallback[0]); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], ULocale[], boolean[])' - */ - public void testAcceptLanguageULocaleArrayULocaleArrayBooleanArray() { - boolean[] fallback = new boolean[1]; - ULocale[] locales = { - new ULocale("en_CA"), - new ULocale("es_US"), - }; - ULocale[] accept_locales = { - new ULocale("en_US"), - new ULocale("en_GB"), - new ULocale("en_CA"), - new ULocale("es_US"), - }; - ULocale[] accept_locales2 = { - new ULocale("en_US"), - new ULocale("en_GB"), - new ULocale("es_US_NEWMEXICO"), - }; - ULocale result = ULocale.acceptLanguage(accept_locales, locales, fallback); - assertEquals(new ULocale("en_CA"), result); - assertFalse(fallback[0]); - result = ULocale.acceptLanguage(accept_locales2, locales, fallback); - assertEquals(new ULocale("es_US"), result); - assertTrue(fallback[0]); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, boolean[])' - */ - public void testAcceptLanguageStringBooleanArray() { - boolean[] fallback = new boolean[1]; - ULocale result = ULocale.acceptLanguage("en-CA, en-GB, es-US", fallback); - assertEquals(new ULocale("en_CA"), result); - assertFalse(fallback[0]); - result = ULocale.acceptLanguage("es-US-NEWMEXICO", fallback); - assertNotNull(result); // actual result depends on jdk - assertTrue(fallback[0]); - } - - /* - * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], boolean[])' - */ - public void testAcceptLanguageULocaleArrayBooleanArray() { - boolean[] fallback = new boolean[1]; - ULocale[] accept_locales = { - new ULocale("en_CA"), - new ULocale("en_GB"), - new ULocale("es_US"), - }; - ULocale[] accept_locales2 = { - new ULocale("es_US_NEWMEXICO"), - }; - ULocale result = ULocale.acceptLanguage(accept_locales, fallback); - assertEquals(new ULocale("en_CA"), result); - assertFalse(fallback[0]); - result = ULocale.acceptLanguage(accept_locales2, fallback); - assertNotNull(result); // actual result depends on jdk - assertTrue(fallback[0]); - } -} +/* + ******************************************************************************* + * Copyright (C) 2006-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.tests; + +import java.util.Iterator; +import java.util.Locale; + +import com.ibm.icu.util.ULocale; + +public class ULocaleTest extends ICUTestCase { + private String sampleName; + private String longULocaleName; + private String longULocaleBasename; + private String nonNormalizedName; + private ULocale longULocale; + private Locale sampleLocale; + + /** + * @Override + */ + protected void setUp() throws Exception { + super.setUp(); + + sampleName = "ll_CC_VVVV"; + longULocaleName = "ll_Ssss_CC_VVVV@collation=phonebook;key=value"; + longULocaleBasename = longULocaleName.substring(0, longULocaleName.indexOf('@')); + nonNormalizedName = "LL_ssss_cc_VVVV@ Key = value ; Collation = phonebook ; "; + longULocale = new ULocale(longULocaleName); + sampleLocale = new ULocale(sampleName).toLocale(); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.hashCode()' + */ + public void testHashCode() { + ULocale obj = ULocale.GERMANY; + ULocale eq = new ULocale("de_DE"); + ULocale neq = new ULocale("de_DE_FRENCH"); + + ICUTestCase.testEHCS(obj, eq, neq); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.forLocale(Locale)' + */ + public void testForLocale() { + assertEquals(ULocale.GERMANY, ULocale.forLocale(Locale.GERMANY)); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String)' + */ + public void testULocaleString() { + assertEquals(ULocale.GERMAN, new ULocale("de")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String)' + */ + public void testULocaleStringString() { + assertEquals(ULocale.GERMANY, new ULocale("de", "DE")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String, String)' + */ + public void testULocaleStringStringString() { + assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.createCanonical(String)' + */ + public void testCreateCanonical() { + ULocale result = ULocale.createCanonical("de__PHONEBOOK"); + assertEquals(new ULocale("de@collation=phonebook"), result); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.toLocale()' + */ + public void testToLocale() { + assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDefault()' + */ + public void testGetDefault() { + assertEquals(Locale.getDefault(), ULocale.getDefault().toLocale()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.setDefault(ULocale)' + */ + public void testSetDefault() { + Locale oldLocale = Locale.getDefault(); + ULocale oldULocale = ULocale.getDefault(); + try { + ULocale.setDefault(longULocale); + ICUTestCase.assertNotEqual(Locale.getDefault(), oldLocale); + ICUTestCase.assertNotEqual(ULocale.getDefault(), oldULocale); + assertEquals(longULocale, ULocale.getDefault()); + assertEquals(sampleLocale, Locale.getDefault()); + } + finally { + ULocale.setDefault(oldULocale); + Locale.setDefault(oldLocale); // in case of some error + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.clone()' + */ + public void testClone() { + // see testHashcode + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.equals(Object)' + */ + public void testEqualsObject() { + // see testHashcode + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getAvailableLocales()' + */ + public void testGetAvailableLocales() { + ULocale[] ulocales = ULocale.getAvailableLocales(); + if (ICUTestCase.testingWrapper) { + Locale[] locales = Locale.getAvailableLocales(); + for (int i = 0; i < ulocales.length; ++i) { + assertEquals(ulocales[i].toLocale(), locales[i]); + } + } + // else nothing to test except that the function returned. + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISOCountries()' + */ + public void testGetISOCountries() { + String[] ucountries = ULocale.getISOCountries(); + assertNotNull(ucountries); + if (ICUTestCase.testingWrapper) { + // keep our own data for now + // our data doesn't match java's so this test would fail + // TODO: enable if we decide to use java's data + // String[] countries = Locale.getISOCountries(); + // TestBoilerplate.assertArraysEqual(ucountries, countries); + } + // else nothing to test except that the function returned. + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISOLanguages()' + */ + public void testGetISOLanguages() { + String[] ulanguages = ULocale.getISOLanguages(); + assertNotNull(ulanguages); + if (ICUTestCase.testingWrapper) { + // keep our own data for now + // our data doesn't match java's so this test would fail + // TODO: enable if we decide to use java's data + // String[] languages = Locale.getISOLanguages(); + // TestBoilerplate.assertArraysEqual(ulanguages, languages); + } + // else nothing to test except that the function returned. + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage()' + */ + public void testGetLanguage() { + assertEquals("ll", longULocale.getLanguage()); + assertEquals("ll", longULocale.toLocale().getLanguage()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage(String)' + */ + public void testGetLanguageString() { + assertEquals("ll", ULocale.getLanguage(longULocale.getName())); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getScript()' + */ + public void testGetScript() { + assertEquals("Ssss", longULocale.getScript()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getScript(String)' + */ + public void testGetScriptString() { + assertEquals("Ssss", ULocale.getScript(longULocale.getName())); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getCountry()' + */ + public void testGetCountry() { + assertEquals("CC", longULocale.getCountry()); + assertEquals("CC", longULocale.toLocale().getCountry()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getCountry(String)' + */ + public void testGetCountryString() { + assertEquals("CC", ULocale.getCountry(longULocale.getName())); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getVariant()' + */ + public void testGetVariant() { + assertEquals("VVVV", longULocale.getVariant()); + assertEquals("VVVV", longULocale.toLocale().getVariant()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getVariant(String)' + */ + public void testGetVariantString() { + assertEquals("VVVV", ULocale.getVariant(longULocale.getName())); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getFallback(String)' + */ + public void testGetFallbackString() { + assertEquals(ULocale.GERMAN, ULocale.getFallback(ULocale.GERMANY.getName())); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getFallback()' + */ + public void testGetFallback() { + assertEquals(ULocale.GERMAN, ULocale.GERMANY.getFallback()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName()' + */ + public void testGetBaseName() { + assertEquals(longULocaleBasename, longULocale.getBaseName()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName(String)' + */ + public void testGetBaseNameString() { + assertEquals(longULocaleBasename, longULocale.getBaseName()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getName()' + */ + public void testGetName() { + assertEquals(longULocaleName, longULocale.getName()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getName(String)' + */ + public void testGetNameString() { + assertEquals(longULocaleName, ULocale.getName(nonNormalizedName)); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.toString()' + */ + public void testToString() { + assertEquals(longULocaleName, longULocale.toString()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords()' + */ + public void testGetKeywords() { + Iterator iter = longULocale.getKeywords(); + assertEquals(iter.next(), "collation"); + assertEquals(iter.next(), "key"); + assertFalse(iter.hasNext()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords(String)' + */ + public void testGetKeywordsString() { + Iterator iter = ULocale.getKeywords(nonNormalizedName); + assertEquals(iter.next(), "collation"); + assertEquals(iter.next(), "key"); + assertFalse(iter.hasNext()); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String)' + */ + public void testGetKeywordValueString() { + assertEquals("value", longULocale.getKeywordValue("key")); + assertEquals("phonebook", longULocale.getKeywordValue("collation")); + assertNull(longULocale.getKeywordValue("zzyzx")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String, String)' + */ + public void testGetKeywordValueStringString() { + assertEquals("value", ULocale.getKeywordValue(longULocaleName, "key")); + assertEquals("phonebook", ULocale.getKeywordValue(longULocaleName, "collation")); + assertNull(ULocale.getKeywordValue(longULocaleName, "zzyzx")); + + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.canonicalize(String)' + */ + public void testCanonicalize() { + assertEquals("de@collation=phonebook", ULocale.canonicalize("de__PHONEBOOK")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String)' + */ + public void testSetKeywordValueStringString() { + ULocale munged = longULocale.setKeywordValue("key", "C#"); + assertEquals("C#", munged.getKeywordValue("key")); + munged = munged.setKeywordValue("zzyzx", "grue"); + assertEquals("grue", munged.getKeywordValue("zzyzx")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String, String)' + */ + public void testSetKeywordValueStringStringString() { + String munged = ULocale.setKeywordValue(longULocaleName, "key", "C#"); + assertEquals("C#", ULocale.getKeywordValue(munged, "key")); + munged = ULocale.setKeywordValue(munged, "zzyzx", "grue"); + assertEquals("grue", ULocale.getKeywordValue(munged, "zzyzx")); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language()' + */ + public void testGetISO3Language() { + String il = ULocale.GERMANY.getISO3Language(); + String jl = Locale.GERMANY.getISO3Language(); + assertEquals(il, jl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language(String)' + */ + public void testGetISO3LanguageString() { + String il = ULocale.getISO3Language(ULocale.GERMANY.getName()); + String jl = Locale.GERMANY.getISO3Language(); + assertEquals(il, jl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country()' + */ + public void testGetISO3Country() { + String ic = ULocale.GERMANY.getISO3Country(); + String jc = Locale.GERMANY.getISO3Country(); + assertEquals(ic, jc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country(String)' + */ + public void testGetISO3CountryString() { + String ic = ULocale.getISO3Country(ULocale.GERMANY.getName()); + String jc = Locale.GERMANY.getISO3Country(); + assertEquals(ic, jc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage()' + */ + public void testGetDisplayLanguage() { + String idl = ULocale.GERMANY.getDisplayLanguage(); + String jdl = Locale.GERMANY.getDisplayLanguage(); + assertEquals(idl, jdl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(ULocale)' + */ + public void testGetDisplayLanguageULocale() { + String idl = ULocale.GERMANY.getDisplayLanguage(ULocale.GERMANY); + String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); + assertEquals(idl, jdl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, String)' + */ + public void testGetDisplayLanguageStringString() { + String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), "de_DE"); + String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); + assertEquals(idl, jdl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, ULocale)' + */ + public void testGetDisplayLanguageStringULocale() { + String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), ULocale.GERMANY); + String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY); + assertEquals(idl, jdl); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript()' + */ + public void testGetDisplayScript() { + String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript(); + if (ICUTestCase.testingWrapper) { + assertEquals("Hant", is); + } else { + assertEquals("Traditional Chinese", is); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(ULocale)' + */ + public void testGetDisplayScriptULocale() { + String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript(ULocale.GERMANY); + if (ICUTestCase.testingWrapper) { + assertEquals("Hant", is); + } else { + // TODO: look up expected value + assertEquals("Hant", is); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, String)' + */ + public void testGetDisplayScriptStringString() { + String is = ULocale.getDisplayScript("zh_Hant", "de_DE"); + if (ICUTestCase.testingWrapper) { + assertEquals("Hant", is); + } else { + // TODO: look up expected value + assertEquals("Hant", is); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, ULocale)' + */ + public void testGetDisplayScriptStringULocale() { + String is = ULocale.getDisplayScript("zh_Hant", ULocale.GERMANY); + if (ICUTestCase.testingWrapper) { + assertEquals("Hant", is); + } else { + // TODO: look up expected value + assertEquals("Hant", is); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry()' + */ + public void testGetDisplayCountry() { + String idc = ULocale.GERMANY.getDisplayCountry(); + String jdc = Locale.GERMANY.getDisplayCountry(); + assertEquals(idc, jdc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(ULocale)' + */ + public void testGetDisplayCountryULocale() { + String idc = ULocale.GERMANY.getDisplayCountry(ULocale.GERMANY); + String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); + assertEquals(idc, jdc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, String)' + */ + public void testGetDisplayCountryStringString() { + String idc = ULocale.getDisplayCountry("de_DE", "de_DE"); + String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); + assertEquals(idc, jdc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, ULocale)' + */ + public void testGetDisplayCountryStringULocale() { + String idc = ULocale.getDisplayCountry("de_DE", ULocale.GERMANY); + String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY); + assertEquals(idc, jdc); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant()' + */ + public void testGetDisplayVariant() { + String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant(); + String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(); + assertEquals(jdv, idv); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(ULocale)' + */ + public void testGetDisplayVariantULocale() { + String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant(ULocale.GERMANY); + String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); + assertEquals(jdv, idv); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, String)' + */ + public void testGetDisplayVariantStringString() { + String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", "de_DE"); + String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); + assertEquals(jdv, idv); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, ULocale)' + */ + public void testGetDisplayVariantStringULocale() { + String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", ULocale.GERMANY); + String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY); + assertEquals(jdv, idv); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String)' + */ + public void testGetDisplayKeywordString() { + String idk = ULocale.getDisplayKeyword("collation"); + assertEquals("collation", idk); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, String)' + */ + public void testGetDisplayKeywordStringString() { + String idk = ULocale.getDisplayKeyword("collation", "de_DE"); + if (ICUTestCase.testingWrapper) { + assertEquals("collation", idk); + } else { + // TODO: find real value + assertEquals("collation", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, ULocale)' + */ + public void testGetDisplayKeywordStringULocale() { + String idk = ULocale.getDisplayKeyword("collation", ULocale.GERMANY); + if (ICUTestCase.testingWrapper) { + assertEquals("collation", idk); + } else { + // TODO: find real value + assertEquals("collation", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String)' + */ + public void testGetDisplayKeywordValueString() { + ULocale ul = new ULocale("de_DE@collation=phonebook"); + String idk = ul.getDisplayKeywordValue("collation"); + if (ICUTestCase.testingWrapper) { + assertEquals("phonebook", idk); + } else { + // TODO: find real value + assertEquals("phonebook", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, ULocale)' + */ + public void testGetDisplayKeywordValueStringULocale() { + ULocale ul = new ULocale("de_DE@collation=phonebook"); + String idk = ul.getDisplayKeywordValue("collation", ULocale.GERMANY); + if (ICUTestCase.testingWrapper) { + assertEquals("phonebook", idk); + } else { + // TODO: find real value + assertEquals("phonebook", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, String)' + */ + public void testGetDisplayKeywordValueStringStringString() { + String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", "de_DE"); + if (ICUTestCase.testingWrapper) { + assertEquals("phonebook", idk); + } else { + // TODO: find real value + assertEquals("phonebook", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, ULocale)' + */ + public void testGetDisplayKeywordValueStringStringULocale() { + String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", ULocale.GERMANY); + if (ICUTestCase.testingWrapper) { + assertEquals("phonebook", idk); + } else { + // TODO: find real value + assertEquals("phonebook", idk); + } + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName()' + */ + public void testGetDisplayName() { + String idn = ULocale.GERMANY.getDisplayName(); + String jdn = Locale.GERMANY.getDisplayName(); + assertEquals(idn, jdn); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(ULocale)' + */ + public void testGetDisplayNameULocale() { + String idn = ULocale.GERMANY.getDisplayName(ULocale.GERMANY); + String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); + assertEquals(idn, jdn); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, String)' + */ + public void testGetDisplayNameStringString() { + String idn = ULocale.getDisplayName("de_DE", "de_DE"); + String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); + assertEquals(idn, jdn); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, ULocale)' + */ + public void testGetDisplayNameStringULocale() { + String idn = ULocale.getDisplayName("de_DE", ULocale.GERMANY); + String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY); + assertEquals(idn, jdn); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, ULocale[], boolean[])' + */ + public void testAcceptLanguageStringULocaleArrayBooleanArray() { + boolean[] fallback = new boolean[1]; + ULocale[] locales = { + new ULocale("en_CA"), + new ULocale("es_US"), + }; + ULocale result = ULocale.acceptLanguage("en-US, en-GB, en-CA, es-US", locales, fallback); + assertEquals(new ULocale("en_CA"), result); + assertFalse(fallback[0]); + result = ULocale.acceptLanguage("en-US, en-GB, es-US-NEWMEXICO", locales, fallback); + assertEquals(new ULocale("es_US"), result); + assertTrue(fallback[0]); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], ULocale[], boolean[])' + */ + public void testAcceptLanguageULocaleArrayULocaleArrayBooleanArray() { + boolean[] fallback = new boolean[1]; + ULocale[] locales = { + new ULocale("en_CA"), + new ULocale("es_US"), + }; + ULocale[] accept_locales = { + new ULocale("en_US"), + new ULocale("en_GB"), + new ULocale("en_CA"), + new ULocale("es_US"), + }; + ULocale[] accept_locales2 = { + new ULocale("en_US"), + new ULocale("en_GB"), + new ULocale("es_US_NEWMEXICO"), + }; + ULocale result = ULocale.acceptLanguage(accept_locales, locales, fallback); + assertEquals(new ULocale("en_CA"), result); + assertFalse(fallback[0]); + result = ULocale.acceptLanguage(accept_locales2, locales, fallback); + assertEquals(new ULocale("es_US"), result); + assertTrue(fallback[0]); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, boolean[])' + */ + public void testAcceptLanguageStringBooleanArray() { + boolean[] fallback = new boolean[1]; + ULocale result = ULocale.acceptLanguage("en-CA, en-GB, es-US", fallback); + assertEquals(new ULocale("en_CA"), result); + assertFalse(fallback[0]); + result = ULocale.acceptLanguage("es-US-NEWMEXICO", fallback); + assertNotNull(result); // actual result depends on jdk + assertTrue(fallback[0]); + } + + /* + * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], boolean[])' + */ + public void testAcceptLanguageULocaleArrayBooleanArray() { + boolean[] fallback = new boolean[1]; + ULocale[] accept_locales = { + new ULocale("en_CA"), + new ULocale("en_GB"), + new ULocale("es_US"), + }; + ULocale[] accept_locales2 = { + new ULocale("es_US_NEWMEXICO"), + }; + ULocale result = ULocale.acceptLanguage(accept_locales, fallback); + assertEquals(new ULocale("en_CA"), result); + assertFalse(fallback[0]); + result = ULocale.acceptLanguage(accept_locales2, fallback); + assertNotNull(result); // actual result depends on jdk + assertTrue(fallback[0]); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java index c3ca4b5a207..17828f7763d 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java @@ -1,21 +1,21 @@ -/* - *************************************************************************** - * Copyright (c) 2007-2011 International Business Machines Corporation and * - * others. All rights reserved. * - *************************************************************************** -*/ - -package com.ibm.icu.impl; - -public interface ICUCache { - // Type of reference holding the Map instance - public static final int SOFT = 0; - public static final int WEAK = 1; - - // NULL object, which may be used for a cache key - public static final Object NULL = new Object(); - - public void clear(); - public void put(K key, V value); - public V get(Object key); -} +/* + *************************************************************************** + * Copyright (c) 2007-2011 International Business Machines Corporation and * + * others. All rights reserved. * + *************************************************************************** +*/ + +package com.ibm.icu.impl; + +public interface ICUCache { + // Type of reference holding the Map instance + public static final int SOFT = 0; + public static final int WEAK = 1; + + // NULL object, which may be used for a cache key + public static final Object NULL = new Object(); + + public void clear(); + public void put(K key, V value); + public V get(Object key); +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java index a9d0d306893..67690da5796 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java @@ -1,741 +1,741 @@ -/* -****************************************************************************** -* Copyright (C) 2003-2011, International Business Machines Corporation and * -* others. All Rights Reserved. * -****************************************************************************** -*/ - -package com.ibm.icu.impl; - -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Map; -import java.util.TreeMap; - -import com.ibm.icu.impl.locale.AsciiUtil; - -/** - * Utility class to parse and normalize locale ids (including POSIX style) - */ -public final class LocaleIDParser { - private char[] id; - private int index; - private char[] buffer; - private int blen; - // um, don't handle POSIX ids unless we request it. why not? well... because. - private boolean canonicalize; - private boolean hadCountry; - - // used when canonicalizing - Map keywords; - String baseName; - - /** - * Parsing constants. - */ - private static final char KEYWORD_SEPARATOR = '@'; - private static final char HYPHEN = '-'; - private static final char KEYWORD_ASSIGN = '='; - private static final char COMMA = ','; - private static final char ITEM_SEPARATOR = ';'; - private static final char DOT = '.'; - private static final char UNDERSCORE = '_'; - - public LocaleIDParser(String localeID) { - this(localeID, false); - } - - public LocaleIDParser(String localeID, boolean canonicalize) { - id = localeID.toCharArray(); - index = 0; - buffer = new char[id.length + 5]; - blen = 0; - this.canonicalize = canonicalize; - } - - private void reset() { - index = blen = 0; - } - - // utilities for working on text in the buffer - - /** - * Append c to the buffer. - */ - private void append(char c) { - try { - buffer[blen] = c; - } - catch (IndexOutOfBoundsException e) { - if (buffer.length > 512) { - // something is seriously wrong, let this go - throw e; - } - char[] nbuffer = new char[buffer.length * 2]; - System.arraycopy(buffer, 0, nbuffer, 0, buffer.length); - nbuffer[blen] = c; - buffer = nbuffer; - } - ++blen; - } - - private void addSeparator() { - append(UNDERSCORE); - } - - /** - * Returns the text in the buffer from start to blen as a String. - */ - private String getString(int start) { - if (start == blen) { - return ""; - } - return new String(buffer, start, blen-start); - } - - /** - * Set the length of the buffer to pos, then append the string. - */ - private void set(int pos, String s) { - this.blen = pos; // no safety - append(s); - } - - /** - * Append the string to the buffer. - */ - private void append(String s) { - for (int i = 0; i < s.length(); ++i) { - append(s.charAt(i)); - } - } - - // utilities for parsing text out of the id - - /** - * Character to indicate no more text is available in the id. - */ - private static final char DONE = '\uffff'; - - /** - * Returns the character at index in the id, and advance index. The returned character - * is DONE if index was at the limit of the buffer. The index is advanced regardless - * so that decrementing the index will always 'unget' the last character returned. - */ - private char next() { - if (index == id.length) { - index++; - return DONE; - } - - return id[index++]; - } - - /** - * Advance index until the next terminator or id separator, and leave it there. - */ - private void skipUntilTerminatorOrIDSeparator() { - while (!isTerminatorOrIDSeparator(next())) { - } - --index; - } - - /** - * Returns true if the character at index in the id is a terminator. - */ - private boolean atTerminator() { - return index >= id.length || isTerminator(id[index]); - } - - /* - * Returns true if the character is an id separator (underscore or hyphen). - */ - /* private boolean isIDSeparator(char c) { - return c == UNDERSCORE || c == HYPHEN; - }*/ - - /** - * Returns true if the character is a terminator (keyword separator, dot, or DONE). - * Dot is a terminator because of the POSIX form, where dot precedes the codepage. - */ - private boolean isTerminator(char c) { - // always terminate at DOT, even if not handling POSIX. It's an error... - return c == KEYWORD_SEPARATOR || c == DONE || c == DOT; - } - - /** - * Returns true if the character is a terminator or id separator. - */ - private boolean isTerminatorOrIDSeparator(char c) { - return c == KEYWORD_SEPARATOR || c == UNDERSCORE || c == HYPHEN || - c == DONE || c == DOT; - } - - /** - * Returns true if the start of the buffer has an experimental or private language - * prefix, the pattern '[ixIX][-_].' shows the syntax checked. - */ - private boolean haveExperimentalLanguagePrefix() { - if (id.length > 2) { - char c = id[1]; - if (c == HYPHEN || c == UNDERSCORE) { - c = id[0]; - return c == 'x' || c == 'X' || c == 'i' || c == 'I'; - } - } - return false; - } - - /** - * Returns true if a value separator occurs at or after index. - */ - private boolean haveKeywordAssign() { - // assume it is safe to start from index - for (int i = index; i < id.length; ++i) { - if (id[i] == KEYWORD_ASSIGN) { - return true; - } - } - return false; - } - - /** - * Advance index past language, and accumulate normalized language code in buffer. - * Index must be at 0 when this is called. Index is left at a terminator or id - * separator. Returns the start of the language code in the buffer. - */ - private int parseLanguage() { - if (haveExperimentalLanguagePrefix()) { - append(Character.toLowerCase(id[0])); - append(HYPHEN); - index = 2; - } - - char c; - while(!isTerminatorOrIDSeparator(c = next())) { - append(Character.toLowerCase(c)); - } - --index; // unget - - if (blen == 3) { - String lang = LocaleIDs.threeToTwoLetterLanguage(getString(0)); - if (lang != null) { - set(0, lang); - } - } - - return 0; - } - - /** - * Advance index past language. Index must be at 0 when this is called. Index - * is left at a terminator or id separator. - */ - private void skipLanguage() { - if (haveExperimentalLanguagePrefix()) { - index = 2; - } - skipUntilTerminatorOrIDSeparator(); - } - - /** - * Advance index past script, and accumulate normalized script in buffer. - * Index must be immediately after the language. - * If the item at this position is not a script (is not four characters - * long) leave index and buffer unchanged. Otherwise index is left at - * a terminator or id separator. Returns the start of the script code - * in the buffer (this may be equal to the buffer length, if there is no - * script). - */ - private int parseScript() { - if (!atTerminator()) { - int oldIndex = index; // save original index - ++index; - - int oldBlen = blen; // get before append hyphen, if we truncate everything is undone - char c; - while(!isTerminatorOrIDSeparator(c = next())) { - if (blen == oldBlen) { // first pass - addSeparator(); - append(Character.toUpperCase(c)); - } else { - append(Character.toLowerCase(c)); - } - } - --index; // unget - - /* If it's not exactly 4 characters long, then it's not a script. */ - if (index - oldIndex != 5) { // +1 to account for separator - index = oldIndex; - blen = oldBlen; - } else { - oldBlen++; // index past hyphen, for clients who want to extract just the script - } - - return oldBlen; - } - return blen; - } - - /** - * Advance index past script. - * Index must be immediately after the language and IDSeparator. - * If the item at this position is not a script (is not four characters - * long) leave index. Otherwise index is left at a terminator or - * id separator. - */ - private void skipScript() { - if (!atTerminator()) { - int oldIndex = index; - ++index; - - skipUntilTerminatorOrIDSeparator(); - if (index - oldIndex != 5) { // +1 to account for separator - index = oldIndex; - } - } - } - - /** - * Advance index past country, and accumulate normalized country in buffer. - * Index must be immediately after the script (if there is one, else language) - * and IDSeparator. Return the start of the country code in the buffer. - */ - private int parseCountry() { - if (!atTerminator()) { - int oldIndex = index; - ++index; - - int oldBlen = blen; - char c; - while (!isTerminatorOrIDSeparator(c = next())) { - if (oldBlen == blen) { // first, add hyphen - hadCountry = true; // we have a country, let variant parsing know - addSeparator(); - ++oldBlen; // increment past hyphen - } - append(Character.toUpperCase(c)); - } - --index; // unget - - int charsAppended = blen - oldBlen; - - if (charsAppended == 0) { - // Do nothing. - } - else if (charsAppended < 2 || charsAppended > 3) { - // It's not a country, so return index and blen to - // their previous values. - index = oldIndex; - --oldBlen; - blen = oldBlen; - hadCountry = false; - } - else if (charsAppended == 3) { - String region = LocaleIDs.threeToTwoLetterRegion(getString(oldBlen)); - if (region != null) { - set(oldBlen, region); - } - } - - return oldBlen; - } - - return blen; - } - - /** - * Advance index past country. - * Index must be immediately after the script (if there is one, else language) - * and IDSeparator. - */ - private void skipCountry() { - if (!atTerminator()) { - ++index; - /* - * Save the index point after the separator, since the format - * requires two separators if the country is not present. - */ - int oldIndex = index; - - skipUntilTerminatorOrIDSeparator(); - int charsSkipped = index - oldIndex; - if (charsSkipped < 2 || charsSkipped > 3) { - index = oldIndex; - } - } - } - - /** - * Advance index past variant, and accumulate normalized variant in buffer. This ignores - * the codepage information from POSIX ids. Index must be immediately after the country - * or script. Index is left at the keyword separator or at the end of the text. Return - * the start of the variant code in the buffer. - * - * In standard form, we can have the following forms: - * ll__VVVV - * ll_CC_VVVV - * ll_Ssss_VVVV - * ll_Ssss_CC_VVVV - * - * This also handles POSIX ids, which can have the following forms (pppp is code page id): - * ll_CC.pppp --> ll_CC - * ll_CC.pppp@VVVV --> ll_CC_VVVV - * ll_CC@VVVV --> ll_CC_VVVV - * - * We identify this use of '@' in POSIX ids by looking for an '=' following - * the '@'. If there is one, we consider '@' to start a keyword list, instead of - * being part of a POSIX id. - * - * Note: since it was decided that we want an option to not handle POSIX ids, this - * becomes a bit more complex. - */ - private int parseVariant() { - int oldBlen = blen; - - boolean start = true; - boolean needSeparator = true; - boolean skipping = false; - char c; - while ((c = next()) != DONE) { - if (c == DOT) { - start = false; - skipping = true; - } else if (c == KEYWORD_SEPARATOR) { - if (haveKeywordAssign()) { - break; - } - skipping = false; - start = false; - needSeparator = true; // add another underscore if we have more text - } else if (start) { - start = false; - } else if (!skipping) { - if (needSeparator) { - boolean incOldBlen = blen == oldBlen; // need to skip separators - needSeparator = false; - if (incOldBlen && !hadCountry) { // no country, we'll need two - addSeparator(); - ++oldBlen; // for sure - } - addSeparator(); - if (incOldBlen) { // only for the first separator - ++oldBlen; - } - } - c = Character.toUpperCase(c); - if (c == HYPHEN || c == COMMA) { - c = UNDERSCORE; - } - append(c); - } - } - --index; // unget - - return oldBlen; - } - - // no need for skipvariant, to get the keywords we'll just scan directly for - // the keyword separator - - /** - * Returns the normalized language id, or the empty string. - */ - public String getLanguage() { - reset(); - return getString(parseLanguage()); - } - - /** - * Returns the normalized script id, or the empty string. - */ - public String getScript() { - reset(); - skipLanguage(); - return getString(parseScript()); - } - - /** - * return the normalized country id, or the empty string. - */ - public String getCountry() { - reset(); - skipLanguage(); - skipScript(); - return getString(parseCountry()); - } - - /** - * Returns the normalized variant id, or the empty string. - */ - public String getVariant() { - reset(); - skipLanguage(); - skipScript(); - skipCountry(); - return getString(parseVariant()); - } - - /** - * Returns the language, script, country, and variant as separate strings. - */ - public String[] getLanguageScriptCountryVariant() { - reset(); - return new String[] { - getString(parseLanguage()), - getString(parseScript()), - getString(parseCountry()), - getString(parseVariant()) - }; - } - - public void setBaseName(String baseName) { - this.baseName = baseName; - } - - public void parseBaseName() { - if (baseName != null) { - set(0, baseName); - } else { - reset(); - parseLanguage(); - parseScript(); - parseCountry(); - parseVariant(); - - // catch unwanted trailing underscore after country if there was no variant - if (blen > 1 && buffer[blen-1] == UNDERSCORE) { - --blen; - } - } - } - - /** - * Returns the normalized base form of the locale id. The base - * form does not include keywords. - */ - public String getBaseName() { - if (baseName != null) { - return baseName; - } - parseBaseName(); - return getString(0); - } - - /** - * Returns the normalized full form of the locale id. The full - * form includes keywords if they are present. - */ - public String getName() { - parseBaseName(); - parseKeywords(); - return getString(0); - } - - // keyword utilities - - /** - * If we have keywords, advance index to the start of the keywords and return true, - * otherwise return false. - */ - private boolean setToKeywordStart() { - for (int i = index; i < id.length; ++i) { - if (id[i] == KEYWORD_SEPARATOR) { - if (canonicalize) { - for (int j = ++i; j < id.length; ++j) { // increment i past separator for return - if (id[j] == KEYWORD_ASSIGN) { - index = i; - return true; - } - } - } else { - if (++i < id.length) { - index = i; - return true; - } - } - break; - } - } - return false; - } - - private static boolean isDoneOrKeywordAssign(char c) { - return c == DONE || c == KEYWORD_ASSIGN; - } - - private static boolean isDoneOrItemSeparator(char c) { - return c == DONE || c == ITEM_SEPARATOR; - } - - private String getKeyword() { - int start = index; - while (!isDoneOrKeywordAssign(next())) { - } - --index; - return AsciiUtil.toLowerString(new String(id, start, index-start).trim()); - } - - private String getValue() { - int start = index; - while (!isDoneOrItemSeparator(next())) { - } - --index; - return new String(id, start, index-start).trim(); // leave case alone - } - - private Comparator getKeyComparator() { - final Comparator comp = new Comparator() { - public int compare(String lhs, String rhs) { - return lhs.compareTo(rhs); - } - }; - return comp; - } - - /** - * Returns a map of the keywords and values, or null if there are none. - */ - public Map getKeywordMap() { - if (keywords == null) { - TreeMap m = null; - if (setToKeywordStart()) { - // trim spaces and convert to lower case, both keywords and values. - do { - String key = getKeyword(); - if (key.length() == 0) { - break; - } - char c = next(); - if (c != KEYWORD_ASSIGN) { - // throw new IllegalArgumentException("key '" + key + "' missing a value."); - if (c == DONE) { - break; - } else { - continue; - } - } - String value = getValue(); - if (value.length() == 0) { - // throw new IllegalArgumentException("key '" + key + "' missing a value."); - continue; - } - if (m == null) { - m = new TreeMap(getKeyComparator()); - } else if (m.containsKey(key)) { - // throw new IllegalArgumentException("key '" + key + "' already has a value."); - continue; - } - m.put(key, value); - } while (next() == ITEM_SEPARATOR); - } - keywords = m != null ? m : Collections.emptyMap(); - } - - return keywords; - } - - - /** - * Parse the keywords and return start of the string in the buffer. - */ - private int parseKeywords() { - int oldBlen = blen; - Map m = getKeywordMap(); - if (!m.isEmpty()) { - boolean first = true; - for (Map.Entry e : m.entrySet()) { - append(first ? KEYWORD_SEPARATOR : ITEM_SEPARATOR); - first = false; - append(e.getKey()); - append(KEYWORD_ASSIGN); - append(e.getValue()); - } - if (blen != oldBlen) { - ++oldBlen; - } - } - return oldBlen; - } - - /** - * Returns an iterator over the keywords, or null if we have an empty map. - */ - public Iterator getKeywords() { - Map m = getKeywordMap(); - return m.isEmpty() ? null : m.keySet().iterator(); - } - - /** - * Returns the value for the named keyword, or null if the keyword is not - * present. - */ - public String getKeywordValue(String keywordName) { - Map m = getKeywordMap(); - return m.isEmpty() ? null : m.get(AsciiUtil.toLowerString(keywordName.trim())); - } - - /** - * Set the keyword value only if it is not already set to something else. - */ - public void defaultKeywordValue(String keywordName, String value) { - setKeywordValue(keywordName, value, false); - } - - /** - * Set the value for the named keyword, or unset it if value is null. If - * keywordName itself is null, unset all keywords. If keywordName is not null, - * value must not be null. - */ - public void setKeywordValue(String keywordName, String value) { - setKeywordValue(keywordName, value, true); - } - - /** - * Set the value for the named keyword, or unset it if value is null. If - * keywordName itself is null, unset all keywords. If keywordName is not null, - * value must not be null. If reset is true, ignore any previous value for - * the keyword, otherwise do not change the keyword (including removal of - * one or all keywords). - */ - private void setKeywordValue(String keywordName, String value, boolean reset) { - if (keywordName == null) { - if (reset) { - // force new map, ignore value - keywords = Collections.emptyMap(); - } - } else { - keywordName = AsciiUtil.toLowerString(keywordName.trim()); - if (keywordName.length() == 0) { - throw new IllegalArgumentException("keyword must not be empty"); - } - if (value != null) { - value = value.trim(); - if (value.length() == 0) { - throw new IllegalArgumentException("value must not be empty"); - } - } - Map m = getKeywordMap(); - if (m.isEmpty()) { // it is EMPTY_MAP - if (value != null) { - // force new map - keywords = new TreeMap(getKeyComparator()); - keywords.put(keywordName, value.trim()); - } - } else { - if (reset || !m.containsKey(keywordName)) { - if (value != null) { - m.put(keywordName, value); - } else { - m.remove(keywordName); - if (m.isEmpty()) { - // force new map - keywords = Collections.emptyMap(); - } - } - } - } - } - } +/* +****************************************************************************** +* Copyright (C) 2003-2011, International Business Machines Corporation and * +* others. All Rights Reserved. * +****************************************************************************** +*/ + +package com.ibm.icu.impl; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import com.ibm.icu.impl.locale.AsciiUtil; + +/** + * Utility class to parse and normalize locale ids (including POSIX style) + */ +public final class LocaleIDParser { + private char[] id; + private int index; + private char[] buffer; + private int blen; + // um, don't handle POSIX ids unless we request it. why not? well... because. + private boolean canonicalize; + private boolean hadCountry; + + // used when canonicalizing + Map keywords; + String baseName; + + /** + * Parsing constants. + */ + private static final char KEYWORD_SEPARATOR = '@'; + private static final char HYPHEN = '-'; + private static final char KEYWORD_ASSIGN = '='; + private static final char COMMA = ','; + private static final char ITEM_SEPARATOR = ';'; + private static final char DOT = '.'; + private static final char UNDERSCORE = '_'; + + public LocaleIDParser(String localeID) { + this(localeID, false); + } + + public LocaleIDParser(String localeID, boolean canonicalize) { + id = localeID.toCharArray(); + index = 0; + buffer = new char[id.length + 5]; + blen = 0; + this.canonicalize = canonicalize; + } + + private void reset() { + index = blen = 0; + } + + // utilities for working on text in the buffer + + /** + * Append c to the buffer. + */ + private void append(char c) { + try { + buffer[blen] = c; + } + catch (IndexOutOfBoundsException e) { + if (buffer.length > 512) { + // something is seriously wrong, let this go + throw e; + } + char[] nbuffer = new char[buffer.length * 2]; + System.arraycopy(buffer, 0, nbuffer, 0, buffer.length); + nbuffer[blen] = c; + buffer = nbuffer; + } + ++blen; + } + + private void addSeparator() { + append(UNDERSCORE); + } + + /** + * Returns the text in the buffer from start to blen as a String. + */ + private String getString(int start) { + if (start == blen) { + return ""; + } + return new String(buffer, start, blen-start); + } + + /** + * Set the length of the buffer to pos, then append the string. + */ + private void set(int pos, String s) { + this.blen = pos; // no safety + append(s); + } + + /** + * Append the string to the buffer. + */ + private void append(String s) { + for (int i = 0; i < s.length(); ++i) { + append(s.charAt(i)); + } + } + + // utilities for parsing text out of the id + + /** + * Character to indicate no more text is available in the id. + */ + private static final char DONE = '\uffff'; + + /** + * Returns the character at index in the id, and advance index. The returned character + * is DONE if index was at the limit of the buffer. The index is advanced regardless + * so that decrementing the index will always 'unget' the last character returned. + */ + private char next() { + if (index == id.length) { + index++; + return DONE; + } + + return id[index++]; + } + + /** + * Advance index until the next terminator or id separator, and leave it there. + */ + private void skipUntilTerminatorOrIDSeparator() { + while (!isTerminatorOrIDSeparator(next())) { + } + --index; + } + + /** + * Returns true if the character at index in the id is a terminator. + */ + private boolean atTerminator() { + return index >= id.length || isTerminator(id[index]); + } + + /* + * Returns true if the character is an id separator (underscore or hyphen). + */ + /* private boolean isIDSeparator(char c) { + return c == UNDERSCORE || c == HYPHEN; + }*/ + + /** + * Returns true if the character is a terminator (keyword separator, dot, or DONE). + * Dot is a terminator because of the POSIX form, where dot precedes the codepage. + */ + private boolean isTerminator(char c) { + // always terminate at DOT, even if not handling POSIX. It's an error... + return c == KEYWORD_SEPARATOR || c == DONE || c == DOT; + } + + /** + * Returns true if the character is a terminator or id separator. + */ + private boolean isTerminatorOrIDSeparator(char c) { + return c == KEYWORD_SEPARATOR || c == UNDERSCORE || c == HYPHEN || + c == DONE || c == DOT; + } + + /** + * Returns true if the start of the buffer has an experimental or private language + * prefix, the pattern '[ixIX][-_].' shows the syntax checked. + */ + private boolean haveExperimentalLanguagePrefix() { + if (id.length > 2) { + char c = id[1]; + if (c == HYPHEN || c == UNDERSCORE) { + c = id[0]; + return c == 'x' || c == 'X' || c == 'i' || c == 'I'; + } + } + return false; + } + + /** + * Returns true if a value separator occurs at or after index. + */ + private boolean haveKeywordAssign() { + // assume it is safe to start from index + for (int i = index; i < id.length; ++i) { + if (id[i] == KEYWORD_ASSIGN) { + return true; + } + } + return false; + } + + /** + * Advance index past language, and accumulate normalized language code in buffer. + * Index must be at 0 when this is called. Index is left at a terminator or id + * separator. Returns the start of the language code in the buffer. + */ + private int parseLanguage() { + if (haveExperimentalLanguagePrefix()) { + append(Character.toLowerCase(id[0])); + append(HYPHEN); + index = 2; + } + + char c; + while(!isTerminatorOrIDSeparator(c = next())) { + append(Character.toLowerCase(c)); + } + --index; // unget + + if (blen == 3) { + String lang = LocaleIDs.threeToTwoLetterLanguage(getString(0)); + if (lang != null) { + set(0, lang); + } + } + + return 0; + } + + /** + * Advance index past language. Index must be at 0 when this is called. Index + * is left at a terminator or id separator. + */ + private void skipLanguage() { + if (haveExperimentalLanguagePrefix()) { + index = 2; + } + skipUntilTerminatorOrIDSeparator(); + } + + /** + * Advance index past script, and accumulate normalized script in buffer. + * Index must be immediately after the language. + * If the item at this position is not a script (is not four characters + * long) leave index and buffer unchanged. Otherwise index is left at + * a terminator or id separator. Returns the start of the script code + * in the buffer (this may be equal to the buffer length, if there is no + * script). + */ + private int parseScript() { + if (!atTerminator()) { + int oldIndex = index; // save original index + ++index; + + int oldBlen = blen; // get before append hyphen, if we truncate everything is undone + char c; + while(!isTerminatorOrIDSeparator(c = next())) { + if (blen == oldBlen) { // first pass + addSeparator(); + append(Character.toUpperCase(c)); + } else { + append(Character.toLowerCase(c)); + } + } + --index; // unget + + /* If it's not exactly 4 characters long, then it's not a script. */ + if (index - oldIndex != 5) { // +1 to account for separator + index = oldIndex; + blen = oldBlen; + } else { + oldBlen++; // index past hyphen, for clients who want to extract just the script + } + + return oldBlen; + } + return blen; + } + + /** + * Advance index past script. + * Index must be immediately after the language and IDSeparator. + * If the item at this position is not a script (is not four characters + * long) leave index. Otherwise index is left at a terminator or + * id separator. + */ + private void skipScript() { + if (!atTerminator()) { + int oldIndex = index; + ++index; + + skipUntilTerminatorOrIDSeparator(); + if (index - oldIndex != 5) { // +1 to account for separator + index = oldIndex; + } + } + } + + /** + * Advance index past country, and accumulate normalized country in buffer. + * Index must be immediately after the script (if there is one, else language) + * and IDSeparator. Return the start of the country code in the buffer. + */ + private int parseCountry() { + if (!atTerminator()) { + int oldIndex = index; + ++index; + + int oldBlen = blen; + char c; + while (!isTerminatorOrIDSeparator(c = next())) { + if (oldBlen == blen) { // first, add hyphen + hadCountry = true; // we have a country, let variant parsing know + addSeparator(); + ++oldBlen; // increment past hyphen + } + append(Character.toUpperCase(c)); + } + --index; // unget + + int charsAppended = blen - oldBlen; + + if (charsAppended == 0) { + // Do nothing. + } + else if (charsAppended < 2 || charsAppended > 3) { + // It's not a country, so return index and blen to + // their previous values. + index = oldIndex; + --oldBlen; + blen = oldBlen; + hadCountry = false; + } + else if (charsAppended == 3) { + String region = LocaleIDs.threeToTwoLetterRegion(getString(oldBlen)); + if (region != null) { + set(oldBlen, region); + } + } + + return oldBlen; + } + + return blen; + } + + /** + * Advance index past country. + * Index must be immediately after the script (if there is one, else language) + * and IDSeparator. + */ + private void skipCountry() { + if (!atTerminator()) { + ++index; + /* + * Save the index point after the separator, since the format + * requires two separators if the country is not present. + */ + int oldIndex = index; + + skipUntilTerminatorOrIDSeparator(); + int charsSkipped = index - oldIndex; + if (charsSkipped < 2 || charsSkipped > 3) { + index = oldIndex; + } + } + } + + /** + * Advance index past variant, and accumulate normalized variant in buffer. This ignores + * the codepage information from POSIX ids. Index must be immediately after the country + * or script. Index is left at the keyword separator or at the end of the text. Return + * the start of the variant code in the buffer. + * + * In standard form, we can have the following forms: + * ll__VVVV + * ll_CC_VVVV + * ll_Ssss_VVVV + * ll_Ssss_CC_VVVV + * + * This also handles POSIX ids, which can have the following forms (pppp is code page id): + * ll_CC.pppp --> ll_CC + * ll_CC.pppp@VVVV --> ll_CC_VVVV + * ll_CC@VVVV --> ll_CC_VVVV + * + * We identify this use of '@' in POSIX ids by looking for an '=' following + * the '@'. If there is one, we consider '@' to start a keyword list, instead of + * being part of a POSIX id. + * + * Note: since it was decided that we want an option to not handle POSIX ids, this + * becomes a bit more complex. + */ + private int parseVariant() { + int oldBlen = blen; + + boolean start = true; + boolean needSeparator = true; + boolean skipping = false; + char c; + while ((c = next()) != DONE) { + if (c == DOT) { + start = false; + skipping = true; + } else if (c == KEYWORD_SEPARATOR) { + if (haveKeywordAssign()) { + break; + } + skipping = false; + start = false; + needSeparator = true; // add another underscore if we have more text + } else if (start) { + start = false; + } else if (!skipping) { + if (needSeparator) { + boolean incOldBlen = blen == oldBlen; // need to skip separators + needSeparator = false; + if (incOldBlen && !hadCountry) { // no country, we'll need two + addSeparator(); + ++oldBlen; // for sure + } + addSeparator(); + if (incOldBlen) { // only for the first separator + ++oldBlen; + } + } + c = Character.toUpperCase(c); + if (c == HYPHEN || c == COMMA) { + c = UNDERSCORE; + } + append(c); + } + } + --index; // unget + + return oldBlen; + } + + // no need for skipvariant, to get the keywords we'll just scan directly for + // the keyword separator + + /** + * Returns the normalized language id, or the empty string. + */ + public String getLanguage() { + reset(); + return getString(parseLanguage()); + } + + /** + * Returns the normalized script id, or the empty string. + */ + public String getScript() { + reset(); + skipLanguage(); + return getString(parseScript()); + } + + /** + * return the normalized country id, or the empty string. + */ + public String getCountry() { + reset(); + skipLanguage(); + skipScript(); + return getString(parseCountry()); + } + + /** + * Returns the normalized variant id, or the empty string. + */ + public String getVariant() { + reset(); + skipLanguage(); + skipScript(); + skipCountry(); + return getString(parseVariant()); + } + + /** + * Returns the language, script, country, and variant as separate strings. + */ + public String[] getLanguageScriptCountryVariant() { + reset(); + return new String[] { + getString(parseLanguage()), + getString(parseScript()), + getString(parseCountry()), + getString(parseVariant()) + }; + } + + public void setBaseName(String baseName) { + this.baseName = baseName; + } + + public void parseBaseName() { + if (baseName != null) { + set(0, baseName); + } else { + reset(); + parseLanguage(); + parseScript(); + parseCountry(); + parseVariant(); + + // catch unwanted trailing underscore after country if there was no variant + if (blen > 1 && buffer[blen-1] == UNDERSCORE) { + --blen; + } + } + } + + /** + * Returns the normalized base form of the locale id. The base + * form does not include keywords. + */ + public String getBaseName() { + if (baseName != null) { + return baseName; + } + parseBaseName(); + return getString(0); + } + + /** + * Returns the normalized full form of the locale id. The full + * form includes keywords if they are present. + */ + public String getName() { + parseBaseName(); + parseKeywords(); + return getString(0); + } + + // keyword utilities + + /** + * If we have keywords, advance index to the start of the keywords and return true, + * otherwise return false. + */ + private boolean setToKeywordStart() { + for (int i = index; i < id.length; ++i) { + if (id[i] == KEYWORD_SEPARATOR) { + if (canonicalize) { + for (int j = ++i; j < id.length; ++j) { // increment i past separator for return + if (id[j] == KEYWORD_ASSIGN) { + index = i; + return true; + } + } + } else { + if (++i < id.length) { + index = i; + return true; + } + } + break; + } + } + return false; + } + + private static boolean isDoneOrKeywordAssign(char c) { + return c == DONE || c == KEYWORD_ASSIGN; + } + + private static boolean isDoneOrItemSeparator(char c) { + return c == DONE || c == ITEM_SEPARATOR; + } + + private String getKeyword() { + int start = index; + while (!isDoneOrKeywordAssign(next())) { + } + --index; + return AsciiUtil.toLowerString(new String(id, start, index-start).trim()); + } + + private String getValue() { + int start = index; + while (!isDoneOrItemSeparator(next())) { + } + --index; + return new String(id, start, index-start).trim(); // leave case alone + } + + private Comparator getKeyComparator() { + final Comparator comp = new Comparator() { + public int compare(String lhs, String rhs) { + return lhs.compareTo(rhs); + } + }; + return comp; + } + + /** + * Returns a map of the keywords and values, or null if there are none. + */ + public Map getKeywordMap() { + if (keywords == null) { + TreeMap m = null; + if (setToKeywordStart()) { + // trim spaces and convert to lower case, both keywords and values. + do { + String key = getKeyword(); + if (key.length() == 0) { + break; + } + char c = next(); + if (c != KEYWORD_ASSIGN) { + // throw new IllegalArgumentException("key '" + key + "' missing a value."); + if (c == DONE) { + break; + } else { + continue; + } + } + String value = getValue(); + if (value.length() == 0) { + // throw new IllegalArgumentException("key '" + key + "' missing a value."); + continue; + } + if (m == null) { + m = new TreeMap(getKeyComparator()); + } else if (m.containsKey(key)) { + // throw new IllegalArgumentException("key '" + key + "' already has a value."); + continue; + } + m.put(key, value); + } while (next() == ITEM_SEPARATOR); + } + keywords = m != null ? m : Collections.emptyMap(); + } + + return keywords; + } + + + /** + * Parse the keywords and return start of the string in the buffer. + */ + private int parseKeywords() { + int oldBlen = blen; + Map m = getKeywordMap(); + if (!m.isEmpty()) { + boolean first = true; + for (Map.Entry e : m.entrySet()) { + append(first ? KEYWORD_SEPARATOR : ITEM_SEPARATOR); + first = false; + append(e.getKey()); + append(KEYWORD_ASSIGN); + append(e.getValue()); + } + if (blen != oldBlen) { + ++oldBlen; + } + } + return oldBlen; + } + + /** + * Returns an iterator over the keywords, or null if we have an empty map. + */ + public Iterator getKeywords() { + Map m = getKeywordMap(); + return m.isEmpty() ? null : m.keySet().iterator(); + } + + /** + * Returns the value for the named keyword, or null if the keyword is not + * present. + */ + public String getKeywordValue(String keywordName) { + Map m = getKeywordMap(); + return m.isEmpty() ? null : m.get(AsciiUtil.toLowerString(keywordName.trim())); + } + + /** + * Set the keyword value only if it is not already set to something else. + */ + public void defaultKeywordValue(String keywordName, String value) { + setKeywordValue(keywordName, value, false); + } + + /** + * Set the value for the named keyword, or unset it if value is null. If + * keywordName itself is null, unset all keywords. If keywordName is not null, + * value must not be null. + */ + public void setKeywordValue(String keywordName, String value) { + setKeywordValue(keywordName, value, true); + } + + /** + * Set the value for the named keyword, or unset it if value is null. If + * keywordName itself is null, unset all keywords. If keywordName is not null, + * value must not be null. If reset is true, ignore any previous value for + * the keyword, otherwise do not change the keyword (including removal of + * one or all keywords). + */ + private void setKeywordValue(String keywordName, String value, boolean reset) { + if (keywordName == null) { + if (reset) { + // force new map, ignore value + keywords = Collections.emptyMap(); + } + } else { + keywordName = AsciiUtil.toLowerString(keywordName.trim()); + if (keywordName.length() == 0) { + throw new IllegalArgumentException("keyword must not be empty"); + } + if (value != null) { + value = value.trim(); + if (value.length() == 0) { + throw new IllegalArgumentException("value must not be empty"); + } + } + Map m = getKeywordMap(); + if (m.isEmpty()) { // it is EMPTY_MAP + if (value != null) { + // force new map + keywords = new TreeMap(getKeyComparator()); + keywords.put(keywordName, value.trim()); + } + } else { + if (reset || !m.containsKey(keywordName)) { + if (value != null) { + m.put(keywordName, value); + } else { + m.remove(keywordName); + if (m.isEmpty()) { + // force new map + keywords = Collections.emptyMap(); + } + } + } + } + } + } } \ No newline at end of file diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java index 8edd3d48003..34c0a5b26d6 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java @@ -1,536 +1,536 @@ -/* - ******************************************************************************* - * Copyright (C) 2009-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.impl; - -import java.util.MissingResourceException; - -import com.ibm.icu.util.ULocale; - - -/** - * Utilities for mapping between old and new language, country, and other - * locale ID related names. - */ -public class LocaleIDs { - - /** - * Returns a list of all 2-letter country codes defined in ISO 3166. - * Can be used to create Locales. - * @stable ICU 3.0 - */ - public static String[] getISOCountries() { - initCountryTables(); - return _countries.clone(); - } - - /** - * Returns a list of all 2-letter language codes defined in ISO 639. - * Can be used to create Locales. - * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed. - * The list this function returns includes both the new and the old codes for the - * languages whose codes have changed.] - * @stable ICU 3.0 - */ - public static String[] getISOLanguages() { - initLanguageTables(); - return _languages.clone(); - } - - /** - * Returns a three-letter abbreviation for the provided country. If the provided - * country is empty, returns the empty string. Otherwise, returns - * an uppercase ISO 3166 3-letter country code. - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter country abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public static String getISO3Country(String country){ - initCountryTables(); - - int offset = findIndex(_countries, country); - if(offset>=0){ - return _countries3[offset]; - }else{ - offset = findIndex(_obsoleteCountries, country); - if(offset>=0){ - return _obsoleteCountries3[offset]; - } - } - return ""; - } - /** - * Returns a three-letter abbreviation for the language. If language is - * empty, returns the empty string. Otherwise, returns - * a lowercase ISO 639-2/T language code. - * The ISO 639-2 language codes can be found on-line at - * ftp://dkuug.dk/i18n/iso-639-2.txt - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter language abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public static String getISO3Language(String language) { - initLanguageTables(); - - int offset = findIndex(_languages, language); - if(offset>=0){ - return _languages3[offset]; - } else { - offset = findIndex(_obsoleteLanguages, language); - if (offset >= 0) { - return _obsoleteLanguages3[offset]; - } - } - return ""; - } - - public static String threeToTwoLetterLanguage(String lang) { - initLanguageTables(); - - /* convert 3 character code to 2 character code if possible *CWB*/ - int offset = findIndex(_languages3, lang); - if (offset >= 0) { - return _languages[offset]; - } - - offset = findIndex(_obsoleteLanguages3, lang); - if (offset >= 0) { - return _obsoleteLanguages[offset]; - } - - return null; - } - - public static String threeToTwoLetterRegion(String region) { - initCountryTables(); - - /* convert 3 character code to 2 character code if possible *CWB*/ - int offset = findIndex(_countries3, region); - if (offset >= 0) { - return _countries[offset]; - } - - offset = findIndex(_obsoleteCountries3, region); - if (offset >= 0) { - return _obsoleteCountries[offset]; - } - - return null; - } - - /** - * linear search of the string array. the arrays are unfortunately ordered by the - * two-letter target code, not the three-letter search code, which seems backwards. - */ - private static int findIndex(String[] array, String target){ - for (int i = 0; i < array.length; i++) { - if (target.equals(array[i])) { - return i; - } - } - return -1; - } - - - /** - * Tables used in normalizing portions of the id. - */ - /* tables updated per http://lcweb.loc.gov/standards/iso639-2/ - to include the revisions up to 2001/7/27 *CWB*/ - /* The 3 character codes are the terminology codes like RFC 3066. - This is compatible with prior ICU codes */ - /* "in" "iw" "ji" "jw" & "sh" have been withdrawn but are still in - the table but now at the end of the table because - 3 character codes are duplicates. This avoids bad searches - going from 3 to 2 character codes.*/ - /* The range qaa-qtz is reserved for local use. */ - - private static String[] _languages; - private static String[] _replacementLanguages; - private static String[] _obsoleteLanguages; - private static String[] _languages3; - private static String[] _obsoleteLanguages3; - - // Avoid initializing languages tables unless we have to. - private static void initLanguageTables() { - if (_languages == null) { - - /* This list MUST be in sorted order, and MUST contain the two-letter codes - if one exists otherwise use the three letter code */ - String[] tempLanguages = { - "aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", "afa", - "afh", "ak", "akk", "ale", "alg", "am", "an", "ang", "apa", - "ar", "arc", "arn", "arp", "art", "arw", "as", "ast", - "ath", "aus", "av", "awa", "ay", "az", "ba", "bad", - "bai", "bal", "ban", "bas", "bat", "be", "bej", - "bem", "ber", "bg", "bh", "bho", "bi", "bik", "bin", - "bla", "bm", "bn", "bnt", "bo", "br", "bra", "bs", - "btk", "bua", "bug", "byn", "ca", "cad", "cai", "car", "cau", - "ce", "ceb", "cel", "ch", "chb", "chg", "chk", "chm", - "chn", "cho", "chp", "chr", "chy", "cmc", "co", "cop", - "cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", "csb", "cu", "cus", - "cv", "cy", "da", "dak", "dar", "day", "de", "del", "den", - "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv", "dyu", - "dz", "ee", "efi", "egy", "eka", "el", "elx", "en", - "enm", "eo", "es", "et", "eu", "ewo", "fa", - "fan", "fat", "ff", "fi", "fiu", "fj", "fo", "fon", - "fr", "frm", "fro", "fur", "fy", "ga", "gaa", "gay", - "gba", "gd", "gem", "gez", "gil", "gl", "gmh", "gn", - "goh", "gon", "gor", "got", "grb", "grc", "gu", "gv", - "gwi", "ha", "hai", "haw", "he", "hi", "hil", "him", - "hit", "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", "hz", - "ia", "iba", "id", "ie", "ig", "ii", "ijo", "ik", - "ilo", "inc", "ine", "inh", "io", "ira", "iro", "is", "it", - "iu", "ja", "jbo", "jpr", "jrb", "jv", "ka", "kaa", "kab", - "kac", "kam", "kar", "kaw", "kbd", "kg", "kha", "khi", - "kho", "ki", "kj", "kk", "kl", "km", "kmb", "kn", - "ko", "kok", "kos", "kpe", "kr", "krc", "kro", "kru", "ks", - "ku", "kum", "kut", "kv", "kw", "ky", "la", "lad", - "lah", "lam", "lb", "lez", "lg", "li", "ln", "lo", "lol", - "loz", "lt", "lu", "lua", "lui", "lun", "luo", "lus", - "lv", "mad", "mag", "mai", "mak", "man", "map", "mas", - "mdf", "mdr", "men", "mg", "mga", "mh", "mi", "mic", "min", - "mis", "mk", "mkh", "ml", "mn", "mnc", "mni", "mno", - "mo", "moh", "mos", "mr", "ms", "mt", "mul", "mun", - "mus", "mwr", "my", "myn", "myv", "na", "nah", "nai", "nap", - "nb", "nd", "nds", "ne", "new", "ng", "nia", "nic", - "niu", "nl", "nn", "no", "nog", "non", "nr", "nso", "nub", - "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oc", "oj", - "om", "or", "os", "osa", "ota", "oto", "pa", "paa", - "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", - "pi", "pl", "pon", "pra", "pro", "ps", "pt", "qu", - "raj", "rap", "rar", "rm", "rn", "ro", "roa", "rom", - "ru", "rup", "rw", "sa", "sad", "sah", "sai", "sal", "sam", - "sas", "sat", "sc", "sco", "sd", "se", "sel", "sem", - "sg", "sga", "sgn", "shn", "si", "sid", "sio", "sit", - "sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", - "sms", "sn", "snk", "so", "sog", "son", "sq", "sr", - "srr", "ss", "ssa", "st", "su", "suk", "sus", "sux", - "sv", "sw", "syr", "ta", "tai", "te", "tem", "ter", - "tet", "tg", "th", "ti", "tig", "tiv", "tk", "tkl", - "tl", "tlh", "tli", "tmh", "tn", "to", "tog", "tpi", "tr", - "ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", - "ty", "tyv", "udm", "ug", "uga", "uk", "umb", "und", "ur", - "uz", "vai", "ve", "vi", "vo", "vot", "wa", "wak", - "wal", "war", "was", "wen", "wo", "xal", "xh", "yao", "yap", - "yi", "yo", "ypk", "za", "zap", "zen", "zh", "znd", - "zu", "zun", - }; - - String[] tempReplacementLanguages = { - "id", "he", "yi", "jv", "sr", "nb",/* replacement language codes */ - }; - - String[] tempObsoleteLanguages = { - "in", "iw", "ji", "jw", "sh", "no", /* obsolete language codes */ - }; - - /* This list MUST contain a three-letter code for every two-letter code in the - list above, and they MUST ne in the same order (i.e., the same language must - be in the same place in both lists)! */ - String[] tempLanguages3 = { - /*"aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", "afa", */ - "aar", "abk", "ace", "ach", "ada", "ady", "ave", "afr", "afa", - /*"afh", "ak", "akk", "ale", "alg", "am", "an", "ang", "apa", */ - "afh", "aka", "akk", "ale", "alg", "amh", "arg", "ang", "apa", - /*"ar", "arc", "arn", "arp", "art", "arw", "as", "ast", */ - "ara", "arc", "arn", "arp", "art", "arw", "asm", "ast", - /*"ath", "aus", "av", "awa", "ay", "az", "ba", "bad", */ - "ath", "aus", "ava", "awa", "aym", "aze", "bak", "bad", - /*"bai", "bal", "ban", "bas", "bat", "be", "bej", */ - "bai", "bal", "ban", "bas", "bat", "bel", "bej", - /*"bem", "ber", "bg", "bh", "bho", "bi", "bik", "bin", */ - "bem", "ber", "bul", "bih", "bho", "bis", "bik", "bin", - /*"bla", "bm", "bn", "bnt", "bo", "br", "bra", "bs", */ - "bla", "bam", "ben", "bnt", "bod", "bre", "bra", "bos", - /*"btk", "bua", "bug", "byn", "ca", "cad", "cai", "car", "cau", */ - "btk", "bua", "bug", "byn", "cat", "cad", "cai", "car", "cau", - /*"ce", "ceb", "cel", "ch", "chb", "chg", "chk", "chm", */ - "che", "ceb", "cel", "cha", "chb", "chg", "chk", "chm", - /*"chn", "cho", "chp", "chr", "chy", "cmc", "co", "cop", */ - "chn", "cho", "chp", "chr", "chy", "cmc", "cos", "cop", - /*"cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", "csb", "cu", "cus", */ - "cpe", "cpf", "cpp", "cre", "crh", "crp", "ces", "csb", "chu", "cus", - /*"cv", "cy", "da", "dak", "dar", "day", "de", "del", "den", */ - "chv", "cym", "dan", "dak", "dar", "day", "deu", "del", "den", - /*"dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv", "dyu", */ - "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "div", "dyu", - /*"dz", "ee", "efi", "egy", "eka", "el", "elx", "en", */ - "dzo", "ewe", "efi", "egy", "eka", "ell", "elx", "eng", - /*"enm", "eo", "es", "et", "eu", "ewo", "fa", */ - "enm", "epo", "spa", "est", "eus", "ewo", "fas", - /*"fan", "fat", "ff", "fi", "fiu", "fj", "fo", "fon", */ - "fan", "fat", "ful", "fin", "fiu", "fij", "fao", "fon", - /*"fr", "frm", "fro", "fur", "fy", "ga", "gaa", "gay", */ - "fra", "frm", "fro", "fur", "fry", "gle", "gaa", "gay", - /*"gba", "gd", "gem", "gez", "gil", "gl", "gmh", "gn", */ - "gba", "gla", "gem", "gez", "gil", "glg", "gmh", "grn", - /*"goh", "gon", "gor", "got", "grb", "grc", "gu", "gv", */ - "goh", "gon", "gor", "got", "grb", "grc", "guj", "glv", - /*"gwi", "ha", "hai", "haw", "he", "hi", "hil", "him", */ - "gwi", "hau", "hai", "haw", "heb", "hin", "hil", "him", - /*"hit", "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", "hz", */ - "hit", "hmn", "hmo", "hrv", "hsb", "hat", "hun", "hup", "hye", "her", - /*"ia", "iba", "id", "ie", "ig", "ii", "ijo", "ik", */ - "ina", "iba", "ind", "ile", "ibo", "iii", "ijo", "ipk", - /*"ilo", "inc", "ine", "inh", "io", "ira", "iro", "is", "it", */ - "ilo", "inc", "ine", "inh", "ido", "ira", "iro", "isl", "ita", - /*"iu", "ja", "jbo", "jpr", "jrb", "jv", "ka", "kaa", "kab", */ - "iku", "jpn", "jbo", "jpr", "jrb", "jaw", "kat", "kaa", "kab", - /*"kac", "kam", "kar", "kaw", "kbd", "kg", "kha", "khi", */ - "kac", "kam", "kar", "kaw", "kbd", "kon", "kha", "khi", - /*"kho", "ki", "kj", "kk", "kl", "km", "kmb", "kn", */ - "kho", "kik", "kua", "kaz", "kal", "khm", "kmb", "kan", - /*"ko", "kok", "kos", "kpe", "kr", "krc", "kro", "kru", "ks", */ - "kor", "kok", "kos", "kpe", "kau", "krc", "kro", "kru", "kas", - /*"ku", "kum", "kut", "kv", "kw", "ky", "la", "lad", */ - "kur", "kum", "kut", "kom", "cor", "kir", "lat", "lad", - /*"lah", "lam", "lb", "lez", "lg", "li", "ln", "lo", "lol", */ - "lah", "lam", "ltz", "lez", "lug", "lim", "lin", "lao", "lol", - /*"loz", "lt", "lu", "lua", "lui", "lun", "luo", "lus", */ - "loz", "lit", "lub", "lua", "lui", "lun", "luo", "lus", - /*"lv", "mad", "mag", "mai", "mak", "man", "map", "mas", */ - "lav", "mad", "mag", "mai", "mak", "man", "map", "mas", - /*"mdf", "mdr", "men", "mg", "mga", "mh", "mi", "mic", "min", */ - "mdf", "mdr", "men", "mlg", "mga", "mah", "mri", "mic", "min", - /*"mis", "mk", "mkh", "ml", "mn", "mnc", "mni", "mno", */ - "mis", "mkd", "mkh", "mal", "mon", "mnc", "mni", "mno", - /*"mo", "moh", "mos", "mr", "ms", "mt", "mul", "mun", */ - "mol", "moh", "mos", "mar", "msa", "mlt", "mul", "mun", - /*"mus", "mwr", "my", "myn", "myv", "na", "nah", "nai", "nap", */ - "mus", "mwr", "mya", "myn", "myv", "nau", "nah", "nai", "nap", - /*"nb", "nd", "nds", "ne", "new", "ng", "nia", "nic", */ - "nob", "nde", "nds", "nep", "new", "ndo", "nia", "nic", - /*"niu", "nl", "nn", "no", "nog", "non", "nr", "nso", "nub", */ - "niu", "nld", "nno", "nor", "nog", "non", "nbl", "nso", "nub", - /*"nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oc", "oj", */ - "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", "oci", "oji", - /*"om", "or", "os", "osa", "ota", "oto", "pa", "paa", */ - "orm", "ori", "oss", "osa", "ota", "oto", "pan", "paa", - /*"pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", */ - "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", - /*"pi", "pl", "pon", "pra", "pro", "ps", "pt", "qu", */ - "pli", "pol", "pon", "pra", "pro", "pus", "por", "que", - /*"raj", "rap", "rar", "rm", "rn", "ro", "roa", "rom", */ - "raj", "rap", "rar", "roh", "run", "ron", "roa", "rom", - /*"ru", "rup", "rw", "sa", "sad", "sah", "sai", "sal", "sam", */ - "rus", "rup", "kin", "san", "sad", "sah", "sai", "sal", "sam", - /*"sas", "sat", "sc", "sco", "sd", "se", "sel", "sem", */ - "sas", "sat", "srd", "sco", "snd", "sme", "sel", "sem", - /*"sg", "sga", "sgn", "shn", "si", "sid", "sio", "sit", */ - "sag", "sga", "sgn", "shn", "sin", "sid", "sio", "sit", - /*"sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", */ - "slk", "slv", "sla", "smo", "sma", "smi", "smj", "smn", - /*"sms", "sn", "snk", "so", "sog", "son", "sq", "sr", */ - "sms", "sna", "snk", "som", "sog", "son", "sqi", "srp", - /*"srr", "ss", "ssa", "st", "su", "suk", "sus", "sux", */ - "srr", "ssw", "ssa", "sot", "sun", "suk", "sus", "sux", - /*"sv", "sw", "syr", "ta", "tai", "te", "tem", "ter", */ - "swe", "swa", "syr", "tam", "tai", "tel", "tem", "ter", - /*"tet", "tg", "th", "ti", "tig", "tiv", "tk", "tkl", */ - "tet", "tgk", "tha", "tir", "tig", "tiv", "tuk", "tkl", - /*"tl", "tlh", "tli", "tmh", "tn", "to", "tog", "tpi", "tr", */ - "tgl", "tlh", "tli", "tmh", "tsn", "ton", "tog", "tpi", "tur", - /*"ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", */ - "tso", "tsi", "tat", "tum", "tup", "tut", "tvl", "twi", - /*"ty", "tyv", "udm", "ug", "uga", "uk", "umb", "und", "ur", */ - "tah", "tyv", "udm", "uig", "uga", "ukr", "umb", "und", "urd", - /*"uz", "vai", "ve", "vi", "vo", "vot", "wa", "wak", */ - "uzb", "vai", "ven", "vie", "vol", "vot", "wln", "wak", - /*"wal", "war", "was", "wen", "wo", "xal", "xh", "yao", "yap", */ - "wal", "war", "was", "wen", "wol", "xal", "xho", "yao", "yap", - /*"yi", "yo", "ypk", "za", "zap", "zen", "zh", "znd", */ - "yid", "yor", "ypk", "zha", "zap", "zen", "zho", "znd", - /*"zu", "zun", */ - "zul", "zun", - }; - - String[] tempObsoleteLanguages3 = { - /* "in", "iw", "ji", "jw", "sh", */ - "ind", "heb", "yid", "jaw", "srp", - }; - - synchronized (ULocale.class) { - if (_languages == null) { - _languages = tempLanguages; - _replacementLanguages = tempReplacementLanguages; - _obsoleteLanguages = tempObsoleteLanguages; - _languages3 = tempLanguages3; - _obsoleteLanguages3 = tempObsoleteLanguages3; - } - } - } - } - - private static String[] _countries; - private static String[] _deprecatedCountries; - private static String[] _replacementCountries; - private static String[] _obsoleteCountries; - private static String[] _countries3; - private static String[] _obsoleteCountries3; - - // Avoid initializing country tables unless we have to. - private static void initCountryTables() { - if (_countries == null) { - /* ZR(ZAR) is now CD(COD) and FX(FXX) is PS(PSE) as per - http://www.evertype.com/standards/iso3166/iso3166-1-en.html - added new codes keeping the old ones for compatibility - updated to include 1999/12/03 revisions *CWB*/ - - /* RO(ROM) is now RO(ROU) according to - http://www.iso.org/iso/en/prods-services/iso3166ma/03updates-on-iso-3166/nlv3e-rou.html - */ - - /* This list MUST be in sorted order, and MUST contain only two-letter codes! */ - String[] tempCountries = { - "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", - "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", - "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", - "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BV", - "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", - "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", - "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", - "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", - "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", - "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", - "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", - "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", - "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", - "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", - "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", - "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", - "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", - "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", - "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", - "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", - "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", - "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", - "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", - "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", - "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", - "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", - "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", - "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", - "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", - "WS", "YE", "YT", "ZA", "ZM", "ZW", - }; - - /* this table is used for 3 letter codes */ - String[] tempObsoleteCountries = { - "FX", "CS", "RO", "TP", "YU", "ZR", /* obsolete country codes */ - }; - - String[] tempDeprecatedCountries = { - "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" /* deprecated country list */ - }; - String[] tempReplacementCountries = { - /* "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" */ - "MM", "RS", "BJ", "FR", "BF", "VU", "ZW", "TL", "RS", "CD", /* replacement country codes */ - }; - - /* This list MUST contain a three-letter code for every two-letter code in - the above list, and they MUST be listed in the same order! */ - String[] tempCountries3 = { - /* "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", */ - "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "ANT", - /* "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", */ - "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "ALA", "AZE", - /* "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", */ - "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI", - /* "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BV", */ - "BEN", "BLM", "BMU", "BRN", "BOL", "BRA", "BHS", "BTN", "BVT", - /* "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", */ - "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", - /* "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", */ - "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", - /* "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", */ - "CUB", "CPV", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK", - /* "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", */ - "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI", - /* "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", */ - "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", - /* "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", */ - "GAB", "GBR", "GRD", "GEO", "GUF", "GGY", "GHA", "GIB", "GRL", - /* "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", */ - "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM", - /* "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", */ - "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN", - /* "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS" */ - "IDN", "IRL", "ISR", "IMN", "IND", "IOT", "IRQ", "IRN", "ISL", - /* "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", */ - "ITA", "JEY", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", - /* "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", */ - "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO", - /* "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", */ - "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", - /* "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", */ - "LVA", "LBY", "MAR", "MCO", "MDA", "MNE", "MAF", "MDG", "MHL", "MKD", - /* "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", */ - "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR", - /* "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", */ - "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM", - /* "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", */ - "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", - /* "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", */ - "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", - /* "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", */ - "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT", - /* "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", */ - "PLW", "PRY", "QAT", "REU", "ROU", "SRB", "RUS", "RWA", "SAU", - /* "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", */ - "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", - /* "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", */ - "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "STP", "SLV", - /* "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", */ - "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK", - /* "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", */ - "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV", - /* "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", */ - "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", - /* "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", */ - "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", - /* "WS", "YE", "YT", "ZA", "ZM", "ZW" */ - "WSM", "YEM", "MYT", "ZAF", "ZMB", "ZWE", - }; - - String[] tempObsoleteCountries3 = { - /*"FX", "CS", "RO", "TP", "YU", "ZR", */ - "FXX", "SCG", "ROM", "TMP", "YUG", "ZAR", - }; - - synchronized (ULocale.class) { - if (_countries == null) { - _countries = tempCountries; - _deprecatedCountries = tempDeprecatedCountries; - _replacementCountries = tempReplacementCountries; - _obsoleteCountries = tempObsoleteCountries; - _countries3 = tempCountries3; - _obsoleteCountries3 = tempObsoleteCountries3; - } - } - } - } - - public static String getCurrentCountryID(String oldID){ - initCountryTables(); - int offset = findIndex(_deprecatedCountries, oldID); - if (offset >= 0) { - return _replacementCountries[offset]; - } - return oldID; - } - - public static String getCurrentLanguageID(String oldID){ - initLanguageTables(); - int offset = findIndex(_obsoleteLanguages, oldID); - if (offset >= 0) { - return _replacementLanguages[offset]; - } - return oldID; - } - - -} +/* + ******************************************************************************* + * Copyright (C) 2009-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.impl; + +import java.util.MissingResourceException; + +import com.ibm.icu.util.ULocale; + + +/** + * Utilities for mapping between old and new language, country, and other + * locale ID related names. + */ +public class LocaleIDs { + + /** + * Returns a list of all 2-letter country codes defined in ISO 3166. + * Can be used to create Locales. + * @stable ICU 3.0 + */ + public static String[] getISOCountries() { + initCountryTables(); + return _countries.clone(); + } + + /** + * Returns a list of all 2-letter language codes defined in ISO 639. + * Can be used to create Locales. + * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed. + * The list this function returns includes both the new and the old codes for the + * languages whose codes have changed.] + * @stable ICU 3.0 + */ + public static String[] getISOLanguages() { + initLanguageTables(); + return _languages.clone(); + } + + /** + * Returns a three-letter abbreviation for the provided country. If the provided + * country is empty, returns the empty string. Otherwise, returns + * an uppercase ISO 3166 3-letter country code. + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter country abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public static String getISO3Country(String country){ + initCountryTables(); + + int offset = findIndex(_countries, country); + if(offset>=0){ + return _countries3[offset]; + }else{ + offset = findIndex(_obsoleteCountries, country); + if(offset>=0){ + return _obsoleteCountries3[offset]; + } + } + return ""; + } + /** + * Returns a three-letter abbreviation for the language. If language is + * empty, returns the empty string. Otherwise, returns + * a lowercase ISO 639-2/T language code. + * The ISO 639-2 language codes can be found on-line at + * ftp://dkuug.dk/i18n/iso-639-2.txt + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter language abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public static String getISO3Language(String language) { + initLanguageTables(); + + int offset = findIndex(_languages, language); + if(offset>=0){ + return _languages3[offset]; + } else { + offset = findIndex(_obsoleteLanguages, language); + if (offset >= 0) { + return _obsoleteLanguages3[offset]; + } + } + return ""; + } + + public static String threeToTwoLetterLanguage(String lang) { + initLanguageTables(); + + /* convert 3 character code to 2 character code if possible *CWB*/ + int offset = findIndex(_languages3, lang); + if (offset >= 0) { + return _languages[offset]; + } + + offset = findIndex(_obsoleteLanguages3, lang); + if (offset >= 0) { + return _obsoleteLanguages[offset]; + } + + return null; + } + + public static String threeToTwoLetterRegion(String region) { + initCountryTables(); + + /* convert 3 character code to 2 character code if possible *CWB*/ + int offset = findIndex(_countries3, region); + if (offset >= 0) { + return _countries[offset]; + } + + offset = findIndex(_obsoleteCountries3, region); + if (offset >= 0) { + return _obsoleteCountries[offset]; + } + + return null; + } + + /** + * linear search of the string array. the arrays are unfortunately ordered by the + * two-letter target code, not the three-letter search code, which seems backwards. + */ + private static int findIndex(String[] array, String target){ + for (int i = 0; i < array.length; i++) { + if (target.equals(array[i])) { + return i; + } + } + return -1; + } + + + /** + * Tables used in normalizing portions of the id. + */ + /* tables updated per http://lcweb.loc.gov/standards/iso639-2/ + to include the revisions up to 2001/7/27 *CWB*/ + /* The 3 character codes are the terminology codes like RFC 3066. + This is compatible with prior ICU codes */ + /* "in" "iw" "ji" "jw" & "sh" have been withdrawn but are still in + the table but now at the end of the table because + 3 character codes are duplicates. This avoids bad searches + going from 3 to 2 character codes.*/ + /* The range qaa-qtz is reserved for local use. */ + + private static String[] _languages; + private static String[] _replacementLanguages; + private static String[] _obsoleteLanguages; + private static String[] _languages3; + private static String[] _obsoleteLanguages3; + + // Avoid initializing languages tables unless we have to. + private static void initLanguageTables() { + if (_languages == null) { + + /* This list MUST be in sorted order, and MUST contain the two-letter codes + if one exists otherwise use the three letter code */ + String[] tempLanguages = { + "aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", "afa", + "afh", "ak", "akk", "ale", "alg", "am", "an", "ang", "apa", + "ar", "arc", "arn", "arp", "art", "arw", "as", "ast", + "ath", "aus", "av", "awa", "ay", "az", "ba", "bad", + "bai", "bal", "ban", "bas", "bat", "be", "bej", + "bem", "ber", "bg", "bh", "bho", "bi", "bik", "bin", + "bla", "bm", "bn", "bnt", "bo", "br", "bra", "bs", + "btk", "bua", "bug", "byn", "ca", "cad", "cai", "car", "cau", + "ce", "ceb", "cel", "ch", "chb", "chg", "chk", "chm", + "chn", "cho", "chp", "chr", "chy", "cmc", "co", "cop", + "cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", "csb", "cu", "cus", + "cv", "cy", "da", "dak", "dar", "day", "de", "del", "den", + "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv", "dyu", + "dz", "ee", "efi", "egy", "eka", "el", "elx", "en", + "enm", "eo", "es", "et", "eu", "ewo", "fa", + "fan", "fat", "ff", "fi", "fiu", "fj", "fo", "fon", + "fr", "frm", "fro", "fur", "fy", "ga", "gaa", "gay", + "gba", "gd", "gem", "gez", "gil", "gl", "gmh", "gn", + "goh", "gon", "gor", "got", "grb", "grc", "gu", "gv", + "gwi", "ha", "hai", "haw", "he", "hi", "hil", "him", + "hit", "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", "hz", + "ia", "iba", "id", "ie", "ig", "ii", "ijo", "ik", + "ilo", "inc", "ine", "inh", "io", "ira", "iro", "is", "it", + "iu", "ja", "jbo", "jpr", "jrb", "jv", "ka", "kaa", "kab", + "kac", "kam", "kar", "kaw", "kbd", "kg", "kha", "khi", + "kho", "ki", "kj", "kk", "kl", "km", "kmb", "kn", + "ko", "kok", "kos", "kpe", "kr", "krc", "kro", "kru", "ks", + "ku", "kum", "kut", "kv", "kw", "ky", "la", "lad", + "lah", "lam", "lb", "lez", "lg", "li", "ln", "lo", "lol", + "loz", "lt", "lu", "lua", "lui", "lun", "luo", "lus", + "lv", "mad", "mag", "mai", "mak", "man", "map", "mas", + "mdf", "mdr", "men", "mg", "mga", "mh", "mi", "mic", "min", + "mis", "mk", "mkh", "ml", "mn", "mnc", "mni", "mno", + "mo", "moh", "mos", "mr", "ms", "mt", "mul", "mun", + "mus", "mwr", "my", "myn", "myv", "na", "nah", "nai", "nap", + "nb", "nd", "nds", "ne", "new", "ng", "nia", "nic", + "niu", "nl", "nn", "no", "nog", "non", "nr", "nso", "nub", + "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oc", "oj", + "om", "or", "os", "osa", "ota", "oto", "pa", "paa", + "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", + "pi", "pl", "pon", "pra", "pro", "ps", "pt", "qu", + "raj", "rap", "rar", "rm", "rn", "ro", "roa", "rom", + "ru", "rup", "rw", "sa", "sad", "sah", "sai", "sal", "sam", + "sas", "sat", "sc", "sco", "sd", "se", "sel", "sem", + "sg", "sga", "sgn", "shn", "si", "sid", "sio", "sit", + "sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", + "sms", "sn", "snk", "so", "sog", "son", "sq", "sr", + "srr", "ss", "ssa", "st", "su", "suk", "sus", "sux", + "sv", "sw", "syr", "ta", "tai", "te", "tem", "ter", + "tet", "tg", "th", "ti", "tig", "tiv", "tk", "tkl", + "tl", "tlh", "tli", "tmh", "tn", "to", "tog", "tpi", "tr", + "ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", + "ty", "tyv", "udm", "ug", "uga", "uk", "umb", "und", "ur", + "uz", "vai", "ve", "vi", "vo", "vot", "wa", "wak", + "wal", "war", "was", "wen", "wo", "xal", "xh", "yao", "yap", + "yi", "yo", "ypk", "za", "zap", "zen", "zh", "znd", + "zu", "zun", + }; + + String[] tempReplacementLanguages = { + "id", "he", "yi", "jv", "sr", "nb",/* replacement language codes */ + }; + + String[] tempObsoleteLanguages = { + "in", "iw", "ji", "jw", "sh", "no", /* obsolete language codes */ + }; + + /* This list MUST contain a three-letter code for every two-letter code in the + list above, and they MUST ne in the same order (i.e., the same language must + be in the same place in both lists)! */ + String[] tempLanguages3 = { + /*"aa", "ab", "ace", "ach", "ada", "ady", "ae", "af", "afa", */ + "aar", "abk", "ace", "ach", "ada", "ady", "ave", "afr", "afa", + /*"afh", "ak", "akk", "ale", "alg", "am", "an", "ang", "apa", */ + "afh", "aka", "akk", "ale", "alg", "amh", "arg", "ang", "apa", + /*"ar", "arc", "arn", "arp", "art", "arw", "as", "ast", */ + "ara", "arc", "arn", "arp", "art", "arw", "asm", "ast", + /*"ath", "aus", "av", "awa", "ay", "az", "ba", "bad", */ + "ath", "aus", "ava", "awa", "aym", "aze", "bak", "bad", + /*"bai", "bal", "ban", "bas", "bat", "be", "bej", */ + "bai", "bal", "ban", "bas", "bat", "bel", "bej", + /*"bem", "ber", "bg", "bh", "bho", "bi", "bik", "bin", */ + "bem", "ber", "bul", "bih", "bho", "bis", "bik", "bin", + /*"bla", "bm", "bn", "bnt", "bo", "br", "bra", "bs", */ + "bla", "bam", "ben", "bnt", "bod", "bre", "bra", "bos", + /*"btk", "bua", "bug", "byn", "ca", "cad", "cai", "car", "cau", */ + "btk", "bua", "bug", "byn", "cat", "cad", "cai", "car", "cau", + /*"ce", "ceb", "cel", "ch", "chb", "chg", "chk", "chm", */ + "che", "ceb", "cel", "cha", "chb", "chg", "chk", "chm", + /*"chn", "cho", "chp", "chr", "chy", "cmc", "co", "cop", */ + "chn", "cho", "chp", "chr", "chy", "cmc", "cos", "cop", + /*"cpe", "cpf", "cpp", "cr", "crh", "crp", "cs", "csb", "cu", "cus", */ + "cpe", "cpf", "cpp", "cre", "crh", "crp", "ces", "csb", "chu", "cus", + /*"cv", "cy", "da", "dak", "dar", "day", "de", "del", "den", */ + "chv", "cym", "dan", "dak", "dar", "day", "deu", "del", "den", + /*"dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv", "dyu", */ + "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "div", "dyu", + /*"dz", "ee", "efi", "egy", "eka", "el", "elx", "en", */ + "dzo", "ewe", "efi", "egy", "eka", "ell", "elx", "eng", + /*"enm", "eo", "es", "et", "eu", "ewo", "fa", */ + "enm", "epo", "spa", "est", "eus", "ewo", "fas", + /*"fan", "fat", "ff", "fi", "fiu", "fj", "fo", "fon", */ + "fan", "fat", "ful", "fin", "fiu", "fij", "fao", "fon", + /*"fr", "frm", "fro", "fur", "fy", "ga", "gaa", "gay", */ + "fra", "frm", "fro", "fur", "fry", "gle", "gaa", "gay", + /*"gba", "gd", "gem", "gez", "gil", "gl", "gmh", "gn", */ + "gba", "gla", "gem", "gez", "gil", "glg", "gmh", "grn", + /*"goh", "gon", "gor", "got", "grb", "grc", "gu", "gv", */ + "goh", "gon", "gor", "got", "grb", "grc", "guj", "glv", + /*"gwi", "ha", "hai", "haw", "he", "hi", "hil", "him", */ + "gwi", "hau", "hai", "haw", "heb", "hin", "hil", "him", + /*"hit", "hmn", "ho", "hr", "hsb", "ht", "hu", "hup", "hy", "hz", */ + "hit", "hmn", "hmo", "hrv", "hsb", "hat", "hun", "hup", "hye", "her", + /*"ia", "iba", "id", "ie", "ig", "ii", "ijo", "ik", */ + "ina", "iba", "ind", "ile", "ibo", "iii", "ijo", "ipk", + /*"ilo", "inc", "ine", "inh", "io", "ira", "iro", "is", "it", */ + "ilo", "inc", "ine", "inh", "ido", "ira", "iro", "isl", "ita", + /*"iu", "ja", "jbo", "jpr", "jrb", "jv", "ka", "kaa", "kab", */ + "iku", "jpn", "jbo", "jpr", "jrb", "jaw", "kat", "kaa", "kab", + /*"kac", "kam", "kar", "kaw", "kbd", "kg", "kha", "khi", */ + "kac", "kam", "kar", "kaw", "kbd", "kon", "kha", "khi", + /*"kho", "ki", "kj", "kk", "kl", "km", "kmb", "kn", */ + "kho", "kik", "kua", "kaz", "kal", "khm", "kmb", "kan", + /*"ko", "kok", "kos", "kpe", "kr", "krc", "kro", "kru", "ks", */ + "kor", "kok", "kos", "kpe", "kau", "krc", "kro", "kru", "kas", + /*"ku", "kum", "kut", "kv", "kw", "ky", "la", "lad", */ + "kur", "kum", "kut", "kom", "cor", "kir", "lat", "lad", + /*"lah", "lam", "lb", "lez", "lg", "li", "ln", "lo", "lol", */ + "lah", "lam", "ltz", "lez", "lug", "lim", "lin", "lao", "lol", + /*"loz", "lt", "lu", "lua", "lui", "lun", "luo", "lus", */ + "loz", "lit", "lub", "lua", "lui", "lun", "luo", "lus", + /*"lv", "mad", "mag", "mai", "mak", "man", "map", "mas", */ + "lav", "mad", "mag", "mai", "mak", "man", "map", "mas", + /*"mdf", "mdr", "men", "mg", "mga", "mh", "mi", "mic", "min", */ + "mdf", "mdr", "men", "mlg", "mga", "mah", "mri", "mic", "min", + /*"mis", "mk", "mkh", "ml", "mn", "mnc", "mni", "mno", */ + "mis", "mkd", "mkh", "mal", "mon", "mnc", "mni", "mno", + /*"mo", "moh", "mos", "mr", "ms", "mt", "mul", "mun", */ + "mol", "moh", "mos", "mar", "msa", "mlt", "mul", "mun", + /*"mus", "mwr", "my", "myn", "myv", "na", "nah", "nai", "nap", */ + "mus", "mwr", "mya", "myn", "myv", "nau", "nah", "nai", "nap", + /*"nb", "nd", "nds", "ne", "new", "ng", "nia", "nic", */ + "nob", "nde", "nds", "nep", "new", "ndo", "nia", "nic", + /*"niu", "nl", "nn", "no", "nog", "non", "nr", "nso", "nub", */ + "niu", "nld", "nno", "nor", "nog", "non", "nbl", "nso", "nub", + /*"nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oc", "oj", */ + "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", "oci", "oji", + /*"om", "or", "os", "osa", "ota", "oto", "pa", "paa", */ + "orm", "ori", "oss", "osa", "ota", "oto", "pan", "paa", + /*"pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", */ + "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn", + /*"pi", "pl", "pon", "pra", "pro", "ps", "pt", "qu", */ + "pli", "pol", "pon", "pra", "pro", "pus", "por", "que", + /*"raj", "rap", "rar", "rm", "rn", "ro", "roa", "rom", */ + "raj", "rap", "rar", "roh", "run", "ron", "roa", "rom", + /*"ru", "rup", "rw", "sa", "sad", "sah", "sai", "sal", "sam", */ + "rus", "rup", "kin", "san", "sad", "sah", "sai", "sal", "sam", + /*"sas", "sat", "sc", "sco", "sd", "se", "sel", "sem", */ + "sas", "sat", "srd", "sco", "snd", "sme", "sel", "sem", + /*"sg", "sga", "sgn", "shn", "si", "sid", "sio", "sit", */ + "sag", "sga", "sgn", "shn", "sin", "sid", "sio", "sit", + /*"sk", "sl", "sla", "sm", "sma", "smi", "smj", "smn", */ + "slk", "slv", "sla", "smo", "sma", "smi", "smj", "smn", + /*"sms", "sn", "snk", "so", "sog", "son", "sq", "sr", */ + "sms", "sna", "snk", "som", "sog", "son", "sqi", "srp", + /*"srr", "ss", "ssa", "st", "su", "suk", "sus", "sux", */ + "srr", "ssw", "ssa", "sot", "sun", "suk", "sus", "sux", + /*"sv", "sw", "syr", "ta", "tai", "te", "tem", "ter", */ + "swe", "swa", "syr", "tam", "tai", "tel", "tem", "ter", + /*"tet", "tg", "th", "ti", "tig", "tiv", "tk", "tkl", */ + "tet", "tgk", "tha", "tir", "tig", "tiv", "tuk", "tkl", + /*"tl", "tlh", "tli", "tmh", "tn", "to", "tog", "tpi", "tr", */ + "tgl", "tlh", "tli", "tmh", "tsn", "ton", "tog", "tpi", "tur", + /*"ts", "tsi", "tt", "tum", "tup", "tut", "tvl", "tw", */ + "tso", "tsi", "tat", "tum", "tup", "tut", "tvl", "twi", + /*"ty", "tyv", "udm", "ug", "uga", "uk", "umb", "und", "ur", */ + "tah", "tyv", "udm", "uig", "uga", "ukr", "umb", "und", "urd", + /*"uz", "vai", "ve", "vi", "vo", "vot", "wa", "wak", */ + "uzb", "vai", "ven", "vie", "vol", "vot", "wln", "wak", + /*"wal", "war", "was", "wen", "wo", "xal", "xh", "yao", "yap", */ + "wal", "war", "was", "wen", "wol", "xal", "xho", "yao", "yap", + /*"yi", "yo", "ypk", "za", "zap", "zen", "zh", "znd", */ + "yid", "yor", "ypk", "zha", "zap", "zen", "zho", "znd", + /*"zu", "zun", */ + "zul", "zun", + }; + + String[] tempObsoleteLanguages3 = { + /* "in", "iw", "ji", "jw", "sh", */ + "ind", "heb", "yid", "jaw", "srp", + }; + + synchronized (ULocale.class) { + if (_languages == null) { + _languages = tempLanguages; + _replacementLanguages = tempReplacementLanguages; + _obsoleteLanguages = tempObsoleteLanguages; + _languages3 = tempLanguages3; + _obsoleteLanguages3 = tempObsoleteLanguages3; + } + } + } + } + + private static String[] _countries; + private static String[] _deprecatedCountries; + private static String[] _replacementCountries; + private static String[] _obsoleteCountries; + private static String[] _countries3; + private static String[] _obsoleteCountries3; + + // Avoid initializing country tables unless we have to. + private static void initCountryTables() { + if (_countries == null) { + /* ZR(ZAR) is now CD(COD) and FX(FXX) is PS(PSE) as per + http://www.evertype.com/standards/iso3166/iso3166-1-en.html + added new codes keeping the old ones for compatibility + updated to include 1999/12/03 revisions *CWB*/ + + /* RO(ROM) is now RO(ROU) according to + http://www.iso.org/iso/en/prods-services/iso3166ma/03updates-on-iso-3166/nlv3e-rou.html + */ + + /* This list MUST be in sorted order, and MUST contain only two-letter codes! */ + String[] tempCountries = { + "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", + "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", + "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", + "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BV", + "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", + "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", + "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", + "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", + "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", + "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", + "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", + "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", + "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", + "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", + "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", + "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", + "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", + "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", + "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", + "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", + "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", + "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", + "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", + "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", + "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", + "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", + "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", + "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", + "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", + "WS", "YE", "YT", "ZA", "ZM", "ZW", + }; + + /* this table is used for 3 letter codes */ + String[] tempObsoleteCountries = { + "FX", "CS", "RO", "TP", "YU", "ZR", /* obsolete country codes */ + }; + + String[] tempDeprecatedCountries = { + "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" /* deprecated country list */ + }; + String[] tempReplacementCountries = { + /* "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" */ + "MM", "RS", "BJ", "FR", "BF", "VU", "ZW", "TL", "RS", "CD", /* replacement country codes */ + }; + + /* This list MUST contain a three-letter code for every two-letter code in + the above list, and they MUST be listed in the same order! */ + String[] tempCountries3 = { + /* "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", */ + "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "ANT", + /* "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", */ + "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "ALA", "AZE", + /* "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", */ + "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI", + /* "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BV", */ + "BEN", "BLM", "BMU", "BRN", "BOL", "BRA", "BHS", "BTN", "BVT", + /* "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", */ + "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", + /* "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", */ + "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", + /* "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", */ + "CUB", "CPV", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK", + /* "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", */ + "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI", + /* "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", */ + "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", + /* "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", */ + "GAB", "GBR", "GRD", "GEO", "GUF", "GGY", "GHA", "GIB", "GRL", + /* "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", */ + "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM", + /* "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", */ + "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN", + /* "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS" */ + "IDN", "IRL", "ISR", "IMN", "IND", "IOT", "IRQ", "IRN", "ISL", + /* "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", */ + "ITA", "JEY", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", + /* "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", */ + "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO", + /* "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", */ + "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", + /* "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", */ + "LVA", "LBY", "MAR", "MCO", "MDA", "MNE", "MAF", "MDG", "MHL", "MKD", + /* "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", */ + "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR", + /* "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", */ + "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM", + /* "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", */ + "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", + /* "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", */ + "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", + /* "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", */ + "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT", + /* "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", */ + "PLW", "PRY", "QAT", "REU", "ROU", "SRB", "RUS", "RWA", "SAU", + /* "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", */ + "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", + /* "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", */ + "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "STP", "SLV", + /* "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", */ + "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK", + /* "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", */ + "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV", + /* "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", */ + "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", + /* "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", */ + "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF", + /* "WS", "YE", "YT", "ZA", "ZM", "ZW" */ + "WSM", "YEM", "MYT", "ZAF", "ZMB", "ZWE", + }; + + String[] tempObsoleteCountries3 = { + /*"FX", "CS", "RO", "TP", "YU", "ZR", */ + "FXX", "SCG", "ROM", "TMP", "YUG", "ZAR", + }; + + synchronized (ULocale.class) { + if (_countries == null) { + _countries = tempCountries; + _deprecatedCountries = tempDeprecatedCountries; + _replacementCountries = tempReplacementCountries; + _obsoleteCountries = tempObsoleteCountries; + _countries3 = tempCountries3; + _obsoleteCountries3 = tempObsoleteCountries3; + } + } + } + } + + public static String getCurrentCountryID(String oldID){ + initCountryTables(); + int offset = findIndex(_deprecatedCountries, oldID); + if (offset >= 0) { + return _replacementCountries[offset]; + } + return oldID; + } + + public static String getCurrentLanguageID(String oldID){ + initLanguageTables(); + int offset = findIndex(_obsoleteLanguages, oldID); + if (offset >= 0) { + return _replacementLanguages[offset]; + } + return oldID; + } + + +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java index f219f099676..143ac9d2d29 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java @@ -1,132 +1,132 @@ -/* - ****************************************************************************** - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ****************************************************************************** - * - ****************************************************************************** - */ - -package com.ibm.icu.impl; - -import java.util.Locale; - -/** - * A class to hold utility functions missing from java.util.Locale. - */ -public class LocaleUtility { - - /** - * A helper function to convert a string of the form - * aa_BB_CC to a locale object. Why isn't this in Locale? - */ - public static Locale getLocaleFromName(String name) { - String language = ""; - String country = ""; - String variant = ""; - - int i1 = name.indexOf('_'); - if (i1 < 0) { - language = name; - } else { - language = name.substring(0, i1); - ++i1; - int i2 = name.indexOf('_', i1); - if (i2 < 0) { - country = name.substring(i1); - } else { - country = name.substring(i1, i2); - variant = name.substring(i2+1); - } - } - - return new Locale(language, country, variant); - } - - /** - * Compare two locale strings of the form aa_BB_CC, and - * return true if parent is a 'strict' fallback of child, that is, - * if child =~ "^parent(_.+)*" (roughly). - */ - public static boolean isFallbackOf(String parent, String child) { - if (!child.startsWith(parent)) { - return false; - } - int i = parent.length(); - return (i == child.length() || - child.charAt(i) == '_'); - } - - /** - * Compare two locales, and return true if the parent is a - * 'strict' fallback of the child (parent string is a fallback - * of child string). - */ - public static boolean isFallbackOf(Locale parent, Locale child) { - return isFallbackOf(parent.toString(), child.toString()); - } - - - /* - * Convenience method that calls canonicalLocaleString(String) with - * locale.toString(); - */ - /*public static String canonicalLocaleString(Locale locale) { - return canonicalLocaleString(locale.toString()); - }*/ - - /* - * You'd think that Locale canonicalizes, since it munges the - * renamed languages, but it doesn't quite. It forces the region - * to be upper case but doesn't do anything about the language or - * variant. Our canonical form is 'lower_UPPER_UPPER'. - */ - /*public static String canonicalLocaleString(String id) { - if (id != null) { - int x = id.indexOf("_"); - if (x == -1) { - id = id.toLowerCase(Locale.ENGLISH); - } else { - StringBuffer buf = new StringBuffer(); - buf.append(id.substring(0, x).toLowerCase(Locale.ENGLISH)); - buf.append(id.substring(x).toUpperCase(Locale.ENGLISH)); - - int len = buf.length(); - int n = len; - while (--n >= 0 && buf.charAt(n) == '_') { - } - if (++n != len) { - buf.delete(n, len); - } - id = buf.toString(); - } - } - return id; - }*/ - - /** - * Fallback from the given locale name by removing the rightmost _-delimited - * element. If there is none, return the root locale ("", "", ""). If this - * is the root locale, return null. NOTE: The string "root" is not - * recognized; do not use it. - * - * @return a new Locale that is a fallback from the given locale, or null. - */ - public static Locale fallback(Locale loc) { - - // Split the locale into parts and remove the rightmost part - String[] parts = new String[] - { loc.getLanguage(), loc.getCountry(), loc.getVariant() }; - int i; - for (i=2; i>=0; --i) { - if (parts[i].length() != 0) { - parts[i] = ""; - break; - } - } - if (i<0) { - return null; // All parts were empty - } - return new Locale(parts[0], parts[1], parts[2]); - } -} +/* + ****************************************************************************** + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ****************************************************************************** + * + ****************************************************************************** + */ + +package com.ibm.icu.impl; + +import java.util.Locale; + +/** + * A class to hold utility functions missing from java.util.Locale. + */ +public class LocaleUtility { + + /** + * A helper function to convert a string of the form + * aa_BB_CC to a locale object. Why isn't this in Locale? + */ + public static Locale getLocaleFromName(String name) { + String language = ""; + String country = ""; + String variant = ""; + + int i1 = name.indexOf('_'); + if (i1 < 0) { + language = name; + } else { + language = name.substring(0, i1); + ++i1; + int i2 = name.indexOf('_', i1); + if (i2 < 0) { + country = name.substring(i1); + } else { + country = name.substring(i1, i2); + variant = name.substring(i2+1); + } + } + + return new Locale(language, country, variant); + } + + /** + * Compare two locale strings of the form aa_BB_CC, and + * return true if parent is a 'strict' fallback of child, that is, + * if child =~ "^parent(_.+)*" (roughly). + */ + public static boolean isFallbackOf(String parent, String child) { + if (!child.startsWith(parent)) { + return false; + } + int i = parent.length(); + return (i == child.length() || + child.charAt(i) == '_'); + } + + /** + * Compare two locales, and return true if the parent is a + * 'strict' fallback of the child (parent string is a fallback + * of child string). + */ + public static boolean isFallbackOf(Locale parent, Locale child) { + return isFallbackOf(parent.toString(), child.toString()); + } + + + /* + * Convenience method that calls canonicalLocaleString(String) with + * locale.toString(); + */ + /*public static String canonicalLocaleString(Locale locale) { + return canonicalLocaleString(locale.toString()); + }*/ + + /* + * You'd think that Locale canonicalizes, since it munges the + * renamed languages, but it doesn't quite. It forces the region + * to be upper case but doesn't do anything about the language or + * variant. Our canonical form is 'lower_UPPER_UPPER'. + */ + /*public static String canonicalLocaleString(String id) { + if (id != null) { + int x = id.indexOf("_"); + if (x == -1) { + id = id.toLowerCase(Locale.ENGLISH); + } else { + StringBuffer buf = new StringBuffer(); + buf.append(id.substring(0, x).toLowerCase(Locale.ENGLISH)); + buf.append(id.substring(x).toUpperCase(Locale.ENGLISH)); + + int len = buf.length(); + int n = len; + while (--n >= 0 && buf.charAt(n) == '_') { + } + if (++n != len) { + buf.delete(n, len); + } + id = buf.toString(); + } + } + return id; + }*/ + + /** + * Fallback from the given locale name by removing the rightmost _-delimited + * element. If there is none, return the root locale ("", "", ""). If this + * is the root locale, return null. NOTE: The string "root" is not + * recognized; do not use it. + * + * @return a new Locale that is a fallback from the given locale, or null. + */ + public static Locale fallback(Locale loc) { + + // Split the locale into parts and remove the rightmost part + String[] parts = new String[] + { loc.getLanguage(), loc.getCountry(), loc.getVariant() }; + int i; + for (i=2; i>=0; --i) { + if (parts[i].length() != 0) { + parts[i] = ""; + break; + } + } + if (i<0) { + return null; // All parts were empty + } + return new Locale(parts[0], parts[1], parts[2]); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java index fc431b05e19..7ee2dc50dff 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java @@ -1,73 +1,73 @@ -/* - **************************************************************************** - * Copyright (c) 2007-2011 International Business Machines Corporation and * - * others. All rights reserved. * - **************************************************************************** - */ - -package com.ibm.icu.impl; - -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public class SimpleCache implements ICUCache { - private static final int DEFAULT_CAPACITY = 16; - - private Reference> cacheRef = null; - private int type = ICUCache.SOFT; - private int capacity = DEFAULT_CAPACITY; - - public SimpleCache() { - } - - public SimpleCache(int cacheType) { - this(cacheType, DEFAULT_CAPACITY); - } - - public SimpleCache(int cacheType, int initialCapacity) { - if (cacheType == ICUCache.WEAK) { - type = cacheType; - } - if (initialCapacity > 0) { - capacity = initialCapacity; - } - } - - public V get(Object key) { - Reference> ref = cacheRef; - if (ref != null) { - Map map = ref.get(); - if (map != null) { - return map.get(key); - } - } - return null; - } - - public void put(K key, V value) { - Reference> ref = cacheRef; - Map map = null; - if (ref != null) { - map = ref.get(); - } - if (map == null) { - map = Collections.synchronizedMap(new HashMap(capacity)); - if (type == ICUCache.WEAK) { - ref = new WeakReference>(map); - } else { - ref = new SoftReference>(map); - } - cacheRef = ref; - } - map.put(key, value); - } - - public void clear() { - cacheRef = null; - } - -} +/* + **************************************************************************** + * Copyright (c) 2007-2011 International Business Machines Corporation and * + * others. All rights reserved. * + **************************************************************************** + */ + +package com.ibm.icu.impl; + +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class SimpleCache implements ICUCache { + private static final int DEFAULT_CAPACITY = 16; + + private Reference> cacheRef = null; + private int type = ICUCache.SOFT; + private int capacity = DEFAULT_CAPACITY; + + public SimpleCache() { + } + + public SimpleCache(int cacheType) { + this(cacheType, DEFAULT_CAPACITY); + } + + public SimpleCache(int cacheType, int initialCapacity) { + if (cacheType == ICUCache.WEAK) { + type = cacheType; + } + if (initialCapacity > 0) { + capacity = initialCapacity; + } + } + + public V get(Object key) { + Reference> ref = cacheRef; + if (ref != null) { + Map map = ref.get(); + if (map != null) { + return map.get(key); + } + } + return null; + } + + public void put(K key, V value) { + Reference> ref = cacheRef; + Map map = null; + if (ref != null) { + map = ref.get(); + } + if (map == null) { + map = Collections.synchronizedMap(new HashMap(capacity)); + if (type == ICUCache.WEAK) { + ref = new WeakReference>(map); + } else { + ref = new SoftReference>(map); + } + cacheRef = ref; + } + map.put(key, value); + } + + public void clear() { + cacheRef = null; + } + +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java index 24383f0d39c..7600914c5f3 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java @@ -1,180 +1,180 @@ -/* - ******************************************************************************* - * Copyright (C) 2009-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.impl.locale; - -public final class AsciiUtil { - public static boolean caseIgnoreMatch(String s1, String s2) { - if (s1 == s2) { - return true; - } - int len = s1.length(); - if (len != s2.length()) { - return false; - } - int i = 0; - while (i < len) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - if (c1 != c2 && toLower(c1) != toLower(c2)) { - break; - } - i++; - } - return (i == len); - } - - public static int caseIgnoreCompare(String s1, String s2) { - if (s1 == s2) { - return 0; - } - return AsciiUtil.toLowerString(s1).compareTo(AsciiUtil.toLowerString(s2)); - } - - - public static char toUpper(char c) { - if (c >= 'a' && c <= 'z') { - c -= 0x20; - } - return c; - } - - public static char toLower(char c) { - if (c >= 'A' && c <= 'Z') { - c += 0x20; - } - return c; - } - - public static String toLowerString(String s) { - int idx = 0; - for (; idx < s.length(); idx++) { - char c = s.charAt(idx); - if (c >= 'A' && c <= 'Z') { - break; - } - } - if (idx == s.length()) { - return s; - } - StringBuilder buf = new StringBuilder(s.substring(0, idx)); - for (; idx < s.length(); idx++) { - buf.append(toLower(s.charAt(idx))); - } - return buf.toString(); - } - - public static String toUpperString(String s) { - int idx = 0; - for (; idx < s.length(); idx++) { - char c = s.charAt(idx); - if (c >= 'a' && c <= 'z') { - break; - } - } - if (idx == s.length()) { - return s; - } - StringBuilder buf = new StringBuilder(s.substring(0, idx)); - for (; idx < s.length(); idx++) { - buf.append(toUpper(s.charAt(idx))); - } - return buf.toString(); - } - - public static String toTitleString(String s) { - if (s.length() == 0) { - return s; - } - int idx = 0; - char c = s.charAt(idx); - if (!(c >= 'a' && c <= 'z')) { - for (idx = 1; idx < s.length(); idx++) { - if (c >= 'A' && c <= 'Z') { - break; - } - } - } - if (idx == s.length()) { - return s; - } - StringBuilder buf = new StringBuilder(s.substring(0, idx)); - if (idx == 0) { - buf.append(toUpper(s.charAt(idx))); - idx++; - } - for (; idx < s.length(); idx++) { - buf.append(toLower(s.charAt(idx))); - } - return buf.toString(); - } - - public static boolean isAlpha(char c) { - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - } - - public static boolean isAlphaString(String s) { - boolean b = true; - for (int i = 0; i < s.length(); i++) { - if (!isAlpha(s.charAt(i))) { - b = false; - break; - } - } - return b; - } - - public static boolean isNumeric(char c) { - return (c >= '0' && c <= '9'); - } - - public static boolean isNumericString(String s) { - boolean b = true; - for (int i = 0; i < s.length(); i++) { - if (!isNumeric(s.charAt(i))) { - b = false; - break; - } - } - return b; - } - - public static boolean isAlphaNumeric(char c) { - return isAlpha(c) || isNumeric(c); - } - - public static boolean isAlphaNumericString(String s) { - boolean b = true; - for (int i = 0; i < s.length(); i++) { - if (!isAlphaNumeric(s.charAt(i))) { - b = false; - break; - } - } - return b; - } - - public static class CaseInsensitiveKey { - private String _key; - private int _hash; - - public CaseInsensitiveKey(String key) { - _key = key; - _hash = AsciiUtil.toLowerString(key).hashCode(); - } - - public boolean equals(Object o) { - if (o instanceof CaseInsensitiveKey) { - return AsciiUtil.caseIgnoreMatch(_key, ((CaseInsensitiveKey)o)._key); - } - return false; - } - - public int hashCode() { - return _hash; - } - } -} +/* + ******************************************************************************* + * Copyright (C) 2009-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.impl.locale; + +public final class AsciiUtil { + public static boolean caseIgnoreMatch(String s1, String s2) { + if (s1 == s2) { + return true; + } + int len = s1.length(); + if (len != s2.length()) { + return false; + } + int i = 0; + while (i < len) { + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + if (c1 != c2 && toLower(c1) != toLower(c2)) { + break; + } + i++; + } + return (i == len); + } + + public static int caseIgnoreCompare(String s1, String s2) { + if (s1 == s2) { + return 0; + } + return AsciiUtil.toLowerString(s1).compareTo(AsciiUtil.toLowerString(s2)); + } + + + public static char toUpper(char c) { + if (c >= 'a' && c <= 'z') { + c -= 0x20; + } + return c; + } + + public static char toLower(char c) { + if (c >= 'A' && c <= 'Z') { + c += 0x20; + } + return c; + } + + public static String toLowerString(String s) { + int idx = 0; + for (; idx < s.length(); idx++) { + char c = s.charAt(idx); + if (c >= 'A' && c <= 'Z') { + break; + } + } + if (idx == s.length()) { + return s; + } + StringBuilder buf = new StringBuilder(s.substring(0, idx)); + for (; idx < s.length(); idx++) { + buf.append(toLower(s.charAt(idx))); + } + return buf.toString(); + } + + public static String toUpperString(String s) { + int idx = 0; + for (; idx < s.length(); idx++) { + char c = s.charAt(idx); + if (c >= 'a' && c <= 'z') { + break; + } + } + if (idx == s.length()) { + return s; + } + StringBuilder buf = new StringBuilder(s.substring(0, idx)); + for (; idx < s.length(); idx++) { + buf.append(toUpper(s.charAt(idx))); + } + return buf.toString(); + } + + public static String toTitleString(String s) { + if (s.length() == 0) { + return s; + } + int idx = 0; + char c = s.charAt(idx); + if (!(c >= 'a' && c <= 'z')) { + for (idx = 1; idx < s.length(); idx++) { + if (c >= 'A' && c <= 'Z') { + break; + } + } + } + if (idx == s.length()) { + return s; + } + StringBuilder buf = new StringBuilder(s.substring(0, idx)); + if (idx == 0) { + buf.append(toUpper(s.charAt(idx))); + idx++; + } + for (; idx < s.length(); idx++) { + buf.append(toLower(s.charAt(idx))); + } + return buf.toString(); + } + + public static boolean isAlpha(char c) { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); + } + + public static boolean isAlphaString(String s) { + boolean b = true; + for (int i = 0; i < s.length(); i++) { + if (!isAlpha(s.charAt(i))) { + b = false; + break; + } + } + return b; + } + + public static boolean isNumeric(char c) { + return (c >= '0' && c <= '9'); + } + + public static boolean isNumericString(String s) { + boolean b = true; + for (int i = 0; i < s.length(); i++) { + if (!isNumeric(s.charAt(i))) { + b = false; + break; + } + } + return b; + } + + public static boolean isAlphaNumeric(char c) { + return isAlpha(c) || isNumeric(c); + } + + public static boolean isAlphaNumericString(String s) { + boolean b = true; + for (int i = 0; i < s.length(); i++) { + if (!isAlphaNumeric(s.charAt(i))) { + b = false; + break; + } + } + return b; + } + + public static class CaseInsensitiveKey { + private String _key; + private int _hash; + + public CaseInsensitiveKey(String key) { + _key = key; + _hash = AsciiUtil.toLowerString(key).hashCode(); + } + + public boolean equals(Object o) { + if (o instanceof CaseInsensitiveKey) { + return AsciiUtil.caseIgnoreMatch(_key, ((CaseInsensitiveKey)o)._key); + } + return false; + } + + public int hashCode() { + return _hash; + } + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java index 3dfa95bc2a7..a90150384f7 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java @@ -1,3880 +1,3880 @@ -/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */ -/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */ -package com.ibm.icu.math; - -import java.math.BigInteger; - -/* ------------------------------------------------------------------ */ -/* BigDecimal -- Decimal arithmetic for Java */ -/* ------------------------------------------------------------------ */ -/* Copyright IBM Corporation, 1996-2011. All Rights Reserved. */ -/* */ -/* The BigDecimal class provides immutable arbitrary-precision */ -/* floating point (including integer) decimal numbers. */ -/* */ -/* As the numbers are decimal, there is an exact correspondence */ -/* between an instance of a BigDecimal object and its String */ -/* representation; the BigDecimal class provides direct conversions */ -/* to and from String and character array objects, and well as */ -/* conversions to and from the Java primitive types (which may not */ -/* be exact). */ -/* ------------------------------------------------------------------ */ -/* Notes: */ -/* */ -/* 1. A BigDecimal object is never changed in value once constructed; */ -/* this avoids the need for locking. Note in particular that the */ -/* mantissa array may be shared between many BigDecimal objects, */ -/* so that once exposed it must not be altered. */ -/* */ -/* 2. This class looks at MathContext class fields directly (for */ -/* performance). It must not and does not change them. */ -/* */ -/* 3. Exponent checking is delayed until finish(), as we know */ -/* intermediate calculations cannot cause 31-bit overflow. */ -/* [This assertion depends on MAX_DIGITS in MathContext.] */ -/* */ -/* 4. Comments for the public API now follow the javadoc conventions. */ -/* The NetRexx -comments option is used to pass these comments */ -/* through to the generated Java code (with -format, if desired). */ -/* */ -/* 5. System.arraycopy is faster than explicit loop as follows */ -/* Mean length 4: equal */ -/* Mean length 8: x2 */ -/* Mean length 16: x3 */ -/* Mean length 24: x4 */ -/* From prior experience, we expect mean length a little below 8, */ -/* but arraycopy is still the one to use, in general, until later */ -/* measurements suggest otherwise. */ -/* */ -/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */ -/* assembler code implementation of the algorithms below; it is */ -/* now called IXXRCN and is available with the OS/390 and VM/ESA */ -/* operating systems. */ -/* ------------------------------------------------------------------ */ -/* Change History: */ -/* 1997.09.02 Initial version (derived from netrexx.lang classes) */ -/* 1997.09.12 Add lostDigits checking */ -/* 1997.10.06 Change mantissa to a byte array */ -/* 1997.11.22 Rework power [did not prepare arguments, etc.] */ -/* 1997.12.13 multiply did not prepare arguments */ -/* 1997.12.14 add did not prepare and align arguments correctly */ -/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */ -/* 1998.05.21 adjust remainder operator finalization */ -/* 1998.06.04 rework to pass MathContext to finish() and round() */ -/* 1998.06.06 change format to use round(); support rounding modes */ -/* 1998.06.25 rename to BigDecimal and begin merge */ -/* zero can now have trailing zeros (i.e., exp\=0) */ -/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */ -/* unscaledValue, valueof */ -/* 1998.07.01 improve byteaddsub to allow array reuse, etc. */ -/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */ -/* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */ -/* 1998.07.08 setScale, faster equals */ -/* 1998.07.11 allow 1E6 (no sign) ; new double/float conversion */ -/* 1998.10.12 change package to com.ibm.icu.math */ -/* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */ -/* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */ -/* 1998.12.29 improve byteaddsub by using table lookup */ -/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */ -/* 1999.02.05 cleaner code for BigDecimal(char[]) */ -/* 1999.02.06 add javadoc comments */ -/* 1999.02.11 format() changed from 7 to 2 method form */ -/* 1999.03.05 null pointer checking is no longer explicit */ -/* 1999.03.05 simplify; changes from discussion with J. Bloch: */ -/* null no longer permitted for MathContext; drop boolean, */ -/* byte, char, float, short constructor, deprecate double */ -/* constructor, no blanks in string constructor, add */ -/* offset and length version of char[] constructor; */ -/* add valueOf(double); drop booleanValue, charValue; */ -/* add ...Exact versions of remaining convertors */ -/* 1999.03.13 add toBigIntegerExact */ -/* 1999.03.13 1.00 release to IBM Centre for Java Technology */ -/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */ -/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */ -/* 1999.07.03 1.03 lost digits should not be checked if digits=0 */ -/* 1999.07.06 lost digits Exception message changed */ -/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */ -/* 1999.07.17 improve messages from pow method */ -/* 1999.08.08 performance tweaks */ -/* 1999.08.15 fastpath in multiply */ -/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */ -/* 1999.12.22 1.06 remove multiply fastpath, and improve performance */ -/* 2000.01.01 copyright update [Y2K has arrived] */ -/* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */ -/* ------------------------------------------------------------------ */ - -/** - * The BigDecimal class implements immutable arbitrary-precision decimal numbers. The methods of the - * BigDecimal class provide operations for fixed and floating point arithmetic, comparison, format - * conversions, and hashing. - *

- * As the numbers are decimal, there is an exact correspondence between an instance of a BigDecimal object - * and its String representation; the BigDecimal class provides direct conversions to and from - * String and character array (char[]) objects, as well as conversions to and from the Java - * primitive types (which may not be exact) and BigInteger. - *

- * In the descriptions of constructors and methods in this documentation, the value of a BigDecimal number - * object is shown as the result of invoking the toString() method on the object. The internal - * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any - * operation. - *

- * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also - * documented at http://www2.hursley.ibm.com/decimal
- * [This URL will change.] - * - *

Operator methods

- *

- * Operations on BigDecimal numbers are controlled by a {@link MathContext} object, which provides the - * context (precision and other information) for the operation. Methods that can take a MathContext - * parameter implement the standard arithmetic operators for BigDecimal objects and are known as - * operator methods. The default settings provided by the constant {@link MathContext#DEFAULT} (digits=9, - * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP) perform general-purpose floating point - * arithmetic to nine digits of precision. The MathContext parameter must not be null. - *

- * Each operator method also has a version provided which does not take a MathContext parameter. For this - * version of each method, the context settings used are digits=0, - * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP; these settings perform fixed point arithmetic with - * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2. - *

- * For monadic operators, only the optional MathContext parameter is present; the operation acts upon the - * current object. - *

- * For dyadic operators, a BigDecimal parameter is always present; it must not be null. The - * operation acts with the current object being the left-hand operand and the BigDecimal parameter being - * the right-hand operand. - *

- * For example, adding two BigDecimal objects referred to by the names award and - * extra could be written as any of: - *

- * - * award.add(extra) - *
award.add(extra, MathContext.DEFAULT) - *
award.add(extra, acontext) - *
- *

- * (where acontext is a MathContext object), which would return a BigDecimal - * object whose value is the result of adding award and extra under the appropriate context - * settings. - *

- * When a BigDecimal operator method is used, a set of rules define what the result will be (and, by - * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal - * arithmetic documentation (see the URL above), but in summary: - *

    - *
  • Results are normally calculated with up to some maximum number of significant digits. For example, if the - * MathContext parameter for an operation were MathContext.DEFAULT then the result would be - * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667.
    - * You can change the default of 9 significant digits by providing the method with a suitable MathContext - * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled) - * arithmetic is indicated by using a digits setting of 0 (or omitting the MathContext - * parameter).
    - * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm. - *
  • - * In standard arithmetic (that is, when the form setting is not PLAIN), a zero result is - * always expressed as the single digit '0' (that is, with no sign, decimal point, or exponent part). - *
  • - * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast - * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros - * in the fractional part of results).
    - * So, for example: - *

    - * - * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40" - *
    new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40" - *
    new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80" - *
    new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2" - *
    - *

    - * where the value on the right of the => would be the result of the operation, expressed as a - * String, and def (in this and following examples) refers to MathContext.DEFAULT - * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If - * necessary, trailing zeros may be easily removed using division by 1. - *

  • - * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of - * digits (the default is 9 digits). If the number of places needed before the decimal point exceeds the - * digits setting, or the absolute value of the number is less than 0.000001, then the number - * will be expressed in exponential notation; thus - *

    - * - * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def) - * - *

    - * results in 1E+12 instead of 1000000000000, and - *

    - * - * new BigDecimal("1").divide(new BigDecimal("3E+10"), def) - * - *

    - * results in 3.33333333E-11 instead of 0.0000000000333333333. - *

    - * The form of the exponential notation (scientific or engineering) is determined by the form setting. - * - *

    - * The names of methods in this class follow the conventions established by java.lang.Number, - * java.math.BigInteger, and java.math.BigDecimal in Java 1.1 and Java 1.2. - * - * @see MathContext - * @author Mike Cowlishaw - * @stable ICU 2.0 - */ - -public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable { - // private static final java.lang.String $0="BigDecimal.nrx"; - - /* ----- Constants ----- */ - /* properties constant public */// useful to others - /** - * The BigDecimal constant "0". - * - * @see #ONE - * @see #TEN - * @stable ICU 2.0 - */ - public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we - // want the int - // constructor - // .. to be able to use this, for speed - - /** - * The BigDecimal constant "1". - * - * @see #TEN - * @see #ZERO - * @stable ICU 2.0 - */ - public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we - // want the int - // constructor - // .. to be able to use this, for speed - - /** - * The BigDecimal constant "10". - * - * @see #ONE - * @see #ZERO - * @stable ICU 2.0 - */ - public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10); - - // the rounding modes (copied here for upwards compatibility) - /** - * Rounding mode to round to a more positive number. - * - * @see MathContext#ROUND_CEILING - * @stable ICU 2.0 - */ - public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING; - - /** - * Rounding mode to round towards zero. - * - * @see MathContext#ROUND_DOWN - * @stable ICU 2.0 - */ - public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN; - - /** - * Rounding mode to round to a more negative number. - * - * @see MathContext#ROUND_FLOOR - * @stable ICU 2.0 - */ - public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down. - * - * @see MathContext#ROUND_HALF_DOWN - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor. - * - * @see MathContext#ROUND_HALF_EVEN - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up. - * - * @see MathContext#ROUND_HALF_UP - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP; - - /** - * Rounding mode to assert that no rounding is necessary. - * - * @see MathContext#ROUND_UNNECESSARY - * @stable ICU 2.0 - */ - public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY; - - /** - * Rounding mode to round away from zero. - * - * @see MathContext#ROUND_UP - * @stable ICU 2.0 - */ - public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP; - - /* properties constant private */// locals - private static final byte ispos = 1; // ind: indicates positive (must be 1) - private static final byte iszero = 0; // ind: indicates zero (must be 0) - private static final byte isneg = -1; // ind: indicates negative (must be -1) - // [later could add NaN, +/- infinity, here] - - private static final int MinExp = -999999999; // minimum exponent allowed - private static final int MaxExp = 999999999; // maximum exponent allowed - private static final int MinArg = -999999999; // minimum argument integer - private static final int MaxArg = 999999999; // maximum argument integer - - private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0, - com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math - - /* properties constant private unused */// present but not referenced - // Serialization version - private static final long serialVersionUID = 8245355804974198832L; - - // private static final java.lang.String - // copyright=" Copyright (c) IBM Corporation 1996, 2000. All rights reserved. "; - - /* properties static private */ - // Precalculated constant arrays (used by byteaddsub) - private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array - private static byte bytedig[] = diginit(); // next digit array - - /* ----- Instance properties [all private and immutable] ----- */ - /* properties private */ - - /** - * The indicator. This may take the values: - *

      - *
    • ispos -- the number is positive
    • iszero -- the number is zero
    • isneg -- the number is negative - *
    - * - * @serial - */ - private byte ind; // assumed undefined - // Note: some code below assumes IND = Sign [-1, 0, 1], at present. - // We only need two bits for this, but use a byte [also permits - // smooth future extension]. - - /** - * The formatting style. This may take the values: - *
      - *
    • MathContext.PLAIN -- no exponent needed
    • MathContext.SCIENTIFIC -- scientific notation required
    • - * MathContext.ENGINEERING -- engineering notation required - *
    - *

    - * This property is an optimization; it allows us to defer number layout until it is actually needed as a string, - * hence avoiding unnecessary formatting. - * - * @serial - */ - private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN - // We only need two bits for this, at present, but use a byte - // [again, to allow for smooth future extension] - - /** - * The value of the mantissa. - *

    - * Once constructed, this may become shared between several BigDecimal objects, so must not be altered. - *

    - * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9. - *

    - * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a - * plain number, for example, 0.000). - * - * @serial - */ - private byte mant[]; // assumed null - - /** - * The exponent. - *

    - * For fixed point arithmetic, scale is -exp, and can apply to zero. - * - * Note that this property can have a value less than MinExp when the mantissa has more than one digit. - * - * @serial - */ - private int exp; - - // assumed 0 - - /* ---------------------------------------------------------------- */ - /* Constructors */ - /* ---------------------------------------------------------------- */ - - /** - * Constructs a BigDecimal object from a java.math.BigDecimal. - *

    - * Constructs a BigDecimal as though the parameter had been represented as a String (using - * its toString method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. - * The parameter must not be null. - *

    - * (Note: this constructor is provided only in the com.ibm.icu.math version of the BigDecimal class. - * It would not be present in a java.math version.) - * - * @param bd The BigDecimal to be translated. - * @stable ICU 2.0 - */ - - public BigDecimal(java.math.BigDecimal bd) { - this(bd.toString()); - return; - } - - /** - * Constructs a BigDecimal object from a BigInteger, with scale 0. - *

    - * Constructs a BigDecimal which is the exact decimal representation of the BigInteger, - * with a scale of zero. The value of the BigDecimal is identical to the value of the BigInteger - * . The parameter must not be null. - *

    - * The BigDecimal will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the - * BigInteger is negative. A leading zero will be present only if the BigInteger is zero. - * - * @param bi The BigInteger to be converted. - * @stable ICU 2.0 - */ - - public BigDecimal(java.math.BigInteger bi) { - this(bi.toString(10)); - return; - } - - // exp remains 0 - - /** - * Constructs a BigDecimal object from a BigInteger and a scale. - *

    - * Constructs a BigDecimal which is the exact decimal representation of the BigInteger, - * scaled by the second parameter, which may not be negative. The value of the BigDecimal is the - * BigInteger divided by ten to the power of the scale. The BigInteger parameter must not be - * null. - *

    - * The BigDecimal will contain only decimal digits, (with an embedded decimal point followed by - * scale decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the - * BigInteger is negative. A leading zero will be present only if the BigInteger is zero. - * - * @param bi The BigInteger to be converted. - * @param scale The int specifying the scale. - * @throws NumberFormatException If the scale is negative. - * @stable ICU 2.0 - */ - - public BigDecimal(java.math.BigInteger bi, int scale) { - this(bi.toString(10)); - if (scale < 0) - throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); - exp = -scale; // exponent is -scale - return; - } - - /** - * Constructs a BigDecimal object from an array of characters. - *

    - * Constructs a BigDecimal as though a String had been constructed from the character - * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be - * null. - *

    - * Using this constructor is faster than using the BigDecimal(String) constructor if the string is - * already available in character array form. - * - * @param inchars The char[] array containing the number to be converted. - * @throws NumberFormatException If the parameter is not a valid number. - * @stable ICU 2.0 - */ - - public BigDecimal(char inchars[]) { - this(inchars, 0, inchars.length); - return; - } - - /** - * Constructs a BigDecimal object from an array of characters. - *

    - * Constructs a BigDecimal as though a String had been constructed from the character - * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. - * The first parameter must not be null, and the subarray must be wholly contained within it. - *

    - * Using this constructor is faster than using the BigDecimal(String) constructor if the string is - * already available within a character array. - * - * @param inchars The char[] array containing the number to be converted. - * @param offset The int offset into the array of the start of the number to be converted. - * @param length The int length of the number. - * @throws NumberFormatException If the parameter is not a valid number for any reason. - * @stable ICU 2.0 - */ - - public BigDecimal(char inchars[], int offset, int length) { - super(); - boolean exotic; - boolean hadexp; - int d; - int dotoff; - int last; - int i = 0; - char si = 0; - boolean eneg = false; - int k = 0; - int elen = 0; - int j = 0; - char sj = 0; - int dvalue = 0; - int mag = 0; - // This is the primary constructor; all incoming strings end up - // here; it uses explicit (inline) parsing for speed and to avoid - // generating intermediate (temporary) objects of any kind. - // 1998.06.25: exponent form built only if E/e in string - // 1998.06.25: trailing zeros not removed for zero - // 1999.03.06: no embedded blanks; allow offset and length - if (length <= 0) - bad(inchars); // bad conversion (empty string) - // [bad offset will raise array bounds exception] - - /* Handle and step past sign */ - ind = ispos; // assume positive - if (inchars[offset] == ('-')) { - length--; - if (length == 0) - bad(inchars); // nothing after sign - ind = isneg; - offset++; - } else if (inchars[offset] == ('+')) { - length--; - if (length == 0) - bad(inchars); // nothing after sign - offset++; - } - - /* We're at the start of the number */ - exotic = false; // have extra digits - hadexp = false; // had explicit exponent - d = 0; // count of digits found - dotoff = -1; // offset where dot was found - last = -1; // last character of mantissa - { - int $1 = length; - i = offset; - i: for (; $1 > 0; $1--, i++) { - si = inchars[i]; - if (si >= '0') // test for Arabic digit - if (si <= '9') { - last = i; - d++; // still in mantissa - continue i; - } - if (si == '.') { // record and ignore - if (dotoff >= 0) - bad(inchars); // two dots - dotoff = i - offset; // offset into mantissa - continue i; - } - if (si != 'e') - if (si != 'E') { // expect an extra digit - if ((!(Character.isDigit(si)))) - bad(inchars); // not a number - // defer the base 10 check until later to avoid extra method call - exotic = true; // will need conversion later - last = i; - d++; // still in mantissa - continue i; - } - /* Found 'e' or 'E' -- now process explicit exponent */ - // 1998.07.11: sign no longer required - if ((i - offset) > (length - 2)) - bad(inchars); // no room for even one digit - eneg = false; - if ((inchars[i + 1]) == ('-')) { - eneg = true; - k = i + 2; - } else if ((inchars[i + 1]) == ('+')) - k = i + 2; - else - k = i + 1; - // k is offset of first expected digit - elen = length - ((k - offset)); // possible number of digits - if ((elen == 0) | (elen > 9)) - bad(inchars); // 0 or more than 9 digits - { - int $2 = elen; - j = k; - for (; $2 > 0; $2--, j++) { - sj = inchars[j]; - if (sj < '0') - bad(inchars); // always bad - if (sj > '9') { // maybe an exotic digit - if ((!(Character.isDigit(sj)))) - bad(inchars); // not a number - dvalue = Character.digit(sj, 10); // check base - if (dvalue < 0) - bad(inchars); // not base 10 - } else - dvalue = ((int) (sj)) - ((int) ('0')); - exp = (exp * 10) + dvalue; - } - }/* j */ - if (eneg) - exp = -exp; // was negative - hadexp = true; // remember we had one - break i; // we are done - } - }/* i */ - - /* Here when all inspected */ - if (d == 0) - bad(inchars); // no mantissa digits - if (dotoff >= 0) - exp = (exp + dotoff) - d; // adjust exponent if had dot - - /* strip leading zeros/dot (leave final if all 0's) */ - { - int $3 = last - 1; - i = offset; - i: for (; i <= $3; i++) { - si = inchars[i]; - if (si == '0') { - offset++; - dotoff--; - d--; - } else if (si == '.') { - offset++; // step past dot - dotoff--; - } else if (si <= '9') - break i;/* non-0 */ - else {/* exotic */ - if ((Character.digit(si, 10)) != 0) - break i; // non-0 or bad - // is 0 .. strip like '0' - offset++; - dotoff--; - d--; - } - } - }/* i */ - - /* Create the mantissa array */ - mant = new byte[d]; // we know the length - j = offset; // input offset - if (exotic) { - do { // slow: check for exotica - { - int $4 = d; - i = 0; - for (; $4 > 0; $4--, i++) { - if (i == dotoff) - j++; // at dot - sj = inchars[j]; - if (sj <= '9') - mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */ - else { - dvalue = Character.digit(sj, 10); - if (dvalue < 0) - bad(inchars); // not a number after all - mant[i] = (byte) dvalue; - } - j++; - } - }/* i */ - } while (false); - }/* exotica */ - else { - do { - { - int $5 = d; - i = 0; - for (; $5 > 0; $5--, i++) { - if (i == dotoff) - j++; - mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0'))); - j++; - } - }/* i */ - } while (false); - }/* simple */ - - /* Looks good. Set the sign indicator and form, as needed. */ - // Trailing zeros are preserved - // The rule here for form is: - // If no E-notation, then request plain notation - // Otherwise act as though add(0,DEFAULT) and request scientific notation - // [form is already PLAIN] - if (mant[0] == 0) { - ind = iszero; // force to show zero - // negative exponent is significant (e.g., -3 for 0.000) if plain - if (exp > 0) - exp = 0; // positive exponent can be ignored - if (hadexp) { // zero becomes single digit from add - mant = ZERO.mant; - exp = 0; - } - } else { // non-zero - // [ind was set earlier] - // now determine form - if (hadexp) { - form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC; - // 1999.06.29 check for overflow - mag = (exp + mant.length) - 1; // true exponent in scientific notation - if ((mag < MinExp) | (mag > MaxExp)) - bad(inchars); - } - } - // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form - return; - } - - /** - * Constructs a BigDecimal object directly from a double. - *

    - * Constructs a BigDecimal which is the exact decimal representation of the 64-bit signed binary - * floating point parameter. - *

    - * Note that this constructor it an exact conversion; it does not give the same result as converting num - * to a String using the Double.toString() method and then using the - * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)} - * method to construct a BigDecimal from a double. - * - * @param num The double to be converted. - * @throws NumberFormatException If the parameter is infinite or not a number. - * @stable ICU 2.0 - */ - - public BigDecimal(double num) { - // 1999.03.06: use exactly the old algorithm - // 2000.01.01: note that this constructor does give an exact result, - // so perhaps it should not be deprecated - // 2000.06.18: no longer deprecated - this((new java.math.BigDecimal(num)).toString()); - return; - } - - /** - * Constructs a BigDecimal object directly from a int. - *

    - * Constructs a BigDecimal which is the exact decimal representation of the 32-bit signed binary - * integer parameter. The BigDecimal will contain only decimal digits, prefixed with a leading minus - * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. - * - * @param num The int to be converted. - * @stable ICU 2.0 - */ - - public BigDecimal(int num) { - super(); - int mun; - int i = 0; - // We fastpath commoners - if (num <= 9) - if (num >= (-9)) { - do { - // very common single digit case - {/* select */ - if (num == 0) { - mant = ZERO.mant; - ind = iszero; - } else if (num == 1) { - mant = ONE.mant; - ind = ispos; - } else if (num == (-1)) { - mant = ONE.mant; - ind = isneg; - } else { - { - mant = new byte[1]; - if (num > 0) { - mant[0] = (byte) num; - ind = ispos; - } else { // num<-1 - mant[0] = (byte) -num; - ind = isneg; - } - } - } - } - return; - } while (false); - }/* singledigit */ - - /* We work on negative numbers so we handle the most negative number */ - if (num > 0) { - ind = ispos; - num = -num; - } else - ind = isneg;/* negative */// [0 case already handled] - // [it is quicker, here, to pre-calculate the length with - // one loop, then allocate exactly the right length of byte array, - // then re-fill it with another loop] - mun = num; // working copy - { - i = 9; - i: for (;; i--) { - mun = mun / 10; - if (mun == 0) - break i; - } - }/* i */ - // i is the position of the leftmost digit placed - mant = new byte[10 - i]; - { - i = (10 - i) - 1; - i: for (;; i--) { - mant[i] = (byte) -(((byte) (num % 10))); - num = num / 10; - if (num == 0) - break i; - } - }/* i */ - return; - } - - /** - * Constructs a BigDecimal object directly from a long. - *

    - * Constructs a BigDecimal which is the exact decimal representation of the 64-bit signed binary - * integer parameter. The BigDecimal will contain only decimal digits, prefixed with a leading minus - * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. - * - * @param num The long to be converted. - * @stable ICU 2.0 - */ - - public BigDecimal(long num) { - super(); - long mun; - int i = 0; - // Not really worth fastpathing commoners in this constructor [also, - // we use this to construct the static constants]. - // This is much faster than: this(String.valueOf(num).toCharArray()) - /* We work on negative num so we handle the most negative number */ - if (num > 0) { - ind = ispos; - num = -num; - } else if (num == 0) - ind = iszero; - else - ind = isneg;/* negative */ - mun = num; - { - i = 18; - i: for (;; i--) { - mun = mun / 10; - if (mun == 0) - break i; - } - }/* i */ - // i is the position of the leftmost digit placed - mant = new byte[19 - i]; - { - i = (19 - i) - 1; - i: for (;; i--) { - mant[i] = (byte) -(((byte) (num % 10))); - num = num / 10; - if (num == 0) - break i; - } - }/* i */ - return; - } - - /** - * Constructs a BigDecimal object from a String. - *

    - * Constructs a BigDecimal from the parameter, which must not be null and must represent a - * valid number, as described formally in the documentation referred to {@link BigDecimal above}. - *

    - * In summary, numbers in String form must have at least one digit, may have a leading sign, may have a - * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks. - *

    - * Some valid strings from which a BigDecimal might be constructed are: - * - *

    -     * 
    -     * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
    -     * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
    -     * Exponential notation
    -     * 
    -     * 
    - *

    - * (Exponential notation means that the number includes an optional sign and a power of ten following an - * 'E' that indicates how the decimal point will be shifted. Thus the "4E+9" above is - * just a short way of writing 4000000000, and the "0.73e-7" is short for - * 0.000000073.) - *

    - * The BigDecimal constructed from the String is in a standard form, with no blanks, as though the - * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string - * uses exponential notation (that is, includes an e or an E), then the BigDecimal - * number will be expressed in scientific notation (where the power of ten is adjusted so there is a single - * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as - * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must - * fit in nine digits both before and after it is expressed in scientific notation. - *

    - * Any digits in the parameter must be decimal; that is, Character.digit(c, 10) (where c - * is the character in question) would not return -1. - * - * @param string The String to be converted. - * @throws NumberFormatException If the parameter is not a valid number. - * @stable ICU 2.0 - */ - - public BigDecimal(java.lang.String string) { - this(string.toCharArray(), 0, string.length()); - return; - } - - /* Make a default BigDecimal object for local use. */ - - private BigDecimal() { - super(); - return; - } - - /* ---------------------------------------------------------------- */ - /* Operator methods [methods which take a context parameter] */ - /* ---------------------------------------------------------------- */ - - /** - * Returns a plain BigDecimal whose value is the absolute value of this BigDecimal. - *

    - * The same as {@link #abs(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN). - *

    - * The length of the decimal part (the scale) of the result will be this.scale() - * - * @return A BigDecimal whose value is the absolute value of this BigDecimal. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal abs() { - return this.abs(plainMC); - } - - /** - * Returns a BigDecimal whose value is the absolute value of this BigDecimal. - *

    - * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method - * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)} - * method with the same parameter is returned. - * - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is the absolute value of this BigDecimal. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) { - if (this.ind == isneg) - return this.negate(set); - return this.plus(set); - } - - /** - * Returns a plain BigDecimal whose value is this+rhs, using fixed point arithmetic. - *

    - * The same as {@link #add(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the - * context is new MathContext(0, MathContext.PLAIN). - *

    - * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. - * - * @param rhs The BigDecimal for the right hand side of the addition. - * @return A BigDecimal whose value is this+rhs, using fixed point arithmetic. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) { - return this.add(rhs, plainMC); - } - - /** - * Returns a BigDecimal whose value is this+rhs. - *

    - * Implements the addition (+) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - * - * @param rhs The BigDecimal for the right hand side of the addition. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is this+rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - com.ibm.icu.math.BigDecimal lhs; - int reqdig; - com.ibm.icu.math.BigDecimal res; - byte usel[]; - int usellen; - byte user[]; - int userlen; - int newlen = 0; - int tlen = 0; - int mult = 0; - byte t[] = null; - int ia = 0; - int ib = 0; - int ea = 0; - int eb = 0; - byte ca = 0; - byte cb = 0; - /* determine requested digits and form */ - if (set.lostDigits) - checkdigits(rhs, set.digits); - lhs = this; // name for clarity and proxy - - /* Quick exit for add floating 0 */ - // plus() will optimize to return same object if possible - if (lhs.ind == 0) - if (set.form != com.ibm.icu.math.MathContext.PLAIN) - return rhs.plus(set); - if (rhs.ind == 0) - if (set.form != com.ibm.icu.math.MathContext.PLAIN) - return lhs.plus(set); - - /* Prepare numbers (round, unless unlimited precision) */ - reqdig = set.digits; // local copy (heavily used) - if (reqdig > 0) { - if (lhs.mant.length > reqdig) - lhs = clone(lhs).round(set); - if (rhs.mant.length > reqdig) - rhs = clone(rhs).round(set); - // [we could reuse the new LHS for result in this case] - } - - res = new com.ibm.icu.math.BigDecimal(); // build result here - - /* - * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much - * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to - * DIGITS trailing zeros]. - */ - // Note sign may be 0 if digits (reqdig) is 0 - // usel and user will be the byte arrays passed to the adder; we'll - // use them on all paths except quick exits - usel = lhs.mant; - usellen = lhs.mant.length; - user = rhs.mant; - userlen = rhs.mant.length; - { - do {/* select */ - if (lhs.exp == rhs.exp) {/* no padding needed */ - // This is the most common, and fastest, path - res.exp = lhs.exp; - } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs - newlen = (usellen + lhs.exp) - rhs.exp; - /* - * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot - * affect answer, so we only need to pad up to a length of DIGITS+1. - */ - if (newlen >= ((userlen + reqdig) + 1)) - if (reqdig > 0) { - // LHS is sufficient - res.mant = usel; - res.exp = lhs.exp; - res.ind = lhs.ind; - if (usellen < reqdig) { // need 0 padding - res.mant = extend(lhs.mant, reqdig); - res.exp = res.exp - ((reqdig - usellen)); - } - return res.finish(set, false); - } - // RHS may affect result - res.exp = rhs.exp; // expected final exponent - if (newlen > (reqdig + 1)) - if (reqdig > 0) { - // LHS will be max; RHS truncated - tlen = (newlen - reqdig) - 1; // truncation length - userlen = userlen - tlen; - res.exp = res.exp + tlen; - newlen = reqdig + 1; - } - if (newlen > usellen) - usellen = newlen; // need to pad LHS - } else { // need to pad rhs and/or truncate lhs - newlen = (userlen + rhs.exp) - lhs.exp; - if (newlen >= ((usellen + reqdig) + 1)) - if (reqdig > 0) { - // RHS is sufficient - res.mant = user; - res.exp = rhs.exp; - res.ind = rhs.ind; - if (userlen < reqdig) { // need 0 padding - res.mant = extend(rhs.mant, reqdig); - res.exp = res.exp - ((reqdig - userlen)); - } - return res.finish(set, false); - } - // LHS may affect result - res.exp = lhs.exp; // expected final exponent - if (newlen > (reqdig + 1)) - if (reqdig > 0) { - // RHS will be max; LHS truncated - tlen = (newlen - reqdig) - 1; // truncation length - usellen = usellen - tlen; - res.exp = res.exp + tlen; - newlen = reqdig + 1; - } - if (newlen > userlen) - userlen = newlen; // need to pad RHS - } - } while (false); - }/* padder */ - - /* OK, we have aligned mantissas. Now add or subtract. */ - // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive - // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs] - // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs] - if (lhs.ind == iszero) - res.ind = ispos; - else - res.ind = lhs.ind; // likely sign, all paths - if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative - mult = 1; - else { - do { // different signs, so subtraction is needed - mult = -1; // will cause subtract - /* - * Before we can subtract we must determine which is the larger, as our add/subtract routine only - * handles non-negative results so we may need to swap the operands. - */ - { - do {/* select */ - if (rhs.ind == iszero) { - // original A bigger - } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger - t = usel; - usel = user; - user = t; // swap - tlen = usellen; - usellen = userlen; - userlen = tlen; // .. - res.ind = (byte) -res.ind; // and set sign - } else if (usellen > userlen) { - // original A bigger - } else { - {/* logical lengths the same */// need compare - /* may still need to swap: compare the strings */ - ia = 0; - ib = 0; - ea = usel.length - 1; - eb = user.length - 1; - { - compare: for (;;) { - if (ia <= ea) - ca = usel[ia]; - else { - if (ib > eb) {/* identical */ - if (set.form != com.ibm.icu.math.MathContext.PLAIN) - return ZERO; - // [if PLAIN we must do the subtract, in case of 0.000 results] - break compare; - } - ca = (byte) 0; - } - if (ib <= eb) - cb = user[ib]; - else - cb = (byte) 0; - if (ca != cb) { - if (ca < cb) {/* swap needed */ - t = usel; - usel = user; - user = t; // swap - tlen = usellen; - usellen = userlen; - userlen = tlen; // .. - res.ind = (byte) -res.ind; - } - break compare; - } - /* mantissas the same, so far */ - ia++; - ib++; - } - }/* compare */ - } // lengths the same - } - } while (false); - }/* swaptest */ - } while (false); - }/* signdiff */ - - /* here, A is > B if subtracting */ - // add [A+B*1] or subtract [A+(B*-1)] - res.mant = byteaddsub(usel, usellen, user, userlen, mult, false); - // [reuse possible only after chop; accounting makes not worthwhile] - - // Finish() rounds before stripping leading 0's, then sets form, etc. - return res.finish(set, false); - } - - /** - * Compares this BigDecimal to another, using unlimited precision. - *

    - * The same as {@link #compareTo(BigDecimal, MathContext)}, where the BigDecimal is rhs, - * and the context is new MathContext(0, MathContext.PLAIN). - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @return An int whose value is -1, 0, or 1 as this is numerically less than, equal to, - * or greater than rhs. - * @stable ICU 2.0 - */ - - public int compareTo(com.ibm.icu.math.BigDecimal rhs) { - return this.compareTo(rhs, plainMC); - } - - /** - * Compares this BigDecimal to another. - *

    - * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}), - * and returns a result of type int. - *

    - * The result will be: - * - * - * - * - * - * - * - * - * - * - *
    -1 if the current object is less than the first parameter
    0 if the current object is equal to the first parameter
    1 if the current object is greater than the first parameter.
    - *

    - * A {@link #compareTo(BigDecimal)} method is also provided. - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @param set The MathContext arithmetic settings. - * @return An int whose value is -1, 0, or 1 as this is numerically less than, equal to, - * or greater than rhs. - * @stable ICU 2.0 - */ - - public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - int thislength = 0; - int i = 0; - com.ibm.icu.math.BigDecimal newrhs; - // rhs=null will raise NullPointerException, as per Comparable interface - if (set.lostDigits) - checkdigits(rhs, set.digits); - // [add will recheck in slowpath cases .. but would report -rhs] - if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) { - /* sign & exponent the same [very common] */ - thislength = this.mant.length; - if (thislength < rhs.mant.length) - return (byte) -this.ind; - if (thislength > rhs.mant.length) - return this.ind; - /* - * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very - * unusual] - */ - if ((thislength <= set.digits) | (set.digits == 0)) { - { - int $6 = thislength; - i = 0; - for (; $6 > 0; $6--, i++) { - if (this.mant[i] < rhs.mant[i]) - return (byte) -this.ind; - if (this.mant[i] > rhs.mant[i]) - return this.ind; - } - }/* i */ - return 0; // identical - } - /* drop through for full comparison */ - } else { - /* More fastpaths possible */ - if (this.ind < rhs.ind) - return -1; - if (this.ind > rhs.ind) - return 1; - } - /* carry out a subtract to make the comparison */ - newrhs = clone(rhs); // safe copy - newrhs.ind = (byte) -newrhs.ind; // prepare to subtract - return this.add(newrhs, set).ind; // add, and return sign of result - } - - /** - * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic. - *

    - * The same as {@link #divide(BigDecimal, int)}, where the BigDecimal is rhs, and the - * rounding mode is {@link MathContext#ROUND_HALF_UP}. - * - * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if - * the latter were formatted without exponential notation. - * - * @param rhs The BigDecimal for the right hand side of the division. - * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic. - * @throws ArithmeticException If rhs is zero. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) { - return this.dodivide('D', rhs, plainMC, -1); - } - - /** - * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic and a - * rounding mode. - *

    - * The same as {@link #divide(BigDecimal, int, int)}, where the BigDecimal is rhs, and the - * second parameter is this.scale(), and the third is round. - *

    - * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current - * object, if the latter were formatted without exponential notation. - *

    - * - * @param rhs The BigDecimal for the right hand side of the division. - * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). - * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic and - * the specified rounding mode. - * @throws IllegalArgumentException if round is not a valid rounding mode. - * @throws ArithmeticException if rhs is zero. - * @throws ArithmeticException if round is {@link MathContext#ROUND_UNNECESSARY} and this.scale() is insufficient to represent the result exactly. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) { - com.ibm.icu.math.MathContext set; - set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round, - // too] - return this.dodivide('D', rhs, set, -1); // take scale from LHS - } - - /** - * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic and a - * given scale and rounding mode. - *

    - * The same as {@link #divide(BigDecimal, MathContext)}, where the BigDecimal is rhs, - * new MathContext(0, MathContext.PLAIN, false, round), except that the length of the decimal part (the - * scale) to be used for the result is explicit rather than being taken from this. - *

    - * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if - * the latter were formatted without exponential notation. - *

    - * - * @param rhs The BigDecimal for the right hand side of the division. - * @param scale The int scale to be used for the result. - * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). - * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic and - * the specified rounding mode. - * @throws IllegalArgumentException if round is not a valid rounding mode. - * @throws ArithmeticException if rhs is zero. - * @throws ArithmeticException if scale is negative. - * @throws ArithmeticException if round is {@link MathContext#ROUND_UNNECESSARY} and scale is insufficient - * to represent the result exactly. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) { - com.ibm.icu.math.MathContext set; - if (scale < 0) - throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); - set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round] - return this.dodivide('D', rhs, set, scale); - } - - /** - * Returns a BigDecimal whose value is this/rhs. - *

    - * Implements the division (/) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - * - * @param rhs The BigDecimal for the right hand side of the division. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is this/rhs. - * @throws ArithmeticException if rhs is zero. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - return this.dodivide('D', rhs, set, -1); - } - - /** - * Returns a plain BigDecimal whose value is the integer part of this/rhs. - *

    - * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the BigDecimal is rhs - * , and the context is new MathContext(0, MathContext.PLAIN). - * - * @param rhs The BigDecimal for the right hand side of the integer division. - * @return A BigDecimal whose value is the integer part of this/rhs. - * @throws ArithmeticException if rhs is zero. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) { - // scale 0 to drop .000 when plain - return this.dodivide('I', rhs, plainMC, 0); - } - - /** - * Returns a BigDecimal whose value is the integer part of this/rhs. - *

    - * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class - * header}), and returns the result as a BigDecimal object. - * - * @param rhs The BigDecimal for the right hand side of the integer division. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is the integer part of this/rhs. - * @throws ArithmeticException if rhs is zero. - * @throws ArithmeticException if the result will not fit in the number of digits specified for the context. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - // scale 0 to drop .000 when plain - return this.dodivide('I', rhs, set, 0); - } - - /** - * Returns a plain BigDecimal whose value is the maximum of this and rhs. - *

    - * The same as {@link #max(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the - * context is new MathContext(0, MathContext.PLAIN). - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @return A BigDecimal whose value is the maximum of this and rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) { - return this.max(rhs, plainMC); - } - - /** - * Returns a BigDecimal whose value is the maximum of this and rhs. - *

    - * Returns the larger of the current object and the first parameter. - *

    - * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return 1 - * or 0, then the result of calling the {@link #plus(MathContext)} method on the current object - * (using the same MathContext parameter) is returned. Otherwise, the result of calling the - * {@link #plus(MathContext)} method on the first parameter object (using the same MathContext - * parameter) is returned. - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is the maximum of this and rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - if ((this.compareTo(rhs, set)) >= 0) - return this.plus(set); - else - return rhs.plus(set); - } - - /** - * Returns a plain BigDecimal whose value is the minimum of this and rhs. - *

    - * The same as {@link #min(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the - * context is new MathContext(0, MathContext.PLAIN). - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @return A BigDecimal whose value is the minimum of this and rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) { - return this.min(rhs, plainMC); - } - - /** - * Returns a BigDecimal whose value is the minimum of this and rhs. - *

    - * Returns the smaller of the current object and the first parameter. - *

    - * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return -1 - * or 0, then the result of calling the {@link #plus(MathContext)} method on the current object - * (using the same MathContext parameter) is returned. Otherwise, the result of calling the - * {@link #plus(MathContext)} method on the first parameter object (using the same MathContext - * parameter) is returned. - * - * @param rhs The BigDecimal for the right hand side of the comparison. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is the minimum of this and rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - if ((this.compareTo(rhs, set)) <= 0) - return this.plus(set); - else - return rhs.plus(set); - } - - /** - * Returns a plain BigDecimal whose value is this*rhs, using fixed point arithmetic. - *

    - * The same as {@link #add(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the - * context is new MathContext(0, MathContext.PLAIN). - *

    - * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they - * were formatted without exponential notation. - * - * @param rhs The BigDecimal for the right hand side of the multiplication. - * @return A BigDecimal whose value is this*rhs, using fixed point arithmetic. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) { - return this.multiply(rhs, plainMC); - } - - /** - * Returns a BigDecimal whose value is this*rhs. - *

    - * Implements the multiplication ( ) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - * - * @param rhs The BigDecimal for the right hand side of the multiplication. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is this*rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - com.ibm.icu.math.BigDecimal lhs; - int padding; - int reqdig; - byte multer[] = null; - byte multand[] = null; - int multandlen; - int acclen = 0; - com.ibm.icu.math.BigDecimal res; - byte acc[]; - int n = 0; - byte mult = 0; - if (set.lostDigits) - checkdigits(rhs, set.digits); - lhs = this; // name for clarity and proxy - - /* Prepare numbers (truncate, unless unlimited precision) */ - padding = 0; // trailing 0's to add - reqdig = set.digits; // local copy - if (reqdig > 0) { - if (lhs.mant.length > reqdig) - lhs = clone(lhs).round(set); - if (rhs.mant.length > reqdig) - rhs = clone(rhs).round(set); - // [we could reuse the new LHS for result in this case] - } else {/* unlimited */ - // fixed point arithmetic will want every trailing 0; we add these - // after the calculation rather than before, for speed. - if (lhs.exp > 0) - padding = padding + lhs.exp; - if (rhs.exp > 0) - padding = padding + rhs.exp; - } - - // For best speed, as in DMSRCN, we use the shorter number as the - // multiplier and the longer as the multiplicand. - // 1999.12.22: We used to special case when the result would fit in - // a long, but with Java 1.3 this gave no advantage. - if (lhs.mant.length < rhs.mant.length) { - multer = lhs.mant; - multand = rhs.mant; - } else { - multer = rhs.mant; - multand = lhs.mant; - } - - /* Calculate how long result byte array will be */ - multandlen = (multer.length + multand.length) - 1; // effective length - // optimize for 75% of the cases where a carry is expected... - if ((multer[0] * multand[0]) > 9) - acclen = multandlen + 1; - else - acclen = multandlen; - - /* Now the main long multiplication loop */ - res = new com.ibm.icu.math.BigDecimal(); // where we'll build result - acc = new byte[acclen]; // accumulator, all zeros - // 1998.07.01: calculate from left to right so that accumulator goes - // to likely final length on first addition; this avoids a one-digit - // extension (and object allocation) each time around the loop. - // Initial number therefore has virtual zeros added to right. - { - int $7 = multer.length; - n = 0; - for (; $7 > 0; $7--, n++) { - mult = multer[n]; - if (mult != 0) { // [optimization] - // accumulate [accumulator is reusable array] - acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true); - } - // divide multiplicand by 10 for next digit to right - multandlen--; // 'virtual length' - } - }/* n */ - - res.ind = (byte) (lhs.ind * rhs.ind); // final sign - res.exp = (lhs.exp + rhs.exp) - padding; // final exponent - // [overflow is checked by finish] - - /* add trailing zeros to the result, if necessary */ - if (padding == 0) - res.mant = acc; - else - res.mant = extend(acc, acc.length + padding); // add trailing 0s - return res.finish(set, false); - } - - /** - * Returns a plain BigDecimal whose value is -this. - *

    - * The same as {@link #negate(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN) - * . - *

    - * The length of the decimal part (the scale) of the result will be be this.scale() - * - * - * @return A BigDecimal whose value is -this. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal negate() { - return this.negate(plainMC); - } - - /** - * Returns a BigDecimal whose value is -this. - *

    - * Implements the negation (Prefix -) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - * - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is -this. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) { - com.ibm.icu.math.BigDecimal res; - // Originally called minus(), changed to matched Java precedents - // This simply clones, flips the sign, and possibly rounds - if (set.lostDigits) - checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits); - res = clone(this); // safe copy - res.ind = (byte) -res.ind; - return res.finish(set, false); - } - - /** - * Returns a plain BigDecimal whose value is +this. Note that this is not - * necessarily a plain BigDecimal, but the result will always be. - *

    - * The same as {@link #plus(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN). - *

    - * The length of the decimal part (the scale) of the result will be be this.scale() - * - * @return A BigDecimal whose value is +this. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal plus() { - return this.plus(plainMC); - } - - /** - * Returns a BigDecimal whose value is +this. - *

    - * Implements the plus (Prefix +) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - *

    - * This method is useful for rounding or otherwise applying a context to a decimal value. - * - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is +this. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) { - // This clones and forces the result to the new settings - // May return same object - if (set.lostDigits) - checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits); - // Optimization: returns same object for some common cases - if (set.form == com.ibm.icu.math.MathContext.PLAIN) - if (this.form == com.ibm.icu.math.MathContext.PLAIN) { - if (this.mant.length <= set.digits) - return this; - if (set.digits == 0) - return this; - } - return clone(this).finish(set, false); - } - - /** - * Returns a plain BigDecimal whose value is this**rhs, using fixed point arithmetic. - *

    - * The same as {@link #pow(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the - * context is new MathContext(0, MathContext.PLAIN). - *

    - * The parameter is the power to which the this will be raised; it must be in the range 0 through - * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so - * they should not be used as a test for a whole number. - *

    - * In addition, the power must not be negative, as no MathContext is used and so the result would then - * always be 0. - * - * @param rhs The BigDecimal for the right hand side of the operation (the power). - * @return A BigDecimal whose value is this**rhs, using fixed point arithmetic. - * @throws ArithmeticException if rhs is out of range or is not a whole number. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) { - return this.pow(rhs, plainMC); - } - - // The name for this method is inherited from the precedent set by the - // BigInteger and Math classes. - - /** - * Returns a BigDecimal whose value is this**rhs. - *

    - * Implements the power ( ) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - *

    - * The first parameter is the power to which the this will be raised; it must be in the range - * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed - * in the future, so they should not be used as a test for a whole number. - *

    - * If the digits setting of the MathContext parameter is 0, the power must be zero or - * positive. - * - * @param rhs The BigDecimal for the right hand side of the operation (the power). - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is this**rhs. - * @throws ArithmeticException if rhs is out of range or is not a whole number. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - int n; - com.ibm.icu.math.BigDecimal lhs; - int reqdig; - int workdigits = 0; - int L = 0; - com.ibm.icu.math.MathContext workset; - com.ibm.icu.math.BigDecimal res; - boolean seenbit; - int i = 0; - if (set.lostDigits) - checkdigits(rhs, set.digits); - n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules - lhs = this; // clarified name - - reqdig = set.digits; // local copy (heavily used) - if (reqdig == 0) { - if (rhs.ind == isneg) - throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString()); - workdigits = 0; - } else {/* non-0 digits */ - if ((rhs.mant.length + rhs.exp) > reqdig) - throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); - - /* Round the lhs to DIGITS if need be */ - if (lhs.mant.length > reqdig) - lhs = clone(lhs).round(set); - - /* L for precision calculation [see ANSI X3.274-1996] */ - L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp - workdigits = (reqdig + L) + 1; // calculate the working DIGITS - } - - /* Create a copy of set for working settings */ - // Note: no need to check for lostDigits again. - // 1999.07.17 Note: this construction must follow RHS check - workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode); - - res = ONE; // accumulator - if (n == 0) - return res; // x**0 == 1 - if (n < 0) - n = -n; // [rhs.ind records the sign] - seenbit = false; // set once we've seen a 1-bit - { - i = 1; - i: for (;; i++) { // for each bit [top bit ignored] - n = n + n; // shift left 1 bit - if (n < 0) { // top bit is set - seenbit = true; // OK, we're off - res = res.multiply(lhs, workset); // acc=acc*x - } - if (i == 31) - break i; // that was the last bit - if ((!seenbit)) - continue i; // we don't have to square 1 - res = res.multiply(res, workset); // acc=acc*acc [square] - } - }/* i */// 32 bits - if (rhs.ind < 0) // was a **-n [hence digits>0] - res = ONE.divide(res, workset); // .. so acc=1/acc - return res.finish(set, true); // round and strip [original digits] - } - - /** - * Returns a plain BigDecimal whose value is the remainder of this/rhs, using fixed point - * arithmetic. - *

    - * The same as {@link #remainder(BigDecimal, MathContext)}, where the BigDecimal is rhs, - * and the context is new MathContext(0, MathContext.PLAIN). - *

    - * This is not the modulo operator -- the result may be negative. - * - * @param rhs The BigDecimal for the right hand side of the remainder operation. - * @return A BigDecimal whose value is the remainder of this/rhs, using fixed point - * arithmetic. - * @throws ArithmeticException if rhs is zero. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) { - return this.dodivide('R', rhs, plainMC, -1); - } - - /** - * Returns a BigDecimal whose value is the remainder of this/rhs. - *

    - * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}), - * and returns the result as a BigDecimal object. - *

    - * This is not the modulo operator -- the result may be negative. - * - * @param rhs The BigDecimal for the right hand side of the remainder operation. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is the remainder of this+rhs. - * @throws ArithmeticException if rhs is zero. - * @throws ArithmeticException if the integer part of the result will not fit in the number of digits specified for the context. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - return this.dodivide('R', rhs, set, -1); - } - - /** - * Returns a plain BigDecimal whose value is this-rhs, using fixed point arithmetic. - *

    - * The same as {@link #subtract(BigDecimal, MathContext)}, where the BigDecimal is rhs, - * and the context is new MathContext(0, MathContext.PLAIN). - *

    - * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. - * - * @param rhs The BigDecimal for the right hand side of the subtraction. - * @return A BigDecimal whose value is this-rhs, using fixed point arithmetic. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) { - return this.subtract(rhs, plainMC); - } - - /** - * Returns a BigDecimal whose value is this-rhs. - *

    - * Implements the subtraction (-) operator (as defined in the decimal documentation, see - * {@link BigDecimal class header}), and returns the result as a BigDecimal object. - * - * @param rhs The BigDecimal for the right hand side of the subtraction. - * @param set The MathContext arithmetic settings. - * @return A BigDecimal whose value is this-rhs. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { - com.ibm.icu.math.BigDecimal newrhs; - if (set.lostDigits) - checkdigits(rhs, set.digits); - // [add will recheck .. but would report -rhs] - /* carry out the subtraction */ - // we could fastpath -0, but it is too rare. - newrhs = clone(rhs); // safe copy - newrhs.ind = (byte) -newrhs.ind; // prepare to subtract - return this.add(newrhs, set); // arithmetic - } - - /* ---------------------------------------------------------------- */ - /* Other methods */ - /* ---------------------------------------------------------------- */ - - /** - * Converts this BigDecimal to a byte. If the BigDecimal has a non-zero - * decimal part or is out of the possible range for a byte (8-bit signed integer) result then an - * ArithmeticException is thrown. - * - * @return A byte equal in value to this. - * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a byte. - * @stable ICU 2.0 - */ - - public byte byteValueExact() { - int num; - num = this.intValueExact(); // will check decimal part too - if ((num > 127) | (num < (-128))) - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - return (byte) num; - } - - /** - * Converts this BigDecimal to a double. If the BigDecimal is out of the - * possible range for a double (64-bit signed floating point) result then an ArithmeticException - * is thrown. - *

    - * The double produced is identical to result of expressing the BigDecimal as a String and - * then converting it using the Double(String) constructor; this can result in values of - * Double.NEGATIVE_INFINITY or Double.POSITIVE_INFINITY. - * - * @return A double corresponding to this. - * @stable ICU 2.0 - */ - - public double doubleValue() { - // We go via a String [as does BigDecimal in JDK 1.2] - // Next line could possibly raise NumberFormatException - return java.lang.Double.valueOf(this.toString()).doubleValue(); - } - - /** - * Compares this BigDecimal with rhs for equality. - *

    - * If the parameter is null, or is not an instance of the BigDecimal type, or is not exactly equal to - * the current BigDecimal object, then false is returned. Otherwise, true is returned. - *

    - * "Exactly equal", here, means that the String representations of the BigDecimal numbers - * are identical (they have the same characters in the same sequence). - *

    - * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons. - * - * @param obj The Object for the right hand side of the comparison. - * @return A boolean whose value true if and only if the operands have identical string - * representations. - * @throws ClassCastException if rhs cannot be cast to a BigDecimal object. - * @stable ICU 2.0 - * @see #compareTo(BigDecimal) - * @see #compareTo(BigDecimal, MathContext) - */ - - public boolean equals(java.lang.Object obj) { - com.ibm.icu.math.BigDecimal rhs; - int i = 0; - char lca[] = null; - char rca[] = null; - // We are equal iff toString of both are exactly the same - if (obj == null) - return false; // not equal - if ((!(((obj instanceof com.ibm.icu.math.BigDecimal))))) - return false; // not a decimal - rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work - if (this.ind != rhs.ind) - return false; // different signs never match - if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form)) - - { // mantissas say all - // here with equal-length byte arrays to compare - { - int $8 = this.mant.length; - i = 0; - for (; $8 > 0; $8--, i++) { - if (this.mant[i] != rhs.mant[i]) - return false; - } - }/* i */ - } else { // need proper layout - lca = this.layout(); // layout to character array - rca = rhs.layout(); - if (lca.length != rca.length) - return false; // mismatch - // here with equal-length character arrays to compare - { - int $9 = lca.length; - i = 0; - for (; $9 > 0; $9--, i++) { - if (lca[i] != rca[i]) - return false; - } - }/* i */ - } - return true; // arrays have identical content - } - - /** - * Converts this BigDecimal to a float. If the BigDecimal is out of the - * possible range for a float (32-bit signed floating point) result then an ArithmeticException - * is thrown. - *

    - * The float produced is identical to result of expressing the BigDecimal as a String and - * then converting it using the Float(String) constructor; this can result in values of - * Float.NEGATIVE_INFINITY or Float.POSITIVE_INFINITY. - * - * @return A float corresponding to this. - * @stable ICU 2.0 - */ - - public float floatValue() { - return java.lang.Float.valueOf(this.toString()).floatValue(); - } - - /** - * Returns the String representation of this BigDecimal, modified by layout parameters. - *

    - * This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat - * , that can apply locale-sensitive editing of the result. The level of formatting that it provides is a - * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules - * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. - * - *

    - * The parameters, for both forms of the format method are all of type int. A value of -1 - * for any parameter indicates that the default action or value for that parameter should be used. - *

    - * The parameters, before and after, specify the number of characters to be used for the - * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter - * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed - * for that part. - *

    - * before must be a positive number; if it is larger than is needed to contain the integer part, that - * part is padded on the left with blanks to the requested length. If before is not large enough to - * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown. - *

    - * after must be a non-negative number; if it is not the same size as the decimal part of the number, - * the number will be rounded (or extended with zeros) to fit. Specifying 0 for after will cause the - * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method - * will be the default, MathContext.ROUND_HALF_UP. - *

    - * Other rounding methods, and the use of exponential notation, can be selected by using - * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect - * as using the six-parameter form with the final four parameters all being -1. - * - * @param before The int specifying the number of places before the decimal point. Use -1 for 'as many as are needed'. - * @param after The int specifying the number of places after the decimal point. Use -1 for 'as many as are needed'. - * @return A String representing this BigDecimal, laid out according to the specified parameters - * @throws ArithmeticException if the number cannot be laid out as requested. - * @throws IllegalArgumentException if a parameter is out of range. - * @stable ICU 2.0 - * @see #toString - * @see #toCharArray - */ - - public java.lang.String format(int before, int after) { - return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP); - } - - /** - * Returns the String representation of this BigDecimal, modified by layout parameters and - * allowing exponential notation. - *

    - * This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat - * , that can apply locale-sensitive editing of the result. The level of formatting that it provides is a - * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules - * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. - * - *

    - * The parameters are all of type int. A value of -1 for any parameter indicates that the default - * action or value for that parameter should be used. - *

    - * The first two parameters (before and after) specify the number of characters to be used - * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If - * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many - * as are needed for that part. - *

    - * The remaining parameters control the use of exponential notation and rounding. Three (explaces, - * exdigits, and exform) control the exponent part of the result. As before, the default - * action for any of these parameters may be selected by using the value -1. - *

    - * explaces must be a positive number; it sets the number of places (digits after the sign of the - * exponent) to be used for any exponent part, the default (when explaces is -1) being to use as many - * as are needed. If explaces is not -1, space is always reserved for an exponent; if one is not needed - * (for example, if the exponent will be 0) then explaces+2 blanks are appended to the result. If explaces - * is not -1 and is not large enough to contain the exponent, an exception is thrown. - *

    - * exdigits sets the trigger point for use of exponential notation. If, before any rounding, the number - * of places needed before the decimal point exceeds exdigits, or if the absolute value of the result - * is less than 0.000001, then exponential form will be used, provided that exdigits was - * specified. When exdigits is -1, exponential notation will never be used. If 0 is specified for - * exdigits, exponential notation is always used unless the exponent would be 0. - *

    - * exform sets the form for exponential notation (if needed). It may be either - * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested, - * up to three digits (plus sign, if negative) may be needed for the integer part of the result (before - * ). Otherwise, only one digit (plus sign, if negative) is needed. - *

    - * Finally, the sixth argument, exround, selects the rounding algorithm to be used, and must be one of - * the values indicated by a public constant in the {@link MathContext} class whose name starts with ROUND_ - * . The default (ROUND_HALF_UP) may also be selected by using the value -1, as before. - *

    - * The special value MathContext.ROUND_UNNECESSARY may be used to detect whether non-zero digits are - * discarded -- if exround has this value than if non-zero digits would be discarded (rounded) during - * formatting then an ArithmeticException is thrown. - * - * @param before The int specifying the number of places before the decimal point. Use -1 for 'as many as - * are needed'. - * @param after The int specifying the number of places after the decimal point. Use -1 for 'as many as - * are needed'. - * @param explaces The int specifying the number of places to be used for any exponent. Use -1 for 'as many - * as are needed'. - * @param exdigits The int specifying the trigger (digits before the decimal point) which if exceeded causes - * exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation - * (no exponential notation). - * @param exformint The int specifying the form of exponential notation to be used ( - * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}). - * @param exround The int specifying the rounding mode to use. Use -1 for the default, - * {@link MathContext#ROUND_HALF_UP}. - * @return A String representing this BigDecimal, laid out according to the specified - * parameters - * @throws ArithmeticException if the number cannot be laid out as requested. - * @throws IllegalArgumentException if a parameter is out of range. - * @see #toString - * @see #toCharArray - * @stable ICU 2.0 - */ - - public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) { - com.ibm.icu.math.BigDecimal num; - int mag = 0; - int thisafter = 0; - int lead = 0; - byte newmant[] = null; - int chop = 0; - int need = 0; - int oldexp = 0; - char a[]; - int p = 0; - char newa[] = null; - int i = 0; - int places = 0; - - /* Check arguments */ - if ((before < (-1)) | (before == 0)) - badarg("format", 1, java.lang.String.valueOf(before)); - if (after < (-1)) - badarg("format", 2, java.lang.String.valueOf(after)); - if ((explaces < (-1)) | (explaces == 0)) - badarg("format", 3, java.lang.String.valueOf(explaces)); - if (exdigits < (-1)) - badarg("format", 4, java.lang.String.valueOf(explaces)); - {/* select */ - if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) { - } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) { - } else if (exformint == (-1)) - exformint = com.ibm.icu.math.MathContext.SCIENTIFIC; - // note PLAIN isn't allowed - else { - badarg("format", 5, java.lang.String.valueOf(exformint)); - } - } - // checking the rounding mode is done by trying to construct a - // MathContext object with that mode; it will fail if bad - if (exround != ROUND_HALF_UP) { - try { // if non-default... - if (exround == (-1)) - exround = ROUND_HALF_UP; - else - new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround); - } catch (java.lang.IllegalArgumentException $10) { - badarg("format", 6, java.lang.String.valueOf(exround)); - } - } - - num = clone(this); // make private copy - - /* - * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0] - * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two] - * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified - */ - - /* determine form */ - { - do {/* select */ - if (exdigits == (-1)) - num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; - else if (num.ind == iszero) - num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; - else { - // determine whether triggers - mag = num.exp + num.mant.length; - if (mag > exdigits) - num.form = (byte) exformint; - else if (mag < (-5)) - num.form = (byte) exformint; - else - num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; - } - } while (false); - }/* setform */ - - /* - * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform - * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific). - */ - if (after >= 0) { - setafter: for (;;) { - // calculate the current after-length - {/* select */ - if (num.form == com.ibm.icu.math.MathContext.PLAIN) - thisafter = -num.exp; // has decimal part - else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC) - thisafter = num.mant.length - 1; - else { // engineering - lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use - if (lead < 0) - lead = 3 + lead; // negative exponent case - lead++; // number of leading digits - if (lead >= num.mant.length) - thisafter = 0; - else - thisafter = num.mant.length - lead; - } - } - if (thisafter == after) - break setafter; // we're in luck - if (thisafter < after) { // need added trailing zeros - // [thisafter can be negative] - newmant = extend(num.mant, (num.mant.length + after) - thisafter); - num.mant = newmant; - num.exp = num.exp - ((after - thisafter)); // adjust exponent - if (num.exp < MinExp) - throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp); - break setafter; - } - // We have too many digits after the decimal point; this could - // cause a carry, which could change the mantissa... - // Watch out for implied leading zeros in PLAIN case - chop = thisafter - after; // digits to lop [is >0] - if (chop > num.mant.length) { // all digits go, no chance of carry - // carry on with zero - num.mant = ZERO.mant; - num.ind = iszero; - num.exp = 0; - continue setafter; // recheck: we may need trailing zeros - } - // we have a digit to inspect from existing mantissa - // round the number as required - need = num.mant.length - chop; // digits to end up with [may be 0] - oldexp = num.exp; // save old exponent - num.round(need, exround); - // if the exponent grew by more than the digits we chopped, then - // we must have had a carry, so will need to recheck the layout - if ((num.exp - oldexp) == chop) - break setafter; // number did not have carry - // mantissa got extended .. so go around and check again - } - }/* setafter */ - - a = num.layout(); // lay out, with exponent if required, etc. - - /* Here we have laid-out number in 'a' */ - // now apply 'before' and 'explaces' as needed - if (before > 0) { - // look for '.' or 'E' - { - int $11 = a.length; - p = 0; - p: for (; $11 > 0; $11--, p++) { - if (a[p] == '.') - break p; - if (a[p] == 'E') - break p; - } - }/* p */ - // p is now offset of '.', 'E', or character after end of array - // that is, the current length of before part - if (p > before) - badarg("format", 1, java.lang.String.valueOf(before)); // won't fit - if (p < before) { // need leading blanks - newa = new char[(a.length + before) - p]; - { - int $12 = before - p; - i = 0; - for (; $12 > 0; $12--, i++) { - newa[i] = ' '; - } - }/* i */ - java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, i, a.length); - a = newa; - } - // [if p=before then it's just the right length] - } - - if (explaces > 0) { - // look for 'E' [cannot be at offset 0] - { - int $13 = a.length - 1; - p = a.length - 1; - p: for (; $13 > 0; $13--, p--) { - if (a[p] == 'E') - break p; - } - }/* p */ - // p is now offset of 'E', or 0 - if (p == 0) { // no E part; add trailing blanks - newa = new char[(a.length + explaces) + 2]; - java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, a.length); - { - int $14 = explaces + 2; - i = a.length; - for (; $14 > 0; $14--, i++) { - newa[i] = ' '; - } - }/* i */ - a = newa; - } else {/* found E */// may need to insert zeros - places = (a.length - p) - 2; // number so far - if (places > explaces) - badarg("format", 3, java.lang.String.valueOf(explaces)); - if (places < explaces) { // need to insert zeros - newa = new char[(a.length + explaces) - places]; - java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, p + 2); // through E - // and sign - { - int $15 = explaces - places; - i = p + 2; - for (; $15 > 0; $15--, i++) { - newa[i] = '0'; - } - }/* i */ - java.lang.System.arraycopy((java.lang.Object) a, p + 2, (java.lang.Object) newa, i, places); // remainder - // of - // exponent - a = newa; - } - // [if places=explaces then it's just the right length] - } - } - return new java.lang.String(a); - } - - /** - * Returns the hashcode for this BigDecimal. This hashcode is suitable for use by the - * java.util.Hashtable class. - *

    - * Note that two BigDecimal objects are only guaranteed to produce the same hashcode if they are - * exactly equal (that is, the String representations of the BigDecimal numbers are - * identical -- they have the same characters in the same sequence). - * - * @return An int that is the hashcode for this. - * @stable ICU 2.0 - */ - - public int hashCode() { - // Maybe calculate ourselves, later. If so, note that there can be - // more than one internal representation for a given toString() result. - return this.toString().hashCode(); - } - - /** - * Converts this BigDecimal to an int. If the BigDecimal has a non-zero - * decimal part it is discarded. If the BigDecimal is out of the possible range for an int - * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be - * decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact} - * method. - * - * @return An int converted from this, truncated and decapitated if necessary. - * @stable ICU 2.0 - */ - - public int intValue() { - return toBigInteger().intValue(); - } - - /** - * Converts this BigDecimal to an int. If the BigDecimal has a non-zero - * decimal part or is out of the possible range for an int (32-bit signed integer) result then an - * ArithmeticException is thrown. - * - * @return An int equal in value to this. - * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in an int. - * @stable ICU 2.0 - */ - - public int intValueExact() { - int lodigit; - int useexp = 0; - int result; - int i = 0; - int topdig = 0; - // This does not use longValueExact() as the latter can be much - // slower. - // intcheck (from pow) relies on this to check decimal part - if (ind == iszero) - return 0; // easy, and quite common - /* test and drop any trailing decimal part */ - lodigit = mant.length - 1; - if (exp < 0) { - lodigit = lodigit + exp; // reduces by -(-exp) - /* all decimal places must be 0 */ - if ((!(allzero(mant, lodigit + 1)))) - throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); - if (lodigit < 0) - return 0; // -1=0 */ - if ((exp + lodigit) > 9) // early exit - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - useexp = exp; - } - /* convert the mantissa to binary, inline for speed */ - result = 0; - { - int $16 = lodigit + useexp; - i = 0; - for (; i <= $16; i++) { - result = result * 10; - if (i <= lodigit) - result = result + mant[i]; - } - }/* i */ - - /* Now, if the risky length, check for overflow */ - if ((lodigit + useexp) == 9) { - // note we cannot just test for -ve result, as overflow can move a - // zero into the top bit [consider 5555555555] - topdig = result / 1000000000; // get top digit, preserving sign - if (topdig != mant[0]) { // digit must match and be positive - // except in the special case ... - if (result == java.lang.Integer.MIN_VALUE) // looks like the special - if (ind == isneg) // really was negative - if (mant[0] == 2) - return result; // really had top digit 2 - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - } - } - - /* Looks good */ - if (ind == ispos) - return result; - return -result; - } - - /** - * Converts this BigDecimal to a long. If the BigDecimal has a non-zero - * decimal part it is discarded. If the BigDecimal is out of the possible range for a long - * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be - * decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact} - * method. - * - * @return A long converted from this, truncated and decapitated if necessary. - * @stable ICU 2.0 - */ - - public long longValue() { - return toBigInteger().longValue(); - } - - /** - * Converts this BigDecimal to a long. If the BigDecimal has a non-zero - * decimal part or is out of the possible range for a long (64-bit signed integer) result then an - * ArithmeticException is thrown. - * - * @return A long equal in value to this. - * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a long. - * @stable ICU 2.0 - */ - - public long longValueExact() { - int lodigit; - int cstart = 0; - int useexp = 0; - long result; - int i = 0; - long topdig = 0; - // Identical to intValueExact except for result=long, and exp>=20 test - if (ind == 0) - return 0; // easy, and quite common - lodigit = mant.length - 1; // last included digit - if (exp < 0) { - lodigit = lodigit + exp; // -(-exp) - /* all decimal places must be 0 */ - if (lodigit < 0) - cstart = 0; - else - cstart = lodigit + 1; - if ((!(allzero(mant, cstart)))) - throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); - if (lodigit < 0) - return 0; // -1=0 */ - if ((exp + mant.length) > 18) // early exit - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - useexp = exp; - } - - /* convert the mantissa to binary, inline for speed */ - // note that we could safely use the 'test for wrap to negative' - // algorithm here, but instead we parallel the intValueExact - // algorithm for ease of checking and maintenance. - result = (long) 0; - { - int $17 = lodigit + useexp; - i = 0; - for (; i <= $17; i++) { - result = result * 10; - if (i <= lodigit) - result = result + mant[i]; - } - }/* i */ - - /* Now, if the risky length, check for overflow */ - if ((lodigit + useexp) == 18) { - topdig = result / 1000000000000000000L; // get top digit, preserving sign - if (topdig != mant[0]) { // digit must match and be positive - // except in the special case ... - if (result == java.lang.Long.MIN_VALUE) // looks like the special - if (ind == isneg) // really was negative - if (mant[0] == 9) - return result; // really had top digit 9 - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - } - } - - /* Looks good */ - if (ind == ispos) - return result; - return -result; - } - - /** - * Returns a plain BigDecimal whose decimal point has been moved to the left by a specified number of - * positions. The parameter, n, specifies the number of positions to move the decimal point. That is, - * if n is 0 or positive, the number returned is given by: - *

    - * this.multiply(TEN.pow(new BigDecimal(-n))) - *

    - * n may be negative, in which case the method returns the same result as movePointRight(-n) - * . - * - * @param n The int specifying the number of places to move the decimal point leftwards. - * @return A BigDecimal derived from this, with the decimal point moved n - * places to the left. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal movePointLeft(int n) { - com.ibm.icu.math.BigDecimal res; - // very little point in optimizing for shift of 0 - res = clone(this); - res.exp = res.exp - n; - return res.finish(plainMC, false); // finish sets form and checks exponent - } - - /** - * Returns a plain BigDecimal whose decimal point has been moved to the right by a specified number of - * positions. The parameter, n, specifies the number of positions to move the decimal point. That is, - * if n is 0 or positive, the number returned is given by: - *

    - * this.multiply(TEN.pow(new BigDecimal(n))) - *

    - * n may be negative, in which case the method returns the same result as movePointLeft(-n) - * . - * - * @param n The int specifying the number of places to move the decimal point rightwards. - * @return A BigDecimal derived from this, with the decimal point moved n - * places to the right. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal movePointRight(int n) { - com.ibm.icu.math.BigDecimal res; - res = clone(this); - res.exp = res.exp + n; - return res.finish(plainMC, false); - } - - /** - * Returns the scale of this BigDecimal. Returns a non-negative int which is the scale of - * the number. The scale is the number of digits in the decimal part of the number if the number were formatted - * without exponential notation. - * - * @return An int whose value is the scale of this BigDecimal. - * @stable ICU 2.0 - */ - - public int scale() { - if (exp >= 0) - return 0; // scale can never be negative - return -exp; - } - - /** - * Returns a plain BigDecimal with a given scale. - *

    - * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part - * (the scale) of this BigDecimal then trailing zeros will be added to the decimal part as necessary. - *

    - * If the given scale is less than the length of the decimal part (the scale) of this BigDecimal then - * trailing digits will be removed, and in this case an ArithmeticException is thrown if any discarded - * digits are non-zero. - *

    - * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is - * MathContext.ROUND_UNNECESSARY. - * - * @param scale The int specifying the scale of the resulting BigDecimal. - * @return A plain BigDecimal with the given scale. - * @throws ArithmeticException if scale is negative. - * @throws ArithmeticException if reducing scale would discard non-zero digits. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal setScale(int scale) { - return setScale(scale, ROUND_UNNECESSARY); - } - - /** - * Returns a plain BigDecimal with a given scale. - *

    - * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part - * (the scale) of this BigDecimal then trailing zeros will be added to the decimal part as necessary. - *

    - * If the given scale is less than the length of the decimal part (the scale) of this BigDecimal then - * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the - * remaining digits are affected by a carry. In this case, an IllegalArgumentException is thrown if - * round is not a valid rounding mode. - *

    - * If round is MathContext.ROUND_UNNECESSARY, an ArithmeticException is - * thrown if any discarded digits are non-zero. - * - * @param scale The int specifying the scale of the resulting BigDecimal. - * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). - * @return A plain BigDecimal with the given scale. - * @throws IllegalArgumentException if round is not a valid rounding mode. - * @throws ArithmeticException if scale is negative. - * @throws ArithmeticException if round is MathContext.ROUND_UNNECESSARY, and reducing scale would discard - * non-zero digits. - * @stable ICU 2.0 - */ - - public com.ibm.icu.math.BigDecimal setScale(int scale, int round) { - int ourscale; - com.ibm.icu.math.BigDecimal res; - int padding = 0; - int newlen = 0; - // at present this naughtily only checks the round value if it is - // needed (used), for speed - ourscale = this.scale(); - if (ourscale == scale) // already correct scale - if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form - return this; - res = clone(this); // need copy - if (ourscale <= scale) { // simply zero-padding/changing form - // if ourscale is 0 we may have lots of 0s to add - if (ourscale == 0) - padding = res.exp + scale; - else - padding = scale - ourscale; - res.mant = extend(res.mant, res.mant.length + padding); - res.exp = -scale; // as requested - } else {/* ourscale>scale: shortening, probably */ - if (scale < 0) - throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); - // [round() will raise exception if invalid round] - newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK] - res = res.round(newlen, round); // round to required length - // This could have shifted left if round (say) 0.9->1[.0] - // Repair if so by adding a zero and reducing exponent - if (res.exp != -scale) { - res.mant = extend(res.mant, res.mant.length + 1); - res.exp = res.exp - 1; - } - } - res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition - return res; - } - - /** - * Converts this BigDecimal to a short. If the BigDecimal has a non-zero - * decimal part or is out of the possible range for a short (16-bit signed integer) result then an - * ArithmeticException is thrown. - * - * @return A short equal in value to this. - * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a short. - * @stable ICU 2.0 - */ - - public short shortValueExact() { - int num; - num = this.intValueExact(); // will check decimal part too - if ((num > 32767) | (num < (-32768))) - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); - return (short) num; - } - - /** - * Returns the sign of this BigDecimal, as an int. This returns the signum function - * value that represents the sign of this BigDecimal. That is, -1 if the BigDecimal is - * negative, 0 if it is numerically equal to zero, or 1 if it is positive. - * - * @return An int which is -1 if the BigDecimal is negative, 0 if it is numerically equal - * to zero, or 1 if it is positive. - * @stable ICU 2.0 - */ - - public int signum() { - return (int) this.ind; // [note this assumes values for ind.] - } - - /** - * Converts this BigDecimal to a java.math.BigDecimal. - *

    - * This is an exact conversion; the result is the same as if the BigDecimal were formatted as a plain - * number without any rounding or exponent and then the java.math.BigDecimal(java.lang.String) - * constructor were used to construct the result. - *

    - * (Note: this method is provided only in the com.ibm.icu.math version of the BigDecimal class. It - * would not be present in a java.math version.) - * - * @return The java.math.BigDecimal equal in value to this BigDecimal. - * @stable ICU 2.0 - */ - - public java.math.BigDecimal toBigDecimal() { - return new java.math.BigDecimal(this.unscaledValue(), this.scale()); - } - - /** - * Converts this BigDecimal to a java.math.BigInteger. - *

    - * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use - * {@link #toBigIntegerExact()}. - * - * @return The java.math.BigInteger equal in value to the integer part of this BigDecimal. - * @stable ICU 2.0 - */ - - public java.math.BigInteger toBigInteger() { - com.ibm.icu.math.BigDecimal res = null; - int newlen = 0; - byte newmant[] = null; - {/* select */ - if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN)) - res = this; // can layout simply - else if (exp >= 0) { - res = clone(this); // safe copy - res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN - } else { - { // exp<0; scale to be truncated - // we could use divideInteger, but we may as well be quicker - if (-this.exp >= this.mant.length) - res = ZERO; // all blows away - else { - res = clone(this); // safe copy - newlen = res.mant.length + res.exp; - newmant = new byte[newlen]; // [shorter] - java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, - newlen); - res.mant = newmant; - res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; - res.exp = 0; - } - } - } - } - return new BigInteger(new java.lang.String(res.layout())); - } - - /** - * Converts this BigDecimal to a java.math.BigInteger. - *

    - * An exception is thrown if the decimal part (if any) is non-zero. - * - * @return The java.math.BigInteger equal in value to the integer part of this BigDecimal. - * @throws ArithmeticException if this has a non-zero decimal part. - * @stable ICU 2.0 - */ - - public java.math.BigInteger toBigIntegerExact() { - /* test any trailing decimal part */ - if (exp < 0) { // possible decimal part - /* all decimal places must be 0; note exp<0 */ - if ((!(allzero(mant, mant.length + exp)))) - throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); - } - return toBigInteger(); - } - - /** - * Returns the BigDecimal as a character array. The result of this method is the same as using the - * sequence toString().toCharArray(), but avoids creating the intermediate String and - * char[] objects. - * - * @return The char[] array corresponding to this BigDecimal. - * @stable ICU 2.0 - */ - - public char[] toCharArray() { - return layout(); - } - - /** - * Returns the BigDecimal as a String. This returns a String that exactly - * represents this BigDecimal, as defined in the decimal documentation (see {@link BigDecimal class - * header}). - *

    - * By definition, using the {@link #BigDecimal(String)} constructor on the result String will create a - * BigDecimal that is exactly equal to the original BigDecimal. - * - * @return The String exactly corresponding to this BigDecimal. - * @see #format(int, int) - * @see #format(int, int, int, int, int, int) - * @see #toCharArray() - * @stable ICU 2.0 - */ - - public java.lang.String toString() { - return new java.lang.String(layout()); - } - - /** - * Returns the number as a BigInteger after removing the scale. That is, the number is expressed as a - * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is - * then converted to a BigInteger. - * - * @return The java.math.BigInteger equal in value to this BigDecimal multiplied by ten to - * the power of this.scale(). - * @stable ICU 2.0 - */ - - public java.math.BigInteger unscaledValue() { - com.ibm.icu.math.BigDecimal res = null; - if (exp >= 0) - res = this; - else { - res = clone(this); // safe copy - res.exp = 0; // drop scale - } - return res.toBigInteger(); - } - - /** - * Translates a double to a BigDecimal. - *

    - * Returns a BigDecimal which is the decimal representation of the 64-bit signed binary floating point - * parameter. If the parameter is infinite, or is not a number (NaN), a NumberFormatException is - * thrown. - *

    - * The number is constructed as though num had been converted to a String using the - * Double.toString() method and the {@link #BigDecimal(java.lang.String)} constructor had then been used. - * This is typically not an exact conversion. - * - * @param dub The double to be translated. - * @return The BigDecimal equal in value to dub. - * @throws NumberFormatException if the parameter is infinite or not a number. - * @stable ICU 2.0 - */ - - public static com.ibm.icu.math.BigDecimal valueOf(double dub) { - // Reminder: a zero double returns '0.0', so we cannot fastpath to - // use the constant ZERO. This might be important enough to justify - // a factory approach, a cache, or a few private constants, later. - return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString()); - } - - /** - * Translates a long to a BigDecimal. That is, returns a plain BigDecimal - * whose value is equal to the given long. - * - * @param lint The long to be translated. - * @return The BigDecimal equal in value to lint. - * @stable ICU 2.0 - */ - - public static com.ibm.icu.math.BigDecimal valueOf(long lint) { - return valueOf(lint, 0); - } - - /** - * Translates a long to a BigDecimal with a given scale. That is, returns a plain - * BigDecimal whose unscaled value is equal to the given long, adjusted by the second parameter, - * scale. - *

    - * The result is given by: - *

    - * (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) - *

    - * A NumberFormatException is thrown if scale is negative. - * - * @param lint The long to be translated. - * @param scale The int scale to be applied. - * @return The BigDecimal equal in value to lint. - * @throws NumberFormatException if the scale is negative. - * @stable ICU 2.0 - */ - - public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) { - com.ibm.icu.math.BigDecimal res = null; - {/* select */ - if (lint == 0) - res = ZERO; - else if (lint == 1) - res = ONE; - else if (lint == 10) - res = TEN; - else { - res = new com.ibm.icu.math.BigDecimal(lint); - } - } - if (scale == 0) - return res; - if (scale < 0) - throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); - res = clone(res); // safe copy [do not mutate] - res.exp = -scale; // exponent is -scale - return res; - } - - /* ---------------------------------------------------------------- */ - /* Private methods */ - /* ---------------------------------------------------------------- */ - - /* - * Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array). - *

    The mantissa will either already have been rounded (following an operation) or will be of length appropriate - * (in the case of construction from an int, for example).

    We must not alter the mantissa, here.

    'form' - * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure - * numeric. - */ - - private char[] layout() { - char cmant[]; - int i = 0; - StringBuilder sb = null; - int euse = 0; - int sig = 0; - char csign = 0; - char rec[] = null; - int needsign; - int mag; - int len = 0; - cmant = new char[mant.length]; // copy byte[] to a char[] - { - int $18 = mant.length; - i = 0; - for (; $18 > 0; $18--, i++) { - cmant[i] = (char) (mant[i] + ((int) ('0'))); - } - }/* i */ - - if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */ - sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999 - if (ind == isneg) - sb.append('-'); - euse = (exp + cmant.length) - 1; // exponent to use - /* setup sig=significant digits and copy to result */ - if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default] - sb.append(cmant[0]); // significant character - if (cmant.length > 1) // have decimal part - sb.append('.').append(cmant, 1, cmant.length - 1); - } else { - do { - sig = euse % 3; // common - if (sig < 0) - sig = 3 + sig; // negative exponent - euse = euse - sig; - sig++; - if (sig >= cmant.length) { // zero padding may be needed - sb.append(cmant, 0, cmant.length); - { - int $19 = sig - cmant.length; - for (; $19 > 0; $19--) { - sb.append('0'); - } - } - } else { // decimal point needed - sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig); - } - } while (false); - }/* engineering */ - if (euse != 0) { - if (euse < 0) { - csign = '-'; - euse = -euse; - } else - csign = '+'; - sb.append('E').append(csign).append(euse); - } - rec = new char[sb.length()]; - int srcEnd = sb.length(); - if (0 != srcEnd) { - sb.getChars(0, srcEnd, rec, 0); - } - return rec; - } - - /* Here for non-exponential (plain) notation */ - if (exp == 0) {/* easy */ - if (ind >= 0) - return cmant; // non-negative integer - rec = new char[cmant.length + 1]; - rec[0] = '-'; - java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, 1, cmant.length); - return rec; - } - - /* Need a '.' and/or some zeros */ - needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1 - - /* - * MAG is the position of the point in the mantissa (index of the character it follows) - */ - mag = exp + cmant.length; - - if (mag < 1) {/* 0.00xxxx form */ - len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length - rec = new char[len]; - if (needsign != 0) - rec[0] = '-'; - rec[needsign] = '0'; - rec[needsign + 1] = '.'; - { - int $20 = -mag; - i = needsign + 2; - for (; $20 > 0; $20--, i++) { // maybe none - rec[i] = '0'; - } - }/* i */ - java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, (needsign + 2) - mag, - cmant.length); - return rec; - } - - if (mag > cmant.length) {/* xxxx0000 form */ - len = needsign + mag; - rec = new char[len]; - if (needsign != 0) - rec[0] = '-'; - java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, cmant.length); - { - int $21 = mag - cmant.length; - i = needsign + cmant.length; - for (; $21 > 0; $21--, i++) { // never 0 - rec[i] = '0'; - } - }/* i */ - return rec; - } - - /* decimal point is in the middle of the mantissa */ - len = (needsign + 1) + cmant.length; - rec = new char[len]; - if (needsign != 0) - rec[0] = '-'; - java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, mag); - rec[needsign + mag] = '.'; - java.lang.System.arraycopy((java.lang.Object) cmant, mag, (java.lang.Object) rec, (needsign + mag) + 1, - cmant.length - mag); - return rec; - } - - /* - * Checks a BigDecimal argument to ensure it's a true integer in a given range.

    If OK, returns it as an - * int. - */ - // [currently only used by pow] - private int intcheck(int min, int max) { - int i; - i = this.intValueExact(); // [checks for non-0 decimal part] - // Use same message as though intValueExact failed due to size - if ((i < min) | (i > max)) - throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i); - return i; - } - - /* Carry out division operations. */ - /* - * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is - * explicit scale iff code='D' or 'I' (-1 if none). - * - * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity): - * - * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1) - * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for - * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave - * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -) - * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If - * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor - * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do - * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if - * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1 - * - * For extended commentary, see DMSRCN. - */ - - private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs, - com.ibm.icu.math.MathContext set, int scale) { - com.ibm.icu.math.BigDecimal lhs; - int reqdig; - int newexp; - com.ibm.icu.math.BigDecimal res; - int newlen; - byte var1[]; - int var1len; - byte var2[]; - int var2len; - int b2b; - int have; - int thisdigit = 0; - int i = 0; - byte v2 = 0; - int ba = 0; - int mult = 0; - int start = 0; - int padding = 0; - int d = 0; - byte newvar1[] = null; - byte lasthave = 0; - int actdig = 0; - byte newmant[] = null; - - if (set.lostDigits) - checkdigits(rhs, set.digits); - lhs = this; // name for clarity - - // [note we must have checked lostDigits before the following checks] - if (rhs.ind == 0) - throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0 - if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s] - if (set.form != com.ibm.icu.math.MathContext.PLAIN) - return ZERO; - if (scale == (-1)) - return lhs; - return lhs.setScale(scale); - } - - /* Prepare numbers according to BigDecimal rules */ - reqdig = set.digits; // local copy (heavily used) - if (reqdig > 0) { - if (lhs.mant.length > reqdig) - lhs = clone(lhs).round(set); - if (rhs.mant.length > reqdig) - rhs = clone(rhs).round(set); - } else {/* scaled divide */ - if (scale == (-1)) - scale = lhs.scale(); - // set reqdig to be at least large enough for the computation - reqdig = lhs.mant.length; // base length - // next line handles both positive lhs.exp and also scale mismatch - if (scale != -lhs.exp) - reqdig = (reqdig + scale) + lhs.exp; - reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect - if (reqdig < lhs.mant.length) - reqdig = lhs.mant.length; // clamp - if (reqdig < rhs.mant.length) - reqdig = rhs.mant.length; // .. - } - - /* precalculate exponent */ - newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length; - /* If new exponent -ve, then some quick exits are possible */ - if (newexp < 0) - if (code != 'D') { - if (code == 'I') - return ZERO; // easy - no integer part - /* Must be 'R'; remainder is [finished clone of] input value */ - return clone(lhs).finish(set, false); - } - - /* We need slow division */ - res = new com.ibm.icu.math.BigDecimal(); // where we'll build result - res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I) - res.exp = newexp; // initial exponent (for D/I) - res.mant = new byte[reqdig + 1]; // where build the result - - /* Now [virtually pad the mantissae with trailing zeros */ - // Also copy the LHS, which will be our working array - newlen = (reqdig + reqdig) + 1; - var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array - var1len = newlen; // [remaining digits are 0] - - var2 = rhs.mant; - var2len = newlen; - - /* Calculate first two digits of rhs (var2), +1 for later estimations */ - b2b = (var2[0] * 10) + 1; - if (var2.length > 1) - b2b = b2b + var2[1]; - - /* start the long-division loops */ - have = 0; - { - outer: for (;;) { - thisdigit = 0; - /* find the next digit */ - { - inner: for (;;) { - if (var1len < var2len) - break inner; // V1 too low - if (var1len == var2len) { // compare needed - { - compare: do { // comparison - { - int $22 = var1len; - i = 0; - for (; $22 > 0; $22--, i++) { - // var1len is always <= var1.length - if (i < var2.length) - v2 = var2[i]; - else - v2 = (byte) 0; - if (var1[i] < v2) - break inner; // V1 too low - if (var1[i] > v2) - break compare; // OK to subtract - } - }/* i */ - /* - * reach here if lhs and rhs are identical; subtraction will increase digit by one, - * and the residue will be 0 so we are done; leave the loop with residue set to 0 - * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked) - */ - thisdigit++; - res.mant[have] = (byte) thisdigit; - have++; - var1[0] = (byte) 0; // residue to 0 [this is all we'll test] - // var1len=1 -- [optimized out] - break outer; - } while (false); - }/* compare */ - /* prepare for subtraction. Estimate BA (lengths the same) */ - ba = (int) var1[0]; // use only first digit - } // lengths the same - else {/* lhs longer than rhs */ - /* use first two digits for estimate */ - ba = var1[0] * 10; - if (var1len > 1) - ba = ba + var1[1]; - } - /* subtraction needed; V1>=V2 */ - mult = (ba * 10) / b2b; - if (mult == 0) - mult = 1; - thisdigit = thisdigit + mult; - // subtract; var1 reusable - var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true); - if (var1[0] != 0) - continue inner; // maybe another subtract needed - /* - * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than - * V2) - */ - { - int $23 = var1len - 2; - start = 0; - start: for (; start <= $23; start++) { - if (var1[start] != 0) - break start; - var1len--; - } - }/* start */ - if (start == 0) - continue inner; - // shift left - java.lang.System.arraycopy((java.lang.Object) var1, start, (java.lang.Object) var1, 0, var1len); - } - }/* inner */ - - /* We have the next digit */ - if ((have != 0) | (thisdigit != 0)) { // put the digit we got - res.mant[have] = (byte) thisdigit; - have++; - if (have == (reqdig + 1)) - break outer; // we have all we need - if (var1[0] == 0) - break outer; // residue now 0 - } - /* can leave now if a scaled divide and exponent is small enough */ - if (scale >= 0) - if (-res.exp > scale) - break outer; - /* can leave now if not Divide and no integer part left */ - if (code != 'D') - if (res.exp <= 0) - break outer; - res.exp = res.exp - 1; // reduce the exponent - /* - * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit - */ - var2len--; - } - }/* outer */ - - /* here when we have finished dividing, for some reason */ - // have is the number of digits we collected in res.mant - if (have == 0) - have = 1; // res.mant[0] is 0; we always want a digit - - if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */ - if ((have + res.exp) > reqdig) - throw new java.lang.ArithmeticException("Integer overflow"); - - if (code == 'R') { - do { - /* We were doing Remainder -- return the residue */ - if (res.mant[0] == 0) // no integer part was found - return clone(lhs).finish(set, false); // .. so return lhs, canonical - if (var1[0] == 0) - return ZERO; // simple 0 residue - res.ind = lhs.ind; // sign is always as LHS - /* - * Calculate the exponent by subtracting the number of padding zeros we added and adding the - * original exponent - */ - padding = ((reqdig + reqdig) + 1) - lhs.mant.length; - res.exp = (res.exp - padding) + lhs.exp; - - /* - * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be - */ - d = var1len; - { - i = d - 1; - i: for (; i >= 1; i--) { - if (!((res.exp < lhs.exp) & (res.exp < rhs.exp))) - break; - if (var1[i] != 0) - break i; - d--; - res.exp = res.exp + 1; - } - }/* i */ - if (d < var1.length) {/* need to reduce */ - newvar1 = new byte[d]; - java.lang.System.arraycopy((java.lang.Object) var1, 0, (java.lang.Object) newvar1, 0, d); // shorten - var1 = newvar1; - } - res.mant = var1; - return res.finish(set, false); - } while (false); - }/* remainder */ - } - - else {/* 'D' -- no overflow check needed */ - // If there was a residue then bump the final digit (iff 0 or 5) - // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and - // ROUND_UNNECESSARY checks (etc.) later. - // [if we finished early, the residue will be 0] - if (var1[0] != 0) { // residue not 0 - lasthave = res.mant[have - 1]; - if (((lasthave % 5)) == 0) - res.mant[have - 1] = (byte) (lasthave + 1); - } - } - - /* Here for Divide or Integer Divide */ - // handle scaled results first ['I' always scale 0, optional for 'D'] - if (scale >= 0) { - do { - // say 'scale have res.exp len' scale have res.exp res.mant.length - if (have != res.mant.length) - // already padded with 0's, so just adjust exponent - res.exp = res.exp - ((res.mant.length - have)); - // calculate number of digits we really want [may be 0] - actdig = res.mant.length - (-res.exp - scale); - res.round(actdig, set.roundingMode); // round to desired length - // This could have shifted left if round (say) 0.9->1[.0] - // Repair if so by adding a zero and reducing exponent - if (res.exp != -scale) { - res.mant = extend(res.mant, res.mant.length + 1); - res.exp = res.exp - 1; - } - return res.finish(set, true); // [strip if not PLAIN] - } while (false); - }/* scaled */ - - // reach here only if a non-scaled - if (have == res.mant.length) { // got digits+1 digits - res.round(set); - have = reqdig; - } else {/* have<=reqdig */ - if (res.mant[0] == 0) - return ZERO; // fastpath - // make the mantissa truly just 'have' long - // [we could let finish do this, during strip, if we adjusted - // the exponent; however, truncation avoids the strip loop] - newmant = new byte[have]; // shorten - java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, have); - res.mant = newmant; - } - return res.finish(set, true); - } - - /* Report a conversion exception. */ - - private void bad(char s[]) { - throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s)); - } - - /* - * Report a bad argument to a method. Arg1 is method name Arg2 is argument position Arg3 is what was - * found - */ - - private void badarg(java.lang.String name, int pos, java.lang.String value) { - throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " " - + value); - } - - /* - * Extend byte array to given length, padding with 0s. If no extension is required then return the same - * array. - * - * Arg1 is the source byte array Arg2 is the new length (longer) - */ - - private static final byte[] extend(byte inarr[], int newlen) { - byte newarr[]; - if (inarr.length == newlen) - return inarr; - newarr = new byte[newlen]; - java.lang.System.arraycopy((java.lang.Object) inarr, 0, (java.lang.Object) newarr, 0, inarr.length); - // 0 padding is carried out by the JVM on allocation initialization - return newarr; - } - - /* - * Add or subtract two >=0 integers in byte arrays

    This routine performs the calculation:

     C=A+(BM)
    -     * 
    Where M is in the range -9 through +9

    If M<0 then A>=B must be true, so the result is always - * non-negative. - * - * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B, - * or 1 longer than that (if a carry occurred). - * - * A is not altered unless Arg6 is 1. B is never altered. - * - * Arg1 is A Arg2 is A length to use (if longer than A, pad with 0's) Arg3 is B Arg4 is B length to use (if longer - * than B, pad with 0's) Arg5 is M, the multiplier Arg6 is 1 if A can be used to build the result (if it fits) - * - * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance - * degradation. - */ - // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981) - // 1997.10.05 -- changed to byte arrays (from char arrays) - // 1998.07.01 -- changed to allow destructive reuse of LHS - // 1998.07.01 -- changed to allow virtual lengths for the arrays - // 1998.12.29 -- use lookaside for digit/carry calculation - // 1999.08.07 -- avoid multiply when mult=1, and make db an int - // 1999.12.22 -- special case m=-1, also drop 0 special case - private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) { - int alength; - int blength; - int ap; - int bp; - int maxarr; - byte reb[]; - boolean quickm; - int digit; - int op = 0; - int dp90 = 0; - byte newarr[]; - int i = 0; - - // We'll usually be right if we assume no carry - alength = a.length; // physical lengths - blength = b.length; // .. - ap = avlen - 1; // -> final (rightmost) digit - bp = bvlen - 1; // .. - maxarr = bp; - if (maxarr < ap) - maxarr = ap; - reb = (byte[]) null; // result byte array - if (reuse) - if ((maxarr + 1) == alength) - reb = a; // OK to reuse A - if (reb == null) - reb = new byte[maxarr + 1]; // need new array - - quickm = false; // 1 if no multiply needed - if (m == 1) - quickm = true; // most common - else if (m == (-1)) - quickm = true; // also common - - digit = 0; // digit, with carry or borrow - { - op = maxarr; - op: for (; op >= 0; op--) { - if (ap >= 0) { - if (ap < alength) - digit = digit + a[ap]; // within A - ap--; - } - if (bp >= 0) { - if (bp < blength) { // within B - if (quickm) { - if (m > 0) - digit = digit + b[bp]; // most common - else - digit = digit - b[bp]; // also common - } else - digit = digit + (b[bp] * m); - } - bp--; - } - /* result so far (digit) could be -90 through 99 */ - if (digit < 10) - if (digit >= 0) { - do { // 0-9 - reb[op] = (byte) digit; - digit = 0; // no carry - continue op; - } while (false); - }/* quick */ - dp90 = digit + 90; - reb[op] = bytedig[dp90]; // this digit - digit = bytecar[dp90]; // carry or borrow - } - }/* op */ - - if (digit == 0) - return reb; // no carry - // following line will become an Assert, later - // if digit<0 then signal ArithmeticException("internal.error ["digit"]") - - /* We have carry -- need to make space for the extra digit */ - newarr = (byte[]) null; - if (reuse) - if ((maxarr + 2) == a.length) - newarr = a; // OK to reuse A - if (newarr == null) - newarr = new byte[maxarr + 2]; - newarr[0] = (byte) digit; // the carried digit .. - // .. and all the rest [use local loop for short numbers] - if (maxarr < 10) { - int $24 = maxarr + 1; - i = 0; - for (; $24 > 0; $24--, i++) { - newarr[i + 1] = reb[i]; - } - }/* i */ - else - java.lang.System.arraycopy((java.lang.Object) reb, 0, (java.lang.Object) newarr, 1, maxarr + 1); - return newarr; - } - - /* - * Initializer for digit array properties (lookaside). Returns the digit array, and initializes the - * carry array. - */ - - private static final byte[] diginit() { - byte work[]; - int op = 0; - int digit = 0; - work = new byte[(90 + 99) + 1]; - { - op = 0; - op: for (; op <= (90 + 99); op++) { - digit = op - 90; - if (digit >= 0) { - work[op] = (byte) (digit % 10); - bytecar[op] = (byte) (digit / 10); // calculate carry - continue op; - } - // borrowing... - digit = digit + 100; // yes, this is right [consider -50] - work[op] = (byte) (digit % 10); - bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %] - } - }/* op */ - return work; - } - - /* - * Create a copy of BigDecimal object for local use.

    This does NOT make a copy of the mantissa array. - * Arg1 is the BigDecimal to clone (non-null) - */ - - private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) { - com.ibm.icu.math.BigDecimal copy; - copy = new com.ibm.icu.math.BigDecimal(); - copy.ind = dec.ind; - copy.exp = dec.exp; - copy.form = dec.form; - copy.mant = dec.mant; - return copy; - } - - /* - * Check one or two numbers for lost digits. Arg1 is RHS (or null, if none) Arg2 is current DIGITS - * setting returns quietly or throws an exception - */ - - private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) { - if (dig == 0) - return; // don't check if digits=0 - // first check lhs... - if (this.mant.length > dig) - if ((!(allzero(this.mant, dig)))) - throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString()); - if (rhs == null) - return; // monadic - if (rhs.mant.length > dig) - if ((!(allzero(rhs.mant, dig)))) - throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); - } - - /* - * Round to specified digits, if necessary. Arg1 is requested MathContext [with length and rounding - * mode] returns this, for convenience - */ - - private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) { - return round(set.digits, set.roundingMode); - } - - /* - * Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when - * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience - * - * ind and exp are adjusted, but not cleared for a mantissa of zero - * - * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa - * length will be 1. - */ - - private com.ibm.icu.math.BigDecimal round(int len, int mode) { - int adjust; - int sign; - byte oldmant[]; - boolean reuse = false; - byte first = 0; - int increment; - byte newmant[] = null; - adjust = mant.length - len; - if (adjust <= 0) - return this; // nowt to do - - exp = exp + adjust; // exponent of result - sign = (int) ind; // save [assumes -1, 0, 1] - oldmant = mant; // save - if (len > 0) { - // remove the unwanted digits - mant = new byte[len]; - java.lang.System.arraycopy((java.lang.Object) oldmant, 0, (java.lang.Object) mant, 0, len); - reuse = true; // can reuse mantissa - first = oldmant[len]; // first of discarded digits - } else {/* len<=0 */ - mant = ZERO.mant; - ind = iszero; - reuse = false; // cannot reuse mantissa - if (len == 0) - first = oldmant[0]; - else - first = (byte) 0; // [virtual digit] - } - - // decide rounding adjustment depending on mode, sign, and discarded digits - increment = 0; // bumper - { - do {/* select */ - if (mode == ROUND_HALF_UP) { // default first [most common] - if (first >= 5) - increment = sign; - } else if (mode == ROUND_UNNECESSARY) { // default for setScale() - // discarding any non-zero digits is an error - if ((!(allzero(oldmant, len)))) - throw new java.lang.ArithmeticException("Rounding necessary"); - } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down - if (first > 5) - increment = sign; - else if (first == 5) - if ((!(allzero(oldmant, len + 1)))) - increment = sign; - } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even - if (first > 5) - increment = sign; - else if (first == 5) { - if ((!(allzero(oldmant, len + 1)))) - increment = sign; - else /* 0.5000 */ - if ((((mant[mant.length - 1]) % 2)) == 1) - increment = sign; - } - } else if (mode == ROUND_DOWN) { - // never increment - } else if (mode == ROUND_UP) { // increment if discarded non-zero - if ((!(allzero(oldmant, len)))) - increment = sign; - } else if (mode == ROUND_CEILING) { // more positive - if (sign > 0) - if ((!(allzero(oldmant, len)))) - increment = sign; - } else if (mode == ROUND_FLOOR) { // more negative - if (sign < 0) - if ((!(allzero(oldmant, len)))) - increment = sign; - } else { - throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode); - } - } while (false); - }/* modes */ - - if (increment != 0) { - do { - if (ind == iszero) { - // we must not subtract from 0, but result is trivial anyway - mant = ONE.mant; - ind = (byte) increment; - } else { - // mantissa is non-0; we can safely add or subtract 1 - if (ind == isneg) - increment = -increment; - newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse); - if (newmant.length > mant.length) { // had a carry - // drop rightmost digit and raise exponent - exp++; - // mant is already the correct length - java.lang.System.arraycopy((java.lang.Object) newmant, 0, (java.lang.Object) mant, 0, - mant.length); - } else - mant = newmant; - } - } while (false); - }/* bump */ - // rounding can increase exponent significantly - if (exp > MaxExp) - throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); - return this; - } - - /* - * Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to - * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0 - * - * Arg2 may be beyond array bounds, in which case 1 is returned - */ - - private static final boolean allzero(byte array[], int start) { - int i = 0; - if (start < 0) - start = 0; - { - int $25 = array.length - 1; - i = start; - for (; i <= $25; i++) { - if (array[i] != 0) - return false; - } - }/* i */ - return true; - } - - /* - * Carry out final checks and canonicalization

    This finishes off the current number by: 1. Rounding if - * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping - * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0' - * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. Arg1 is requested - * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed - * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience - */ - - private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) { - int d = 0; - int i = 0; - byte newmant[] = null; - int mag = 0; - int sig = 0; - /* Round if mantissa too long and digits requested */ - if (set.digits != 0) - if (this.mant.length > set.digits) - this.round(set); - - /* - * If strip requested (and standard formatting), remove insignificant trailing zeros. - */ - if (strip) - if (set.form != com.ibm.icu.math.MathContext.PLAIN) { - d = this.mant.length; - /* see if we need to drop any trailing zeros */ - { - i = d - 1; - i: for (; i >= 1; i--) { - if (this.mant[i] != 0) - break i; - d--; - exp++; - } - }/* i */ - if (d < this.mant.length) {/* need to reduce */ - newmant = new byte[d]; - java.lang.System.arraycopy((java.lang.Object) this.mant, 0, (java.lang.Object) newmant, 0, d); - this.mant = newmant; - } - } - - form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset - - /* Now check for leading- and all- zeros in mantissa */ - { - int $26 = this.mant.length; - i = 0; - for (; $26 > 0; $26--, i++) { - if (this.mant[i] != 0) { - // non-0 result; ind will be correct - // remove leading zeros [e.g., after subtract] - if (i > 0) { - do { - newmant = new byte[this.mant.length - i]; - java.lang.System.arraycopy((java.lang.Object) this.mant, i, (java.lang.Object) newmant, 0, - this.mant.length - i); - this.mant = newmant; - } while (false); - }/* delead */ - // now determine form if not PLAIN - mag = exp + mant.length; - if (mag > 0) { // most common path - if (mag > set.digits) - if (set.digits != 0) - form = (byte) set.form; - if ((mag - 1) <= MaxExp) - return this; // no overflow; quick return - } else if (mag < (-5)) - form = (byte) set.form; - /* check for overflow */ - mag--; - if ((mag < MinExp) | (mag > MaxExp)) { - overflow: do { - // possible reprieve if form is engineering - if (form == com.ibm.icu.math.MathContext.ENGINEERING) { - sig = mag % 3; // leftover - if (sig < 0) - sig = 3 + sig; // negative exponent - mag = mag - sig; // exponent to use - // 1999.06.29: second test here must be MaxExp - if (mag >= MinExp) - if (mag <= MaxExp) - break overflow; - } - throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag); - } while (false); - }/* overflow */ - return this; - } - } - }/* i */ - - // Drop through to here only if mantissa is all zeros - ind = iszero; - {/* select */ - if (set.form != com.ibm.icu.math.MathContext.PLAIN) - exp = 0; // standard result; go to '0' - else if (exp > 0) - exp = 0; // +ve exponent also goes to '0' - else { - // a plain number with -ve exponent; preserve and check exponent - if (exp < MinExp) - throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); - } - } - mant = ZERO.mant; // canonical mantissa - return this; - } -} +/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */ +/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */ +package com.ibm.icu.math; + +import java.math.BigInteger; + +/* ------------------------------------------------------------------ */ +/* BigDecimal -- Decimal arithmetic for Java */ +/* ------------------------------------------------------------------ */ +/* Copyright IBM Corporation, 1996-2011. All Rights Reserved. */ +/* */ +/* The BigDecimal class provides immutable arbitrary-precision */ +/* floating point (including integer) decimal numbers. */ +/* */ +/* As the numbers are decimal, there is an exact correspondence */ +/* between an instance of a BigDecimal object and its String */ +/* representation; the BigDecimal class provides direct conversions */ +/* to and from String and character array objects, and well as */ +/* conversions to and from the Java primitive types (which may not */ +/* be exact). */ +/* ------------------------------------------------------------------ */ +/* Notes: */ +/* */ +/* 1. A BigDecimal object is never changed in value once constructed; */ +/* this avoids the need for locking. Note in particular that the */ +/* mantissa array may be shared between many BigDecimal objects, */ +/* so that once exposed it must not be altered. */ +/* */ +/* 2. This class looks at MathContext class fields directly (for */ +/* performance). It must not and does not change them. */ +/* */ +/* 3. Exponent checking is delayed until finish(), as we know */ +/* intermediate calculations cannot cause 31-bit overflow. */ +/* [This assertion depends on MAX_DIGITS in MathContext.] */ +/* */ +/* 4. Comments for the public API now follow the javadoc conventions. */ +/* The NetRexx -comments option is used to pass these comments */ +/* through to the generated Java code (with -format, if desired). */ +/* */ +/* 5. System.arraycopy is faster than explicit loop as follows */ +/* Mean length 4: equal */ +/* Mean length 8: x2 */ +/* Mean length 16: x3 */ +/* Mean length 24: x4 */ +/* From prior experience, we expect mean length a little below 8, */ +/* but arraycopy is still the one to use, in general, until later */ +/* measurements suggest otherwise. */ +/* */ +/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */ +/* assembler code implementation of the algorithms below; it is */ +/* now called IXXRCN and is available with the OS/390 and VM/ESA */ +/* operating systems. */ +/* ------------------------------------------------------------------ */ +/* Change History: */ +/* 1997.09.02 Initial version (derived from netrexx.lang classes) */ +/* 1997.09.12 Add lostDigits checking */ +/* 1997.10.06 Change mantissa to a byte array */ +/* 1997.11.22 Rework power [did not prepare arguments, etc.] */ +/* 1997.12.13 multiply did not prepare arguments */ +/* 1997.12.14 add did not prepare and align arguments correctly */ +/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */ +/* 1998.05.21 adjust remainder operator finalization */ +/* 1998.06.04 rework to pass MathContext to finish() and round() */ +/* 1998.06.06 change format to use round(); support rounding modes */ +/* 1998.06.25 rename to BigDecimal and begin merge */ +/* zero can now have trailing zeros (i.e., exp\=0) */ +/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */ +/* unscaledValue, valueof */ +/* 1998.07.01 improve byteaddsub to allow array reuse, etc. */ +/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */ +/* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */ +/* 1998.07.08 setScale, faster equals */ +/* 1998.07.11 allow 1E6 (no sign) ; new double/float conversion */ +/* 1998.10.12 change package to com.ibm.icu.math */ +/* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */ +/* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */ +/* 1998.12.29 improve byteaddsub by using table lookup */ +/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */ +/* 1999.02.05 cleaner code for BigDecimal(char[]) */ +/* 1999.02.06 add javadoc comments */ +/* 1999.02.11 format() changed from 7 to 2 method form */ +/* 1999.03.05 null pointer checking is no longer explicit */ +/* 1999.03.05 simplify; changes from discussion with J. Bloch: */ +/* null no longer permitted for MathContext; drop boolean, */ +/* byte, char, float, short constructor, deprecate double */ +/* constructor, no blanks in string constructor, add */ +/* offset and length version of char[] constructor; */ +/* add valueOf(double); drop booleanValue, charValue; */ +/* add ...Exact versions of remaining convertors */ +/* 1999.03.13 add toBigIntegerExact */ +/* 1999.03.13 1.00 release to IBM Centre for Java Technology */ +/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */ +/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */ +/* 1999.07.03 1.03 lost digits should not be checked if digits=0 */ +/* 1999.07.06 lost digits Exception message changed */ +/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */ +/* 1999.07.17 improve messages from pow method */ +/* 1999.08.08 performance tweaks */ +/* 1999.08.15 fastpath in multiply */ +/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */ +/* 1999.12.22 1.06 remove multiply fastpath, and improve performance */ +/* 2000.01.01 copyright update [Y2K has arrived] */ +/* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */ +/* ------------------------------------------------------------------ */ + +/** + * The BigDecimal class implements immutable arbitrary-precision decimal numbers. The methods of the + * BigDecimal class provide operations for fixed and floating point arithmetic, comparison, format + * conversions, and hashing. + *

    + * As the numbers are decimal, there is an exact correspondence between an instance of a BigDecimal object + * and its String representation; the BigDecimal class provides direct conversions to and from + * String and character array (char[]) objects, as well as conversions to and from the Java + * primitive types (which may not be exact) and BigInteger. + *

    + * In the descriptions of constructors and methods in this documentation, the value of a BigDecimal number + * object is shown as the result of invoking the toString() method on the object. The internal + * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any + * operation. + *

    + * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also + * documented at http://www2.hursley.ibm.com/decimal
    + * [This URL will change.] + * + *

    Operator methods

    + *

    + * Operations on BigDecimal numbers are controlled by a {@link MathContext} object, which provides the + * context (precision and other information) for the operation. Methods that can take a MathContext + * parameter implement the standard arithmetic operators for BigDecimal objects and are known as + * operator methods. The default settings provided by the constant {@link MathContext#DEFAULT} (digits=9, + * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP) perform general-purpose floating point + * arithmetic to nine digits of precision. The MathContext parameter must not be null. + *

    + * Each operator method also has a version provided which does not take a MathContext parameter. For this + * version of each method, the context settings used are digits=0, + * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP; these settings perform fixed point arithmetic with + * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2. + *

    + * For monadic operators, only the optional MathContext parameter is present; the operation acts upon the + * current object. + *

    + * For dyadic operators, a BigDecimal parameter is always present; it must not be null. The + * operation acts with the current object being the left-hand operand and the BigDecimal parameter being + * the right-hand operand. + *

    + * For example, adding two BigDecimal objects referred to by the names award and + * extra could be written as any of: + *

    + * + * award.add(extra) + *
    award.add(extra, MathContext.DEFAULT) + *
    award.add(extra, acontext) + *
    + *

    + * (where acontext is a MathContext object), which would return a BigDecimal + * object whose value is the result of adding award and extra under the appropriate context + * settings. + *

    + * When a BigDecimal operator method is used, a set of rules define what the result will be (and, by + * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal + * arithmetic documentation (see the URL above), but in summary: + *

      + *
    • Results are normally calculated with up to some maximum number of significant digits. For example, if the + * MathContext parameter for an operation were MathContext.DEFAULT then the result would be + * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667.
      + * You can change the default of 9 significant digits by providing the method with a suitable MathContext + * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled) + * arithmetic is indicated by using a digits setting of 0 (or omitting the MathContext + * parameter).
      + * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm. + *
    • + * In standard arithmetic (that is, when the form setting is not PLAIN), a zero result is + * always expressed as the single digit '0' (that is, with no sign, decimal point, or exponent part). + *
    • + * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast + * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros + * in the fractional part of results).
      + * So, for example: + *

      + * + * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40" + *
      new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40" + *
      new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80" + *
      new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2" + *
      + *

      + * where the value on the right of the => would be the result of the operation, expressed as a + * String, and def (in this and following examples) refers to MathContext.DEFAULT + * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If + * necessary, trailing zeros may be easily removed using division by 1. + *

    • + * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of + * digits (the default is 9 digits). If the number of places needed before the decimal point exceeds the + * digits setting, or the absolute value of the number is less than 0.000001, then the number + * will be expressed in exponential notation; thus + *

      + * + * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def) + * + *

      + * results in 1E+12 instead of 1000000000000, and + *

      + * + * new BigDecimal("1").divide(new BigDecimal("3E+10"), def) + * + *

      + * results in 3.33333333E-11 instead of 0.0000000000333333333. + *

      + * The form of the exponential notation (scientific or engineering) is determined by the form setting. + * + *

      + * The names of methods in this class follow the conventions established by java.lang.Number, + * java.math.BigInteger, and java.math.BigDecimal in Java 1.1 and Java 1.2. + * + * @see MathContext + * @author Mike Cowlishaw + * @stable ICU 2.0 + */ + +public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable { + // private static final java.lang.String $0="BigDecimal.nrx"; + + /* ----- Constants ----- */ + /* properties constant public */// useful to others + /** + * The BigDecimal constant "0". + * + * @see #ONE + * @see #TEN + * @stable ICU 2.0 + */ + public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we + // want the int + // constructor + // .. to be able to use this, for speed + + /** + * The BigDecimal constant "1". + * + * @see #TEN + * @see #ZERO + * @stable ICU 2.0 + */ + public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we + // want the int + // constructor + // .. to be able to use this, for speed + + /** + * The BigDecimal constant "10". + * + * @see #ONE + * @see #ZERO + * @stable ICU 2.0 + */ + public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10); + + // the rounding modes (copied here for upwards compatibility) + /** + * Rounding mode to round to a more positive number. + * + * @see MathContext#ROUND_CEILING + * @stable ICU 2.0 + */ + public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING; + + /** + * Rounding mode to round towards zero. + * + * @see MathContext#ROUND_DOWN + * @stable ICU 2.0 + */ + public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN; + + /** + * Rounding mode to round to a more negative number. + * + * @see MathContext#ROUND_FLOOR + * @stable ICU 2.0 + */ + public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down. + * + * @see MathContext#ROUND_HALF_DOWN + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor. + * + * @see MathContext#ROUND_HALF_EVEN + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up. + * + * @see MathContext#ROUND_HALF_UP + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP; + + /** + * Rounding mode to assert that no rounding is necessary. + * + * @see MathContext#ROUND_UNNECESSARY + * @stable ICU 2.0 + */ + public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY; + + /** + * Rounding mode to round away from zero. + * + * @see MathContext#ROUND_UP + * @stable ICU 2.0 + */ + public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP; + + /* properties constant private */// locals + private static final byte ispos = 1; // ind: indicates positive (must be 1) + private static final byte iszero = 0; // ind: indicates zero (must be 0) + private static final byte isneg = -1; // ind: indicates negative (must be -1) + // [later could add NaN, +/- infinity, here] + + private static final int MinExp = -999999999; // minimum exponent allowed + private static final int MaxExp = 999999999; // maximum exponent allowed + private static final int MinArg = -999999999; // minimum argument integer + private static final int MaxArg = 999999999; // maximum argument integer + + private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0, + com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math + + /* properties constant private unused */// present but not referenced + // Serialization version + private static final long serialVersionUID = 8245355804974198832L; + + // private static final java.lang.String + // copyright=" Copyright (c) IBM Corporation 1996, 2000. All rights reserved. "; + + /* properties static private */ + // Precalculated constant arrays (used by byteaddsub) + private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array + private static byte bytedig[] = diginit(); // next digit array + + /* ----- Instance properties [all private and immutable] ----- */ + /* properties private */ + + /** + * The indicator. This may take the values: + *

        + *
      • ispos -- the number is positive
      • iszero -- the number is zero
      • isneg -- the number is negative + *
      + * + * @serial + */ + private byte ind; // assumed undefined + // Note: some code below assumes IND = Sign [-1, 0, 1], at present. + // We only need two bits for this, but use a byte [also permits + // smooth future extension]. + + /** + * The formatting style. This may take the values: + *
        + *
      • MathContext.PLAIN -- no exponent needed
      • MathContext.SCIENTIFIC -- scientific notation required
      • + * MathContext.ENGINEERING -- engineering notation required + *
      + *

      + * This property is an optimization; it allows us to defer number layout until it is actually needed as a string, + * hence avoiding unnecessary formatting. + * + * @serial + */ + private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN + // We only need two bits for this, at present, but use a byte + // [again, to allow for smooth future extension] + + /** + * The value of the mantissa. + *

      + * Once constructed, this may become shared between several BigDecimal objects, so must not be altered. + *

      + * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9. + *

      + * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a + * plain number, for example, 0.000). + * + * @serial + */ + private byte mant[]; // assumed null + + /** + * The exponent. + *

      + * For fixed point arithmetic, scale is -exp, and can apply to zero. + * + * Note that this property can have a value less than MinExp when the mantissa has more than one digit. + * + * @serial + */ + private int exp; + + // assumed 0 + + /* ---------------------------------------------------------------- */ + /* Constructors */ + /* ---------------------------------------------------------------- */ + + /** + * Constructs a BigDecimal object from a java.math.BigDecimal. + *

      + * Constructs a BigDecimal as though the parameter had been represented as a String (using + * its toString method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. + * The parameter must not be null. + *

      + * (Note: this constructor is provided only in the com.ibm.icu.math version of the BigDecimal class. + * It would not be present in a java.math version.) + * + * @param bd The BigDecimal to be translated. + * @stable ICU 2.0 + */ + + public BigDecimal(java.math.BigDecimal bd) { + this(bd.toString()); + return; + } + + /** + * Constructs a BigDecimal object from a BigInteger, with scale 0. + *

      + * Constructs a BigDecimal which is the exact decimal representation of the BigInteger, + * with a scale of zero. The value of the BigDecimal is identical to the value of the BigInteger + * . The parameter must not be null. + *

      + * The BigDecimal will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the + * BigInteger is negative. A leading zero will be present only if the BigInteger is zero. + * + * @param bi The BigInteger to be converted. + * @stable ICU 2.0 + */ + + public BigDecimal(java.math.BigInteger bi) { + this(bi.toString(10)); + return; + } + + // exp remains 0 + + /** + * Constructs a BigDecimal object from a BigInteger and a scale. + *

      + * Constructs a BigDecimal which is the exact decimal representation of the BigInteger, + * scaled by the second parameter, which may not be negative. The value of the BigDecimal is the + * BigInteger divided by ten to the power of the scale. The BigInteger parameter must not be + * null. + *

      + * The BigDecimal will contain only decimal digits, (with an embedded decimal point followed by + * scale decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the + * BigInteger is negative. A leading zero will be present only if the BigInteger is zero. + * + * @param bi The BigInteger to be converted. + * @param scale The int specifying the scale. + * @throws NumberFormatException If the scale is negative. + * @stable ICU 2.0 + */ + + public BigDecimal(java.math.BigInteger bi, int scale) { + this(bi.toString(10)); + if (scale < 0) + throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); + exp = -scale; // exponent is -scale + return; + } + + /** + * Constructs a BigDecimal object from an array of characters. + *

      + * Constructs a BigDecimal as though a String had been constructed from the character + * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be + * null. + *

      + * Using this constructor is faster than using the BigDecimal(String) constructor if the string is + * already available in character array form. + * + * @param inchars The char[] array containing the number to be converted. + * @throws NumberFormatException If the parameter is not a valid number. + * @stable ICU 2.0 + */ + + public BigDecimal(char inchars[]) { + this(inchars, 0, inchars.length); + return; + } + + /** + * Constructs a BigDecimal object from an array of characters. + *

      + * Constructs a BigDecimal as though a String had been constructed from the character + * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. + * The first parameter must not be null, and the subarray must be wholly contained within it. + *

      + * Using this constructor is faster than using the BigDecimal(String) constructor if the string is + * already available within a character array. + * + * @param inchars The char[] array containing the number to be converted. + * @param offset The int offset into the array of the start of the number to be converted. + * @param length The int length of the number. + * @throws NumberFormatException If the parameter is not a valid number for any reason. + * @stable ICU 2.0 + */ + + public BigDecimal(char inchars[], int offset, int length) { + super(); + boolean exotic; + boolean hadexp; + int d; + int dotoff; + int last; + int i = 0; + char si = 0; + boolean eneg = false; + int k = 0; + int elen = 0; + int j = 0; + char sj = 0; + int dvalue = 0; + int mag = 0; + // This is the primary constructor; all incoming strings end up + // here; it uses explicit (inline) parsing for speed and to avoid + // generating intermediate (temporary) objects of any kind. + // 1998.06.25: exponent form built only if E/e in string + // 1998.06.25: trailing zeros not removed for zero + // 1999.03.06: no embedded blanks; allow offset and length + if (length <= 0) + bad(inchars); // bad conversion (empty string) + // [bad offset will raise array bounds exception] + + /* Handle and step past sign */ + ind = ispos; // assume positive + if (inchars[offset] == ('-')) { + length--; + if (length == 0) + bad(inchars); // nothing after sign + ind = isneg; + offset++; + } else if (inchars[offset] == ('+')) { + length--; + if (length == 0) + bad(inchars); // nothing after sign + offset++; + } + + /* We're at the start of the number */ + exotic = false; // have extra digits + hadexp = false; // had explicit exponent + d = 0; // count of digits found + dotoff = -1; // offset where dot was found + last = -1; // last character of mantissa + { + int $1 = length; + i = offset; + i: for (; $1 > 0; $1--, i++) { + si = inchars[i]; + if (si >= '0') // test for Arabic digit + if (si <= '9') { + last = i; + d++; // still in mantissa + continue i; + } + if (si == '.') { // record and ignore + if (dotoff >= 0) + bad(inchars); // two dots + dotoff = i - offset; // offset into mantissa + continue i; + } + if (si != 'e') + if (si != 'E') { // expect an extra digit + if ((!(Character.isDigit(si)))) + bad(inchars); // not a number + // defer the base 10 check until later to avoid extra method call + exotic = true; // will need conversion later + last = i; + d++; // still in mantissa + continue i; + } + /* Found 'e' or 'E' -- now process explicit exponent */ + // 1998.07.11: sign no longer required + if ((i - offset) > (length - 2)) + bad(inchars); // no room for even one digit + eneg = false; + if ((inchars[i + 1]) == ('-')) { + eneg = true; + k = i + 2; + } else if ((inchars[i + 1]) == ('+')) + k = i + 2; + else + k = i + 1; + // k is offset of first expected digit + elen = length - ((k - offset)); // possible number of digits + if ((elen == 0) | (elen > 9)) + bad(inchars); // 0 or more than 9 digits + { + int $2 = elen; + j = k; + for (; $2 > 0; $2--, j++) { + sj = inchars[j]; + if (sj < '0') + bad(inchars); // always bad + if (sj > '9') { // maybe an exotic digit + if ((!(Character.isDigit(sj)))) + bad(inchars); // not a number + dvalue = Character.digit(sj, 10); // check base + if (dvalue < 0) + bad(inchars); // not base 10 + } else + dvalue = ((int) (sj)) - ((int) ('0')); + exp = (exp * 10) + dvalue; + } + }/* j */ + if (eneg) + exp = -exp; // was negative + hadexp = true; // remember we had one + break i; // we are done + } + }/* i */ + + /* Here when all inspected */ + if (d == 0) + bad(inchars); // no mantissa digits + if (dotoff >= 0) + exp = (exp + dotoff) - d; // adjust exponent if had dot + + /* strip leading zeros/dot (leave final if all 0's) */ + { + int $3 = last - 1; + i = offset; + i: for (; i <= $3; i++) { + si = inchars[i]; + if (si == '0') { + offset++; + dotoff--; + d--; + } else if (si == '.') { + offset++; // step past dot + dotoff--; + } else if (si <= '9') + break i;/* non-0 */ + else {/* exotic */ + if ((Character.digit(si, 10)) != 0) + break i; // non-0 or bad + // is 0 .. strip like '0' + offset++; + dotoff--; + d--; + } + } + }/* i */ + + /* Create the mantissa array */ + mant = new byte[d]; // we know the length + j = offset; // input offset + if (exotic) { + do { // slow: check for exotica + { + int $4 = d; + i = 0; + for (; $4 > 0; $4--, i++) { + if (i == dotoff) + j++; // at dot + sj = inchars[j]; + if (sj <= '9') + mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */ + else { + dvalue = Character.digit(sj, 10); + if (dvalue < 0) + bad(inchars); // not a number after all + mant[i] = (byte) dvalue; + } + j++; + } + }/* i */ + } while (false); + }/* exotica */ + else { + do { + { + int $5 = d; + i = 0; + for (; $5 > 0; $5--, i++) { + if (i == dotoff) + j++; + mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0'))); + j++; + } + }/* i */ + } while (false); + }/* simple */ + + /* Looks good. Set the sign indicator and form, as needed. */ + // Trailing zeros are preserved + // The rule here for form is: + // If no E-notation, then request plain notation + // Otherwise act as though add(0,DEFAULT) and request scientific notation + // [form is already PLAIN] + if (mant[0] == 0) { + ind = iszero; // force to show zero + // negative exponent is significant (e.g., -3 for 0.000) if plain + if (exp > 0) + exp = 0; // positive exponent can be ignored + if (hadexp) { // zero becomes single digit from add + mant = ZERO.mant; + exp = 0; + } + } else { // non-zero + // [ind was set earlier] + // now determine form + if (hadexp) { + form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC; + // 1999.06.29 check for overflow + mag = (exp + mant.length) - 1; // true exponent in scientific notation + if ((mag < MinExp) | (mag > MaxExp)) + bad(inchars); + } + } + // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form + return; + } + + /** + * Constructs a BigDecimal object directly from a double. + *

      + * Constructs a BigDecimal which is the exact decimal representation of the 64-bit signed binary + * floating point parameter. + *

      + * Note that this constructor it an exact conversion; it does not give the same result as converting num + * to a String using the Double.toString() method and then using the + * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)} + * method to construct a BigDecimal from a double. + * + * @param num The double to be converted. + * @throws NumberFormatException If the parameter is infinite or not a number. + * @stable ICU 2.0 + */ + + public BigDecimal(double num) { + // 1999.03.06: use exactly the old algorithm + // 2000.01.01: note that this constructor does give an exact result, + // so perhaps it should not be deprecated + // 2000.06.18: no longer deprecated + this((new java.math.BigDecimal(num)).toString()); + return; + } + + /** + * Constructs a BigDecimal object directly from a int. + *

      + * Constructs a BigDecimal which is the exact decimal representation of the 32-bit signed binary + * integer parameter. The BigDecimal will contain only decimal digits, prefixed with a leading minus + * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. + * + * @param num The int to be converted. + * @stable ICU 2.0 + */ + + public BigDecimal(int num) { + super(); + int mun; + int i = 0; + // We fastpath commoners + if (num <= 9) + if (num >= (-9)) { + do { + // very common single digit case + {/* select */ + if (num == 0) { + mant = ZERO.mant; + ind = iszero; + } else if (num == 1) { + mant = ONE.mant; + ind = ispos; + } else if (num == (-1)) { + mant = ONE.mant; + ind = isneg; + } else { + { + mant = new byte[1]; + if (num > 0) { + mant[0] = (byte) num; + ind = ispos; + } else { // num<-1 + mant[0] = (byte) -num; + ind = isneg; + } + } + } + } + return; + } while (false); + }/* singledigit */ + + /* We work on negative numbers so we handle the most negative number */ + if (num > 0) { + ind = ispos; + num = -num; + } else + ind = isneg;/* negative */// [0 case already handled] + // [it is quicker, here, to pre-calculate the length with + // one loop, then allocate exactly the right length of byte array, + // then re-fill it with another loop] + mun = num; // working copy + { + i = 9; + i: for (;; i--) { + mun = mun / 10; + if (mun == 0) + break i; + } + }/* i */ + // i is the position of the leftmost digit placed + mant = new byte[10 - i]; + { + i = (10 - i) - 1; + i: for (;; i--) { + mant[i] = (byte) -(((byte) (num % 10))); + num = num / 10; + if (num == 0) + break i; + } + }/* i */ + return; + } + + /** + * Constructs a BigDecimal object directly from a long. + *

      + * Constructs a BigDecimal which is the exact decimal representation of the 64-bit signed binary + * integer parameter. The BigDecimal will contain only decimal digits, prefixed with a leading minus + * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero. + * + * @param num The long to be converted. + * @stable ICU 2.0 + */ + + public BigDecimal(long num) { + super(); + long mun; + int i = 0; + // Not really worth fastpathing commoners in this constructor [also, + // we use this to construct the static constants]. + // This is much faster than: this(String.valueOf(num).toCharArray()) + /* We work on negative num so we handle the most negative number */ + if (num > 0) { + ind = ispos; + num = -num; + } else if (num == 0) + ind = iszero; + else + ind = isneg;/* negative */ + mun = num; + { + i = 18; + i: for (;; i--) { + mun = mun / 10; + if (mun == 0) + break i; + } + }/* i */ + // i is the position of the leftmost digit placed + mant = new byte[19 - i]; + { + i = (19 - i) - 1; + i: for (;; i--) { + mant[i] = (byte) -(((byte) (num % 10))); + num = num / 10; + if (num == 0) + break i; + } + }/* i */ + return; + } + + /** + * Constructs a BigDecimal object from a String. + *

      + * Constructs a BigDecimal from the parameter, which must not be null and must represent a + * valid number, as described formally in the documentation referred to {@link BigDecimal above}. + *

      + * In summary, numbers in String form must have at least one digit, may have a leading sign, may have a + * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks. + *

      + * Some valid strings from which a BigDecimal might be constructed are: + * + *

      +     * 
      +     * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
      +     * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
      +     * Exponential notation
      +     * 
      +     * 
      + *

      + * (Exponential notation means that the number includes an optional sign and a power of ten following an + * 'E' that indicates how the decimal point will be shifted. Thus the "4E+9" above is + * just a short way of writing 4000000000, and the "0.73e-7" is short for + * 0.000000073.) + *

      + * The BigDecimal constructed from the String is in a standard form, with no blanks, as though the + * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string + * uses exponential notation (that is, includes an e or an E), then the BigDecimal + * number will be expressed in scientific notation (where the power of ten is adjusted so there is a single + * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as + * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must + * fit in nine digits both before and after it is expressed in scientific notation. + *

      + * Any digits in the parameter must be decimal; that is, Character.digit(c, 10) (where c + * is the character in question) would not return -1. + * + * @param string The String to be converted. + * @throws NumberFormatException If the parameter is not a valid number. + * @stable ICU 2.0 + */ + + public BigDecimal(java.lang.String string) { + this(string.toCharArray(), 0, string.length()); + return; + } + + /* Make a default BigDecimal object for local use. */ + + private BigDecimal() { + super(); + return; + } + + /* ---------------------------------------------------------------- */ + /* Operator methods [methods which take a context parameter] */ + /* ---------------------------------------------------------------- */ + + /** + * Returns a plain BigDecimal whose value is the absolute value of this BigDecimal. + *

      + * The same as {@link #abs(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN). + *

      + * The length of the decimal part (the scale) of the result will be this.scale() + * + * @return A BigDecimal whose value is the absolute value of this BigDecimal. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal abs() { + return this.abs(plainMC); + } + + /** + * Returns a BigDecimal whose value is the absolute value of this BigDecimal. + *

      + * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method + * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)} + * method with the same parameter is returned. + * + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is the absolute value of this BigDecimal. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) { + if (this.ind == isneg) + return this.negate(set); + return this.plus(set); + } + + /** + * Returns a plain BigDecimal whose value is this+rhs, using fixed point arithmetic. + *

      + * The same as {@link #add(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the + * context is new MathContext(0, MathContext.PLAIN). + *

      + * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. + * + * @param rhs The BigDecimal for the right hand side of the addition. + * @return A BigDecimal whose value is this+rhs, using fixed point arithmetic. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) { + return this.add(rhs, plainMC); + } + + /** + * Returns a BigDecimal whose value is this+rhs. + *

      + * Implements the addition (+) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + * + * @param rhs The BigDecimal for the right hand side of the addition. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is this+rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + com.ibm.icu.math.BigDecimal lhs; + int reqdig; + com.ibm.icu.math.BigDecimal res; + byte usel[]; + int usellen; + byte user[]; + int userlen; + int newlen = 0; + int tlen = 0; + int mult = 0; + byte t[] = null; + int ia = 0; + int ib = 0; + int ea = 0; + int eb = 0; + byte ca = 0; + byte cb = 0; + /* determine requested digits and form */ + if (set.lostDigits) + checkdigits(rhs, set.digits); + lhs = this; // name for clarity and proxy + + /* Quick exit for add floating 0 */ + // plus() will optimize to return same object if possible + if (lhs.ind == 0) + if (set.form != com.ibm.icu.math.MathContext.PLAIN) + return rhs.plus(set); + if (rhs.ind == 0) + if (set.form != com.ibm.icu.math.MathContext.PLAIN) + return lhs.plus(set); + + /* Prepare numbers (round, unless unlimited precision) */ + reqdig = set.digits; // local copy (heavily used) + if (reqdig > 0) { + if (lhs.mant.length > reqdig) + lhs = clone(lhs).round(set); + if (rhs.mant.length > reqdig) + rhs = clone(rhs).round(set); + // [we could reuse the new LHS for result in this case] + } + + res = new com.ibm.icu.math.BigDecimal(); // build result here + + /* + * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much + * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to + * DIGITS trailing zeros]. + */ + // Note sign may be 0 if digits (reqdig) is 0 + // usel and user will be the byte arrays passed to the adder; we'll + // use them on all paths except quick exits + usel = lhs.mant; + usellen = lhs.mant.length; + user = rhs.mant; + userlen = rhs.mant.length; + { + do {/* select */ + if (lhs.exp == rhs.exp) {/* no padding needed */ + // This is the most common, and fastest, path + res.exp = lhs.exp; + } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs + newlen = (usellen + lhs.exp) - rhs.exp; + /* + * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot + * affect answer, so we only need to pad up to a length of DIGITS+1. + */ + if (newlen >= ((userlen + reqdig) + 1)) + if (reqdig > 0) { + // LHS is sufficient + res.mant = usel; + res.exp = lhs.exp; + res.ind = lhs.ind; + if (usellen < reqdig) { // need 0 padding + res.mant = extend(lhs.mant, reqdig); + res.exp = res.exp - ((reqdig - usellen)); + } + return res.finish(set, false); + } + // RHS may affect result + res.exp = rhs.exp; // expected final exponent + if (newlen > (reqdig + 1)) + if (reqdig > 0) { + // LHS will be max; RHS truncated + tlen = (newlen - reqdig) - 1; // truncation length + userlen = userlen - tlen; + res.exp = res.exp + tlen; + newlen = reqdig + 1; + } + if (newlen > usellen) + usellen = newlen; // need to pad LHS + } else { // need to pad rhs and/or truncate lhs + newlen = (userlen + rhs.exp) - lhs.exp; + if (newlen >= ((usellen + reqdig) + 1)) + if (reqdig > 0) { + // RHS is sufficient + res.mant = user; + res.exp = rhs.exp; + res.ind = rhs.ind; + if (userlen < reqdig) { // need 0 padding + res.mant = extend(rhs.mant, reqdig); + res.exp = res.exp - ((reqdig - userlen)); + } + return res.finish(set, false); + } + // LHS may affect result + res.exp = lhs.exp; // expected final exponent + if (newlen > (reqdig + 1)) + if (reqdig > 0) { + // RHS will be max; LHS truncated + tlen = (newlen - reqdig) - 1; // truncation length + usellen = usellen - tlen; + res.exp = res.exp + tlen; + newlen = reqdig + 1; + } + if (newlen > userlen) + userlen = newlen; // need to pad RHS + } + } while (false); + }/* padder */ + + /* OK, we have aligned mantissas. Now add or subtract. */ + // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive + // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs] + // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs] + if (lhs.ind == iszero) + res.ind = ispos; + else + res.ind = lhs.ind; // likely sign, all paths + if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative + mult = 1; + else { + do { // different signs, so subtraction is needed + mult = -1; // will cause subtract + /* + * Before we can subtract we must determine which is the larger, as our add/subtract routine only + * handles non-negative results so we may need to swap the operands. + */ + { + do {/* select */ + if (rhs.ind == iszero) { + // original A bigger + } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger + t = usel; + usel = user; + user = t; // swap + tlen = usellen; + usellen = userlen; + userlen = tlen; // .. + res.ind = (byte) -res.ind; // and set sign + } else if (usellen > userlen) { + // original A bigger + } else { + {/* logical lengths the same */// need compare + /* may still need to swap: compare the strings */ + ia = 0; + ib = 0; + ea = usel.length - 1; + eb = user.length - 1; + { + compare: for (;;) { + if (ia <= ea) + ca = usel[ia]; + else { + if (ib > eb) {/* identical */ + if (set.form != com.ibm.icu.math.MathContext.PLAIN) + return ZERO; + // [if PLAIN we must do the subtract, in case of 0.000 results] + break compare; + } + ca = (byte) 0; + } + if (ib <= eb) + cb = user[ib]; + else + cb = (byte) 0; + if (ca != cb) { + if (ca < cb) {/* swap needed */ + t = usel; + usel = user; + user = t; // swap + tlen = usellen; + usellen = userlen; + userlen = tlen; // .. + res.ind = (byte) -res.ind; + } + break compare; + } + /* mantissas the same, so far */ + ia++; + ib++; + } + }/* compare */ + } // lengths the same + } + } while (false); + }/* swaptest */ + } while (false); + }/* signdiff */ + + /* here, A is > B if subtracting */ + // add [A+B*1] or subtract [A+(B*-1)] + res.mant = byteaddsub(usel, usellen, user, userlen, mult, false); + // [reuse possible only after chop; accounting makes not worthwhile] + + // Finish() rounds before stripping leading 0's, then sets form, etc. + return res.finish(set, false); + } + + /** + * Compares this BigDecimal to another, using unlimited precision. + *

      + * The same as {@link #compareTo(BigDecimal, MathContext)}, where the BigDecimal is rhs, + * and the context is new MathContext(0, MathContext.PLAIN). + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @return An int whose value is -1, 0, or 1 as this is numerically less than, equal to, + * or greater than rhs. + * @stable ICU 2.0 + */ + + public int compareTo(com.ibm.icu.math.BigDecimal rhs) { + return this.compareTo(rhs, plainMC); + } + + /** + * Compares this BigDecimal to another. + *

      + * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}), + * and returns a result of type int. + *

      + * The result will be: + * + * + * + * + * + * + * + * + * + * + *
      -1 if the current object is less than the first parameter
      0 if the current object is equal to the first parameter
      1 if the current object is greater than the first parameter.
      + *

      + * A {@link #compareTo(BigDecimal)} method is also provided. + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @param set The MathContext arithmetic settings. + * @return An int whose value is -1, 0, or 1 as this is numerically less than, equal to, + * or greater than rhs. + * @stable ICU 2.0 + */ + + public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + int thislength = 0; + int i = 0; + com.ibm.icu.math.BigDecimal newrhs; + // rhs=null will raise NullPointerException, as per Comparable interface + if (set.lostDigits) + checkdigits(rhs, set.digits); + // [add will recheck in slowpath cases .. but would report -rhs] + if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) { + /* sign & exponent the same [very common] */ + thislength = this.mant.length; + if (thislength < rhs.mant.length) + return (byte) -this.ind; + if (thislength > rhs.mant.length) + return this.ind; + /* + * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very + * unusual] + */ + if ((thislength <= set.digits) | (set.digits == 0)) { + { + int $6 = thislength; + i = 0; + for (; $6 > 0; $6--, i++) { + if (this.mant[i] < rhs.mant[i]) + return (byte) -this.ind; + if (this.mant[i] > rhs.mant[i]) + return this.ind; + } + }/* i */ + return 0; // identical + } + /* drop through for full comparison */ + } else { + /* More fastpaths possible */ + if (this.ind < rhs.ind) + return -1; + if (this.ind > rhs.ind) + return 1; + } + /* carry out a subtract to make the comparison */ + newrhs = clone(rhs); // safe copy + newrhs.ind = (byte) -newrhs.ind; // prepare to subtract + return this.add(newrhs, set).ind; // add, and return sign of result + } + + /** + * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic. + *

      + * The same as {@link #divide(BigDecimal, int)}, where the BigDecimal is rhs, and the + * rounding mode is {@link MathContext#ROUND_HALF_UP}. + * + * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if + * the latter were formatted without exponential notation. + * + * @param rhs The BigDecimal for the right hand side of the division. + * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic. + * @throws ArithmeticException If rhs is zero. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) { + return this.dodivide('D', rhs, plainMC, -1); + } + + /** + * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic and a + * rounding mode. + *

      + * The same as {@link #divide(BigDecimal, int, int)}, where the BigDecimal is rhs, and the + * second parameter is this.scale(), and the third is round. + *

      + * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current + * object, if the latter were formatted without exponential notation. + *

      + * + * @param rhs The BigDecimal for the right hand side of the division. + * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). + * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic and + * the specified rounding mode. + * @throws IllegalArgumentException if round is not a valid rounding mode. + * @throws ArithmeticException if rhs is zero. + * @throws ArithmeticException if round is {@link MathContext#ROUND_UNNECESSARY} and this.scale() is insufficient to represent the result exactly. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) { + com.ibm.icu.math.MathContext set; + set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round, + // too] + return this.dodivide('D', rhs, set, -1); // take scale from LHS + } + + /** + * Returns a plain BigDecimal whose value is this/rhs, using fixed point arithmetic and a + * given scale and rounding mode. + *

      + * The same as {@link #divide(BigDecimal, MathContext)}, where the BigDecimal is rhs, + * new MathContext(0, MathContext.PLAIN, false, round), except that the length of the decimal part (the + * scale) to be used for the result is explicit rather than being taken from this. + *

      + * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if + * the latter were formatted without exponential notation. + *

      + * + * @param rhs The BigDecimal for the right hand side of the division. + * @param scale The int scale to be used for the result. + * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). + * @return A plain BigDecimal whose value is this/rhs, using fixed point arithmetic and + * the specified rounding mode. + * @throws IllegalArgumentException if round is not a valid rounding mode. + * @throws ArithmeticException if rhs is zero. + * @throws ArithmeticException if scale is negative. + * @throws ArithmeticException if round is {@link MathContext#ROUND_UNNECESSARY} and scale is insufficient + * to represent the result exactly. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) { + com.ibm.icu.math.MathContext set; + if (scale < 0) + throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); + set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round] + return this.dodivide('D', rhs, set, scale); + } + + /** + * Returns a BigDecimal whose value is this/rhs. + *

      + * Implements the division (/) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + * + * @param rhs The BigDecimal for the right hand side of the division. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is this/rhs. + * @throws ArithmeticException if rhs is zero. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + return this.dodivide('D', rhs, set, -1); + } + + /** + * Returns a plain BigDecimal whose value is the integer part of this/rhs. + *

      + * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the BigDecimal is rhs + * , and the context is new MathContext(0, MathContext.PLAIN). + * + * @param rhs The BigDecimal for the right hand side of the integer division. + * @return A BigDecimal whose value is the integer part of this/rhs. + * @throws ArithmeticException if rhs is zero. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) { + // scale 0 to drop .000 when plain + return this.dodivide('I', rhs, plainMC, 0); + } + + /** + * Returns a BigDecimal whose value is the integer part of this/rhs. + *

      + * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class + * header}), and returns the result as a BigDecimal object. + * + * @param rhs The BigDecimal for the right hand side of the integer division. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is the integer part of this/rhs. + * @throws ArithmeticException if rhs is zero. + * @throws ArithmeticException if the result will not fit in the number of digits specified for the context. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + // scale 0 to drop .000 when plain + return this.dodivide('I', rhs, set, 0); + } + + /** + * Returns a plain BigDecimal whose value is the maximum of this and rhs. + *

      + * The same as {@link #max(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the + * context is new MathContext(0, MathContext.PLAIN). + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @return A BigDecimal whose value is the maximum of this and rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) { + return this.max(rhs, plainMC); + } + + /** + * Returns a BigDecimal whose value is the maximum of this and rhs. + *

      + * Returns the larger of the current object and the first parameter. + *

      + * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return 1 + * or 0, then the result of calling the {@link #plus(MathContext)} method on the current object + * (using the same MathContext parameter) is returned. Otherwise, the result of calling the + * {@link #plus(MathContext)} method on the first parameter object (using the same MathContext + * parameter) is returned. + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is the maximum of this and rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + if ((this.compareTo(rhs, set)) >= 0) + return this.plus(set); + else + return rhs.plus(set); + } + + /** + * Returns a plain BigDecimal whose value is the minimum of this and rhs. + *

      + * The same as {@link #min(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the + * context is new MathContext(0, MathContext.PLAIN). + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @return A BigDecimal whose value is the minimum of this and rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) { + return this.min(rhs, plainMC); + } + + /** + * Returns a BigDecimal whose value is the minimum of this and rhs. + *

      + * Returns the smaller of the current object and the first parameter. + *

      + * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return -1 + * or 0, then the result of calling the {@link #plus(MathContext)} method on the current object + * (using the same MathContext parameter) is returned. Otherwise, the result of calling the + * {@link #plus(MathContext)} method on the first parameter object (using the same MathContext + * parameter) is returned. + * + * @param rhs The BigDecimal for the right hand side of the comparison. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is the minimum of this and rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + if ((this.compareTo(rhs, set)) <= 0) + return this.plus(set); + else + return rhs.plus(set); + } + + /** + * Returns a plain BigDecimal whose value is this*rhs, using fixed point arithmetic. + *

      + * The same as {@link #add(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the + * context is new MathContext(0, MathContext.PLAIN). + *

      + * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they + * were formatted without exponential notation. + * + * @param rhs The BigDecimal for the right hand side of the multiplication. + * @return A BigDecimal whose value is this*rhs, using fixed point arithmetic. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) { + return this.multiply(rhs, plainMC); + } + + /** + * Returns a BigDecimal whose value is this*rhs. + *

      + * Implements the multiplication ( ) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + * + * @param rhs The BigDecimal for the right hand side of the multiplication. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is this*rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + com.ibm.icu.math.BigDecimal lhs; + int padding; + int reqdig; + byte multer[] = null; + byte multand[] = null; + int multandlen; + int acclen = 0; + com.ibm.icu.math.BigDecimal res; + byte acc[]; + int n = 0; + byte mult = 0; + if (set.lostDigits) + checkdigits(rhs, set.digits); + lhs = this; // name for clarity and proxy + + /* Prepare numbers (truncate, unless unlimited precision) */ + padding = 0; // trailing 0's to add + reqdig = set.digits; // local copy + if (reqdig > 0) { + if (lhs.mant.length > reqdig) + lhs = clone(lhs).round(set); + if (rhs.mant.length > reqdig) + rhs = clone(rhs).round(set); + // [we could reuse the new LHS for result in this case] + } else {/* unlimited */ + // fixed point arithmetic will want every trailing 0; we add these + // after the calculation rather than before, for speed. + if (lhs.exp > 0) + padding = padding + lhs.exp; + if (rhs.exp > 0) + padding = padding + rhs.exp; + } + + // For best speed, as in DMSRCN, we use the shorter number as the + // multiplier and the longer as the multiplicand. + // 1999.12.22: We used to special case when the result would fit in + // a long, but with Java 1.3 this gave no advantage. + if (lhs.mant.length < rhs.mant.length) { + multer = lhs.mant; + multand = rhs.mant; + } else { + multer = rhs.mant; + multand = lhs.mant; + } + + /* Calculate how long result byte array will be */ + multandlen = (multer.length + multand.length) - 1; // effective length + // optimize for 75% of the cases where a carry is expected... + if ((multer[0] * multand[0]) > 9) + acclen = multandlen + 1; + else + acclen = multandlen; + + /* Now the main long multiplication loop */ + res = new com.ibm.icu.math.BigDecimal(); // where we'll build result + acc = new byte[acclen]; // accumulator, all zeros + // 1998.07.01: calculate from left to right so that accumulator goes + // to likely final length on first addition; this avoids a one-digit + // extension (and object allocation) each time around the loop. + // Initial number therefore has virtual zeros added to right. + { + int $7 = multer.length; + n = 0; + for (; $7 > 0; $7--, n++) { + mult = multer[n]; + if (mult != 0) { // [optimization] + // accumulate [accumulator is reusable array] + acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true); + } + // divide multiplicand by 10 for next digit to right + multandlen--; // 'virtual length' + } + }/* n */ + + res.ind = (byte) (lhs.ind * rhs.ind); // final sign + res.exp = (lhs.exp + rhs.exp) - padding; // final exponent + // [overflow is checked by finish] + + /* add trailing zeros to the result, if necessary */ + if (padding == 0) + res.mant = acc; + else + res.mant = extend(acc, acc.length + padding); // add trailing 0s + return res.finish(set, false); + } + + /** + * Returns a plain BigDecimal whose value is -this. + *

      + * The same as {@link #negate(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN) + * . + *

      + * The length of the decimal part (the scale) of the result will be be this.scale() + * + * + * @return A BigDecimal whose value is -this. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal negate() { + return this.negate(plainMC); + } + + /** + * Returns a BigDecimal whose value is -this. + *

      + * Implements the negation (Prefix -) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + * + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is -this. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) { + com.ibm.icu.math.BigDecimal res; + // Originally called minus(), changed to matched Java precedents + // This simply clones, flips the sign, and possibly rounds + if (set.lostDigits) + checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits); + res = clone(this); // safe copy + res.ind = (byte) -res.ind; + return res.finish(set, false); + } + + /** + * Returns a plain BigDecimal whose value is +this. Note that this is not + * necessarily a plain BigDecimal, but the result will always be. + *

      + * The same as {@link #plus(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN). + *

      + * The length of the decimal part (the scale) of the result will be be this.scale() + * + * @return A BigDecimal whose value is +this. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal plus() { + return this.plus(plainMC); + } + + /** + * Returns a BigDecimal whose value is +this. + *

      + * Implements the plus (Prefix +) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + *

      + * This method is useful for rounding or otherwise applying a context to a decimal value. + * + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is +this. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) { + // This clones and forces the result to the new settings + // May return same object + if (set.lostDigits) + checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits); + // Optimization: returns same object for some common cases + if (set.form == com.ibm.icu.math.MathContext.PLAIN) + if (this.form == com.ibm.icu.math.MathContext.PLAIN) { + if (this.mant.length <= set.digits) + return this; + if (set.digits == 0) + return this; + } + return clone(this).finish(set, false); + } + + /** + * Returns a plain BigDecimal whose value is this**rhs, using fixed point arithmetic. + *

      + * The same as {@link #pow(BigDecimal, MathContext)}, where the BigDecimal is rhs, and the + * context is new MathContext(0, MathContext.PLAIN). + *

      + * The parameter is the power to which the this will be raised; it must be in the range 0 through + * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so + * they should not be used as a test for a whole number. + *

      + * In addition, the power must not be negative, as no MathContext is used and so the result would then + * always be 0. + * + * @param rhs The BigDecimal for the right hand side of the operation (the power). + * @return A BigDecimal whose value is this**rhs, using fixed point arithmetic. + * @throws ArithmeticException if rhs is out of range or is not a whole number. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) { + return this.pow(rhs, plainMC); + } + + // The name for this method is inherited from the precedent set by the + // BigInteger and Math classes. + + /** + * Returns a BigDecimal whose value is this**rhs. + *

      + * Implements the power ( ) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + *

      + * The first parameter is the power to which the this will be raised; it must be in the range + * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed + * in the future, so they should not be used as a test for a whole number. + *

      + * If the digits setting of the MathContext parameter is 0, the power must be zero or + * positive. + * + * @param rhs The BigDecimal for the right hand side of the operation (the power). + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is this**rhs. + * @throws ArithmeticException if rhs is out of range or is not a whole number. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + int n; + com.ibm.icu.math.BigDecimal lhs; + int reqdig; + int workdigits = 0; + int L = 0; + com.ibm.icu.math.MathContext workset; + com.ibm.icu.math.BigDecimal res; + boolean seenbit; + int i = 0; + if (set.lostDigits) + checkdigits(rhs, set.digits); + n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules + lhs = this; // clarified name + + reqdig = set.digits; // local copy (heavily used) + if (reqdig == 0) { + if (rhs.ind == isneg) + throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString()); + workdigits = 0; + } else {/* non-0 digits */ + if ((rhs.mant.length + rhs.exp) > reqdig) + throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); + + /* Round the lhs to DIGITS if need be */ + if (lhs.mant.length > reqdig) + lhs = clone(lhs).round(set); + + /* L for precision calculation [see ANSI X3.274-1996] */ + L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp + workdigits = (reqdig + L) + 1; // calculate the working DIGITS + } + + /* Create a copy of set for working settings */ + // Note: no need to check for lostDigits again. + // 1999.07.17 Note: this construction must follow RHS check + workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode); + + res = ONE; // accumulator + if (n == 0) + return res; // x**0 == 1 + if (n < 0) + n = -n; // [rhs.ind records the sign] + seenbit = false; // set once we've seen a 1-bit + { + i = 1; + i: for (;; i++) { // for each bit [top bit ignored] + n = n + n; // shift left 1 bit + if (n < 0) { // top bit is set + seenbit = true; // OK, we're off + res = res.multiply(lhs, workset); // acc=acc*x + } + if (i == 31) + break i; // that was the last bit + if ((!seenbit)) + continue i; // we don't have to square 1 + res = res.multiply(res, workset); // acc=acc*acc [square] + } + }/* i */// 32 bits + if (rhs.ind < 0) // was a **-n [hence digits>0] + res = ONE.divide(res, workset); // .. so acc=1/acc + return res.finish(set, true); // round and strip [original digits] + } + + /** + * Returns a plain BigDecimal whose value is the remainder of this/rhs, using fixed point + * arithmetic. + *

      + * The same as {@link #remainder(BigDecimal, MathContext)}, where the BigDecimal is rhs, + * and the context is new MathContext(0, MathContext.PLAIN). + *

      + * This is not the modulo operator -- the result may be negative. + * + * @param rhs The BigDecimal for the right hand side of the remainder operation. + * @return A BigDecimal whose value is the remainder of this/rhs, using fixed point + * arithmetic. + * @throws ArithmeticException if rhs is zero. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) { + return this.dodivide('R', rhs, plainMC, -1); + } + + /** + * Returns a BigDecimal whose value is the remainder of this/rhs. + *

      + * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}), + * and returns the result as a BigDecimal object. + *

      + * This is not the modulo operator -- the result may be negative. + * + * @param rhs The BigDecimal for the right hand side of the remainder operation. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is the remainder of this+rhs. + * @throws ArithmeticException if rhs is zero. + * @throws ArithmeticException if the integer part of the result will not fit in the number of digits specified for the context. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + return this.dodivide('R', rhs, set, -1); + } + + /** + * Returns a plain BigDecimal whose value is this-rhs, using fixed point arithmetic. + *

      + * The same as {@link #subtract(BigDecimal, MathContext)}, where the BigDecimal is rhs, + * and the context is new MathContext(0, MathContext.PLAIN). + *

      + * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands. + * + * @param rhs The BigDecimal for the right hand side of the subtraction. + * @return A BigDecimal whose value is this-rhs, using fixed point arithmetic. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) { + return this.subtract(rhs, plainMC); + } + + /** + * Returns a BigDecimal whose value is this-rhs. + *

      + * Implements the subtraction (-) operator (as defined in the decimal documentation, see + * {@link BigDecimal class header}), and returns the result as a BigDecimal object. + * + * @param rhs The BigDecimal for the right hand side of the subtraction. + * @param set The MathContext arithmetic settings. + * @return A BigDecimal whose value is this-rhs. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) { + com.ibm.icu.math.BigDecimal newrhs; + if (set.lostDigits) + checkdigits(rhs, set.digits); + // [add will recheck .. but would report -rhs] + /* carry out the subtraction */ + // we could fastpath -0, but it is too rare. + newrhs = clone(rhs); // safe copy + newrhs.ind = (byte) -newrhs.ind; // prepare to subtract + return this.add(newrhs, set); // arithmetic + } + + /* ---------------------------------------------------------------- */ + /* Other methods */ + /* ---------------------------------------------------------------- */ + + /** + * Converts this BigDecimal to a byte. If the BigDecimal has a non-zero + * decimal part or is out of the possible range for a byte (8-bit signed integer) result then an + * ArithmeticException is thrown. + * + * @return A byte equal in value to this. + * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a byte. + * @stable ICU 2.0 + */ + + public byte byteValueExact() { + int num; + num = this.intValueExact(); // will check decimal part too + if ((num > 127) | (num < (-128))) + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + return (byte) num; + } + + /** + * Converts this BigDecimal to a double. If the BigDecimal is out of the + * possible range for a double (64-bit signed floating point) result then an ArithmeticException + * is thrown. + *

      + * The double produced is identical to result of expressing the BigDecimal as a String and + * then converting it using the Double(String) constructor; this can result in values of + * Double.NEGATIVE_INFINITY or Double.POSITIVE_INFINITY. + * + * @return A double corresponding to this. + * @stable ICU 2.0 + */ + + public double doubleValue() { + // We go via a String [as does BigDecimal in JDK 1.2] + // Next line could possibly raise NumberFormatException + return java.lang.Double.valueOf(this.toString()).doubleValue(); + } + + /** + * Compares this BigDecimal with rhs for equality. + *

      + * If the parameter is null, or is not an instance of the BigDecimal type, or is not exactly equal to + * the current BigDecimal object, then false is returned. Otherwise, true is returned. + *

      + * "Exactly equal", here, means that the String representations of the BigDecimal numbers + * are identical (they have the same characters in the same sequence). + *

      + * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons. + * + * @param obj The Object for the right hand side of the comparison. + * @return A boolean whose value true if and only if the operands have identical string + * representations. + * @throws ClassCastException if rhs cannot be cast to a BigDecimal object. + * @stable ICU 2.0 + * @see #compareTo(BigDecimal) + * @see #compareTo(BigDecimal, MathContext) + */ + + public boolean equals(java.lang.Object obj) { + com.ibm.icu.math.BigDecimal rhs; + int i = 0; + char lca[] = null; + char rca[] = null; + // We are equal iff toString of both are exactly the same + if (obj == null) + return false; // not equal + if ((!(((obj instanceof com.ibm.icu.math.BigDecimal))))) + return false; // not a decimal + rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work + if (this.ind != rhs.ind) + return false; // different signs never match + if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form)) + + { // mantissas say all + // here with equal-length byte arrays to compare + { + int $8 = this.mant.length; + i = 0; + for (; $8 > 0; $8--, i++) { + if (this.mant[i] != rhs.mant[i]) + return false; + } + }/* i */ + } else { // need proper layout + lca = this.layout(); // layout to character array + rca = rhs.layout(); + if (lca.length != rca.length) + return false; // mismatch + // here with equal-length character arrays to compare + { + int $9 = lca.length; + i = 0; + for (; $9 > 0; $9--, i++) { + if (lca[i] != rca[i]) + return false; + } + }/* i */ + } + return true; // arrays have identical content + } + + /** + * Converts this BigDecimal to a float. If the BigDecimal is out of the + * possible range for a float (32-bit signed floating point) result then an ArithmeticException + * is thrown. + *

      + * The float produced is identical to result of expressing the BigDecimal as a String and + * then converting it using the Float(String) constructor; this can result in values of + * Float.NEGATIVE_INFINITY or Float.POSITIVE_INFINITY. + * + * @return A float corresponding to this. + * @stable ICU 2.0 + */ + + public float floatValue() { + return java.lang.Float.valueOf(this.toString()).floatValue(); + } + + /** + * Returns the String representation of this BigDecimal, modified by layout parameters. + *

      + * This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat + * , that can apply locale-sensitive editing of the result. The level of formatting that it provides is a + * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules + * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. + * + *

      + * The parameters, for both forms of the format method are all of type int. A value of -1 + * for any parameter indicates that the default action or value for that parameter should be used. + *

      + * The parameters, before and after, specify the number of characters to be used for the + * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter + * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed + * for that part. + *

      + * before must be a positive number; if it is larger than is needed to contain the integer part, that + * part is padded on the left with blanks to the requested length. If before is not large enough to + * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown. + *

      + * after must be a non-negative number; if it is not the same size as the decimal part of the number, + * the number will be rounded (or extended with zeros) to fit. Specifying 0 for after will cause the + * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method + * will be the default, MathContext.ROUND_HALF_UP. + *

      + * Other rounding methods, and the use of exponential notation, can be selected by using + * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect + * as using the six-parameter form with the final four parameters all being -1. + * + * @param before The int specifying the number of places before the decimal point. Use -1 for 'as many as are needed'. + * @param after The int specifying the number of places after the decimal point. Use -1 for 'as many as are needed'. + * @return A String representing this BigDecimal, laid out according to the specified parameters + * @throws ArithmeticException if the number cannot be laid out as requested. + * @throws IllegalArgumentException if a parameter is out of range. + * @stable ICU 2.0 + * @see #toString + * @see #toCharArray + */ + + public java.lang.String format(int before, int after) { + return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP); + } + + /** + * Returns the String representation of this BigDecimal, modified by layout parameters and + * allowing exponential notation. + *

      + * This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat + * , that can apply locale-sensitive editing of the result. The level of formatting that it provides is a + * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules + * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class. + * + *

      + * The parameters are all of type int. A value of -1 for any parameter indicates that the default + * action or value for that parameter should be used. + *

      + * The first two parameters (before and after) specify the number of characters to be used + * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If + * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many + * as are needed for that part. + *

      + * The remaining parameters control the use of exponential notation and rounding. Three (explaces, + * exdigits, and exform) control the exponent part of the result. As before, the default + * action for any of these parameters may be selected by using the value -1. + *

      + * explaces must be a positive number; it sets the number of places (digits after the sign of the + * exponent) to be used for any exponent part, the default (when explaces is -1) being to use as many + * as are needed. If explaces is not -1, space is always reserved for an exponent; if one is not needed + * (for example, if the exponent will be 0) then explaces+2 blanks are appended to the result. If explaces + * is not -1 and is not large enough to contain the exponent, an exception is thrown. + *

      + * exdigits sets the trigger point for use of exponential notation. If, before any rounding, the number + * of places needed before the decimal point exceeds exdigits, or if the absolute value of the result + * is less than 0.000001, then exponential form will be used, provided that exdigits was + * specified. When exdigits is -1, exponential notation will never be used. If 0 is specified for + * exdigits, exponential notation is always used unless the exponent would be 0. + *

      + * exform sets the form for exponential notation (if needed). It may be either + * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested, + * up to three digits (plus sign, if negative) may be needed for the integer part of the result (before + * ). Otherwise, only one digit (plus sign, if negative) is needed. + *

      + * Finally, the sixth argument, exround, selects the rounding algorithm to be used, and must be one of + * the values indicated by a public constant in the {@link MathContext} class whose name starts with ROUND_ + * . The default (ROUND_HALF_UP) may also be selected by using the value -1, as before. + *

      + * The special value MathContext.ROUND_UNNECESSARY may be used to detect whether non-zero digits are + * discarded -- if exround has this value than if non-zero digits would be discarded (rounded) during + * formatting then an ArithmeticException is thrown. + * + * @param before The int specifying the number of places before the decimal point. Use -1 for 'as many as + * are needed'. + * @param after The int specifying the number of places after the decimal point. Use -1 for 'as many as + * are needed'. + * @param explaces The int specifying the number of places to be used for any exponent. Use -1 for 'as many + * as are needed'. + * @param exdigits The int specifying the trigger (digits before the decimal point) which if exceeded causes + * exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation + * (no exponential notation). + * @param exformint The int specifying the form of exponential notation to be used ( + * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}). + * @param exround The int specifying the rounding mode to use. Use -1 for the default, + * {@link MathContext#ROUND_HALF_UP}. + * @return A String representing this BigDecimal, laid out according to the specified + * parameters + * @throws ArithmeticException if the number cannot be laid out as requested. + * @throws IllegalArgumentException if a parameter is out of range. + * @see #toString + * @see #toCharArray + * @stable ICU 2.0 + */ + + public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) { + com.ibm.icu.math.BigDecimal num; + int mag = 0; + int thisafter = 0; + int lead = 0; + byte newmant[] = null; + int chop = 0; + int need = 0; + int oldexp = 0; + char a[]; + int p = 0; + char newa[] = null; + int i = 0; + int places = 0; + + /* Check arguments */ + if ((before < (-1)) | (before == 0)) + badarg("format", 1, java.lang.String.valueOf(before)); + if (after < (-1)) + badarg("format", 2, java.lang.String.valueOf(after)); + if ((explaces < (-1)) | (explaces == 0)) + badarg("format", 3, java.lang.String.valueOf(explaces)); + if (exdigits < (-1)) + badarg("format", 4, java.lang.String.valueOf(explaces)); + {/* select */ + if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) { + } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) { + } else if (exformint == (-1)) + exformint = com.ibm.icu.math.MathContext.SCIENTIFIC; + // note PLAIN isn't allowed + else { + badarg("format", 5, java.lang.String.valueOf(exformint)); + } + } + // checking the rounding mode is done by trying to construct a + // MathContext object with that mode; it will fail if bad + if (exround != ROUND_HALF_UP) { + try { // if non-default... + if (exround == (-1)) + exround = ROUND_HALF_UP; + else + new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround); + } catch (java.lang.IllegalArgumentException $10) { + badarg("format", 6, java.lang.String.valueOf(exround)); + } + } + + num = clone(this); // make private copy + + /* + * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0] + * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two] + * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified + */ + + /* determine form */ + { + do {/* select */ + if (exdigits == (-1)) + num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; + else if (num.ind == iszero) + num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; + else { + // determine whether triggers + mag = num.exp + num.mant.length; + if (mag > exdigits) + num.form = (byte) exformint; + else if (mag < (-5)) + num.form = (byte) exformint; + else + num.form = (byte) com.ibm.icu.math.MathContext.PLAIN; + } + } while (false); + }/* setform */ + + /* + * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform + * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific). + */ + if (after >= 0) { + setafter: for (;;) { + // calculate the current after-length + {/* select */ + if (num.form == com.ibm.icu.math.MathContext.PLAIN) + thisafter = -num.exp; // has decimal part + else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC) + thisafter = num.mant.length - 1; + else { // engineering + lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use + if (lead < 0) + lead = 3 + lead; // negative exponent case + lead++; // number of leading digits + if (lead >= num.mant.length) + thisafter = 0; + else + thisafter = num.mant.length - lead; + } + } + if (thisafter == after) + break setafter; // we're in luck + if (thisafter < after) { // need added trailing zeros + // [thisafter can be negative] + newmant = extend(num.mant, (num.mant.length + after) - thisafter); + num.mant = newmant; + num.exp = num.exp - ((after - thisafter)); // adjust exponent + if (num.exp < MinExp) + throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp); + break setafter; + } + // We have too many digits after the decimal point; this could + // cause a carry, which could change the mantissa... + // Watch out for implied leading zeros in PLAIN case + chop = thisafter - after; // digits to lop [is >0] + if (chop > num.mant.length) { // all digits go, no chance of carry + // carry on with zero + num.mant = ZERO.mant; + num.ind = iszero; + num.exp = 0; + continue setafter; // recheck: we may need trailing zeros + } + // we have a digit to inspect from existing mantissa + // round the number as required + need = num.mant.length - chop; // digits to end up with [may be 0] + oldexp = num.exp; // save old exponent + num.round(need, exround); + // if the exponent grew by more than the digits we chopped, then + // we must have had a carry, so will need to recheck the layout + if ((num.exp - oldexp) == chop) + break setafter; // number did not have carry + // mantissa got extended .. so go around and check again + } + }/* setafter */ + + a = num.layout(); // lay out, with exponent if required, etc. + + /* Here we have laid-out number in 'a' */ + // now apply 'before' and 'explaces' as needed + if (before > 0) { + // look for '.' or 'E' + { + int $11 = a.length; + p = 0; + p: for (; $11 > 0; $11--, p++) { + if (a[p] == '.') + break p; + if (a[p] == 'E') + break p; + } + }/* p */ + // p is now offset of '.', 'E', or character after end of array + // that is, the current length of before part + if (p > before) + badarg("format", 1, java.lang.String.valueOf(before)); // won't fit + if (p < before) { // need leading blanks + newa = new char[(a.length + before) - p]; + { + int $12 = before - p; + i = 0; + for (; $12 > 0; $12--, i++) { + newa[i] = ' '; + } + }/* i */ + java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, i, a.length); + a = newa; + } + // [if p=before then it's just the right length] + } + + if (explaces > 0) { + // look for 'E' [cannot be at offset 0] + { + int $13 = a.length - 1; + p = a.length - 1; + p: for (; $13 > 0; $13--, p--) { + if (a[p] == 'E') + break p; + } + }/* p */ + // p is now offset of 'E', or 0 + if (p == 0) { // no E part; add trailing blanks + newa = new char[(a.length + explaces) + 2]; + java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, a.length); + { + int $14 = explaces + 2; + i = a.length; + for (; $14 > 0; $14--, i++) { + newa[i] = ' '; + } + }/* i */ + a = newa; + } else {/* found E */// may need to insert zeros + places = (a.length - p) - 2; // number so far + if (places > explaces) + badarg("format", 3, java.lang.String.valueOf(explaces)); + if (places < explaces) { // need to insert zeros + newa = new char[(a.length + explaces) - places]; + java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, p + 2); // through E + // and sign + { + int $15 = explaces - places; + i = p + 2; + for (; $15 > 0; $15--, i++) { + newa[i] = '0'; + } + }/* i */ + java.lang.System.arraycopy((java.lang.Object) a, p + 2, (java.lang.Object) newa, i, places); // remainder + // of + // exponent + a = newa; + } + // [if places=explaces then it's just the right length] + } + } + return new java.lang.String(a); + } + + /** + * Returns the hashcode for this BigDecimal. This hashcode is suitable for use by the + * java.util.Hashtable class. + *

      + * Note that two BigDecimal objects are only guaranteed to produce the same hashcode if they are + * exactly equal (that is, the String representations of the BigDecimal numbers are + * identical -- they have the same characters in the same sequence). + * + * @return An int that is the hashcode for this. + * @stable ICU 2.0 + */ + + public int hashCode() { + // Maybe calculate ourselves, later. If so, note that there can be + // more than one internal representation for a given toString() result. + return this.toString().hashCode(); + } + + /** + * Converts this BigDecimal to an int. If the BigDecimal has a non-zero + * decimal part it is discarded. If the BigDecimal is out of the possible range for an int + * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be + * decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact} + * method. + * + * @return An int converted from this, truncated and decapitated if necessary. + * @stable ICU 2.0 + */ + + public int intValue() { + return toBigInteger().intValue(); + } + + /** + * Converts this BigDecimal to an int. If the BigDecimal has a non-zero + * decimal part or is out of the possible range for an int (32-bit signed integer) result then an + * ArithmeticException is thrown. + * + * @return An int equal in value to this. + * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in an int. + * @stable ICU 2.0 + */ + + public int intValueExact() { + int lodigit; + int useexp = 0; + int result; + int i = 0; + int topdig = 0; + // This does not use longValueExact() as the latter can be much + // slower. + // intcheck (from pow) relies on this to check decimal part + if (ind == iszero) + return 0; // easy, and quite common + /* test and drop any trailing decimal part */ + lodigit = mant.length - 1; + if (exp < 0) { + lodigit = lodigit + exp; // reduces by -(-exp) + /* all decimal places must be 0 */ + if ((!(allzero(mant, lodigit + 1)))) + throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); + if (lodigit < 0) + return 0; // -1=0 */ + if ((exp + lodigit) > 9) // early exit + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + useexp = exp; + } + /* convert the mantissa to binary, inline for speed */ + result = 0; + { + int $16 = lodigit + useexp; + i = 0; + for (; i <= $16; i++) { + result = result * 10; + if (i <= lodigit) + result = result + mant[i]; + } + }/* i */ + + /* Now, if the risky length, check for overflow */ + if ((lodigit + useexp) == 9) { + // note we cannot just test for -ve result, as overflow can move a + // zero into the top bit [consider 5555555555] + topdig = result / 1000000000; // get top digit, preserving sign + if (topdig != mant[0]) { // digit must match and be positive + // except in the special case ... + if (result == java.lang.Integer.MIN_VALUE) // looks like the special + if (ind == isneg) // really was negative + if (mant[0] == 2) + return result; // really had top digit 2 + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + } + } + + /* Looks good */ + if (ind == ispos) + return result; + return -result; + } + + /** + * Converts this BigDecimal to a long. If the BigDecimal has a non-zero + * decimal part it is discarded. If the BigDecimal is out of the possible range for a long + * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be + * decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact} + * method. + * + * @return A long converted from this, truncated and decapitated if necessary. + * @stable ICU 2.0 + */ + + public long longValue() { + return toBigInteger().longValue(); + } + + /** + * Converts this BigDecimal to a long. If the BigDecimal has a non-zero + * decimal part or is out of the possible range for a long (64-bit signed integer) result then an + * ArithmeticException is thrown. + * + * @return A long equal in value to this. + * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a long. + * @stable ICU 2.0 + */ + + public long longValueExact() { + int lodigit; + int cstart = 0; + int useexp = 0; + long result; + int i = 0; + long topdig = 0; + // Identical to intValueExact except for result=long, and exp>=20 test + if (ind == 0) + return 0; // easy, and quite common + lodigit = mant.length - 1; // last included digit + if (exp < 0) { + lodigit = lodigit + exp; // -(-exp) + /* all decimal places must be 0 */ + if (lodigit < 0) + cstart = 0; + else + cstart = lodigit + 1; + if ((!(allzero(mant, cstart)))) + throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); + if (lodigit < 0) + return 0; // -1=0 */ + if ((exp + mant.length) > 18) // early exit + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + useexp = exp; + } + + /* convert the mantissa to binary, inline for speed */ + // note that we could safely use the 'test for wrap to negative' + // algorithm here, but instead we parallel the intValueExact + // algorithm for ease of checking and maintenance. + result = (long) 0; + { + int $17 = lodigit + useexp; + i = 0; + for (; i <= $17; i++) { + result = result * 10; + if (i <= lodigit) + result = result + mant[i]; + } + }/* i */ + + /* Now, if the risky length, check for overflow */ + if ((lodigit + useexp) == 18) { + topdig = result / 1000000000000000000L; // get top digit, preserving sign + if (topdig != mant[0]) { // digit must match and be positive + // except in the special case ... + if (result == java.lang.Long.MIN_VALUE) // looks like the special + if (ind == isneg) // really was negative + if (mant[0] == 9) + return result; // really had top digit 9 + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + } + } + + /* Looks good */ + if (ind == ispos) + return result; + return -result; + } + + /** + * Returns a plain BigDecimal whose decimal point has been moved to the left by a specified number of + * positions. The parameter, n, specifies the number of positions to move the decimal point. That is, + * if n is 0 or positive, the number returned is given by: + *

      + * this.multiply(TEN.pow(new BigDecimal(-n))) + *

      + * n may be negative, in which case the method returns the same result as movePointRight(-n) + * . + * + * @param n The int specifying the number of places to move the decimal point leftwards. + * @return A BigDecimal derived from this, with the decimal point moved n + * places to the left. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal movePointLeft(int n) { + com.ibm.icu.math.BigDecimal res; + // very little point in optimizing for shift of 0 + res = clone(this); + res.exp = res.exp - n; + return res.finish(plainMC, false); // finish sets form and checks exponent + } + + /** + * Returns a plain BigDecimal whose decimal point has been moved to the right by a specified number of + * positions. The parameter, n, specifies the number of positions to move the decimal point. That is, + * if n is 0 or positive, the number returned is given by: + *

      + * this.multiply(TEN.pow(new BigDecimal(n))) + *

      + * n may be negative, in which case the method returns the same result as movePointLeft(-n) + * . + * + * @param n The int specifying the number of places to move the decimal point rightwards. + * @return A BigDecimal derived from this, with the decimal point moved n + * places to the right. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal movePointRight(int n) { + com.ibm.icu.math.BigDecimal res; + res = clone(this); + res.exp = res.exp + n; + return res.finish(plainMC, false); + } + + /** + * Returns the scale of this BigDecimal. Returns a non-negative int which is the scale of + * the number. The scale is the number of digits in the decimal part of the number if the number were formatted + * without exponential notation. + * + * @return An int whose value is the scale of this BigDecimal. + * @stable ICU 2.0 + */ + + public int scale() { + if (exp >= 0) + return 0; // scale can never be negative + return -exp; + } + + /** + * Returns a plain BigDecimal with a given scale. + *

      + * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part + * (the scale) of this BigDecimal then trailing zeros will be added to the decimal part as necessary. + *

      + * If the given scale is less than the length of the decimal part (the scale) of this BigDecimal then + * trailing digits will be removed, and in this case an ArithmeticException is thrown if any discarded + * digits are non-zero. + *

      + * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is + * MathContext.ROUND_UNNECESSARY. + * + * @param scale The int specifying the scale of the resulting BigDecimal. + * @return A plain BigDecimal with the given scale. + * @throws ArithmeticException if scale is negative. + * @throws ArithmeticException if reducing scale would discard non-zero digits. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal setScale(int scale) { + return setScale(scale, ROUND_UNNECESSARY); + } + + /** + * Returns a plain BigDecimal with a given scale. + *

      + * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part + * (the scale) of this BigDecimal then trailing zeros will be added to the decimal part as necessary. + *

      + * If the given scale is less than the length of the decimal part (the scale) of this BigDecimal then + * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the + * remaining digits are affected by a carry. In this case, an IllegalArgumentException is thrown if + * round is not a valid rounding mode. + *

      + * If round is MathContext.ROUND_UNNECESSARY, an ArithmeticException is + * thrown if any discarded digits are non-zero. + * + * @param scale The int specifying the scale of the resulting BigDecimal. + * @param round The int rounding mode to be used for the division (see the {@link MathContext} class). + * @return A plain BigDecimal with the given scale. + * @throws IllegalArgumentException if round is not a valid rounding mode. + * @throws ArithmeticException if scale is negative. + * @throws ArithmeticException if round is MathContext.ROUND_UNNECESSARY, and reducing scale would discard + * non-zero digits. + * @stable ICU 2.0 + */ + + public com.ibm.icu.math.BigDecimal setScale(int scale, int round) { + int ourscale; + com.ibm.icu.math.BigDecimal res; + int padding = 0; + int newlen = 0; + // at present this naughtily only checks the round value if it is + // needed (used), for speed + ourscale = this.scale(); + if (ourscale == scale) // already correct scale + if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form + return this; + res = clone(this); // need copy + if (ourscale <= scale) { // simply zero-padding/changing form + // if ourscale is 0 we may have lots of 0s to add + if (ourscale == 0) + padding = res.exp + scale; + else + padding = scale - ourscale; + res.mant = extend(res.mant, res.mant.length + padding); + res.exp = -scale; // as requested + } else {/* ourscale>scale: shortening, probably */ + if (scale < 0) + throw new java.lang.ArithmeticException("Negative scale:" + " " + scale); + // [round() will raise exception if invalid round] + newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK] + res = res.round(newlen, round); // round to required length + // This could have shifted left if round (say) 0.9->1[.0] + // Repair if so by adding a zero and reducing exponent + if (res.exp != -scale) { + res.mant = extend(res.mant, res.mant.length + 1); + res.exp = res.exp - 1; + } + } + res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition + return res; + } + + /** + * Converts this BigDecimal to a short. If the BigDecimal has a non-zero + * decimal part or is out of the possible range for a short (16-bit signed integer) result then an + * ArithmeticException is thrown. + * + * @return A short equal in value to this. + * @throws ArithmeticException if this has a non-zero decimal part, or will not fit in a short. + * @stable ICU 2.0 + */ + + public short shortValueExact() { + int num; + num = this.intValueExact(); // will check decimal part too + if ((num > 32767) | (num < (-32768))) + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString()); + return (short) num; + } + + /** + * Returns the sign of this BigDecimal, as an int. This returns the signum function + * value that represents the sign of this BigDecimal. That is, -1 if the BigDecimal is + * negative, 0 if it is numerically equal to zero, or 1 if it is positive. + * + * @return An int which is -1 if the BigDecimal is negative, 0 if it is numerically equal + * to zero, or 1 if it is positive. + * @stable ICU 2.0 + */ + + public int signum() { + return (int) this.ind; // [note this assumes values for ind.] + } + + /** + * Converts this BigDecimal to a java.math.BigDecimal. + *

      + * This is an exact conversion; the result is the same as if the BigDecimal were formatted as a plain + * number without any rounding or exponent and then the java.math.BigDecimal(java.lang.String) + * constructor were used to construct the result. + *

      + * (Note: this method is provided only in the com.ibm.icu.math version of the BigDecimal class. It + * would not be present in a java.math version.) + * + * @return The java.math.BigDecimal equal in value to this BigDecimal. + * @stable ICU 2.0 + */ + + public java.math.BigDecimal toBigDecimal() { + return new java.math.BigDecimal(this.unscaledValue(), this.scale()); + } + + /** + * Converts this BigDecimal to a java.math.BigInteger. + *

      + * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use + * {@link #toBigIntegerExact()}. + * + * @return The java.math.BigInteger equal in value to the integer part of this BigDecimal. + * @stable ICU 2.0 + */ + + public java.math.BigInteger toBigInteger() { + com.ibm.icu.math.BigDecimal res = null; + int newlen = 0; + byte newmant[] = null; + {/* select */ + if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN)) + res = this; // can layout simply + else if (exp >= 0) { + res = clone(this); // safe copy + res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN + } else { + { // exp<0; scale to be truncated + // we could use divideInteger, but we may as well be quicker + if (-this.exp >= this.mant.length) + res = ZERO; // all blows away + else { + res = clone(this); // safe copy + newlen = res.mant.length + res.exp; + newmant = new byte[newlen]; // [shorter] + java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, + newlen); + res.mant = newmant; + res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; + res.exp = 0; + } + } + } + } + return new BigInteger(new java.lang.String(res.layout())); + } + + /** + * Converts this BigDecimal to a java.math.BigInteger. + *

      + * An exception is thrown if the decimal part (if any) is non-zero. + * + * @return The java.math.BigInteger equal in value to the integer part of this BigDecimal. + * @throws ArithmeticException if this has a non-zero decimal part. + * @stable ICU 2.0 + */ + + public java.math.BigInteger toBigIntegerExact() { + /* test any trailing decimal part */ + if (exp < 0) { // possible decimal part + /* all decimal places must be 0; note exp<0 */ + if ((!(allzero(mant, mant.length + exp)))) + throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString()); + } + return toBigInteger(); + } + + /** + * Returns the BigDecimal as a character array. The result of this method is the same as using the + * sequence toString().toCharArray(), but avoids creating the intermediate String and + * char[] objects. + * + * @return The char[] array corresponding to this BigDecimal. + * @stable ICU 2.0 + */ + + public char[] toCharArray() { + return layout(); + } + + /** + * Returns the BigDecimal as a String. This returns a String that exactly + * represents this BigDecimal, as defined in the decimal documentation (see {@link BigDecimal class + * header}). + *

      + * By definition, using the {@link #BigDecimal(String)} constructor on the result String will create a + * BigDecimal that is exactly equal to the original BigDecimal. + * + * @return The String exactly corresponding to this BigDecimal. + * @see #format(int, int) + * @see #format(int, int, int, int, int, int) + * @see #toCharArray() + * @stable ICU 2.0 + */ + + public java.lang.String toString() { + return new java.lang.String(layout()); + } + + /** + * Returns the number as a BigInteger after removing the scale. That is, the number is expressed as a + * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is + * then converted to a BigInteger. + * + * @return The java.math.BigInteger equal in value to this BigDecimal multiplied by ten to + * the power of this.scale(). + * @stable ICU 2.0 + */ + + public java.math.BigInteger unscaledValue() { + com.ibm.icu.math.BigDecimal res = null; + if (exp >= 0) + res = this; + else { + res = clone(this); // safe copy + res.exp = 0; // drop scale + } + return res.toBigInteger(); + } + + /** + * Translates a double to a BigDecimal. + *

      + * Returns a BigDecimal which is the decimal representation of the 64-bit signed binary floating point + * parameter. If the parameter is infinite, or is not a number (NaN), a NumberFormatException is + * thrown. + *

      + * The number is constructed as though num had been converted to a String using the + * Double.toString() method and the {@link #BigDecimal(java.lang.String)} constructor had then been used. + * This is typically not an exact conversion. + * + * @param dub The double to be translated. + * @return The BigDecimal equal in value to dub. + * @throws NumberFormatException if the parameter is infinite or not a number. + * @stable ICU 2.0 + */ + + public static com.ibm.icu.math.BigDecimal valueOf(double dub) { + // Reminder: a zero double returns '0.0', so we cannot fastpath to + // use the constant ZERO. This might be important enough to justify + // a factory approach, a cache, or a few private constants, later. + return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString()); + } + + /** + * Translates a long to a BigDecimal. That is, returns a plain BigDecimal + * whose value is equal to the given long. + * + * @param lint The long to be translated. + * @return The BigDecimal equal in value to lint. + * @stable ICU 2.0 + */ + + public static com.ibm.icu.math.BigDecimal valueOf(long lint) { + return valueOf(lint, 0); + } + + /** + * Translates a long to a BigDecimal with a given scale. That is, returns a plain + * BigDecimal whose unscaled value is equal to the given long, adjusted by the second parameter, + * scale. + *

      + * The result is given by: + *

      + * (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) + *

      + * A NumberFormatException is thrown if scale is negative. + * + * @param lint The long to be translated. + * @param scale The int scale to be applied. + * @return The BigDecimal equal in value to lint. + * @throws NumberFormatException if the scale is negative. + * @stable ICU 2.0 + */ + + public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) { + com.ibm.icu.math.BigDecimal res = null; + {/* select */ + if (lint == 0) + res = ZERO; + else if (lint == 1) + res = ONE; + else if (lint == 10) + res = TEN; + else { + res = new com.ibm.icu.math.BigDecimal(lint); + } + } + if (scale == 0) + return res; + if (scale < 0) + throw new java.lang.NumberFormatException("Negative scale:" + " " + scale); + res = clone(res); // safe copy [do not mutate] + res.exp = -scale; // exponent is -scale + return res; + } + + /* ---------------------------------------------------------------- */ + /* Private methods */ + /* ---------------------------------------------------------------- */ + + /* + * Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array). + *

      The mantissa will either already have been rounded (following an operation) or will be of length appropriate + * (in the case of construction from an int, for example).

      We must not alter the mantissa, here.

      'form' + * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure + * numeric. + */ + + private char[] layout() { + char cmant[]; + int i = 0; + StringBuilder sb = null; + int euse = 0; + int sig = 0; + char csign = 0; + char rec[] = null; + int needsign; + int mag; + int len = 0; + cmant = new char[mant.length]; // copy byte[] to a char[] + { + int $18 = mant.length; + i = 0; + for (; $18 > 0; $18--, i++) { + cmant[i] = (char) (mant[i] + ((int) ('0'))); + } + }/* i */ + + if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */ + sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999 + if (ind == isneg) + sb.append('-'); + euse = (exp + cmant.length) - 1; // exponent to use + /* setup sig=significant digits and copy to result */ + if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default] + sb.append(cmant[0]); // significant character + if (cmant.length > 1) // have decimal part + sb.append('.').append(cmant, 1, cmant.length - 1); + } else { + do { + sig = euse % 3; // common + if (sig < 0) + sig = 3 + sig; // negative exponent + euse = euse - sig; + sig++; + if (sig >= cmant.length) { // zero padding may be needed + sb.append(cmant, 0, cmant.length); + { + int $19 = sig - cmant.length; + for (; $19 > 0; $19--) { + sb.append('0'); + } + } + } else { // decimal point needed + sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig); + } + } while (false); + }/* engineering */ + if (euse != 0) { + if (euse < 0) { + csign = '-'; + euse = -euse; + } else + csign = '+'; + sb.append('E').append(csign).append(euse); + } + rec = new char[sb.length()]; + int srcEnd = sb.length(); + if (0 != srcEnd) { + sb.getChars(0, srcEnd, rec, 0); + } + return rec; + } + + /* Here for non-exponential (plain) notation */ + if (exp == 0) {/* easy */ + if (ind >= 0) + return cmant; // non-negative integer + rec = new char[cmant.length + 1]; + rec[0] = '-'; + java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, 1, cmant.length); + return rec; + } + + /* Need a '.' and/or some zeros */ + needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1 + + /* + * MAG is the position of the point in the mantissa (index of the character it follows) + */ + mag = exp + cmant.length; + + if (mag < 1) {/* 0.00xxxx form */ + len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length + rec = new char[len]; + if (needsign != 0) + rec[0] = '-'; + rec[needsign] = '0'; + rec[needsign + 1] = '.'; + { + int $20 = -mag; + i = needsign + 2; + for (; $20 > 0; $20--, i++) { // maybe none + rec[i] = '0'; + } + }/* i */ + java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, (needsign + 2) - mag, + cmant.length); + return rec; + } + + if (mag > cmant.length) {/* xxxx0000 form */ + len = needsign + mag; + rec = new char[len]; + if (needsign != 0) + rec[0] = '-'; + java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, cmant.length); + { + int $21 = mag - cmant.length; + i = needsign + cmant.length; + for (; $21 > 0; $21--, i++) { // never 0 + rec[i] = '0'; + } + }/* i */ + return rec; + } + + /* decimal point is in the middle of the mantissa */ + len = (needsign + 1) + cmant.length; + rec = new char[len]; + if (needsign != 0) + rec[0] = '-'; + java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, mag); + rec[needsign + mag] = '.'; + java.lang.System.arraycopy((java.lang.Object) cmant, mag, (java.lang.Object) rec, (needsign + mag) + 1, + cmant.length - mag); + return rec; + } + + /* + * Checks a BigDecimal argument to ensure it's a true integer in a given range.

      If OK, returns it as an + * int. + */ + // [currently only used by pow] + private int intcheck(int min, int max) { + int i; + i = this.intValueExact(); // [checks for non-0 decimal part] + // Use same message as though intValueExact failed due to size + if ((i < min) | (i > max)) + throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i); + return i; + } + + /* Carry out division operations. */ + /* + * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is + * explicit scale iff code='D' or 'I' (-1 if none). + * + * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity): + * + * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1) + * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for + * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave + * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -) + * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If + * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor + * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do + * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if + * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1 + * + * For extended commentary, see DMSRCN. + */ + + private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs, + com.ibm.icu.math.MathContext set, int scale) { + com.ibm.icu.math.BigDecimal lhs; + int reqdig; + int newexp; + com.ibm.icu.math.BigDecimal res; + int newlen; + byte var1[]; + int var1len; + byte var2[]; + int var2len; + int b2b; + int have; + int thisdigit = 0; + int i = 0; + byte v2 = 0; + int ba = 0; + int mult = 0; + int start = 0; + int padding = 0; + int d = 0; + byte newvar1[] = null; + byte lasthave = 0; + int actdig = 0; + byte newmant[] = null; + + if (set.lostDigits) + checkdigits(rhs, set.digits); + lhs = this; // name for clarity + + // [note we must have checked lostDigits before the following checks] + if (rhs.ind == 0) + throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0 + if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s] + if (set.form != com.ibm.icu.math.MathContext.PLAIN) + return ZERO; + if (scale == (-1)) + return lhs; + return lhs.setScale(scale); + } + + /* Prepare numbers according to BigDecimal rules */ + reqdig = set.digits; // local copy (heavily used) + if (reqdig > 0) { + if (lhs.mant.length > reqdig) + lhs = clone(lhs).round(set); + if (rhs.mant.length > reqdig) + rhs = clone(rhs).round(set); + } else {/* scaled divide */ + if (scale == (-1)) + scale = lhs.scale(); + // set reqdig to be at least large enough for the computation + reqdig = lhs.mant.length; // base length + // next line handles both positive lhs.exp and also scale mismatch + if (scale != -lhs.exp) + reqdig = (reqdig + scale) + lhs.exp; + reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect + if (reqdig < lhs.mant.length) + reqdig = lhs.mant.length; // clamp + if (reqdig < rhs.mant.length) + reqdig = rhs.mant.length; // .. + } + + /* precalculate exponent */ + newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length; + /* If new exponent -ve, then some quick exits are possible */ + if (newexp < 0) + if (code != 'D') { + if (code == 'I') + return ZERO; // easy - no integer part + /* Must be 'R'; remainder is [finished clone of] input value */ + return clone(lhs).finish(set, false); + } + + /* We need slow division */ + res = new com.ibm.icu.math.BigDecimal(); // where we'll build result + res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I) + res.exp = newexp; // initial exponent (for D/I) + res.mant = new byte[reqdig + 1]; // where build the result + + /* Now [virtually pad the mantissae with trailing zeros */ + // Also copy the LHS, which will be our working array + newlen = (reqdig + reqdig) + 1; + var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array + var1len = newlen; // [remaining digits are 0] + + var2 = rhs.mant; + var2len = newlen; + + /* Calculate first two digits of rhs (var2), +1 for later estimations */ + b2b = (var2[0] * 10) + 1; + if (var2.length > 1) + b2b = b2b + var2[1]; + + /* start the long-division loops */ + have = 0; + { + outer: for (;;) { + thisdigit = 0; + /* find the next digit */ + { + inner: for (;;) { + if (var1len < var2len) + break inner; // V1 too low + if (var1len == var2len) { // compare needed + { + compare: do { // comparison + { + int $22 = var1len; + i = 0; + for (; $22 > 0; $22--, i++) { + // var1len is always <= var1.length + if (i < var2.length) + v2 = var2[i]; + else + v2 = (byte) 0; + if (var1[i] < v2) + break inner; // V1 too low + if (var1[i] > v2) + break compare; // OK to subtract + } + }/* i */ + /* + * reach here if lhs and rhs are identical; subtraction will increase digit by one, + * and the residue will be 0 so we are done; leave the loop with residue set to 0 + * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked) + */ + thisdigit++; + res.mant[have] = (byte) thisdigit; + have++; + var1[0] = (byte) 0; // residue to 0 [this is all we'll test] + // var1len=1 -- [optimized out] + break outer; + } while (false); + }/* compare */ + /* prepare for subtraction. Estimate BA (lengths the same) */ + ba = (int) var1[0]; // use only first digit + } // lengths the same + else {/* lhs longer than rhs */ + /* use first two digits for estimate */ + ba = var1[0] * 10; + if (var1len > 1) + ba = ba + var1[1]; + } + /* subtraction needed; V1>=V2 */ + mult = (ba * 10) / b2b; + if (mult == 0) + mult = 1; + thisdigit = thisdigit + mult; + // subtract; var1 reusable + var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true); + if (var1[0] != 0) + continue inner; // maybe another subtract needed + /* + * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than + * V2) + */ + { + int $23 = var1len - 2; + start = 0; + start: for (; start <= $23; start++) { + if (var1[start] != 0) + break start; + var1len--; + } + }/* start */ + if (start == 0) + continue inner; + // shift left + java.lang.System.arraycopy((java.lang.Object) var1, start, (java.lang.Object) var1, 0, var1len); + } + }/* inner */ + + /* We have the next digit */ + if ((have != 0) | (thisdigit != 0)) { // put the digit we got + res.mant[have] = (byte) thisdigit; + have++; + if (have == (reqdig + 1)) + break outer; // we have all we need + if (var1[0] == 0) + break outer; // residue now 0 + } + /* can leave now if a scaled divide and exponent is small enough */ + if (scale >= 0) + if (-res.exp > scale) + break outer; + /* can leave now if not Divide and no integer part left */ + if (code != 'D') + if (res.exp <= 0) + break outer; + res.exp = res.exp - 1; // reduce the exponent + /* + * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit + */ + var2len--; + } + }/* outer */ + + /* here when we have finished dividing, for some reason */ + // have is the number of digits we collected in res.mant + if (have == 0) + have = 1; // res.mant[0] is 0; we always want a digit + + if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */ + if ((have + res.exp) > reqdig) + throw new java.lang.ArithmeticException("Integer overflow"); + + if (code == 'R') { + do { + /* We were doing Remainder -- return the residue */ + if (res.mant[0] == 0) // no integer part was found + return clone(lhs).finish(set, false); // .. so return lhs, canonical + if (var1[0] == 0) + return ZERO; // simple 0 residue + res.ind = lhs.ind; // sign is always as LHS + /* + * Calculate the exponent by subtracting the number of padding zeros we added and adding the + * original exponent + */ + padding = ((reqdig + reqdig) + 1) - lhs.mant.length; + res.exp = (res.exp - padding) + lhs.exp; + + /* + * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be + */ + d = var1len; + { + i = d - 1; + i: for (; i >= 1; i--) { + if (!((res.exp < lhs.exp) & (res.exp < rhs.exp))) + break; + if (var1[i] != 0) + break i; + d--; + res.exp = res.exp + 1; + } + }/* i */ + if (d < var1.length) {/* need to reduce */ + newvar1 = new byte[d]; + java.lang.System.arraycopy((java.lang.Object) var1, 0, (java.lang.Object) newvar1, 0, d); // shorten + var1 = newvar1; + } + res.mant = var1; + return res.finish(set, false); + } while (false); + }/* remainder */ + } + + else {/* 'D' -- no overflow check needed */ + // If there was a residue then bump the final digit (iff 0 or 5) + // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and + // ROUND_UNNECESSARY checks (etc.) later. + // [if we finished early, the residue will be 0] + if (var1[0] != 0) { // residue not 0 + lasthave = res.mant[have - 1]; + if (((lasthave % 5)) == 0) + res.mant[have - 1] = (byte) (lasthave + 1); + } + } + + /* Here for Divide or Integer Divide */ + // handle scaled results first ['I' always scale 0, optional for 'D'] + if (scale >= 0) { + do { + // say 'scale have res.exp len' scale have res.exp res.mant.length + if (have != res.mant.length) + // already padded with 0's, so just adjust exponent + res.exp = res.exp - ((res.mant.length - have)); + // calculate number of digits we really want [may be 0] + actdig = res.mant.length - (-res.exp - scale); + res.round(actdig, set.roundingMode); // round to desired length + // This could have shifted left if round (say) 0.9->1[.0] + // Repair if so by adding a zero and reducing exponent + if (res.exp != -scale) { + res.mant = extend(res.mant, res.mant.length + 1); + res.exp = res.exp - 1; + } + return res.finish(set, true); // [strip if not PLAIN] + } while (false); + }/* scaled */ + + // reach here only if a non-scaled + if (have == res.mant.length) { // got digits+1 digits + res.round(set); + have = reqdig; + } else {/* have<=reqdig */ + if (res.mant[0] == 0) + return ZERO; // fastpath + // make the mantissa truly just 'have' long + // [we could let finish do this, during strip, if we adjusted + // the exponent; however, truncation avoids the strip loop] + newmant = new byte[have]; // shorten + java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, have); + res.mant = newmant; + } + return res.finish(set, true); + } + + /* Report a conversion exception. */ + + private void bad(char s[]) { + throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s)); + } + + /* + * Report a bad argument to a method. Arg1 is method name Arg2 is argument position Arg3 is what was + * found + */ + + private void badarg(java.lang.String name, int pos, java.lang.String value) { + throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " " + + value); + } + + /* + * Extend byte array to given length, padding with 0s. If no extension is required then return the same + * array. + * + * Arg1 is the source byte array Arg2 is the new length (longer) + */ + + private static final byte[] extend(byte inarr[], int newlen) { + byte newarr[]; + if (inarr.length == newlen) + return inarr; + newarr = new byte[newlen]; + java.lang.System.arraycopy((java.lang.Object) inarr, 0, (java.lang.Object) newarr, 0, inarr.length); + // 0 padding is carried out by the JVM on allocation initialization + return newarr; + } + + /* + * Add or subtract two >=0 integers in byte arrays

      This routine performs the calculation:

       C=A+(BM)
      +     * 
      Where M is in the range -9 through +9

      If M<0 then A>=B must be true, so the result is always + * non-negative. + * + * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B, + * or 1 longer than that (if a carry occurred). + * + * A is not altered unless Arg6 is 1. B is never altered. + * + * Arg1 is A Arg2 is A length to use (if longer than A, pad with 0's) Arg3 is B Arg4 is B length to use (if longer + * than B, pad with 0's) Arg5 is M, the multiplier Arg6 is 1 if A can be used to build the result (if it fits) + * + * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance + * degradation. + */ + // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981) + // 1997.10.05 -- changed to byte arrays (from char arrays) + // 1998.07.01 -- changed to allow destructive reuse of LHS + // 1998.07.01 -- changed to allow virtual lengths for the arrays + // 1998.12.29 -- use lookaside for digit/carry calculation + // 1999.08.07 -- avoid multiply when mult=1, and make db an int + // 1999.12.22 -- special case m=-1, also drop 0 special case + private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) { + int alength; + int blength; + int ap; + int bp; + int maxarr; + byte reb[]; + boolean quickm; + int digit; + int op = 0; + int dp90 = 0; + byte newarr[]; + int i = 0; + + // We'll usually be right if we assume no carry + alength = a.length; // physical lengths + blength = b.length; // .. + ap = avlen - 1; // -> final (rightmost) digit + bp = bvlen - 1; // .. + maxarr = bp; + if (maxarr < ap) + maxarr = ap; + reb = (byte[]) null; // result byte array + if (reuse) + if ((maxarr + 1) == alength) + reb = a; // OK to reuse A + if (reb == null) + reb = new byte[maxarr + 1]; // need new array + + quickm = false; // 1 if no multiply needed + if (m == 1) + quickm = true; // most common + else if (m == (-1)) + quickm = true; // also common + + digit = 0; // digit, with carry or borrow + { + op = maxarr; + op: for (; op >= 0; op--) { + if (ap >= 0) { + if (ap < alength) + digit = digit + a[ap]; // within A + ap--; + } + if (bp >= 0) { + if (bp < blength) { // within B + if (quickm) { + if (m > 0) + digit = digit + b[bp]; // most common + else + digit = digit - b[bp]; // also common + } else + digit = digit + (b[bp] * m); + } + bp--; + } + /* result so far (digit) could be -90 through 99 */ + if (digit < 10) + if (digit >= 0) { + do { // 0-9 + reb[op] = (byte) digit; + digit = 0; // no carry + continue op; + } while (false); + }/* quick */ + dp90 = digit + 90; + reb[op] = bytedig[dp90]; // this digit + digit = bytecar[dp90]; // carry or borrow + } + }/* op */ + + if (digit == 0) + return reb; // no carry + // following line will become an Assert, later + // if digit<0 then signal ArithmeticException("internal.error ["digit"]") + + /* We have carry -- need to make space for the extra digit */ + newarr = (byte[]) null; + if (reuse) + if ((maxarr + 2) == a.length) + newarr = a; // OK to reuse A + if (newarr == null) + newarr = new byte[maxarr + 2]; + newarr[0] = (byte) digit; // the carried digit .. + // .. and all the rest [use local loop for short numbers] + if (maxarr < 10) { + int $24 = maxarr + 1; + i = 0; + for (; $24 > 0; $24--, i++) { + newarr[i + 1] = reb[i]; + } + }/* i */ + else + java.lang.System.arraycopy((java.lang.Object) reb, 0, (java.lang.Object) newarr, 1, maxarr + 1); + return newarr; + } + + /* + * Initializer for digit array properties (lookaside). Returns the digit array, and initializes the + * carry array. + */ + + private static final byte[] diginit() { + byte work[]; + int op = 0; + int digit = 0; + work = new byte[(90 + 99) + 1]; + { + op = 0; + op: for (; op <= (90 + 99); op++) { + digit = op - 90; + if (digit >= 0) { + work[op] = (byte) (digit % 10); + bytecar[op] = (byte) (digit / 10); // calculate carry + continue op; + } + // borrowing... + digit = digit + 100; // yes, this is right [consider -50] + work[op] = (byte) (digit % 10); + bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %] + } + }/* op */ + return work; + } + + /* + * Create a copy of BigDecimal object for local use.

      This does NOT make a copy of the mantissa array. + * Arg1 is the BigDecimal to clone (non-null) + */ + + private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) { + com.ibm.icu.math.BigDecimal copy; + copy = new com.ibm.icu.math.BigDecimal(); + copy.ind = dec.ind; + copy.exp = dec.exp; + copy.form = dec.form; + copy.mant = dec.mant; + return copy; + } + + /* + * Check one or two numbers for lost digits. Arg1 is RHS (or null, if none) Arg2 is current DIGITS + * setting returns quietly or throws an exception + */ + + private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) { + if (dig == 0) + return; // don't check if digits=0 + // first check lhs... + if (this.mant.length > dig) + if ((!(allzero(this.mant, dig)))) + throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString()); + if (rhs == null) + return; // monadic + if (rhs.mant.length > dig) + if ((!(allzero(rhs.mant, dig)))) + throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString()); + } + + /* + * Round to specified digits, if necessary. Arg1 is requested MathContext [with length and rounding + * mode] returns this, for convenience + */ + + private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) { + return round(set.digits, set.roundingMode); + } + + /* + * Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when + * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience + * + * ind and exp are adjusted, but not cleared for a mantissa of zero + * + * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa + * length will be 1. + */ + + private com.ibm.icu.math.BigDecimal round(int len, int mode) { + int adjust; + int sign; + byte oldmant[]; + boolean reuse = false; + byte first = 0; + int increment; + byte newmant[] = null; + adjust = mant.length - len; + if (adjust <= 0) + return this; // nowt to do + + exp = exp + adjust; // exponent of result + sign = (int) ind; // save [assumes -1, 0, 1] + oldmant = mant; // save + if (len > 0) { + // remove the unwanted digits + mant = new byte[len]; + java.lang.System.arraycopy((java.lang.Object) oldmant, 0, (java.lang.Object) mant, 0, len); + reuse = true; // can reuse mantissa + first = oldmant[len]; // first of discarded digits + } else {/* len<=0 */ + mant = ZERO.mant; + ind = iszero; + reuse = false; // cannot reuse mantissa + if (len == 0) + first = oldmant[0]; + else + first = (byte) 0; // [virtual digit] + } + + // decide rounding adjustment depending on mode, sign, and discarded digits + increment = 0; // bumper + { + do {/* select */ + if (mode == ROUND_HALF_UP) { // default first [most common] + if (first >= 5) + increment = sign; + } else if (mode == ROUND_UNNECESSARY) { // default for setScale() + // discarding any non-zero digits is an error + if ((!(allzero(oldmant, len)))) + throw new java.lang.ArithmeticException("Rounding necessary"); + } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down + if (first > 5) + increment = sign; + else if (first == 5) + if ((!(allzero(oldmant, len + 1)))) + increment = sign; + } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even + if (first > 5) + increment = sign; + else if (first == 5) { + if ((!(allzero(oldmant, len + 1)))) + increment = sign; + else /* 0.5000 */ + if ((((mant[mant.length - 1]) % 2)) == 1) + increment = sign; + } + } else if (mode == ROUND_DOWN) { + // never increment + } else if (mode == ROUND_UP) { // increment if discarded non-zero + if ((!(allzero(oldmant, len)))) + increment = sign; + } else if (mode == ROUND_CEILING) { // more positive + if (sign > 0) + if ((!(allzero(oldmant, len)))) + increment = sign; + } else if (mode == ROUND_FLOOR) { // more negative + if (sign < 0) + if ((!(allzero(oldmant, len)))) + increment = sign; + } else { + throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode); + } + } while (false); + }/* modes */ + + if (increment != 0) { + do { + if (ind == iszero) { + // we must not subtract from 0, but result is trivial anyway + mant = ONE.mant; + ind = (byte) increment; + } else { + // mantissa is non-0; we can safely add or subtract 1 + if (ind == isneg) + increment = -increment; + newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse); + if (newmant.length > mant.length) { // had a carry + // drop rightmost digit and raise exponent + exp++; + // mant is already the correct length + java.lang.System.arraycopy((java.lang.Object) newmant, 0, (java.lang.Object) mant, 0, + mant.length); + } else + mant = newmant; + } + } while (false); + }/* bump */ + // rounding can increase exponent significantly + if (exp > MaxExp) + throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); + return this; + } + + /* + * Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to + * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0 + * + * Arg2 may be beyond array bounds, in which case 1 is returned + */ + + private static final boolean allzero(byte array[], int start) { + int i = 0; + if (start < 0) + start = 0; + { + int $25 = array.length - 1; + i = start; + for (; i <= $25; i++) { + if (array[i] != 0) + return false; + } + }/* i */ + return true; + } + + /* + * Carry out final checks and canonicalization

      This finishes off the current number by: 1. Rounding if + * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping + * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0' + * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. Arg1 is requested + * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed + * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience + */ + + private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) { + int d = 0; + int i = 0; + byte newmant[] = null; + int mag = 0; + int sig = 0; + /* Round if mantissa too long and digits requested */ + if (set.digits != 0) + if (this.mant.length > set.digits) + this.round(set); + + /* + * If strip requested (and standard formatting), remove insignificant trailing zeros. + */ + if (strip) + if (set.form != com.ibm.icu.math.MathContext.PLAIN) { + d = this.mant.length; + /* see if we need to drop any trailing zeros */ + { + i = d - 1; + i: for (; i >= 1; i--) { + if (this.mant[i] != 0) + break i; + d--; + exp++; + } + }/* i */ + if (d < this.mant.length) {/* need to reduce */ + newmant = new byte[d]; + java.lang.System.arraycopy((java.lang.Object) this.mant, 0, (java.lang.Object) newmant, 0, d); + this.mant = newmant; + } + } + + form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset + + /* Now check for leading- and all- zeros in mantissa */ + { + int $26 = this.mant.length; + i = 0; + for (; $26 > 0; $26--, i++) { + if (this.mant[i] != 0) { + // non-0 result; ind will be correct + // remove leading zeros [e.g., after subtract] + if (i > 0) { + do { + newmant = new byte[this.mant.length - i]; + java.lang.System.arraycopy((java.lang.Object) this.mant, i, (java.lang.Object) newmant, 0, + this.mant.length - i); + this.mant = newmant; + } while (false); + }/* delead */ + // now determine form if not PLAIN + mag = exp + mant.length; + if (mag > 0) { // most common path + if (mag > set.digits) + if (set.digits != 0) + form = (byte) set.form; + if ((mag - 1) <= MaxExp) + return this; // no overflow; quick return + } else if (mag < (-5)) + form = (byte) set.form; + /* check for overflow */ + mag--; + if ((mag < MinExp) | (mag > MaxExp)) { + overflow: do { + // possible reprieve if form is engineering + if (form == com.ibm.icu.math.MathContext.ENGINEERING) { + sig = mag % 3; // leftover + if (sig < 0) + sig = 3 + sig; // negative exponent + mag = mag - sig; // exponent to use + // 1999.06.29: second test here must be MaxExp + if (mag >= MinExp) + if (mag <= MaxExp) + break overflow; + } + throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag); + } while (false); + }/* overflow */ + return this; + } + } + }/* i */ + + // Drop through to here only if mantissa is all zeros + ind = iszero; + {/* select */ + if (set.form != com.ibm.icu.math.MathContext.PLAIN) + exp = 0; // standard result; go to '0' + else if (exp > 0) + exp = 0; // +ve exponent also goes to '0' + else { + // a plain number with -ve exponent; preserve and check exponent + if (exp < MinExp) + throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp); + } + } + mant = ZERO.mant; // canonical mantissa + return this; + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java index f7d2032c7c0..010c083596b 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java @@ -1,601 +1,601 @@ -/* Generated from 'MathContext.nrx' 8 Sep 2000 11:07:48 [v2.00] */ -/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */ -package com.ibm.icu.math; - -/* ------------------------------------------------------------------ */ -/* MathContext -- Math context settings */ -/* ------------------------------------------------------------------ */ -/* Copyright IBM Corporation, 1997-2011. All Rights Reserved. */ -/* */ -/* The MathContext object encapsulates the settings used by the */ -/* BigDecimal class; it could also be used by other arithmetics. */ -/* ------------------------------------------------------------------ */ -/* Notes: */ -/* */ -/* 1. The properties are checked for validity on construction, so */ -/* the BigDecimal class may assume that they are correct. */ -/* ------------------------------------------------------------------ */ -/* Author: Mike Cowlishaw */ -/* 1997.09.03 Initial version (edited from netrexx.lang.RexxSet) */ -/* 1997.09.12 Add lostDigits property */ -/* 1998.05.02 Make the class immutable and final; drop set methods */ -/* 1998.06.05 Add Round (rounding modes) property */ -/* 1998.06.25 Rename from DecimalContext; allow digits=0 */ -/* 1998.10.12 change to com.ibm.icu.math package */ -/* 1999.02.06 add javadoc comments */ -/* 1999.03.05 simplify; changes from discussion with J. Bloch */ -/* 1999.03.13 1.00 release to IBM Centre for Java Technology */ -/* 1999.07.10 1.04 flag serialization unused */ -/* 2000.01.01 1.06 copyright update */ -/* ------------------------------------------------------------------ */ - - - - -/** - * The MathContext immutable class encapsulates the - * settings understood by the operator methods of the {@link BigDecimal} - * class (and potentially other classes). Operator methods are those - * that effect an operation on a number or a pair of numbers. - *

      - * The settings, which are not base-dependent, comprise: - *

        - *
      1. digits: - * the number of digits (precision) to be used for an operation - *
      2. form: - * the form of any exponent that results from the operation - *
      3. lostDigits: - * whether checking for lost digits is enabled - *
      4. roundingMode: - * the algorithm to be used for rounding. - *
      - *

      - * When provided, a MathContext object supplies the - * settings for an operation directly. - *

      - * When MathContext.DEFAULT is provided for a - * MathContext parameter then the default settings are used - * (9, SCIENTIFIC, false, ROUND_HALF_UP). - *

      - * In the BigDecimal class, all methods which accept a - * MathContext object defaults) also have a version of the - * method which does not accept a MathContext parameter. These versions - * carry out unlimited precision fixed point arithmetic (as though the - * settings were (0, PLAIN, false, ROUND_HALF_UP). - *

      - * The instance variables are shared with default access (so they are - * directly accessible to the BigDecimal class), but must - * never be changed. - *

      - * The rounding mode constants have the same names and values as the - * constants of the same name in java.math.BigDecimal, to - * maintain compatibility with earlier versions of - * BigDecimal. - * - * @see BigDecimal - * @author Mike Cowlishaw - * @stable ICU 2.0 - */ - -public final class MathContext implements java.io.Serializable{ - //private static final java.lang.String $0="MathContext.nrx"; - - /* ----- Properties ----- */ - /* properties public constant */ - /** - * Plain (fixed point) notation, without any exponent. - * Used as a setting to control the form of the result of a - * BigDecimal operation. - * A zero result in plain form may have a decimal part of one or - * more zeros. - * - * @see #ENGINEERING - * @see #SCIENTIFIC - * @stable ICU 2.0 - */ - public static final int PLAIN=0; // [no exponent] - - /** - * Standard floating point notation (with scientific exponential - * format, where there is one digit before any decimal point). - * Used as a setting to control the form of the result of a - * BigDecimal operation. - * A zero result in plain form may have a decimal part of one or - * more zeros. - * - * @see #ENGINEERING - * @see #PLAIN - * @stable ICU 2.0 - */ - public static final int SCIENTIFIC=1; // 1 digit before . - - /** - * Standard floating point notation (with engineering exponential - * format, where the power of ten is a multiple of 3). - * Used as a setting to control the form of the result of a - * BigDecimal operation. - * A zero result in plain form may have a decimal part of one or - * more zeros. - * - * @see #PLAIN - * @see #SCIENTIFIC - * @stable ICU 2.0 - */ - public static final int ENGINEERING=2; // 1-3 digits before . - - // The rounding modes match the original BigDecimal class values - /** - * Rounding mode to round to a more positive number. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If any of the discarded digits are non-zero then the result - * should be rounded towards the next more positive digit. - * @stable ICU 2.0 - */ - public static final int ROUND_CEILING=2; - - /** - * Rounding mode to round towards zero. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * All discarded digits are ignored (truncated). The result is - * neither incremented nor decremented. - * @stable ICU 2.0 - */ - public static final int ROUND_DOWN=1; - - /** - * Rounding mode to round to a more negative number. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If any of the discarded digits are non-zero then the result - * should be rounded towards the next more negative digit. - * @stable ICU 2.0 - */ - public static final int ROUND_FLOOR=3; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant - * value is rounded down. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If the discarded digits represent greater than half (0.5 times) - * the value of a one in the next position then the result should be - * rounded up (away from zero). Otherwise the discarded digits are - * ignored. - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_DOWN=5; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant - * value is rounded to the nearest even neighbor. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If the discarded digits represent greater than half (0.5 times) - * the value of a one in the next position then the result should be - * rounded up (away from zero). If they represent less than half, - * then the result should be rounded down. - *

      - * Otherwise (they represent exactly half) the result is rounded - * down if its rightmost digit is even, or rounded up if its - * rightmost digit is odd (to make an even digit). - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_EVEN=6; - - /** - * Rounding mode to round to nearest neighbor, where an equidistant - * value is rounded up. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If the discarded digits represent greater than or equal to half - * (0.5 times) the value of a one in the next position then the result - * should be rounded up (away from zero). Otherwise the discarded - * digits are ignored. - * @stable ICU 2.0 - */ - public static final int ROUND_HALF_UP=4; - - /** - * Rounding mode to assert that no rounding is necessary. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * Rounding (potential loss of information) is not permitted. - * If any of the discarded digits are non-zero then an - * ArithmeticException should be thrown. - * @stable ICU 2.0 - */ - public static final int ROUND_UNNECESSARY=7; - - /** - * Rounding mode to round away from zero. - * Used as a setting to control the rounding mode used during a - * BigDecimal operation. - *

      - * If any of the discarded digits are non-zero then the result will - * be rounded up (away from zero). - * @stable ICU 2.0 - */ - public static final int ROUND_UP=0; - - - /* properties shared */ - /** - * The number of digits (precision) to be used for an operation. - * A value of 0 indicates that unlimited precision (as many digits - * as are required) will be used. - *

      - * The {@link BigDecimal} operator methods use this value to - * determine the precision of results. - * Note that leading zeros (in the integer part of a number) are - * never significant. - *

      - * digits will always be non-negative. - * - * @serial - */ - int digits; - - /** - * The form of results from an operation. - *

      - * The {@link BigDecimal} operator methods use this value to - * determine the form of results, in particular whether and how - * exponential notation should be used. - * - * @see #ENGINEERING - * @see #PLAIN - * @see #SCIENTIFIC - * @serial - */ - int form; // values for this must fit in a byte - - /** - * Controls whether lost digits checking is enabled for an - * operation. - * Set to true to enable checking, or - * to false to disable checking. - *

      - * When enabled, the {@link BigDecimal} operator methods check - * the precision of their operand or operands, and throw an - * ArithmeticException if an operand is more precise - * than the digits setting (that is, digits would be lost). - * When disabled, operands are rounded to the specified digits. - * - * @serial - */ - boolean lostDigits; - - /** - * The rounding algorithm to be used for an operation. - *

      - * The {@link BigDecimal} operator methods use this value to - * determine the algorithm to be used when non-zero digits have to - * be discarded in order to reduce the precision of a result. - * The value must be one of the public constants whose name starts - * with ROUND_. - * - * @see #ROUND_CEILING - * @see #ROUND_DOWN - * @see #ROUND_FLOOR - * @see #ROUND_HALF_DOWN - * @see #ROUND_HALF_EVEN - * @see #ROUND_HALF_UP - * @see #ROUND_UNNECESSARY - * @see #ROUND_UP - * @serial - */ - int roundingMode; - - /* properties private constant */ - // default settings - private static final int DEFAULT_FORM=SCIENTIFIC; - private static final int DEFAULT_DIGITS=9; - private static final boolean DEFAULT_LOSTDIGITS=false; - private static final int DEFAULT_ROUNDINGMODE=ROUND_HALF_UP; - - /* properties private constant */ - - private static final int MIN_DIGITS=0; // smallest value for DIGITS. - private static final int MAX_DIGITS=999999999; // largest value for DIGITS. If increased, - // the BigDecimal class may need update. - // list of valid rounding mode values, most common two first - private static final int ROUNDS[]=new int[]{ROUND_HALF_UP,ROUND_UNNECESSARY,ROUND_CEILING,ROUND_DOWN,ROUND_FLOOR,ROUND_HALF_DOWN,ROUND_HALF_EVEN,ROUND_UP}; - - - private static final java.lang.String ROUNDWORDS[]=new java.lang.String[]{"ROUND_HALF_UP","ROUND_UNNECESSARY","ROUND_CEILING","ROUND_DOWN","ROUND_FLOOR","ROUND_HALF_DOWN","ROUND_HALF_EVEN","ROUND_UP"}; // matching names of the ROUNDS values - - - - - /* properties private constant unused */ - - // Serialization version - private static final long serialVersionUID=7163376998892515376L; - - /* properties public constant */ - /** - * A MathContext object initialized to the default - * settings for general-purpose arithmetic. That is, - * digits=9 form=SCIENTIFIC lostDigits=false - * roundingMode=ROUND_HALF_UP. - * - * @see #SCIENTIFIC - * @see #ROUND_HALF_UP - * @stable ICU 2.0 - */ - public static final com.ibm.icu.math.MathContext DEFAULT=new com.ibm.icu.math.MathContext(DEFAULT_DIGITS,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); - - - - - /* ----- Constructors ----- */ - - /** - * Constructs a new MathContext with a specified - * precision. - * The other settings are set to the default values - * (see {@link #DEFAULT}). - * - * An IllegalArgumentException is thrown if the - * setdigits parameter is out of range - * (<0 or >999999999). - * - * @param setdigits The int digits setting - * for this MathContext. - * @throws IllegalArgumentException parameter out of range. - * @stable ICU 2.0 - */ - - public MathContext(int setdigits){ - this(setdigits,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); - return;} - - - /** - * Constructs a new MathContext with a specified - * precision and form. - * The other settings are set to the default values - * (see {@link #DEFAULT}). - * - * An IllegalArgumentException is thrown if the - * setdigits parameter is out of range - * (<0 or >999999999), or if the value given for the - * setform parameter is not one of the appropriate - * constants. - * - * @param setdigits The int digits setting - * for this MathContext. - * @param setform The int form setting - * for this MathContext. - * @throws IllegalArgumentException parameter out of range. - * @stable ICU 2.0 - */ - - public MathContext(int setdigits,int setform){ - this(setdigits,setform,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); - return;} - - /** - * Constructs a new MathContext with a specified - * precision, form, and lostDigits setting. - * The roundingMode setting is set to its default value - * (see {@link #DEFAULT}). - * - * An IllegalArgumentException is thrown if the - * setdigits parameter is out of range - * (<0 or >999999999), or if the value given for the - * setform parameter is not one of the appropriate - * constants. - * - * @param setdigits The int digits setting - * for this MathContext. - * @param setform The int form setting - * for this MathContext. - * @param setlostdigits The boolean lostDigits - * setting for this MathContext. - * @throws IllegalArgumentException parameter out of range. - * @stable ICU 2.0 - */ - - public MathContext(int setdigits,int setform,boolean setlostdigits){ - this(setdigits,setform,setlostdigits,DEFAULT_ROUNDINGMODE); - return;} - - /** - * Constructs a new MathContext with a specified - * precision, form, lostDigits, and roundingMode setting. - * - * An IllegalArgumentException is thrown if the - * setdigits parameter is out of range - * (<0 or >999999999), or if the value given for the - * setform or setroundingmode parameters is - * not one of the appropriate constants. - * - * @param setdigits The int digits setting - * for this MathContext. - * @param setform The int form setting - * for this MathContext. - * @param setlostdigits The boolean lostDigits - * setting for this MathContext. - * @param setroundingmode The int roundingMode setting - * for this MathContext. - * @throws IllegalArgumentException parameter out of range. - * @stable ICU 2.0 - */ - - public MathContext(int setdigits,int setform,boolean setlostdigits,int setroundingmode){super(); - - - // set values, after checking - if (setdigits!=DEFAULT_DIGITS) - { - if (setdigitsMAX_DIGITS) - throw new java.lang.IllegalArgumentException("Digits too large:"+" "+setdigits); - } - {/*select*/ - if (setform==SCIENTIFIC){ - // [most common] - }else if (setform==ENGINEERING){ - }else if (setform==PLAIN){ - }else{ - throw new java.lang.IllegalArgumentException("Bad form value:"+" "+setform); - } - } - if ((!(isValidRound(setroundingmode)))) - throw new java.lang.IllegalArgumentException("Bad roundingMode value:"+" "+setroundingmode); - digits=setdigits; - form=setform; - lostDigits=setlostdigits; // [no bad value possible] - roundingMode=setroundingmode; - return;} - - /** - * Returns the digits setting. - * This value is always non-negative. - * - * @return an int which is the value of the digits - * setting - * @stable ICU 2.0 - */ - - public int getDigits(){ - return digits; - } - - /** - * Returns the form setting. - * This will be one of - * {@link #ENGINEERING}, - * {@link #PLAIN}, or - * {@link #SCIENTIFIC}. - * - * @return an int which is the value of the form setting - * @stable ICU 2.0 - */ - - public int getForm(){ - return form; - } - - /** - * Returns the lostDigits setting. - * This will be either true (enabled) or - * false (disabled). - * - * @return a boolean which is the value of the lostDigits - * setting - * @stable ICU 2.0 - */ - - public boolean getLostDigits(){ - return lostDigits; - } - - /** - * Returns the roundingMode setting. - * This will be one of - * {@link #ROUND_CEILING}, - * {@link #ROUND_DOWN}, - * {@link #ROUND_FLOOR}, - * {@link #ROUND_HALF_DOWN}, - * {@link #ROUND_HALF_EVEN}, - * {@link #ROUND_HALF_UP}, - * {@link #ROUND_UNNECESSARY}, or - * {@link #ROUND_UP}. - * - * @return an int which is the value of the roundingMode - * setting - * @stable ICU 2.0 - */ - - public int getRoundingMode(){ - return roundingMode; - } - - /** Returns the MathContext as a readable string. - * The String returned represents the settings of the - * MathContext object as four blank-delimited words - * separated by a single blank and with no leading or trailing blanks, - * as follows: - *

        - *
      1. - * digits=, immediately followed by - * the value of the digits setting as a numeric word. - *
      2. - * form=, immediately followed by - * the value of the form setting as an uppercase word - * (one of SCIENTIFIC, PLAIN, or - * ENGINEERING). - *
      3. - * lostDigits=, immediately followed by - * the value of the lostDigits setting - * (1 if enabled, 0 if disabled). - *
      4. - * roundingMode=, immediately followed by - * the value of the roundingMode setting as a word. - * This word will be the same as the name of the corresponding public - * constant. - *
      - *

      - * For example: - *
      - * digits=9 form=SCIENTIFIC lostDigits=0 roundingMode=ROUND_HALF_UP - * - *

      - * Additional words may be appended to the result of - * toString in the future if more properties are added - * to the class. - * - * @return a String representing the context settings. - * @stable ICU 2.0 - */ - - public java.lang.String toString(){ - java.lang.String formstr=null; - int r=0; - java.lang.String roundword=null; - {/*select*/ - if (form==SCIENTIFIC) - formstr="SCIENTIFIC"; - else if (form==ENGINEERING) - formstr="ENGINEERING"; - else{ - formstr="PLAIN";/* form=PLAIN */ - } - } - {int $1=ROUNDS.length;r=0;r:for(;$1>0;$1--,r++){ - if (roundingMode==ROUNDS[r]) - { - roundword=ROUNDWORDS[r]; - break r; - } - } - }/*r*/ - return "digits="+digits+" "+"form="+formstr+" "+"lostDigits="+(lostDigits?"1":"0")+" "+"roundingMode="+roundword; - } - - - /* Test whether round is valid. */ - // This could be made shared for use by BigDecimal for setScale. - - private static boolean isValidRound(int testround){ - int r=0; - {int $2=ROUNDS.length;for(r=0;$2>0;$2--,r++){ - if (testround==ROUNDS[r]) - return true; - } - }/*r*/ - return false; - } - } +/* Generated from 'MathContext.nrx' 8 Sep 2000 11:07:48 [v2.00] */ +/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */ +package com.ibm.icu.math; + +/* ------------------------------------------------------------------ */ +/* MathContext -- Math context settings */ +/* ------------------------------------------------------------------ */ +/* Copyright IBM Corporation, 1997-2011. All Rights Reserved. */ +/* */ +/* The MathContext object encapsulates the settings used by the */ +/* BigDecimal class; it could also be used by other arithmetics. */ +/* ------------------------------------------------------------------ */ +/* Notes: */ +/* */ +/* 1. The properties are checked for validity on construction, so */ +/* the BigDecimal class may assume that they are correct. */ +/* ------------------------------------------------------------------ */ +/* Author: Mike Cowlishaw */ +/* 1997.09.03 Initial version (edited from netrexx.lang.RexxSet) */ +/* 1997.09.12 Add lostDigits property */ +/* 1998.05.02 Make the class immutable and final; drop set methods */ +/* 1998.06.05 Add Round (rounding modes) property */ +/* 1998.06.25 Rename from DecimalContext; allow digits=0 */ +/* 1998.10.12 change to com.ibm.icu.math package */ +/* 1999.02.06 add javadoc comments */ +/* 1999.03.05 simplify; changes from discussion with J. Bloch */ +/* 1999.03.13 1.00 release to IBM Centre for Java Technology */ +/* 1999.07.10 1.04 flag serialization unused */ +/* 2000.01.01 1.06 copyright update */ +/* ------------------------------------------------------------------ */ + + + + +/** + * The MathContext immutable class encapsulates the + * settings understood by the operator methods of the {@link BigDecimal} + * class (and potentially other classes). Operator methods are those + * that effect an operation on a number or a pair of numbers. + *

      + * The settings, which are not base-dependent, comprise: + *

        + *
      1. digits: + * the number of digits (precision) to be used for an operation + *
      2. form: + * the form of any exponent that results from the operation + *
      3. lostDigits: + * whether checking for lost digits is enabled + *
      4. roundingMode: + * the algorithm to be used for rounding. + *
      + *

      + * When provided, a MathContext object supplies the + * settings for an operation directly. + *

      + * When MathContext.DEFAULT is provided for a + * MathContext parameter then the default settings are used + * (9, SCIENTIFIC, false, ROUND_HALF_UP). + *

      + * In the BigDecimal class, all methods which accept a + * MathContext object defaults) also have a version of the + * method which does not accept a MathContext parameter. These versions + * carry out unlimited precision fixed point arithmetic (as though the + * settings were (0, PLAIN, false, ROUND_HALF_UP). + *

      + * The instance variables are shared with default access (so they are + * directly accessible to the BigDecimal class), but must + * never be changed. + *

      + * The rounding mode constants have the same names and values as the + * constants of the same name in java.math.BigDecimal, to + * maintain compatibility with earlier versions of + * BigDecimal. + * + * @see BigDecimal + * @author Mike Cowlishaw + * @stable ICU 2.0 + */ + +public final class MathContext implements java.io.Serializable{ + //private static final java.lang.String $0="MathContext.nrx"; + + /* ----- Properties ----- */ + /* properties public constant */ + /** + * Plain (fixed point) notation, without any exponent. + * Used as a setting to control the form of the result of a + * BigDecimal operation. + * A zero result in plain form may have a decimal part of one or + * more zeros. + * + * @see #ENGINEERING + * @see #SCIENTIFIC + * @stable ICU 2.0 + */ + public static final int PLAIN=0; // [no exponent] + + /** + * Standard floating point notation (with scientific exponential + * format, where there is one digit before any decimal point). + * Used as a setting to control the form of the result of a + * BigDecimal operation. + * A zero result in plain form may have a decimal part of one or + * more zeros. + * + * @see #ENGINEERING + * @see #PLAIN + * @stable ICU 2.0 + */ + public static final int SCIENTIFIC=1; // 1 digit before . + + /** + * Standard floating point notation (with engineering exponential + * format, where the power of ten is a multiple of 3). + * Used as a setting to control the form of the result of a + * BigDecimal operation. + * A zero result in plain form may have a decimal part of one or + * more zeros. + * + * @see #PLAIN + * @see #SCIENTIFIC + * @stable ICU 2.0 + */ + public static final int ENGINEERING=2; // 1-3 digits before . + + // The rounding modes match the original BigDecimal class values + /** + * Rounding mode to round to a more positive number. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If any of the discarded digits are non-zero then the result + * should be rounded towards the next more positive digit. + * @stable ICU 2.0 + */ + public static final int ROUND_CEILING=2; + + /** + * Rounding mode to round towards zero. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * All discarded digits are ignored (truncated). The result is + * neither incremented nor decremented. + * @stable ICU 2.0 + */ + public static final int ROUND_DOWN=1; + + /** + * Rounding mode to round to a more negative number. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If any of the discarded digits are non-zero then the result + * should be rounded towards the next more negative digit. + * @stable ICU 2.0 + */ + public static final int ROUND_FLOOR=3; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant + * value is rounded down. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If the discarded digits represent greater than half (0.5 times) + * the value of a one in the next position then the result should be + * rounded up (away from zero). Otherwise the discarded digits are + * ignored. + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_DOWN=5; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant + * value is rounded to the nearest even neighbor. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If the discarded digits represent greater than half (0.5 times) + * the value of a one in the next position then the result should be + * rounded up (away from zero). If they represent less than half, + * then the result should be rounded down. + *

      + * Otherwise (they represent exactly half) the result is rounded + * down if its rightmost digit is even, or rounded up if its + * rightmost digit is odd (to make an even digit). + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_EVEN=6; + + /** + * Rounding mode to round to nearest neighbor, where an equidistant + * value is rounded up. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If the discarded digits represent greater than or equal to half + * (0.5 times) the value of a one in the next position then the result + * should be rounded up (away from zero). Otherwise the discarded + * digits are ignored. + * @stable ICU 2.0 + */ + public static final int ROUND_HALF_UP=4; + + /** + * Rounding mode to assert that no rounding is necessary. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * Rounding (potential loss of information) is not permitted. + * If any of the discarded digits are non-zero then an + * ArithmeticException should be thrown. + * @stable ICU 2.0 + */ + public static final int ROUND_UNNECESSARY=7; + + /** + * Rounding mode to round away from zero. + * Used as a setting to control the rounding mode used during a + * BigDecimal operation. + *

      + * If any of the discarded digits are non-zero then the result will + * be rounded up (away from zero). + * @stable ICU 2.0 + */ + public static final int ROUND_UP=0; + + + /* properties shared */ + /** + * The number of digits (precision) to be used for an operation. + * A value of 0 indicates that unlimited precision (as many digits + * as are required) will be used. + *

      + * The {@link BigDecimal} operator methods use this value to + * determine the precision of results. + * Note that leading zeros (in the integer part of a number) are + * never significant. + *

      + * digits will always be non-negative. + * + * @serial + */ + int digits; + + /** + * The form of results from an operation. + *

      + * The {@link BigDecimal} operator methods use this value to + * determine the form of results, in particular whether and how + * exponential notation should be used. + * + * @see #ENGINEERING + * @see #PLAIN + * @see #SCIENTIFIC + * @serial + */ + int form; // values for this must fit in a byte + + /** + * Controls whether lost digits checking is enabled for an + * operation. + * Set to true to enable checking, or + * to false to disable checking. + *

      + * When enabled, the {@link BigDecimal} operator methods check + * the precision of their operand or operands, and throw an + * ArithmeticException if an operand is more precise + * than the digits setting (that is, digits would be lost). + * When disabled, operands are rounded to the specified digits. + * + * @serial + */ + boolean lostDigits; + + /** + * The rounding algorithm to be used for an operation. + *

      + * The {@link BigDecimal} operator methods use this value to + * determine the algorithm to be used when non-zero digits have to + * be discarded in order to reduce the precision of a result. + * The value must be one of the public constants whose name starts + * with ROUND_. + * + * @see #ROUND_CEILING + * @see #ROUND_DOWN + * @see #ROUND_FLOOR + * @see #ROUND_HALF_DOWN + * @see #ROUND_HALF_EVEN + * @see #ROUND_HALF_UP + * @see #ROUND_UNNECESSARY + * @see #ROUND_UP + * @serial + */ + int roundingMode; + + /* properties private constant */ + // default settings + private static final int DEFAULT_FORM=SCIENTIFIC; + private static final int DEFAULT_DIGITS=9; + private static final boolean DEFAULT_LOSTDIGITS=false; + private static final int DEFAULT_ROUNDINGMODE=ROUND_HALF_UP; + + /* properties private constant */ + + private static final int MIN_DIGITS=0; // smallest value for DIGITS. + private static final int MAX_DIGITS=999999999; // largest value for DIGITS. If increased, + // the BigDecimal class may need update. + // list of valid rounding mode values, most common two first + private static final int ROUNDS[]=new int[]{ROUND_HALF_UP,ROUND_UNNECESSARY,ROUND_CEILING,ROUND_DOWN,ROUND_FLOOR,ROUND_HALF_DOWN,ROUND_HALF_EVEN,ROUND_UP}; + + + private static final java.lang.String ROUNDWORDS[]=new java.lang.String[]{"ROUND_HALF_UP","ROUND_UNNECESSARY","ROUND_CEILING","ROUND_DOWN","ROUND_FLOOR","ROUND_HALF_DOWN","ROUND_HALF_EVEN","ROUND_UP"}; // matching names of the ROUNDS values + + + + + /* properties private constant unused */ + + // Serialization version + private static final long serialVersionUID=7163376998892515376L; + + /* properties public constant */ + /** + * A MathContext object initialized to the default + * settings for general-purpose arithmetic. That is, + * digits=9 form=SCIENTIFIC lostDigits=false + * roundingMode=ROUND_HALF_UP. + * + * @see #SCIENTIFIC + * @see #ROUND_HALF_UP + * @stable ICU 2.0 + */ + public static final com.ibm.icu.math.MathContext DEFAULT=new com.ibm.icu.math.MathContext(DEFAULT_DIGITS,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); + + + + + /* ----- Constructors ----- */ + + /** + * Constructs a new MathContext with a specified + * precision. + * The other settings are set to the default values + * (see {@link #DEFAULT}). + * + * An IllegalArgumentException is thrown if the + * setdigits parameter is out of range + * (<0 or >999999999). + * + * @param setdigits The int digits setting + * for this MathContext. + * @throws IllegalArgumentException parameter out of range. + * @stable ICU 2.0 + */ + + public MathContext(int setdigits){ + this(setdigits,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); + return;} + + + /** + * Constructs a new MathContext with a specified + * precision and form. + * The other settings are set to the default values + * (see {@link #DEFAULT}). + * + * An IllegalArgumentException is thrown if the + * setdigits parameter is out of range + * (<0 or >999999999), or if the value given for the + * setform parameter is not one of the appropriate + * constants. + * + * @param setdigits The int digits setting + * for this MathContext. + * @param setform The int form setting + * for this MathContext. + * @throws IllegalArgumentException parameter out of range. + * @stable ICU 2.0 + */ + + public MathContext(int setdigits,int setform){ + this(setdigits,setform,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE); + return;} + + /** + * Constructs a new MathContext with a specified + * precision, form, and lostDigits setting. + * The roundingMode setting is set to its default value + * (see {@link #DEFAULT}). + * + * An IllegalArgumentException is thrown if the + * setdigits parameter is out of range + * (<0 or >999999999), or if the value given for the + * setform parameter is not one of the appropriate + * constants. + * + * @param setdigits The int digits setting + * for this MathContext. + * @param setform The int form setting + * for this MathContext. + * @param setlostdigits The boolean lostDigits + * setting for this MathContext. + * @throws IllegalArgumentException parameter out of range. + * @stable ICU 2.0 + */ + + public MathContext(int setdigits,int setform,boolean setlostdigits){ + this(setdigits,setform,setlostdigits,DEFAULT_ROUNDINGMODE); + return;} + + /** + * Constructs a new MathContext with a specified + * precision, form, lostDigits, and roundingMode setting. + * + * An IllegalArgumentException is thrown if the + * setdigits parameter is out of range + * (<0 or >999999999), or if the value given for the + * setform or setroundingmode parameters is + * not one of the appropriate constants. + * + * @param setdigits The int digits setting + * for this MathContext. + * @param setform The int form setting + * for this MathContext. + * @param setlostdigits The boolean lostDigits + * setting for this MathContext. + * @param setroundingmode The int roundingMode setting + * for this MathContext. + * @throws IllegalArgumentException parameter out of range. + * @stable ICU 2.0 + */ + + public MathContext(int setdigits,int setform,boolean setlostdigits,int setroundingmode){super(); + + + // set values, after checking + if (setdigits!=DEFAULT_DIGITS) + { + if (setdigitsMAX_DIGITS) + throw new java.lang.IllegalArgumentException("Digits too large:"+" "+setdigits); + } + {/*select*/ + if (setform==SCIENTIFIC){ + // [most common] + }else if (setform==ENGINEERING){ + }else if (setform==PLAIN){ + }else{ + throw new java.lang.IllegalArgumentException("Bad form value:"+" "+setform); + } + } + if ((!(isValidRound(setroundingmode)))) + throw new java.lang.IllegalArgumentException("Bad roundingMode value:"+" "+setroundingmode); + digits=setdigits; + form=setform; + lostDigits=setlostdigits; // [no bad value possible] + roundingMode=setroundingmode; + return;} + + /** + * Returns the digits setting. + * This value is always non-negative. + * + * @return an int which is the value of the digits + * setting + * @stable ICU 2.0 + */ + + public int getDigits(){ + return digits; + } + + /** + * Returns the form setting. + * This will be one of + * {@link #ENGINEERING}, + * {@link #PLAIN}, or + * {@link #SCIENTIFIC}. + * + * @return an int which is the value of the form setting + * @stable ICU 2.0 + */ + + public int getForm(){ + return form; + } + + /** + * Returns the lostDigits setting. + * This will be either true (enabled) or + * false (disabled). + * + * @return a boolean which is the value of the lostDigits + * setting + * @stable ICU 2.0 + */ + + public boolean getLostDigits(){ + return lostDigits; + } + + /** + * Returns the roundingMode setting. + * This will be one of + * {@link #ROUND_CEILING}, + * {@link #ROUND_DOWN}, + * {@link #ROUND_FLOOR}, + * {@link #ROUND_HALF_DOWN}, + * {@link #ROUND_HALF_EVEN}, + * {@link #ROUND_HALF_UP}, + * {@link #ROUND_UNNECESSARY}, or + * {@link #ROUND_UP}. + * + * @return an int which is the value of the roundingMode + * setting + * @stable ICU 2.0 + */ + + public int getRoundingMode(){ + return roundingMode; + } + + /** Returns the MathContext as a readable string. + * The String returned represents the settings of the + * MathContext object as four blank-delimited words + * separated by a single blank and with no leading or trailing blanks, + * as follows: + *

        + *
      1. + * digits=, immediately followed by + * the value of the digits setting as a numeric word. + *
      2. + * form=, immediately followed by + * the value of the form setting as an uppercase word + * (one of SCIENTIFIC, PLAIN, or + * ENGINEERING). + *
      3. + * lostDigits=, immediately followed by + * the value of the lostDigits setting + * (1 if enabled, 0 if disabled). + *
      4. + * roundingMode=, immediately followed by + * the value of the roundingMode setting as a word. + * This word will be the same as the name of the corresponding public + * constant. + *
      + *

      + * For example: + *
      + * digits=9 form=SCIENTIFIC lostDigits=0 roundingMode=ROUND_HALF_UP + * + *

      + * Additional words may be appended to the result of + * toString in the future if more properties are added + * to the class. + * + * @return a String representing the context settings. + * @stable ICU 2.0 + */ + + public java.lang.String toString(){ + java.lang.String formstr=null; + int r=0; + java.lang.String roundword=null; + {/*select*/ + if (form==SCIENTIFIC) + formstr="SCIENTIFIC"; + else if (form==ENGINEERING) + formstr="ENGINEERING"; + else{ + formstr="PLAIN";/* form=PLAIN */ + } + } + {int $1=ROUNDS.length;r=0;r:for(;$1>0;$1--,r++){ + if (roundingMode==ROUNDS[r]) + { + roundword=ROUNDWORDS[r]; + break r; + } + } + }/*r*/ + return "digits="+digits+" "+"form="+formstr+" "+"lostDigits="+(lostDigits?"1":"0")+" "+"roundingMode="+roundword; + } + + + /* Test whether round is valid. */ + // This could be made shared for use by BigDecimal for setScale. + + private static boolean isValidRound(int testround){ + int r=0; + {int $2=ROUNDS.length;for(r=0;$2>0;$2--,r++){ + if (testround==ROUNDS[r]) + return true; + } + }/*r*/ + return false; + } + } diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java index cb72af42683..c37d38500c8 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java @@ -1,2586 +1,2586 @@ -/* -******************************************************************************* -* Copyright (C) 2001-2011, International Business Machines -* Corporation and others. All Rights Reserved. -******************************************************************************* -*/ - -/* FOOD FOR THOUGHT: currently the reordering modes are a mixture of - * algorithm for direct BiDi, algorithm for inverse Bidi and the bizarre - * concept of RUNS_ONLY which is a double operation. - * It could be advantageous to divide this into 3 concepts: - * a) Operation: direct / inverse / RUNS_ONLY - * b) Direct algorithm: default / NUMBERS_SPECIAL / GROUP_NUMBERS_WITH_L - * c) Inverse algorithm: default / INVERSE_LIKE_DIRECT / NUMBERS_SPECIAL - * This would allow combinations not possible today like RUNS_ONLY with - * NUMBERS_SPECIAL. - * Also allow to set INSERT_MARKS for the direct step of RUNS_ONLY and - * REMOVE_CONTROLS for the inverse step. - * Not all combinations would be supported, and probably not all do make sense. - * This would need to document which ones are supported and what are the - * fallbacks for unsupported combinations. - */ - -//TODO: make sample program do something simple but real and complete - -package com.ibm.icu.text; - -import java.text.AttributedCharacterIterator; - -/** - * - *

      Bidi algorithm for ICU

      - * - * This is an implementation of the Unicode Bidirectional algorithm. The - * algorithm is defined in the Unicode Standard Annex #9, - * version 13, also described in The Unicode Standard, Version 4.0 . - *

      - * - * Note: Libraries that perform a bidirectional algorithm and reorder strings - * accordingly are sometimes called "Storage Layout Engines". ICU's Bidi and - * shaping (ArabicShaping) classes can be used at the core of such "Storage - * Layout Engines". - * - *

      General remarks about the API:

      - * - * The "limit" of a sequence of characters is the position just after - * their last character, i.e., one more than that position. - *

      - * - * Some of the API methods provide access to "runs". Such a - * "run" is defined as a sequence of characters that are at the same - * embedding level after performing the Bidi algorithm. - *

      - * - *

      Basic concept: paragraph

      - * A piece of text can be divided into several paragraphs by characters - * with the Bidi class Block Separator. For handling of - * paragraphs, see: - *
        - *
      • {@link #countParagraphs} - *
      • {@link #getParaLevel} - *
      • {@link #getParagraph} - *
      • {@link #getParagraphByIndex} - *
      - * - *

      Basic concept: text direction

      - * The direction of a piece of text may be: - *
        - *
      • {@link #LTR} - *
      • {@link #RTL} - *
      • {@link #MIXED} - *
      - * - *

      Basic concept: levels

      - * - * Levels in this API represent embedding levels according to the Unicode - * Bidirectional Algorithm. - * Their low-order bit (even/odd value) indicates the visual direction.

      - * - * Levels can be abstract values when used for the - * paraLevel and embeddingLevels - * arguments of setPara(); there: - *

        - *
      • the high-order bit of an embeddingLevels[] - * value indicates whether the using application is - * specifying the level of a character to override whatever the - * Bidi implementation would resolve it to.
      • - *
      • paraLevel can be set to the - * pseudo-level values LEVEL_DEFAULT_LTR - * and LEVEL_DEFAULT_RTL.
      • - *
      - * - *

      The related constants are not real, valid level values. - * DEFAULT_XXX can be used to specify - * a default for the paragraph level for - * when the setPara() method - * shall determine it but there is no - * strongly typed character in the input.

      - * - * Note that the value for LEVEL_DEFAULT_LTR is even - * and the one for LEVEL_DEFAULT_RTL is odd, - * just like with normal LTR and RTL level values - - * these special values are designed that way. Also, the implementation - * assumes that MAX_EXPLICIT_LEVEL is odd. - * - *

        See Also: - *
      • {@link #LEVEL_DEFAULT_LTR} - *
      • {@link #LEVEL_DEFAULT_RTL} - *
      • {@link #LEVEL_OVERRIDE} - *
      • {@link #MAX_EXPLICIT_LEVEL} - *
      • {@link #setPara} - *
      - * - *

      Basic concept: Reordering Mode

      - * Reordering mode values indicate which variant of the Bidi algorithm to - * use. - * - *
        See Also: - *
      • {@link #setReorderingMode} - *
      • {@link #REORDER_DEFAULT} - *
      • {@link #REORDER_NUMBERS_SPECIAL} - *
      • {@link #REORDER_GROUP_NUMBERS_WITH_R} - *
      • {@link #REORDER_RUNS_ONLY} - *
      • {@link #REORDER_INVERSE_NUMBERS_AS_L} - *
      • {@link #REORDER_INVERSE_LIKE_DIRECT} - *
      • {@link #REORDER_INVERSE_FOR_NUMBERS_SPECIAL} - *
      - * - *

      Basic concept: Reordering Options

      - * Reordering options can be applied during Bidi text transformations. - *
        See Also: - *
      • {@link #setReorderingOptions} - *
      • {@link #OPTION_DEFAULT} - *
      • {@link #OPTION_INSERT_MARKS} - *
      • {@link #OPTION_REMOVE_CONTROLS} - *
      • {@link #OPTION_STREAMING} - *
      - * - * - * @author Simon Montagu, Matitiahu Allouche (ported from C code written by Markus W. Scherer) - * @stable ICU 3.8 - * - * - *

      Sample code for the ICU Bidi API

      - * - *
      Rendering a paragraph with the ICU Bidi API
      - * - * This is (hypothetical) sample code that illustrates how the ICU Bidi API - * could be used to render a paragraph of text. Rendering code depends highly on - * the graphics system, therefore this sample code must make a lot of - * assumptions, which may or may not match any existing graphics system's - * properties. - * - *

      - * The basic assumptions are: - *

      - *
        - *
      • Rendering is done from left to right on a horizontal line.
      • - *
      • A run of single-style, unidirectional text can be rendered at once. - *
      • - *
      • Such a run of text is passed to the graphics system with characters - * (code units) in logical order.
      • - *
      • The line-breaking algorithm is very complicated and Locale-dependent - - * and therefore its implementation omitted from this sample code.
      • - *
      - * - *
      - *
      - *  package com.ibm.icu.dev.test.bidi;
      - *
      - *  import com.ibm.icu.text.Bidi;
      - *  import com.ibm.icu.text.BidiRun;
      - *
      - *  public class Sample {
      - *
      - *      static final int styleNormal = 0;
      - *      static final int styleSelected = 1;
      - *      static final int styleBold = 2;
      - *      static final int styleItalics = 4;
      - *      static final int styleSuper=8;
      - *      static final int styleSub = 16;
      - *
      - *      static class StyleRun {
      - *          int limit;
      - *          int style;
      - *
      - *          public StyleRun(int limit, int style) {
      - *              this.limit = limit;
      - *              this.style = style;
      - *          }
      - *      }
      - *
      - *      static class Bounds {
      - *          int start;
      - *          int limit;
      - *
      - *          public Bounds(int start, int limit) {
      - *              this.start = start;
      - *              this.limit = limit;
      - *          }
      - *      }
      - *
      - *      static int getTextWidth(String text, int start, int limit,
      - *                              StyleRun[] styleRuns, int styleRunCount) {
      - *          // simplistic way to compute the width
      - *          return limit - start;
      - *      }
      - *
      - *      // set limit and StyleRun limit for a line
      - *      // from text[start] and from styleRuns[styleRunStart]
      - *      // using Bidi.getLogicalRun(...)
      - *      // returns line width
      - *      static int getLineBreak(String text, Bounds line, Bidi para,
      - *                              StyleRun styleRuns[], Bounds styleRun) {
      - *          // dummy return
      - *          return 0;
      - *      }
      - *
      - *      // render runs on a line sequentially, always from left to right
      - *
      - *      // prepare rendering a new line
      - *      static void startLine(byte textDirection, int lineWidth) {
      - *          System.out.println();
      - *      }
      - *
      - *      // render a run of text and advance to the right by the run width
      - *      // the text[start..limit-1] is always in logical order
      - *      static void renderRun(String text, int start, int limit,
      - *                            byte textDirection, int style) {
      - *      }
      - *
      - *      // We could compute a cross-product
      - *      // from the style runs with the directional runs
      - *      // and then reorder it.
      - *      // Instead, here we iterate over each run type
      - *      // and render the intersections -
      - *      // with shortcuts in simple (and common) cases.
      - *      // renderParagraph() is the main function.
      - *
      - *      // render a directional run with
      - *      // (possibly) multiple style runs intersecting with it
      - *      static void renderDirectionalRun(String text, int start, int limit,
      - *                                       byte direction, StyleRun styleRuns[],
      - *                                       int styleRunCount) {
      - *          int i;
      - *
      - *          // iterate over style runs
      - *          if (direction == Bidi.LTR) {
      - *              int styleLimit;
      - *              for (i = 0; i < styleRunCount; ++i) {
      - *                  styleLimit = styleRuns[i].limit;
      - *                  if (start < styleLimit) {
      - *                      if (styleLimit > limit) {
      - *                          styleLimit = limit;
      - *                      }
      - *                      renderRun(text, start, styleLimit,
      - *                                direction, styleRuns[i].style);
      - *                      if (styleLimit == limit) {
      - *                          break;
      - *                      }
      - *                      start = styleLimit;
      - *                  }
      - *              }
      - *          } else {
      - *              int styleStart;
      - *
      - *              for (i = styleRunCount-1; i >= 0; --i) {
      - *                  if (i > 0) {
      - *                      styleStart = styleRuns[i-1].limit;
      - *                  } else {
      - *                      styleStart = 0;
      - *                  }
      - *                  if (limit >= styleStart) {
      - *                      if (styleStart < start) {
      - *                          styleStart = start;
      - *                      }
      - *                      renderRun(text, styleStart, limit, direction,
      - *                                styleRuns[i].style);
      - *                      if (styleStart == start) {
      - *                          break;
      - *                      }
      - *                      limit = styleStart;
      - *                  }
      - *              }
      - *          }
      - *      }
      - *
      - *      // the line object represents text[start..limit-1]
      - *      static void renderLine(Bidi line, String text, int start, int limit,
      - *                             StyleRun styleRuns[], int styleRunCount) {
      - *          byte direction = line.getDirection();
      - *          if (direction != Bidi.MIXED) {
      - *              // unidirectional
      - *              if (styleRunCount <= 1) {
      - *                  renderRun(text, start, limit, direction, styleRuns[0].style);
      - *              } else {
      - *                  renderDirectionalRun(text, start, limit, direction,
      - *                                       styleRuns, styleRunCount);
      - *              }
      - *          } else {
      - *              // mixed-directional
      - *              int count, i;
      - *              BidiRun run;
      - *
      - *              try {
      - *                  count = line.countRuns();
      - *              } catch (IllegalStateException e) {
      - *                  e.printStackTrace();
      - *                  return;
      - *              }
      - *              if (styleRunCount <= 1) {
      - *                  int style = styleRuns[0].style;
      - *
      - *                  // iterate over directional runs
      - *                  for (i = 0; i < count; ++i) {
      - *                      run = line.getVisualRun(i);
      - *                      renderRun(text, run.getStart(), run.getLimit(),
      - *                                run.getDirection(), style);
      - *                  }
      - *              } else {
      - *                  // iterate over both directional and style runs
      - *                  for (i = 0; i < count; ++i) {
      - *                      run = line.getVisualRun(i);
      - *                      renderDirectionalRun(text, run.getStart(),
      - *                                           run.getLimit(), run.getDirection(),
      - *                                           styleRuns, styleRunCount);
      - *                  }
      - *              }
      - *          }
      - *      }
      - *
      - *      static void renderParagraph(String text, byte textDirection,
      - *                                  StyleRun styleRuns[], int styleRunCount,
      - *                                  int lineWidth) {
      - *          int length = text.length();
      - *          Bidi para = new Bidi();
      - *          try {
      - *              para.setPara(text,
      - *                           textDirection != 0 ? Bidi.LEVEL_DEFAULT_RTL
      - *                                              : Bidi.LEVEL_DEFAULT_LTR,
      - *                           null);
      - *          } catch (Exception e) {
      - *              e.printStackTrace();
      - *              return;
      - *          }
      - *          byte paraLevel = (byte)(1 & para.getParaLevel());
      - *          StyleRun styleRun = new StyleRun(length, styleNormal);
      - *
      - *          if (styleRuns == null || styleRunCount <= 0) {
      - *              styleRuns = new StyleRun[1];
      - *              styleRunCount = 1;
      - *              styleRuns[0] = styleRun;
      - *          }
      - *          // assume styleRuns[styleRunCount-1].limit>=length
      - *
      - *          int width = getTextWidth(text, 0, length, styleRuns, styleRunCount);
      - *          if (width <= lineWidth) {
      - *              // everything fits onto one line
      - *
      - *              // prepare rendering a new line from either left or right
      - *              startLine(paraLevel, width);
      - *
      - *              renderLine(para, text, 0, length, styleRuns, styleRunCount);
      - *          } else {
      - *              // we need to render several lines
      - *              Bidi line = new Bidi(length, 0);
      - *              int start = 0, limit;
      - *              int styleRunStart = 0, styleRunLimit;
      - *
      - *              for (;;) {
      - *                  limit = length;
      - *                  styleRunLimit = styleRunCount;
      - *                  width = getLineBreak(text, new Bounds(start, limit),
      - *                                       para, styleRuns,
      - *                                       new Bounds(styleRunStart, styleRunLimit));
      - *                  try {
      - *                      line = para.setLine(start, limit);
      - *                  } catch (Exception e) {
      - *                      e.printStackTrace();
      - *                      return;
      - *                  }
      - *                  // prepare rendering a new line
      - *                  // from either left or right
      - *                  startLine(paraLevel, width);
      - *
      - *                  if (styleRunStart > 0) {
      - *                      int newRunCount = styleRuns.length - styleRunStart;
      - *                      StyleRun[] newRuns = new StyleRun[newRunCount];
      - *                      System.arraycopy(styleRuns, styleRunStart, newRuns, 0,
      - *                                       newRunCount);
      - *                      renderLine(line, text, start, limit, newRuns,
      - *                                 styleRunLimit - styleRunStart);
      - *                  } else {
      - *                      renderLine(line, text, start, limit, styleRuns,
      - *                                 styleRunLimit - styleRunStart);
      - *                  }
      - *                  if (limit == length) {
      - *                      break;
      - *                  }
      - *                  start = limit;
      - *                  styleRunStart = styleRunLimit - 1;
      - *                  if (start >= styleRuns[styleRunStart].limit) {
      - *                      ++styleRunStart;
      - *                  }
      - *              }
      - *          }
      - *      }
      - *
      - *      public static void main(String[] args)
      - *      {
      - *          renderParagraph("Some Latin text...", Bidi.LTR, null, 0, 80);
      - *          renderParagraph("Some Hebrew text...", Bidi.RTL, null, 0, 60);
      - *      }
      - *  }
      - *
      - * 
      - */ - -public class Bidi { - - private java.text.Bidi bidi; - - private Bidi(java.text.Bidi delegate) { - this.bidi = delegate; - } - - /** Paragraph level setting

      - * - * Constant indicating that the base direction depends on the first strong - * directional character in the text according to the Unicode Bidirectional - * Algorithm. If no strong directional character is present, - * then set the paragraph level to 0 (left-to-right).

      - * - * If this value is used in conjunction with reordering modes - * REORDER_INVERSE_LIKE_DIRECT or - * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder - * is assumed to be visual LTR, and the text after reordering is required - * to be the corresponding logical string with appropriate contextual - * direction. The direction of the result string will be RTL if either - * the righmost or leftmost strong character of the source text is RTL - * or Arabic Letter, the direction will be LTR otherwise.

      - * - * If reordering option OPTION_INSERT_MARKS is set, an RLM may - * be added at the beginning of the result string to ensure round trip - * (that the result string, when reordered back to visual, will produce - * the original source text). - * @see #REORDER_INVERSE_LIKE_DIRECT - * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL - * @stable ICU 3.8 - */ - public static final byte LEVEL_DEFAULT_LTR = (byte)0x7e; - - /** Paragraph level setting

      - * - * Constant indicating that the base direction depends on the first strong - * directional character in the text according to the Unicode Bidirectional - * Algorithm. If no strong directional character is present, - * then set the paragraph level to 1 (right-to-left).

      - * - * If this value is used in conjunction with reordering modes - * REORDER_INVERSE_LIKE_DIRECT or - * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder - * is assumed to be visual LTR, and the text after reordering is required - * to be the corresponding logical string with appropriate contextual - * direction. The direction of the result string will be RTL if either - * the righmost or leftmost strong character of the source text is RTL - * or Arabic Letter, or if the text contains no strong character; - * the direction will be LTR otherwise.

      - * - * If reordering option OPTION_INSERT_MARKS is set, an RLM may - * be added at the beginning of the result string to ensure round trip - * (that the result string, when reordered back to visual, will produce - * the original source text). - * @see #REORDER_INVERSE_LIKE_DIRECT - * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL - * @stable ICU 3.8 - */ - public static final byte LEVEL_DEFAULT_RTL = (byte)0x7f; - - /** - * Maximum explicit embedding level. - * (The maximum resolved level can be up to MAX_EXPLICIT_LEVEL+1). - * @stable ICU 3.8 - */ - public static final byte MAX_EXPLICIT_LEVEL = 61; - - /** - * Bit flag for level input. - * Overrides directional properties. - * @stable ICU 3.8 - */ - public static final byte LEVEL_OVERRIDE = (byte)0x80; - - /** - * Special value which can be returned by the mapping methods when a - * logical index has no corresponding visual index or vice-versa. This may - * happen for the logical-to-visual mapping of a Bidi control when option - * OPTION_REMOVE_CONTROLS is - * specified. This can also happen for the visual-to-logical mapping of a - * Bidi mark (LRM or RLM) inserted by option - * OPTION_INSERT_MARKS. - * @see #getVisualIndex - * @see #getVisualMap - * @see #getLogicalIndex - * @see #getLogicalMap - * @see #OPTION_INSERT_MARKS - * @see #OPTION_REMOVE_CONTROLS - * @stable ICU 3.8 - */ - public static final int MAP_NOWHERE = -1; - - /** - * All left-to-right text. - * @stable ICU 3.8 - */ - public static final byte LTR = 0; - - /** - * All right-to-left text. - * @stable ICU 3.8 - */ - public static final byte RTL = 1; - - /** - * Mixed-directional text. - * @stable ICU 3.8 - */ - public static final byte MIXED = 2; - - /** - * option bit for writeReordered(): - * keep combining characters after their base characters in RTL runs - * - * @see #writeReordered - * @stable ICU 3.8 - */ - public static final short KEEP_BASE_COMBINING = 1; - - /** - * option bit for writeReordered(): - * replace characters with the "mirrored" property in RTL runs - * by their mirror-image mappings - * - * @see #writeReordered - * @stable ICU 3.8 - */ - public static final short DO_MIRRORING = 2; - - /** - * option bit for writeReordered(): - * surround the run with LRMs if necessary; - * this is part of the approximate "inverse Bidi" algorithm - * - *

      This option does not imply corresponding adjustment of the index - * mappings.

      - * - * @see #setInverse - * @see #writeReordered - * @stable ICU 3.8 - */ - public static final short INSERT_LRM_FOR_NUMERIC = 4; - - /** - * option bit for writeReordered(): - * remove Bidi control characters - * (this does not affect INSERT_LRM_FOR_NUMERIC) - * - *

      This option does not imply corresponding adjustment of the index - * mappings.

      - * - * @see #writeReordered - * @see #INSERT_LRM_FOR_NUMERIC - * @stable ICU 3.8 - */ - public static final short REMOVE_BIDI_CONTROLS = 8; - - /** - * option bit for writeReordered(): - * write the output in reverse order - * - *

      This has the same effect as calling writeReordered() - * first without this option, and then calling - * writeReverse() without mirroring. - * Doing this in the same step is faster and avoids a temporary buffer. - * An example for using this option is output to a character terminal that - * is designed for RTL scripts and stores text in reverse order.

      - * - * @see #writeReordered - * @stable ICU 3.8 - */ - public static final short OUTPUT_REVERSE = 16; - - /** Reordering mode: Regular Logical to Visual Bidi algorithm according to Unicode. - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_DEFAULT = 0; - - /** Reordering mode: Logical to Visual algorithm which handles numbers in - * a way which mimicks the behavior of Windows XP. - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_NUMBERS_SPECIAL = 1; - - /** Reordering mode: Logical to Visual algorithm grouping numbers with - * adjacent R characters (reversible algorithm). - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_GROUP_NUMBERS_WITH_R = 2; - - /** Reordering mode: Reorder runs only to transform a Logical LTR string - * to the logical RTL string with the same display, or vice-versa.
      - * If this mode is set together with option - * OPTION_INSERT_MARKS, some Bidi controls in the source - * text may be removed and other controls may be added to produce the - * minimum combination which has the required display. - * @see #OPTION_INSERT_MARKS - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_RUNS_ONLY = 3; - - /** Reordering mode: Visual to Logical algorithm which handles numbers - * like L (same algorithm as selected by setInverse(true). - * @see #setInverse - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_INVERSE_NUMBERS_AS_L = 4; - - /** Reordering mode: Visual to Logical algorithm equivalent to the regular - * Logical to Visual algorithm. - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_INVERSE_LIKE_DIRECT = 5; - - /** Reordering mode: Inverse Bidi (Visual to Logical) algorithm for the - * REORDER_NUMBERS_SPECIAL Bidi algorithm. - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6; - - /** - * Option value for setReorderingOptions: - * disable all the options which can be set with this method - * @see #setReorderingOptions - * @stable ICU 3.8 - */ - public static final int OPTION_DEFAULT = 0; - - /** - * Option bit for setReorderingOptions: - * insert Bidi marks (LRM or RLM) when needed to ensure correct result of - * a reordering to a Logical order - * - *

      This option must be set or reset before calling - * setPara.

      - * - *

      This option is significant only with reordering modes which generate - * a result with Logical order, specifically.

      - *
        - *
      • REORDER_RUNS_ONLY
      • - *
      • REORDER_INVERSE_NUMBERS_AS_L
      • - *
      • REORDER_INVERSE_LIKE_DIRECT
      • - *
      • REORDER_INVERSE_FOR_NUMBERS_SPECIAL
      • - *
      - * - *

      If this option is set in conjunction with reordering mode - * REORDER_INVERSE_NUMBERS_AS_L or with calling - * setInverse(true), it implies option - * INSERT_LRM_FOR_NUMERIC in calls to method - * writeReordered().

      - * - *

      For other reordering modes, a minimum number of LRM or RLM characters - * will be added to the source text after reordering it so as to ensure - * round trip, i.e. when applying the inverse reordering mode on the - * resulting logical text with removal of Bidi marks - * (option OPTION_REMOVE_CONTROLS set before calling - * setPara() or option - * REMOVE_BIDI_CONTROLS in - * writeReordered), the result will be identical to the - * source text in the first transformation. - * - *

      This option will be ignored if specified together with option - * OPTION_REMOVE_CONTROLS. It inhibits option - * REMOVE_BIDI_CONTROLS in calls to method - * writeReordered() and it implies option - * INSERT_LRM_FOR_NUMERIC in calls to method - * writeReordered() if the reordering mode is - * REORDER_INVERSE_NUMBERS_AS_L.

      - * - * @see #setReorderingMode - * @see #setReorderingOptions - * @see #INSERT_LRM_FOR_NUMERIC - * @see #REMOVE_BIDI_CONTROLS - * @see #OPTION_REMOVE_CONTROLS - * @see #REORDER_RUNS_ONLY - * @see #REORDER_INVERSE_NUMBERS_AS_L - * @see #REORDER_INVERSE_LIKE_DIRECT - * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL - * @stable ICU 3.8 - */ - public static final int OPTION_INSERT_MARKS = 1; - - /** - * Option bit for setReorderingOptions: - * remove Bidi control characters - * - *

      This option must be set or reset before calling - * setPara.

      - * - *

      This option nullifies option - * OPTION_INSERT_MARKS. It inhibits option - * INSERT_LRM_FOR_NUMERIC in calls to method - * writeReordered() and it implies option - * REMOVE_BIDI_CONTROLS in calls to that method.

      - * - * @see #setReorderingMode - * @see #setReorderingOptions - * @see #OPTION_INSERT_MARKS - * @see #INSERT_LRM_FOR_NUMERIC - * @see #REMOVE_BIDI_CONTROLS - * @stable ICU 3.8 - */ - public static final int OPTION_REMOVE_CONTROLS = 2; - - /** - * Option bit for setReorderingOptions: - * process the output as part of a stream to be continued - * - *

      This option must be set or reset before calling - * setPara.

      - * - *

      This option specifies that the caller is interested in processing - * large text object in parts. The results of the successive calls are - * expected to be concatenated by the caller. Only the call for the last - * part will have this option bit off.

      - * - *

      When this option bit is on, setPara() may process - * less than the full source text in order to truncate the text at a - * meaningful boundary. The caller should call - * getProcessedLength() immediately after calling - * setPara() in order to determine how much of the source - * text has been processed. Source text beyond that length should be - * resubmitted in following calls to setPara. The - * processed length may be less than the length of the source text if a - * character preceding the last character of the source text constitutes a - * reasonable boundary (like a block separator) for text to be continued.
      - * If the last character of the source text constitutes a reasonable - * boundary, the whole text will be processed at once.
      - * If nowhere in the source text there exists - * such a reasonable boundary, the processed length will be zero.
      - * The caller should check for such an occurrence and do one of the following: - *

      • submit a larger amount of text with a better chance to include - * a reasonable boundary.
      • - *
      • resubmit the same text after turning off option - * OPTION_STREAMING.
      - * In all cases, this option should be turned off before processing the last - * part of the text.

      - * - *

      When the OPTION_STREAMING option is used, it is - * recommended to call orderParagraphsLTR(true) before calling - * setPara() so that later paragraphs may be concatenated to - * previous paragraphs on the right. - *

      - * - * @see #setReorderingMode - * @see #setReorderingOptions - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public static final int OPTION_STREAMING = 4; - - /** - * Value returned by BidiClassifier when there is no need to - * override the standard Bidi class for a given code point. - * @see BidiClassifier - * @stable ICU 3.8 - */ - public static final int CLASS_DEFAULT = 19; //UCharacterDirection.CHAR_DIRECTION_COUNT; - - /** - * Allocate a Bidi object. - * Such an object is initially empty. It is assigned - * the Bidi properties of a piece of text containing one or more paragraphs - * by setPara() - * or the Bidi properties of a line within a paragraph by - * setLine().

      - * This object can be reused.

      - * setPara() and setLine() will allocate - * additional memory for internal structures as necessary. - * - * @stable ICU 3.8 - */ - public Bidi() - { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Allocate a Bidi object with preallocated memory - * for internal structures. - * This method provides a Bidi object like the default constructor - * but it also preallocates memory for internal structures - * according to the sizings supplied by the caller.

      - * The preallocation can be limited to some of the internal memory - * by setting some values to 0 here. That means that if, e.g., - * maxRunCount cannot be reasonably predetermined and should not - * be set to maxLength (the only failproof value) to avoid - * wasting memory, then maxRunCount could be set to 0 here - * and the internal structures that are associated with it will be allocated - * on demand, just like with the default constructor. - * - * @param maxLength is the maximum text or line length that internal memory - * will be preallocated for. An attempt to associate this object with a - * longer text will fail, unless this value is 0, which leaves the allocation - * up to the implementation. - * - * @param maxRunCount is the maximum anticipated number of same-level runs - * that internal memory will be preallocated for. An attempt to access - * visual runs on an object that was not preallocated for as many runs - * as the text was actually resolved to will fail, - * unless this value is 0, which leaves the allocation up to the implementation.

      - * The number of runs depends on the actual text and maybe anywhere between - * 1 and maxLength. It is typically small. - * - * @throws IllegalArgumentException if maxLength or maxRunCount is less than 0 - * @stable ICU 3.8 - */ - public Bidi(int maxLength, int maxRunCount) - { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Modify the operation of the Bidi algorithm such that it - * approximates an "inverse Bidi" algorithm. This method - * must be called before setPara(). - * - *

      The normal operation of the Bidi algorithm as described - * in the Unicode Technical Report is to take text stored in logical - * (keyboard, typing) order and to determine the reordering of it for visual - * rendering. - * Some legacy systems store text in visual order, and for operations - * with standard, Unicode-based algorithms, the text needs to be transformed - * to logical order. This is effectively the inverse algorithm of the - * described Bidi algorithm. Note that there is no standard algorithm for - * this "inverse Bidi" and that the current implementation provides only an - * approximation of "inverse Bidi".

      - * - *

      With isInversed set to true, - * this method changes the behavior of some of the subsequent methods - * in a way that they can be used for the inverse Bidi algorithm. - * Specifically, runs of text with numeric characters will be treated in a - * special way and may need to be surrounded with LRM characters when they are - * written in reordered sequence.

      - * - *

      Output runs should be retrieved using getVisualRun(). - * Since the actual input for "inverse Bidi" is visually ordered text and - * getVisualRun() gets the reordered runs, these are actually - * the runs of the logically ordered output.

      - * - *

      Calling this method with argument isInverse set to - * true is equivalent to calling setReorderingMode - * with argument reorderingMode - * set to REORDER_INVERSE_NUMBERS_AS_L.
      - * Calling this method with argument isInverse set to - * false is equivalent to calling setReorderingMode - * with argument reorderingMode - * set to REORDER_DEFAULT. - * - * @param isInverse specifies "forward" or "inverse" Bidi operation. - * - * @see #setPara - * @see #writeReordered - * @see #setReorderingMode - * @see #REORDER_INVERSE_NUMBERS_AS_L - * @see #REORDER_DEFAULT - * @stable ICU 3.8 - */ - public void setInverse(boolean isInverse) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Is this Bidi object set to perform the inverse Bidi - * algorithm? - *

      Note: calling this method after setting the reordering mode with - * setReorderingMode will return true if the - * reordering mode was set to - * REORDER_INVERSE_NUMBERS_AS_L, false - * for all other values.

      - * - * @return true if the Bidi object is set to - * perform the inverse Bidi algorithm by handling numbers as L. - * - * @see #setInverse - * @see #setReorderingMode - * @see #REORDER_INVERSE_NUMBERS_AS_L - * @stable ICU 3.8 - */ - public boolean isInverse() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Modify the operation of the Bidi algorithm such that it implements some - * variant to the basic Bidi algorithm or approximates an "inverse Bidi" - * algorithm, depending on different values of the "reordering mode". - * This method must be called before setPara(), and stays in - * effect until called again with a different argument. - * - *

      The normal operation of the Bidi algorithm as described in the Unicode - * Standard Annex #9 is to take text stored in logical (keyboard, typing) - * order and to determine how to reorder it for visual rendering.

      - * - *

      With the reordering mode set to a value other than - * REORDER_DEFAULT, this method changes the behavior of some of - * the subsequent methods in a way such that they implement an inverse Bidi - * algorithm or some other algorithm variants.

      - * - *

      Some legacy systems store text in visual order, and for operations - * with standard, Unicode-based algorithms, the text needs to be transformed - * into logical order. This is effectively the inverse algorithm of the - * described Bidi algorithm. Note that there is no standard algorithm for - * this "inverse Bidi", so a number of variants are implemented here.

      - * - *

      In other cases, it may be desirable to emulate some variant of the - * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a - * Logical to Logical transformation.

      - * - *
        - *
      • When the Reordering Mode is set to - * REORDER_DEFAULT, - * the standard Bidi Logical to Visual algorithm is applied.
      • - * - *
      • When the reordering mode is set to - * REORDER_NUMBERS_SPECIAL, - * the algorithm used to perform Bidi transformations when calling - * setPara should approximate the algorithm used in Microsoft - * Windows XP rather than strictly conform to the Unicode Bidi algorithm. - *
        - * The differences between the basic algorithm and the algorithm addressed - * by this option are as follows: - *
          - *
        • Within text at an even embedding level, the sequence "123AB" - * (where AB represent R or AL letters) is transformed to "123BA" by the - * Unicode algorithm and to "BA123" by the Windows algorithm.
        • - * - *
        • Arabic-Indic numbers (AN) are handled by the Windows algorithm just - * like regular numbers (EN).
        • - *
      • - * - *
      • When the reordering mode is set to - * REORDER_GROUP_NUMBERS_WITH_R, - * numbers located between LTR text and RTL text are associated with the RTL - * text. For instance, an LTR paragraph with content "abc 123 DEF" (where - * upper case letters represent RTL characters) will be transformed to - * "abc FED 123" (and not "abc 123 FED"), "DEF 123 abc" will be transformed - * to "123 FED abc" and "123 FED abc" will be transformed to "DEF 123 abc". - * This makes the algorithm reversible and makes it useful when round trip - * (from visual to logical and back to visual) must be achieved without - * adding LRM characters. However, this is a variation from the standard - * Unicode Bidi algorithm.
        - * The source text should not contain Bidi control characters other than LRM - * or RLM.
      • - * - *
      • When the reordering mode is set to - * REORDER_RUNS_ONLY, - * a "Logical to Logical" transformation must be performed: - *
          - *
        • If the default text level of the source text (argument - * paraLevel in setPara) is even, the source text - * will be handled as LTR logical text and will be transformed to the RTL - * logical text which has the same LTR visual display.
        • - *
        • If the default level of the source text is odd, the source text - * will be handled as RTL logical text and will be transformed to the - * LTR logical text which has the same LTR visual display.
        • - *
        - * This mode may be needed when logical text which is basically Arabic or - * Hebrew, with possible included numbers or phrases in English, has to be - * displayed as if it had an even embedding level (this can happen if the - * displaying application treats all text as if it was basically LTR). - *
        - * This mode may also be needed in the reverse case, when logical text which - * is basically English, with possible included phrases in Arabic or Hebrew, - * has to be displayed as if it had an odd embedding level. - *
        - * Both cases could be handled by adding LRE or RLE at the head of the - * text, if the display subsystem supports these formatting controls. If it - * does not, the problem may be handled by transforming the source text in - * this mode before displaying it, so that it will be displayed properly. - *
        - * The source text should not contain Bidi control characters other than LRM - * or RLM.
      • - * - *
      • When the reordering mode is set to - * REORDER_INVERSE_NUMBERS_AS_L, an "inverse Bidi" - * algorithm is applied. - * Runs of text with numeric characters will be treated like LTR letters and - * may need to be surrounded with LRM characters when they are written in - * reordered sequence (the option INSERT_LRM_FOR_NUMERIC can - * be used with method writeReordered to this end. This mode - * is equivalent to calling setInverse() with - * argument isInverse set to true.
      • - * - *
      • When the reordering mode is set to - * REORDER_INVERSE_LIKE_DIRECT, the "direct" Logical to - * Visual Bidi algorithm is used as an approximation of an "inverse Bidi" - * algorithm. This mode is similar to mode - * REORDER_INVERSE_NUMBERS_AS_L but is closer to the - * regular Bidi algorithm. - *
        - * For example, an LTR paragraph with the content "FED 123 456 CBA" (where - * upper case represents RTL characters) will be transformed to - * "ABC 456 123 DEF", as opposed to "DEF 123 456 ABC" - * with mode REORDER_INVERSE_NUMBERS_AS_L.
        - * When used in conjunction with option - * OPTION_INSERT_MARKS, this mode generally - * adds Bidi marks to the output significantly more sparingly than mode - * REORDER_INVERSE_NUMBERS_AS_L.
        with option - * INSERT_LRM_FOR_NUMERIC in calls to - * writeReordered.
      • - * - *
      • When the reordering mode is set to - * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the Logical to Visual - * Bidi algorithm used in Windows XP is used as an approximation of an "inverse - * Bidi" algorithm. - *
        - * For example, an LTR paragraph with the content "abc FED123" (where - * upper case represents RTL characters) will be transformed to - * "abc 123DEF.
      • - *
      - * - *

      In all the reordering modes specifying an "inverse Bidi" algorithm - * (i.e. those with a name starting with REORDER_INVERSE), - * output runs should be retrieved using getVisualRun(), and - * the output text with writeReordered(). The caller should - * keep in mind that in "inverse Bidi" modes the input is actually visually - * ordered text and reordered output returned by getVisualRun() - * or writeReordered() are actually runs or character string - * of logically ordered output.
      - * For all the "inverse Bidi" modes, the source text should not contain - * Bidi control characters other than LRM or RLM.

      - * - *

      Note that option OUTPUT_REVERSE of - * writeReordered has no useful meaning and should not be used - * in conjunction with any value of the reordering mode specifying "inverse - * Bidi" or with value REORDER_RUNS_ONLY. - * - * @param reorderingMode specifies the required variant of the Bidi - * algorithm. - * - * @see #setInverse - * @see #setPara - * @see #writeReordered - * @see #INSERT_LRM_FOR_NUMERIC - * @see #OUTPUT_REVERSE - * @see #REORDER_DEFAULT - * @see #REORDER_NUMBERS_SPECIAL - * @see #REORDER_GROUP_NUMBERS_WITH_R - * @see #REORDER_RUNS_ONLY - * @see #REORDER_INVERSE_NUMBERS_AS_L - * @see #REORDER_INVERSE_LIKE_DIRECT - * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL - * @stable ICU 3.8 - */ - public void setReorderingMode(int reorderingMode) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * What is the requested reordering mode for a given Bidi object? - * - * @return the current reordering mode of the Bidi object - * - * @see #setReorderingMode - * @stable ICU 3.8 - */ - public int getReorderingMode() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Specify which of the reordering options should be applied during Bidi - * transformations. - * - * @param options A combination of zero or more of the following - * reordering options: - * OPTION_DEFAULT, OPTION_INSERT_MARKS, - * OPTION_REMOVE_CONTROLS, OPTION_STREAMING. - * - * @see #getReorderingOptions - * @see #OPTION_DEFAULT - * @see #OPTION_INSERT_MARKS - * @see #OPTION_REMOVE_CONTROLS - * @see #OPTION_STREAMING - * @stable ICU 3.8 - */ - public void setReorderingOptions(int options) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * What are the reordering options applied to a given Bidi object? - * - * @return the current reordering options of the Bidi object - * - * @see #setReorderingOptions - * @stable ICU 3.8 - */ - public int getReorderingOptions() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Perform the Unicode Bidi algorithm. It is defined in the - * Unicode Standard Annex #9, - * version 13, - * also described in The Unicode Standard, Version 4.0 .

      - * - * This method takes a piece of plain text containing one or more paragraphs, - * with or without externally specified embedding levels from styled - * text and computes the left-right-directionality of each character.

      - * - * If the entire text is all of the same directionality, then - * the method may not perform all the steps described by the algorithm, - * i.e., some levels may not be the same as if all steps were performed. - * This is not relevant for unidirectional text.
      - * For example, in pure LTR text with numbers the numbers would get - * a resolved level of 2 higher than the surrounding text according to - * the algorithm. This implementation may set all resolved levels to - * the same value in such a case.

      - * - * The text can be composed of multiple paragraphs. Occurrence of a block - * separator in the text terminates a paragraph, and whatever comes next starts - * a new paragraph. The exception to this rule is when a Carriage Return (CR) - * is followed by a Line Feed (LF). Both CR and LF are block separators, but - * in that case, the pair of characters is considered as terminating the - * preceding paragraph, and a new paragraph will be started by a character - * coming after the LF. - * - * Although the text is passed here as a String, it is - * stored internally as an array of characters. Therefore the - * documentation will refer to indexes of the characters in the text. - * - * @param text contains the text that the Bidi algorithm will be performed - * on. This text can be retrieved with getText() or - * getTextAsString.
      - * - * @param paraLevel specifies the default level for the text; - * it is typically 0 (LTR) or 1 (RTL). - * If the method shall determine the paragraph level from the text, - * then paraLevel can be set to - * either LEVEL_DEFAULT_LTR - * or LEVEL_DEFAULT_RTL; if the text contains multiple - * paragraphs, the paragraph level shall be determined separately for - * each paragraph; if a paragraph does not include any strongly typed - * character, then the desired default is used (0 for LTR or 1 for RTL). - * Any other value between 0 and MAX_EXPLICIT_LEVEL - * is also valid, with odd levels indicating RTL. - * - * @param embeddingLevels (in) may be used to preset the embedding and override levels, - * ignoring characters like LRE and PDF in the text. - * A level overrides the directional property of its corresponding - * (same index) character if the level has the - * LEVEL_OVERRIDE bit set.

      - * Except for that bit, it must be - * paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL, - * with one exception: a level of zero may be specified for a - * paragraph separator even if paraLevel>0 when multiple - * paragraphs are submitted in the same call to setPara().

      - * Caution: A reference to this array, not a copy - * of the levels, will be stored in the Bidi object; - * the embeddingLevels - * should not be modified to avoid unexpected results on subsequent - * Bidi operations. However, the setPara() and - * setLine() methods may modify some or all of the - * levels.

      - * Note: the embeddingLevels array must - * have one entry for each character in text. - * - * @throws IllegalArgumentException if the values in embeddingLevels are - * not within the allowed range - * - * @see #LEVEL_DEFAULT_LTR - * @see #LEVEL_DEFAULT_RTL - * @see #LEVEL_OVERRIDE - * @see #MAX_EXPLICIT_LEVEL - * @stable ICU 3.8 - */ - public void setPara(String text, byte paraLevel, byte[] embeddingLevels) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Perform the Unicode Bidi algorithm. It is defined in the - * Unicode Standard Annex #9, - * version 13, - * also described in The Unicode Standard, Version 4.0 .

      - * - * This method takes a piece of plain text containing one or more paragraphs, - * with or without externally specified embedding levels from styled - * text and computes the left-right-directionality of each character.

      - * - * If the entire text is all of the same directionality, then - * the method may not perform all the steps described by the algorithm, - * i.e., some levels may not be the same as if all steps were performed. - * This is not relevant for unidirectional text.
      - * For example, in pure LTR text with numbers the numbers would get - * a resolved level of 2 higher than the surrounding text according to - * the algorithm. This implementation may set all resolved levels to - * the same value in such a case.

      - * - * The text can be composed of multiple paragraphs. Occurrence of a block - * separator in the text terminates a paragraph, and whatever comes next starts - * a new paragraph. The exception to this rule is when a Carriage Return (CR) - * is followed by a Line Feed (LF). Both CR and LF are block separators, but - * in that case, the pair of characters is considered as terminating the - * preceding paragraph, and a new paragraph will be started by a character - * coming after the LF. - * - * The text is stored internally as an array of characters. Therefore the - * documentation will refer to indexes of the characters in the text. - * - * @param chars contains the text that the Bidi algorithm will be performed - * on. This text can be retrieved with getText() or - * getTextAsString.
      - * - * @param paraLevel specifies the default level for the text; - * it is typically 0 (LTR) or 1 (RTL). - * If the method shall determine the paragraph level from the text, - * then paraLevel can be set to - * either LEVEL_DEFAULT_LTR - * or LEVEL_DEFAULT_RTL; if the text contains multiple - * paragraphs, the paragraph level shall be determined separately for - * each paragraph; if a paragraph does not include any strongly typed - * character, then the desired default is used (0 for LTR or 1 for RTL). - * Any other value between 0 and MAX_EXPLICIT_LEVEL - * is also valid, with odd levels indicating RTL. - * - * @param embeddingLevels (in) may be used to preset the embedding and - * override levels, ignoring characters like LRE and PDF in the text. - * A level overrides the directional property of its corresponding - * (same index) character if the level has the - * LEVEL_OVERRIDE bit set.

      - * Except for that bit, it must be - * paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL, - * with one exception: a level of zero may be specified for a - * paragraph separator even if paraLevel>0 when multiple - * paragraphs are submitted in the same call to setPara().

      - * Caution: A reference to this array, not a copy - * of the levels, will be stored in the Bidi object; - * the embeddingLevels - * should not be modified to avoid unexpected results on subsequent - * Bidi operations. However, the setPara() and - * setLine() methods may modify some or all of the - * levels.

      - * Note: the embeddingLevels array must - * have one entry for each character in text. - * - * @throws IllegalArgumentException if the values in embeddingLevels are - * not within the allowed range - * - * @see #LEVEL_DEFAULT_LTR - * @see #LEVEL_DEFAULT_RTL - * @see #LEVEL_OVERRIDE - * @see #MAX_EXPLICIT_LEVEL - * @stable ICU 3.8 - */ - public void setPara(char[] chars, byte paraLevel, byte[] embeddingLevels) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the - * Unicode Standard Annex #9, - * version 13, - * also described in The Unicode Standard, Version 4.0 .

      - * - * This method takes a paragraph of text and computes the - * left-right-directionality of each character. The text should not - * contain any Unicode block separators.

      - * - * The RUN_DIRECTION attribute in the text, if present, determines the base - * direction (left-to-right or right-to-left). If not present, the base - * direction is computed using the Unicode Bidirectional Algorithm, - * defaulting to left-to-right if there are no strong directional characters - * in the text. This attribute, if present, must be applied to all the text - * in the paragraph.

      - * - * The BIDI_EMBEDDING attribute in the text, if present, represents - * embedding level information. Negative values from -1 to -62 indicate - * overrides at the absolute value of the level. Positive values from 1 to - * 62 indicate embeddings. Where values are zero or not defined, the base - * embedding level as determined by the base direction is assumed.

      - * - * The NUMERIC_SHAPING attribute in the text, if present, converts European - * digits to other decimal digits before running the bidi algorithm. This - * attribute, if present, must be applied to all the text in the paragraph. - * - * If the entire text is all of the same directionality, then - * the method may not perform all the steps described by the algorithm, - * i.e., some levels may not be the same as if all steps were performed. - * This is not relevant for unidirectional text.
      - * For example, in pure LTR text with numbers the numbers would get - * a resolved level of 2 higher than the surrounding text according to - * the algorithm. This implementation may set all resolved levels to - * the same value in such a case.

      - * - * @param paragraph a paragraph of text with optional character and - * paragraph attribute information - * @stable ICU 3.8 - */ - public void setPara(AttributedCharacterIterator paragraph) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Specify whether block separators must be allocated level zero, - * so that successive paragraphs will progress from left to right. - * This method must be called before setPara(). - * Paragraph separators (B) may appear in the text. Setting them to level zero - * means that all paragraph separators (including one possibly appearing - * in the last text position) are kept in the reordered text after the text - * that they follow in the source text. - * When this feature is not enabled, a paragraph separator at the last - * position of the text before reordering will go to the first position - * of the reordered text when the paragraph level is odd. - * - * @param ordarParaLTR specifies whether paragraph separators (B) must - * receive level 0, so that successive paragraphs progress from left to right. - * - * @see #setPara - * @stable ICU 3.8 - */ - public void orderParagraphsLTR(boolean ordarParaLTR) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Is this Bidi object set to allocate level 0 to block - * separators so that successive paragraphs progress from left to right? - * - * @return true if the Bidi object is set to - * allocate level 0 to block separators. - * - * @stable ICU 3.8 - */ - public boolean isOrderParagraphsLTR() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the directionality of the text. - * - * @return a value of LTR, RTL or MIXED - * that indicates if the entire text - * represented by this object is unidirectional, - * and which direction, or if it is mixed-directional. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #LTR - * @see #RTL - * @see #MIXED - * @stable ICU 3.8 - */ - public byte getDirection() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the text. - * - * @return A String containing the text that the - * Bidi object was created for. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #setPara - * @see #setLine - * @stable ICU 3.8 - */ - public String getTextAsString() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the text. - * - * @return A char array containing the text that the - * Bidi object was created for. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #setPara - * @see #setLine - * @stable ICU 3.8 - */ - public char[] getText() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the length of the text. - * - * @return The length of the text that the Bidi object was - * created for. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @stable ICU 3.8 - */ - public int getLength() - { - return bidi.getLength(); - } - - /** - * Get the length of the source text processed by the last call to - * setPara(). This length may be different from the length of - * the source text if option OPTION_STREAMING has been - * set. - *
      - * Note that whenever the length of the text affects the execution or the - * result of a method, it is the processed length which must be considered, - * except for setPara (which receives unprocessed source text) - * and getLength (which returns the original length of the - * source text).
      - * In particular, the processed length is the one to consider in the - * following cases: - *

        - *
      • maximum value of the limit argument of - * setLine
      • - *
      • maximum value of the charIndex argument of - * getParagraph
      • - *
      • maximum value of the charIndex argument of - * getLevelAt
      • - *
      • number of elements in the array returned by getLevels - *
      • - *
      • maximum value of the logicalStart argument of - * getLogicalRun
      • - *
      • maximum value of the logicalIndex argument of - * getVisualIndex
      • - *
      • number of elements returned by getLogicalMap
      • - *
      • length of text processed by writeReordered
      • - *
      - * - * @return The length of the part of the source text processed by - * the last call to setPara. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #setPara - * @see #OPTION_STREAMING - * @stable ICU 3.8 - */ - public int getProcessedLength() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the length of the reordered text resulting from the last call to - * setPara(). This length may be different from the length - * of the source text if option OPTION_INSERT_MARKS - * or option OPTION_REMOVE_CONTROLS has been set. - *
      - * This resulting length is the one to consider in the following cases: - *
        - *
      • maximum value of the visualIndex argument of - * getLogicalIndex
      • - *
      • number of elements returned by getVisualMap
      • - *
      - * Note that this length stays identical to the source text length if - * Bidi marks are inserted or removed using option bits of - * writeReordered, or if option - * REORDER_INVERSE_NUMBERS_AS_L has been set. - * - * @return The length of the reordered text resulting from - * the last call to setPara. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #setPara - * @see #OPTION_INSERT_MARKS - * @see #OPTION_REMOVE_CONTROLS - * @see #REORDER_INVERSE_NUMBERS_AS_L - * @stable ICU 3.8 - */ - public int getResultLength() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /* paragraphs API methods ------------------------------------------------- */ - - /** - * Get the paragraph level of the text. - * - * @return The paragraph level. If there are multiple paragraphs, their - * level may vary if the required paraLevel is LEVEL_DEFAULT_LTR or - * LEVEL_DEFAULT_RTL. In that case, the level of the first paragraph - * is returned. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #LEVEL_DEFAULT_LTR - * @see #LEVEL_DEFAULT_RTL - * @see #getParagraph - * @see #getParagraphByIndex - * @stable ICU 3.8 - */ - public byte getParaLevel() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the number of paragraphs. - * - * @return The number of paragraphs. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @stable ICU 3.8 - */ - public int countParagraphs() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get a paragraph, given the index of this paragraph. - * - * This method returns information about a paragraph.

      - * - * @param paraIndex is the number of the paragraph, in the - * range [0..countParagraphs()-1]. - * - * @return a BidiRun object with the details of the paragraph:
      - * start will receive the index of the first character - * of the paragraph in the text.
      - * limit will receive the limit of the paragraph.
      - * embeddingLevel will receive the level of the paragraph. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if paraIndex is not in the range - * [0..countParagraphs()-1] - * - * @see com.ibm.icu.text.BidiRun - * @stable ICU 3.8 - */ - public BidiRun getParagraphByIndex(int paraIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get a paragraph, given a position within the text. - * This method returns information about a paragraph.
      - * Note: if the paragraph index is known, it is more efficient to - * retrieve the paragraph information using getParagraphByIndex().

      - * - * @param charIndex is the index of a character within the text, in the - * range [0..getProcessedLength()-1]. - * - * @return a BidiRun object with the details of the paragraph:
      - * start will receive the index of the first character - * of the paragraph in the text.
      - * limit will receive the limit of the paragraph.
      - * embeddingLevel will receive the level of the paragraph. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if charIndex is not within the legal range - * - * @see com.ibm.icu.text.BidiRun - * @see #getParagraphByIndex - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public BidiRun getParagraph(int charIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the index of a paragraph, given a position within the text.

      - * - * @param charIndex is the index of a character within the text, in the - * range [0..getProcessedLength()-1]. - * - * @return The index of the paragraph containing the specified position, - * starting from 0. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if charIndex is not within the legal range - * - * @see com.ibm.icu.text.BidiRun - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public int getParagraphIndex(int charIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Set a custom Bidi classifier used by the UBA implementation for Bidi - * class determination. - * - * @param classifier A new custom classifier. This can be null. - * - * @see #getCustomClassifier - * @stable ICU 3.8 - */ - public void setCustomClassifier(BidiClassifier classifier) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Gets the current custom class classifier used for Bidi class - * determination. - * - * @return An instance of class BidiClassifier - * - * @see #setCustomClassifier - * @stable ICU 3.8 - */ - public BidiClassifier getCustomClassifier() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Retrieves the Bidi class for a given code point. - *

      If a BidiClassifier is defined and returns a value - * other than CLASS_DEFAULT, that value is used; otherwise - * the default class determination mechanism is invoked.

      - * - * @param c The code point to get a Bidi class for. - * - * @return The Bidi class for the character c that is in effect - * for this Bidi instance. - * - * @see BidiClassifier - * @stable ICU 3.8 - */ - public int getCustomizedClass(int c) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * setLine() returns a Bidi object to - * contain the reordering information, especially the resolved levels, - * for all the characters in a line of text. This line of text is - * specified by referring to a Bidi object representing - * this information for a piece of text containing one or more paragraphs, - * and by specifying a range of indexes in this text.

      - * In the new line object, the indexes will range from 0 to limit-start-1.

      - * - * This is used after calling setPara() - * for a piece of text, and after line-breaking on that text. - * It is not necessary if each paragraph is treated as a single line.

      - * - * After line-breaking, rules (L1) and (L2) for the treatment of - * trailing WS and for reordering are performed on - * a Bidi object that represents a line.

      - * - * Important: the line Bidi object may - * reference data within the global text Bidi object. - * You should not alter the content of the global text object until - * you are finished using the line object. - * - * @param start is the line's first index into the text. - * - * @param limit is just behind the line's last index into the text - * (its last index +1). - * - * @return a Bidi object that will now represent a line of the text. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara - * @throws IllegalArgumentException if start and limit are not in the range - * 0<=start<limit<=getProcessedLength(), - * or if the specified line crosses a paragraph boundary - * - * @see #setPara - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public Bidi setLine(int start, int limit) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the level for one character. - * - * @param charIndex the index of a character. - * - * @return The level for the character at charIndex. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if charIndex is not in the range - * 0<=charIndex<getProcessedLength() - * - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public byte getLevelAt(int charIndex) - { - return (byte)bidi.getLevelAt(charIndex); - } - - /** - * Get an array of levels for each character.

      - * - * Note that this method may allocate memory under some - * circumstances, unlike getLevelAt(). - * - * @return The levels array for the text, - * or null if an error occurs. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @stable ICU 3.8 - */ - public byte[] getLevels() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get a logical run. - * This method returns information about a run and is used - * to retrieve runs in logical order.

      - * This is especially useful for line-breaking on a paragraph. - * - * @param logicalPosition is a logical position within the source text. - * - * @return a BidiRun object filled with start containing - * the first character of the run, limit containing - * the limit of the run, and embeddingLevel containing - * the level of the run. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if logicalPosition is not in the range - * 0<=logicalPosition<getProcessedLength() - * - * @see com.ibm.icu.text.BidiRun - * @see com.ibm.icu.text.BidiRun#getStart() - * @see com.ibm.icu.text.BidiRun#getLimit() - * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel() - * - * @stable ICU 3.8 - */ - public BidiRun getLogicalRun(int logicalPosition) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the number of runs. - * This method may invoke the actual reordering on the - * Bidi object, after setPara() - * may have resolved only the levels of the text. Therefore, - * countRuns() may have to allocate memory, - * and may throw an exception if it fails to do so. - * - * @return The number of runs. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @stable ICU 3.8 - */ - public int countRuns() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * - * Get a BidiRun object according to its index. BidiRun methods - * may be used to retrieve the run's logical start, length and level, - * which can be even for an LTR run or odd for an RTL run. - * In an RTL run, the character at the logical start is - * visually on the right of the displayed run. - * The length is the number of characters in the run.

      - * countRuns() is normally called - * before the runs are retrieved. - * - *

      - * Example: - *

      -     *  Bidi bidi = new Bidi();
      -     *  String text = "abc 123 DEFG xyz";
      -     *  bidi.setPara(text, Bidi.RTL, null);
      -     *  int i, count=bidi.countRuns(), logicalStart, visualIndex=0, length;
      -     *  BidiRun run;
      -     *  for (i = 0; i < count; ++i) {
      -     *      run = bidi.getVisualRun(i);
      -     *      logicalStart = run.getStart();
      -     *      length = run.getLength();
      -     *      if (Bidi.LTR == run.getEmbeddingLevel()) {
      -     *          do { // LTR
      -     *              show_char(text.charAt(logicalStart++), visualIndex++);
      -     *          } while (--length > 0);
      -     *      } else {
      -     *          logicalStart += length;  // logicalLimit
      -     *          do { // RTL
      -     *              show_char(text.charAt(--logicalStart), visualIndex++);
      -     *          } while (--length > 0);
      -     *      }
      -     *  }
      -     * 
      - *

      - * Note that in right-to-left runs, code like this places - * second surrogates before first ones (which is generally a bad idea) - * and combining characters before base characters. - *

      - * Use of {@link #writeReordered}, optionally with the - * {@link #KEEP_BASE_COMBINING} option, can be considered in - * order to avoid these issues. - * - * @param runIndex is the number of the run in visual order, in the - * range [0..countRuns()-1]. - * - * @return a BidiRun object containing the details of the run. The - * directionality of the run is - * LTR==0 or RTL==1, - * never MIXED. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if runIndex is not in - * the range 0<=runIndex<countRuns() - * - * @see #countRuns() - * @see com.ibm.icu.text.BidiRun - * @see com.ibm.icu.text.BidiRun#getStart() - * @see com.ibm.icu.text.BidiRun#getLength() - * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel() - * @stable ICU 3.8 - */ - public BidiRun getVisualRun(int runIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get the visual position from a logical text position. - * If such a mapping is used many times on the same - * Bidi object, then calling - * getLogicalMap() is more efficient. - *

      - * The value returned may be MAP_NOWHERE if there is no - * visual position because the corresponding text character is a Bidi - * control removed from output by the option - * OPTION_REMOVE_CONTROLS. - *

      - * When the visual output is altered by using options of - * writeReordered() such as INSERT_LRM_FOR_NUMERIC, - * KEEP_BASE_COMBINING, OUTPUT_REVERSE, - * REMOVE_BIDI_CONTROLS, the visual position returned may not - * be correct. It is advised to use, when possible, reordering options - * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. - *

      - * Note that in right-to-left runs, this mapping places - * second surrogates before first ones (which is generally a bad idea) - * and combining characters before base characters. - * Use of {@link #writeReordered}, optionally with the - * {@link #KEEP_BASE_COMBINING} option can be considered instead - * of using the mapping, in order to avoid these issues. - * - * @param logicalIndex is the index of a character in the text. - * - * @return The visual position of this character. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if logicalIndex is not in - * the range 0<=logicalIndex<getProcessedLength() - * - * @see #getLogicalMap - * @see #getLogicalIndex - * @see #getProcessedLength - * @see #MAP_NOWHERE - * @see #OPTION_REMOVE_CONTROLS - * @see #writeReordered - * @stable ICU 3.8 - */ - public int getVisualIndex(int logicalIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - - /** - * Get the logical text position from a visual position. - * If such a mapping is used many times on the same - * Bidi object, then calling - * getVisualMap() is more efficient. - *

      - * The value returned may be MAP_NOWHERE if there is no - * logical position because the corresponding text character is a Bidi - * mark inserted in the output by option - * OPTION_INSERT_MARKS. - *

      - * This is the inverse method to getVisualIndex(). - *

      - * When the visual output is altered by using options of - * writeReordered() such as INSERT_LRM_FOR_NUMERIC, - * KEEP_BASE_COMBINING, OUTPUT_REVERSE, - * REMOVE_BIDI_CONTROLS, the logical position returned may not - * be correct. It is advised to use, when possible, reordering options - * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. - * - * @param visualIndex is the visual position of a character. - * - * @return The index of this character in the text. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if visualIndex is not in - * the range 0<=visualIndex<getResultLength() - * - * @see #getVisualMap - * @see #getVisualIndex - * @see #getResultLength - * @see #MAP_NOWHERE - * @see #OPTION_INSERT_MARKS - * @see #writeReordered - * @stable ICU 3.8 - */ - public int getLogicalIndex(int visualIndex) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get a logical-to-visual index map (array) for the characters in the - * Bidi (paragraph or line) object. - *

      - * Some values in the map may be MAP_NOWHERE if the - * corresponding text characters are Bidi controls removed from the visual - * output by the option OPTION_REMOVE_CONTROLS. - *

      - * When the visual output is altered by using options of - * writeReordered() such as INSERT_LRM_FOR_NUMERIC, - * KEEP_BASE_COMBINING, OUTPUT_REVERSE, - * REMOVE_BIDI_CONTROLS, the visual positions returned may not - * be correct. It is advised to use, when possible, reordering options - * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. - *

      - * Note that in right-to-left runs, this mapping places - * second surrogates before first ones (which is generally a bad idea) - * and combining characters before base characters. - * Use of {@link #writeReordered}, optionally with the - * {@link #KEEP_BASE_COMBINING} option can be considered instead - * of using the mapping, in order to avoid these issues. - * - * @return an array of getProcessedLength() - * indexes which will reflect the reordering of the characters.

      - * The index map will result in - * indexMap[logicalIndex]==visualIndex, where - * indexMap represents the returned array. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #getVisualMap - * @see #getVisualIndex - * @see #getProcessedLength - * @see #MAP_NOWHERE - * @see #OPTION_REMOVE_CONTROLS - * @see #writeReordered - * @stable ICU 3.8 - */ - public int[] getLogicalMap() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Get a visual-to-logical index map (array) for the characters in the - * Bidi (paragraph or line) object. - *

      - * Some values in the map may be MAP_NOWHERE if the - * corresponding text characters are Bidi marks inserted in the visual - * output by the option OPTION_INSERT_MARKS. - *

      - * When the visual output is altered by using options of - * writeReordered() such as INSERT_LRM_FOR_NUMERIC, - * KEEP_BASE_COMBINING, OUTPUT_REVERSE, - * REMOVE_BIDI_CONTROLS, the logical positions returned may not - * be correct. It is advised to use, when possible, reordering options - * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. - * - * @return an array of getResultLength() - * indexes which will reflect the reordering of the characters.

      - * The index map will result in - * indexMap[visualIndex]==logicalIndex, where - * indexMap represents the returned array. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #getLogicalMap - * @see #getLogicalIndex - * @see #getResultLength - * @see #MAP_NOWHERE - * @see #OPTION_INSERT_MARKS - * @see #writeReordered - * @stable ICU 3.8 - */ - public int[] getVisualMap() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * This is a convenience method that does not use a Bidi object. - * It is intended to be used for when an application has determined the levels - * of objects (character sequences) and just needs to have them reordered (L2). - * This is equivalent to using getLogicalMap() on a - * Bidi object. - * - * @param levels is an array of levels that have been determined by - * the application. - * - * @return an array of levels.length - * indexes which will reflect the reordering of the characters.

      - * The index map will result in - * indexMap[logicalIndex]==visualIndex, where - * indexMap represents the returned array. - * - * @stable ICU 3.8 - */ - public static int[] reorderLogical(byte[] levels) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * This is a convenience method that does not use a Bidi object. - * It is intended to be used for when an application has determined the levels - * of objects (character sequences) and just needs to have them reordered (L2). - * This is equivalent to using getVisualMap() on a - * Bidi object. - * - * @param levels is an array of levels that have been determined by - * the application. - * - * @return an array of levels.length - * indexes which will reflect the reordering of the characters.

      - * The index map will result in - * indexMap[visualIndex]==logicalIndex, where - * indexMap represents the returned array. - * - * @stable ICU 3.8 - */ - public static int[] reorderVisual(byte[] levels) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Invert an index map. - * The index mapping of the argument map is inverted and returned as - * an array of indexes that we will call the inverse map. - * - * @param srcMap is an array whose elements define the original mapping - * from a source array to a destination array. - * Some elements of the source array may have no mapping in the - * destination array. In that case, their value will be - * the special value MAP_NOWHERE. - * All elements must be >=0 or equal to MAP_NOWHERE. - * Some elements in the source map may have a value greater than the - * srcMap.length if the destination array has more elements than the - * source array. - * There must be no duplicate indexes (two or more elements with the - * same value except MAP_NOWHERE). - * - * @return an array representing the inverse map. - * This array has a number of elements equal to 1 + the highest - * value in srcMap. - * For elements of the result array which have no matching elements - * in the source array, the corresponding elements in the inverse - * map will receive a value equal to MAP_NOWHERE. - * If element with index i in srcMap has a value k different - * from MAP_NOWHERE, this means that element i of - * the source array maps to element k in the destination array. - * The inverse map will have value i in its k-th element. - * For all elements of the destination array which do not map to - * an element in the source array, the corresponding element in the - * inverse map will have a value equal to MAP_NOWHERE. - * - * @see #MAP_NOWHERE - * @stable ICU 3.8 - */ - public static int[] invertMap(int[] srcMap) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /* - * Fields and methods for compatibility with java.text.bidi (Sun implementation) - */ - - /** - * Constant indicating base direction is left-to-right. - * @stable ICU 3.8 - */ - public static final int DIRECTION_LEFT_TO_RIGHT = LTR; - - /** - * Constant indicating base direction is right-to-left. - * @stable ICU 3.8 - */ - public static final int DIRECTION_RIGHT_TO_LEFT = RTL; - - /** - * Constant indicating that the base direction depends on the first strong - * directional character in the text according to the Unicode Bidirectional - * Algorithm. If no strong directional character is present, the base - * direction is left-to-right. - * @stable ICU 3.8 - */ - public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = LEVEL_DEFAULT_LTR; - - /** - * Constant indicating that the base direction depends on the first strong - * directional character in the text according to the Unicode Bidirectional - * Algorithm. If no strong directional character is present, the base - * direction is right-to-left. - * @stable ICU 3.8 - */ - public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = LEVEL_DEFAULT_RTL; - - /** - * Create Bidi from the given paragraph of text and base direction. - * - * @param paragraph a paragraph of text - * @param flags a collection of flags that control the algorithm. The - * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, - * DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and - * DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved. - * @see #DIRECTION_LEFT_TO_RIGHT - * @see #DIRECTION_RIGHT_TO_LEFT - * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT - * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT - * @stable ICU 3.8 - */ - public Bidi(String paragraph, int flags) - { - // Note: ICU and Oracle JDK are using the - // same DIRECTION_* flags definitions. - this(new java.text.Bidi(paragraph, flags)); - } - - /** - * Create Bidi from the given paragraph of text.

      - * - * The RUN_DIRECTION attribute in the text, if present, determines the base - * direction (left-to-right or right-to-left). If not present, the base - * direction is computed using the Unicode Bidirectional Algorithm, - * defaulting to left-to-right if there are no strong directional characters - * in the text. This attribute, if present, must be applied to all the text - * in the paragraph.

      - * - * The BIDI_EMBEDDING attribute in the text, if present, represents - * embedding level information. Negative values from -1 to -62 indicate - * overrides at the absolute value of the level. Positive values from 1 to - * 62 indicate embeddings. Where values are zero or not defined, the base - * embedding level as determined by the base direction is assumed.

      - * - * The NUMERIC_SHAPING attribute in the text, if present, converts European - * digits to other decimal digits before running the bidi algorithm. This - * attribute, if present, must be applied to all the text in the paragraph.

      - * - * Note: this constructor calls setPara() internally. - * - * @param paragraph a paragraph of text with optional character and - * paragraph attribute information - * @stable ICU 3.8 - */ - public Bidi(AttributedCharacterIterator paragraph) - { - // ICU does not define its own attributes and just - // use java.awt.font.TextAttribute. Thus, no mappings - // are necessary. - this(new java.text.Bidi(paragraph)); - } - - /** - * Create Bidi from the given text, embedding, and direction information. - * The embeddings array may be null. If present, the values represent - * embedding level information. Negative values from -1 to -61 indicate - * overrides at the absolute value of the level. Positive values from 1 to - * 61 indicate embeddings. Where values are zero, the base embedding level - * as determined by the base direction is assumed.

      - * - * Note: this constructor calls setPara() internally. - * - * @param text an array containing the paragraph of text to process. - * @param textStart the index into the text array of the start of the - * paragraph. - * @param embeddings an array containing embedding values for each character - * in the paragraph. This can be null, in which case it is assumed - * that there is no external embedding information. - * @param embStart the index into the embedding array of the start of the - * paragraph. - * @param paragraphLength the length of the paragraph in the text and - * embeddings arrays. - * @param flags a collection of flags that control the algorithm. The - * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, - * DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and - * DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved. - * - * @throws IllegalArgumentException if the values in embeddings are - * not within the allowed range - * - * @see #DIRECTION_LEFT_TO_RIGHT - * @see #DIRECTION_RIGHT_TO_LEFT - * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT - * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT - * @stable ICU 3.8 - */ - public Bidi(char[] text, - int textStart, - byte[] embeddings, - int embStart, - int paragraphLength, - int flags) - { - // Note: ICU and Oracle JDK are using the - // same DIRECTION_* flags definitions. - this(new java.text.Bidi(text, textStart, embeddings, embStart, paragraphLength, flags)); - } - - /** - * Create a Bidi object representing the bidi information on a line of text - * within the paragraph represented by the current Bidi. This call is not - * required if the entire paragraph fits on one line. - * - * @param lineStart the offset from the start of the paragraph to the start - * of the line. - * @param lineLimit the offset from the start of the paragraph to the limit - * of the line. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara - * @throws IllegalArgumentException if lineStart and lineLimit are not in the range - * 0<=lineStart<lineLimit<=getProcessedLength(), - * or if the specified line crosses a paragraph boundary - * @stable ICU 3.8 - */ - public Bidi createLineBidi(int lineStart, int lineLimit) - { - return new Bidi(bidi.createLineBidi(lineStart, lineLimit)); - } - - /** - * Return true if the line is not left-to-right or right-to-left. This means - * it either has mixed runs of left-to-right and right-to-left text, or the - * base direction differs from the direction of the only run of text. - * - * @return true if the line is not left-to-right or right-to-left. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara - * @stable ICU 3.8 - */ - public boolean isMixed() - { - return bidi.isMixed(); - } - - /** - * Return true if the line is all left-to-right text and the base direction - * is left-to-right. - * - * @return true if the line is all left-to-right text and the base direction - * is left-to-right. - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara - * @stable ICU 3.8 - */ - public boolean isLeftToRight() - { - return bidi.isLeftToRight(); - } - - /** - * Return true if the line is all right-to-left text, and the base direction - * is right-to-left - * - * @return true if the line is all right-to-left text, and the base - * direction is right-to-left - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara - * @stable ICU 3.8 - */ - public boolean isRightToLeft() - { - return bidi.isRightToLeft(); - } - - /** - * Return true if the base direction is left-to-right - * - * @return true if the base direction is left-to-right - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @stable ICU 3.8 - */ - public boolean baseIsLeftToRight() - { - return bidi.baseIsLeftToRight(); - } - - /** - * Return the base level (0 if left-to-right, 1 if right-to-left). - * - * @return the base level - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @stable ICU 3.8 - */ - public int getBaseLevel() - { - return bidi.getBaseLevel(); - } - - /** - * Return the number of level runs. - * - * @return the number of level runs - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @stable ICU 3.8 - */ - public int getRunCount() - { - return bidi.getRunCount(); - } - - /** - * Return the level of the nth logical run in this line. - * - * @param run the index of the run, between 0 and countRuns()-1 - * - * @return the level of the run - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if run is not in - * the range 0<=run<countRuns() - * @stable ICU 3.8 - */ - public int getRunLevel(int run) - { - return bidi.getRunLevel(run); - } - - /** - * Return the index of the character at the start of the nth logical run in - * this line, as an offset from the start of the line. - * - * @param run the index of the run, between 0 and countRuns() - * - * @return the start of the run - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if run is not in - * the range 0<=run<countRuns() - * @stable ICU 3.8 - */ - public int getRunStart(int run) - { - return bidi.getRunStart(run); - } - - /** - * Return the index of the character past the end of the nth logical run in - * this line, as an offset from the start of the line. For example, this - * will return the length of the line for the last run on the line. - * - * @param run the index of the run, between 0 and countRuns() - * - * @return the limit of the run - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * @throws IllegalArgumentException if run is not in - * the range 0<=run<countRuns() - * @stable ICU 3.8 - */ - public int getRunLimit(int run) - { - return bidi.getRunLimit(run); - } - - /** - * Return true if the specified text requires bidi analysis. If this returns - * false, the text will display left-to-right. Clients can then avoid - * constructing a Bidi object. Text in the Arabic Presentation Forms area of - * Unicode is presumed to already be shaped and ordered for display, and so - * will not cause this method to return true. - * - * @param text the text containing the characters to test - * @param start the start of the range of characters to test - * @param limit the limit of the range of characters to test - * - * @return true if the range of characters requires bidi analysis - * - * @stable ICU 3.8 - */ - public static boolean requiresBidi(char[] text, - int start, - int limit) - { - return java.text.Bidi.requiresBidi(text, start, limit); - } - - /** - * Reorder the objects in the array into visual order based on their levels. - * This is a utility method to use when you have a collection of objects - * representing runs of text in logical order, each run containing text at a - * single level. The elements at index from - * objectStart up to objectStart + count in the - * objects array will be reordered into visual order assuming - * each run of text has the level indicated by the corresponding element in - * the levels array (at index - objectStart + levelStart). - * - * @param levels an array representing the bidi level of each object - * @param levelStart the start position in the levels array - * @param objects the array of objects to be reordered into visual order - * @param objectStart the start position in the objects array - * @param count the number of objects to reorder - * @stable ICU 3.8 - */ - public static void reorderVisually(byte[] levels, - int levelStart, - Object[] objects, - int objectStart, - int count) - { - java.text.Bidi.reorderVisually(levels, levelStart, objects, objectStart, count); - } - - /** - * Take a Bidi object containing the reordering - * information for a piece of text (one or more paragraphs) set by - * setPara() or for a line of text set by setLine() - * and return a string containing the reordered text. - * - *

      The text may have been aliased (only a reference was stored - * without copying the contents), thus it must not have been modified - * since the setPara() call.

      - * - * This method preserves the integrity of characters with multiple - * code units and (optionally) combining characters. - * Characters in RTL runs can be replaced by mirror-image characters - * in the returned string. Note that "real" mirroring has to be done in a - * rendering engine by glyph selection and that for many "mirrored" - * characters there are no Unicode characters as mirror-image equivalents. - * There are also options to insert or remove Bidi control - * characters; see the descriptions of the return value and the - * options parameter, and of the option bit flags. - * - * @param options A bit set of options for the reordering that control - * how the reordered text is written. - * The options include mirroring the characters on a code - * point basis and inserting LRM characters, which is used - * especially for transforming visually stored text - * to logically stored text (although this is still an - * imperfect implementation of an "inverse Bidi" algorithm - * because it uses the "forward Bidi" algorithm at its core). - * The available options are: - * DO_MIRRORING, - * INSERT_LRM_FOR_NUMERIC, - * KEEP_BASE_COMBINING, - * OUTPUT_REVERSE, - * REMOVE_BIDI_CONTROLS, - * STREAMING - * - * @return The reordered text. - * If the INSERT_LRM_FOR_NUMERIC option is set, then - * the length of the returned string could be as large as - * getLength()+2*countRuns().
      - * If the REMOVE_BIDI_CONTROLS option is set, then the - * length of the returned string may be less than - * getLength().
      - * If none of these options is set, then the length of the returned - * string will be exactly getProcessedLength(). - * - * @throws IllegalStateException if this call is not preceded by a successful - * call to setPara or setLine - * - * @see #DO_MIRRORING - * @see #INSERT_LRM_FOR_NUMERIC - * @see #KEEP_BASE_COMBINING - * @see #OUTPUT_REVERSE - * @see #REMOVE_BIDI_CONTROLS - * @see #OPTION_STREAMING - * @see #getProcessedLength - * @stable ICU 3.8 - */ - public String writeReordered(int options) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Reverse a Right-To-Left run of Unicode text. - * - * This method preserves the integrity of characters with multiple - * code units and (optionally) combining characters. - * Characters can be replaced by mirror-image characters - * in the destination buffer. Note that "real" mirroring has - * to be done in a rendering engine by glyph selection - * and that for many "mirrored" characters there are no - * Unicode characters as mirror-image equivalents. - * There are also options to insert or remove Bidi control - * characters. - * - * This method is the implementation for reversing RTL runs as part - * of writeReordered(). For detailed descriptions - * of the parameters, see there. - * Since no Bidi controls are inserted here, the output string length - * will never exceed src.length(). - * - * @see #writeReordered - * - * @param src The RTL run text. - * - * @param options A bit set of options for the reordering that control - * how the reordered text is written. - * See the options parameter in writeReordered(). - * - * @return The reordered text. - * If the REMOVE_BIDI_CONTROLS option - * is set, then the length of the returned string may be less than - * src.length(). If this option is not set, - * then the length of the returned string will be exactly - * src.length(). - * - * @throws IllegalArgumentException if src is null. - * @stable ICU 3.8 - */ - public static String writeReverse(String src, int options) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } -} +/* +******************************************************************************* +* Copyright (C) 2001-2011, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +*/ + +/* FOOD FOR THOUGHT: currently the reordering modes are a mixture of + * algorithm for direct BiDi, algorithm for inverse Bidi and the bizarre + * concept of RUNS_ONLY which is a double operation. + * It could be advantageous to divide this into 3 concepts: + * a) Operation: direct / inverse / RUNS_ONLY + * b) Direct algorithm: default / NUMBERS_SPECIAL / GROUP_NUMBERS_WITH_L + * c) Inverse algorithm: default / INVERSE_LIKE_DIRECT / NUMBERS_SPECIAL + * This would allow combinations not possible today like RUNS_ONLY with + * NUMBERS_SPECIAL. + * Also allow to set INSERT_MARKS for the direct step of RUNS_ONLY and + * REMOVE_CONTROLS for the inverse step. + * Not all combinations would be supported, and probably not all do make sense. + * This would need to document which ones are supported and what are the + * fallbacks for unsupported combinations. + */ + +//TODO: make sample program do something simple but real and complete + +package com.ibm.icu.text; + +import java.text.AttributedCharacterIterator; + +/** + * + *

      Bidi algorithm for ICU

      + * + * This is an implementation of the Unicode Bidirectional algorithm. The + * algorithm is defined in the Unicode Standard Annex #9, + * version 13, also described in The Unicode Standard, Version 4.0 . + *

      + * + * Note: Libraries that perform a bidirectional algorithm and reorder strings + * accordingly are sometimes called "Storage Layout Engines". ICU's Bidi and + * shaping (ArabicShaping) classes can be used at the core of such "Storage + * Layout Engines". + * + *

      General remarks about the API:

      + * + * The "limit" of a sequence of characters is the position just after + * their last character, i.e., one more than that position. + *

      + * + * Some of the API methods provide access to "runs". Such a + * "run" is defined as a sequence of characters that are at the same + * embedding level after performing the Bidi algorithm. + *

      + * + *

      Basic concept: paragraph

      + * A piece of text can be divided into several paragraphs by characters + * with the Bidi class Block Separator. For handling of + * paragraphs, see: + *
        + *
      • {@link #countParagraphs} + *
      • {@link #getParaLevel} + *
      • {@link #getParagraph} + *
      • {@link #getParagraphByIndex} + *
      + * + *

      Basic concept: text direction

      + * The direction of a piece of text may be: + *
        + *
      • {@link #LTR} + *
      • {@link #RTL} + *
      • {@link #MIXED} + *
      + * + *

      Basic concept: levels

      + * + * Levels in this API represent embedding levels according to the Unicode + * Bidirectional Algorithm. + * Their low-order bit (even/odd value) indicates the visual direction.

      + * + * Levels can be abstract values when used for the + * paraLevel and embeddingLevels + * arguments of setPara(); there: + *

        + *
      • the high-order bit of an embeddingLevels[] + * value indicates whether the using application is + * specifying the level of a character to override whatever the + * Bidi implementation would resolve it to.
      • + *
      • paraLevel can be set to the + * pseudo-level values LEVEL_DEFAULT_LTR + * and LEVEL_DEFAULT_RTL.
      • + *
      + * + *

      The related constants are not real, valid level values. + * DEFAULT_XXX can be used to specify + * a default for the paragraph level for + * when the setPara() method + * shall determine it but there is no + * strongly typed character in the input.

      + * + * Note that the value for LEVEL_DEFAULT_LTR is even + * and the one for LEVEL_DEFAULT_RTL is odd, + * just like with normal LTR and RTL level values - + * these special values are designed that way. Also, the implementation + * assumes that MAX_EXPLICIT_LEVEL is odd. + * + *

        See Also: + *
      • {@link #LEVEL_DEFAULT_LTR} + *
      • {@link #LEVEL_DEFAULT_RTL} + *
      • {@link #LEVEL_OVERRIDE} + *
      • {@link #MAX_EXPLICIT_LEVEL} + *
      • {@link #setPara} + *
      + * + *

      Basic concept: Reordering Mode

      + * Reordering mode values indicate which variant of the Bidi algorithm to + * use. + * + *
        See Also: + *
      • {@link #setReorderingMode} + *
      • {@link #REORDER_DEFAULT} + *
      • {@link #REORDER_NUMBERS_SPECIAL} + *
      • {@link #REORDER_GROUP_NUMBERS_WITH_R} + *
      • {@link #REORDER_RUNS_ONLY} + *
      • {@link #REORDER_INVERSE_NUMBERS_AS_L} + *
      • {@link #REORDER_INVERSE_LIKE_DIRECT} + *
      • {@link #REORDER_INVERSE_FOR_NUMBERS_SPECIAL} + *
      + * + *

      Basic concept: Reordering Options

      + * Reordering options can be applied during Bidi text transformations. + *
        See Also: + *
      • {@link #setReorderingOptions} + *
      • {@link #OPTION_DEFAULT} + *
      • {@link #OPTION_INSERT_MARKS} + *
      • {@link #OPTION_REMOVE_CONTROLS} + *
      • {@link #OPTION_STREAMING} + *
      + * + * + * @author Simon Montagu, Matitiahu Allouche (ported from C code written by Markus W. Scherer) + * @stable ICU 3.8 + * + * + *

      Sample code for the ICU Bidi API

      + * + *
      Rendering a paragraph with the ICU Bidi API
      + * + * This is (hypothetical) sample code that illustrates how the ICU Bidi API + * could be used to render a paragraph of text. Rendering code depends highly on + * the graphics system, therefore this sample code must make a lot of + * assumptions, which may or may not match any existing graphics system's + * properties. + * + *

      + * The basic assumptions are: + *

      + *
        + *
      • Rendering is done from left to right on a horizontal line.
      • + *
      • A run of single-style, unidirectional text can be rendered at once. + *
      • + *
      • Such a run of text is passed to the graphics system with characters + * (code units) in logical order.
      • + *
      • The line-breaking algorithm is very complicated and Locale-dependent - + * and therefore its implementation omitted from this sample code.
      • + *
      + * + *
      + *
      + *  package com.ibm.icu.dev.test.bidi;
      + *
      + *  import com.ibm.icu.text.Bidi;
      + *  import com.ibm.icu.text.BidiRun;
      + *
      + *  public class Sample {
      + *
      + *      static final int styleNormal = 0;
      + *      static final int styleSelected = 1;
      + *      static final int styleBold = 2;
      + *      static final int styleItalics = 4;
      + *      static final int styleSuper=8;
      + *      static final int styleSub = 16;
      + *
      + *      static class StyleRun {
      + *          int limit;
      + *          int style;
      + *
      + *          public StyleRun(int limit, int style) {
      + *              this.limit = limit;
      + *              this.style = style;
      + *          }
      + *      }
      + *
      + *      static class Bounds {
      + *          int start;
      + *          int limit;
      + *
      + *          public Bounds(int start, int limit) {
      + *              this.start = start;
      + *              this.limit = limit;
      + *          }
      + *      }
      + *
      + *      static int getTextWidth(String text, int start, int limit,
      + *                              StyleRun[] styleRuns, int styleRunCount) {
      + *          // simplistic way to compute the width
      + *          return limit - start;
      + *      }
      + *
      + *      // set limit and StyleRun limit for a line
      + *      // from text[start] and from styleRuns[styleRunStart]
      + *      // using Bidi.getLogicalRun(...)
      + *      // returns line width
      + *      static int getLineBreak(String text, Bounds line, Bidi para,
      + *                              StyleRun styleRuns[], Bounds styleRun) {
      + *          // dummy return
      + *          return 0;
      + *      }
      + *
      + *      // render runs on a line sequentially, always from left to right
      + *
      + *      // prepare rendering a new line
      + *      static void startLine(byte textDirection, int lineWidth) {
      + *          System.out.println();
      + *      }
      + *
      + *      // render a run of text and advance to the right by the run width
      + *      // the text[start..limit-1] is always in logical order
      + *      static void renderRun(String text, int start, int limit,
      + *                            byte textDirection, int style) {
      + *      }
      + *
      + *      // We could compute a cross-product
      + *      // from the style runs with the directional runs
      + *      // and then reorder it.
      + *      // Instead, here we iterate over each run type
      + *      // and render the intersections -
      + *      // with shortcuts in simple (and common) cases.
      + *      // renderParagraph() is the main function.
      + *
      + *      // render a directional run with
      + *      // (possibly) multiple style runs intersecting with it
      + *      static void renderDirectionalRun(String text, int start, int limit,
      + *                                       byte direction, StyleRun styleRuns[],
      + *                                       int styleRunCount) {
      + *          int i;
      + *
      + *          // iterate over style runs
      + *          if (direction == Bidi.LTR) {
      + *              int styleLimit;
      + *              for (i = 0; i < styleRunCount; ++i) {
      + *                  styleLimit = styleRuns[i].limit;
      + *                  if (start < styleLimit) {
      + *                      if (styleLimit > limit) {
      + *                          styleLimit = limit;
      + *                      }
      + *                      renderRun(text, start, styleLimit,
      + *                                direction, styleRuns[i].style);
      + *                      if (styleLimit == limit) {
      + *                          break;
      + *                      }
      + *                      start = styleLimit;
      + *                  }
      + *              }
      + *          } else {
      + *              int styleStart;
      + *
      + *              for (i = styleRunCount-1; i >= 0; --i) {
      + *                  if (i > 0) {
      + *                      styleStart = styleRuns[i-1].limit;
      + *                  } else {
      + *                      styleStart = 0;
      + *                  }
      + *                  if (limit >= styleStart) {
      + *                      if (styleStart < start) {
      + *                          styleStart = start;
      + *                      }
      + *                      renderRun(text, styleStart, limit, direction,
      + *                                styleRuns[i].style);
      + *                      if (styleStart == start) {
      + *                          break;
      + *                      }
      + *                      limit = styleStart;
      + *                  }
      + *              }
      + *          }
      + *      }
      + *
      + *      // the line object represents text[start..limit-1]
      + *      static void renderLine(Bidi line, String text, int start, int limit,
      + *                             StyleRun styleRuns[], int styleRunCount) {
      + *          byte direction = line.getDirection();
      + *          if (direction != Bidi.MIXED) {
      + *              // unidirectional
      + *              if (styleRunCount <= 1) {
      + *                  renderRun(text, start, limit, direction, styleRuns[0].style);
      + *              } else {
      + *                  renderDirectionalRun(text, start, limit, direction,
      + *                                       styleRuns, styleRunCount);
      + *              }
      + *          } else {
      + *              // mixed-directional
      + *              int count, i;
      + *              BidiRun run;
      + *
      + *              try {
      + *                  count = line.countRuns();
      + *              } catch (IllegalStateException e) {
      + *                  e.printStackTrace();
      + *                  return;
      + *              }
      + *              if (styleRunCount <= 1) {
      + *                  int style = styleRuns[0].style;
      + *
      + *                  // iterate over directional runs
      + *                  for (i = 0; i < count; ++i) {
      + *                      run = line.getVisualRun(i);
      + *                      renderRun(text, run.getStart(), run.getLimit(),
      + *                                run.getDirection(), style);
      + *                  }
      + *              } else {
      + *                  // iterate over both directional and style runs
      + *                  for (i = 0; i < count; ++i) {
      + *                      run = line.getVisualRun(i);
      + *                      renderDirectionalRun(text, run.getStart(),
      + *                                           run.getLimit(), run.getDirection(),
      + *                                           styleRuns, styleRunCount);
      + *                  }
      + *              }
      + *          }
      + *      }
      + *
      + *      static void renderParagraph(String text, byte textDirection,
      + *                                  StyleRun styleRuns[], int styleRunCount,
      + *                                  int lineWidth) {
      + *          int length = text.length();
      + *          Bidi para = new Bidi();
      + *          try {
      + *              para.setPara(text,
      + *                           textDirection != 0 ? Bidi.LEVEL_DEFAULT_RTL
      + *                                              : Bidi.LEVEL_DEFAULT_LTR,
      + *                           null);
      + *          } catch (Exception e) {
      + *              e.printStackTrace();
      + *              return;
      + *          }
      + *          byte paraLevel = (byte)(1 & para.getParaLevel());
      + *          StyleRun styleRun = new StyleRun(length, styleNormal);
      + *
      + *          if (styleRuns == null || styleRunCount <= 0) {
      + *              styleRuns = new StyleRun[1];
      + *              styleRunCount = 1;
      + *              styleRuns[0] = styleRun;
      + *          }
      + *          // assume styleRuns[styleRunCount-1].limit>=length
      + *
      + *          int width = getTextWidth(text, 0, length, styleRuns, styleRunCount);
      + *          if (width <= lineWidth) {
      + *              // everything fits onto one line
      + *
      + *              // prepare rendering a new line from either left or right
      + *              startLine(paraLevel, width);
      + *
      + *              renderLine(para, text, 0, length, styleRuns, styleRunCount);
      + *          } else {
      + *              // we need to render several lines
      + *              Bidi line = new Bidi(length, 0);
      + *              int start = 0, limit;
      + *              int styleRunStart = 0, styleRunLimit;
      + *
      + *              for (;;) {
      + *                  limit = length;
      + *                  styleRunLimit = styleRunCount;
      + *                  width = getLineBreak(text, new Bounds(start, limit),
      + *                                       para, styleRuns,
      + *                                       new Bounds(styleRunStart, styleRunLimit));
      + *                  try {
      + *                      line = para.setLine(start, limit);
      + *                  } catch (Exception e) {
      + *                      e.printStackTrace();
      + *                      return;
      + *                  }
      + *                  // prepare rendering a new line
      + *                  // from either left or right
      + *                  startLine(paraLevel, width);
      + *
      + *                  if (styleRunStart > 0) {
      + *                      int newRunCount = styleRuns.length - styleRunStart;
      + *                      StyleRun[] newRuns = new StyleRun[newRunCount];
      + *                      System.arraycopy(styleRuns, styleRunStart, newRuns, 0,
      + *                                       newRunCount);
      + *                      renderLine(line, text, start, limit, newRuns,
      + *                                 styleRunLimit - styleRunStart);
      + *                  } else {
      + *                      renderLine(line, text, start, limit, styleRuns,
      + *                                 styleRunLimit - styleRunStart);
      + *                  }
      + *                  if (limit == length) {
      + *                      break;
      + *                  }
      + *                  start = limit;
      + *                  styleRunStart = styleRunLimit - 1;
      + *                  if (start >= styleRuns[styleRunStart].limit) {
      + *                      ++styleRunStart;
      + *                  }
      + *              }
      + *          }
      + *      }
      + *
      + *      public static void main(String[] args)
      + *      {
      + *          renderParagraph("Some Latin text...", Bidi.LTR, null, 0, 80);
      + *          renderParagraph("Some Hebrew text...", Bidi.RTL, null, 0, 60);
      + *      }
      + *  }
      + *
      + * 
      + */ + +public class Bidi { + + private java.text.Bidi bidi; + + private Bidi(java.text.Bidi delegate) { + this.bidi = delegate; + } + + /** Paragraph level setting

      + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 0 (left-to-right).

      + * + * If this value is used in conjunction with reordering modes + * REORDER_INVERSE_LIKE_DIRECT or + * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, the direction will be LTR otherwise.

      + * + * If reordering option OPTION_INSERT_MARKS is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see #REORDER_INVERSE_LIKE_DIRECT + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 3.8 + */ + public static final byte LEVEL_DEFAULT_LTR = (byte)0x7e; + + /** Paragraph level setting

      + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 1 (right-to-left).

      + * + * If this value is used in conjunction with reordering modes + * REORDER_INVERSE_LIKE_DIRECT or + * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, or if the text contains no strong character; + * the direction will be LTR otherwise.

      + * + * If reordering option OPTION_INSERT_MARKS is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see #REORDER_INVERSE_LIKE_DIRECT + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 3.8 + */ + public static final byte LEVEL_DEFAULT_RTL = (byte)0x7f; + + /** + * Maximum explicit embedding level. + * (The maximum resolved level can be up to MAX_EXPLICIT_LEVEL+1). + * @stable ICU 3.8 + */ + public static final byte MAX_EXPLICIT_LEVEL = 61; + + /** + * Bit flag for level input. + * Overrides directional properties. + * @stable ICU 3.8 + */ + public static final byte LEVEL_OVERRIDE = (byte)0x80; + + /** + * Special value which can be returned by the mapping methods when a + * logical index has no corresponding visual index or vice-versa. This may + * happen for the logical-to-visual mapping of a Bidi control when option + * OPTION_REMOVE_CONTROLS is + * specified. This can also happen for the visual-to-logical mapping of a + * Bidi mark (LRM or RLM) inserted by option + * OPTION_INSERT_MARKS. + * @see #getVisualIndex + * @see #getVisualMap + * @see #getLogicalIndex + * @see #getLogicalMap + * @see #OPTION_INSERT_MARKS + * @see #OPTION_REMOVE_CONTROLS + * @stable ICU 3.8 + */ + public static final int MAP_NOWHERE = -1; + + /** + * All left-to-right text. + * @stable ICU 3.8 + */ + public static final byte LTR = 0; + + /** + * All right-to-left text. + * @stable ICU 3.8 + */ + public static final byte RTL = 1; + + /** + * Mixed-directional text. + * @stable ICU 3.8 + */ + public static final byte MIXED = 2; + + /** + * option bit for writeReordered(): + * keep combining characters after their base characters in RTL runs + * + * @see #writeReordered + * @stable ICU 3.8 + */ + public static final short KEEP_BASE_COMBINING = 1; + + /** + * option bit for writeReordered(): + * replace characters with the "mirrored" property in RTL runs + * by their mirror-image mappings + * + * @see #writeReordered + * @stable ICU 3.8 + */ + public static final short DO_MIRRORING = 2; + + /** + * option bit for writeReordered(): + * surround the run with LRMs if necessary; + * this is part of the approximate "inverse Bidi" algorithm + * + *

      This option does not imply corresponding adjustment of the index + * mappings.

      + * + * @see #setInverse + * @see #writeReordered + * @stable ICU 3.8 + */ + public static final short INSERT_LRM_FOR_NUMERIC = 4; + + /** + * option bit for writeReordered(): + * remove Bidi control characters + * (this does not affect INSERT_LRM_FOR_NUMERIC) + * + *

      This option does not imply corresponding adjustment of the index + * mappings.

      + * + * @see #writeReordered + * @see #INSERT_LRM_FOR_NUMERIC + * @stable ICU 3.8 + */ + public static final short REMOVE_BIDI_CONTROLS = 8; + + /** + * option bit for writeReordered(): + * write the output in reverse order + * + *

      This has the same effect as calling writeReordered() + * first without this option, and then calling + * writeReverse() without mirroring. + * Doing this in the same step is faster and avoids a temporary buffer. + * An example for using this option is output to a character terminal that + * is designed for RTL scripts and stores text in reverse order.

      + * + * @see #writeReordered + * @stable ICU 3.8 + */ + public static final short OUTPUT_REVERSE = 16; + + /** Reordering mode: Regular Logical to Visual Bidi algorithm according to Unicode. + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_DEFAULT = 0; + + /** Reordering mode: Logical to Visual algorithm which handles numbers in + * a way which mimicks the behavior of Windows XP. + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_NUMBERS_SPECIAL = 1; + + /** Reordering mode: Logical to Visual algorithm grouping numbers with + * adjacent R characters (reversible algorithm). + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_GROUP_NUMBERS_WITH_R = 2; + + /** Reordering mode: Reorder runs only to transform a Logical LTR string + * to the logical RTL string with the same display, or vice-versa.
      + * If this mode is set together with option + * OPTION_INSERT_MARKS, some Bidi controls in the source + * text may be removed and other controls may be added to produce the + * minimum combination which has the required display. + * @see #OPTION_INSERT_MARKS + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_RUNS_ONLY = 3; + + /** Reordering mode: Visual to Logical algorithm which handles numbers + * like L (same algorithm as selected by setInverse(true). + * @see #setInverse + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_INVERSE_NUMBERS_AS_L = 4; + + /** Reordering mode: Visual to Logical algorithm equivalent to the regular + * Logical to Visual algorithm. + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_INVERSE_LIKE_DIRECT = 5; + + /** Reordering mode: Inverse Bidi (Visual to Logical) algorithm for the + * REORDER_NUMBERS_SPECIAL Bidi algorithm. + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6; + + /** + * Option value for setReorderingOptions: + * disable all the options which can be set with this method + * @see #setReorderingOptions + * @stable ICU 3.8 + */ + public static final int OPTION_DEFAULT = 0; + + /** + * Option bit for setReorderingOptions: + * insert Bidi marks (LRM or RLM) when needed to ensure correct result of + * a reordering to a Logical order + * + *

      This option must be set or reset before calling + * setPara.

      + * + *

      This option is significant only with reordering modes which generate + * a result with Logical order, specifically.

      + *
        + *
      • REORDER_RUNS_ONLY
      • + *
      • REORDER_INVERSE_NUMBERS_AS_L
      • + *
      • REORDER_INVERSE_LIKE_DIRECT
      • + *
      • REORDER_INVERSE_FOR_NUMBERS_SPECIAL
      • + *
      + * + *

      If this option is set in conjunction with reordering mode + * REORDER_INVERSE_NUMBERS_AS_L or with calling + * setInverse(true), it implies option + * INSERT_LRM_FOR_NUMERIC in calls to method + * writeReordered().

      + * + *

      For other reordering modes, a minimum number of LRM or RLM characters + * will be added to the source text after reordering it so as to ensure + * round trip, i.e. when applying the inverse reordering mode on the + * resulting logical text with removal of Bidi marks + * (option OPTION_REMOVE_CONTROLS set before calling + * setPara() or option + * REMOVE_BIDI_CONTROLS in + * writeReordered), the result will be identical to the + * source text in the first transformation. + * + *

      This option will be ignored if specified together with option + * OPTION_REMOVE_CONTROLS. It inhibits option + * REMOVE_BIDI_CONTROLS in calls to method + * writeReordered() and it implies option + * INSERT_LRM_FOR_NUMERIC in calls to method + * writeReordered() if the reordering mode is + * REORDER_INVERSE_NUMBERS_AS_L.

      + * + * @see #setReorderingMode + * @see #setReorderingOptions + * @see #INSERT_LRM_FOR_NUMERIC + * @see #REMOVE_BIDI_CONTROLS + * @see #OPTION_REMOVE_CONTROLS + * @see #REORDER_RUNS_ONLY + * @see #REORDER_INVERSE_NUMBERS_AS_L + * @see #REORDER_INVERSE_LIKE_DIRECT + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 3.8 + */ + public static final int OPTION_INSERT_MARKS = 1; + + /** + * Option bit for setReorderingOptions: + * remove Bidi control characters + * + *

      This option must be set or reset before calling + * setPara.

      + * + *

      This option nullifies option + * OPTION_INSERT_MARKS. It inhibits option + * INSERT_LRM_FOR_NUMERIC in calls to method + * writeReordered() and it implies option + * REMOVE_BIDI_CONTROLS in calls to that method.

      + * + * @see #setReorderingMode + * @see #setReorderingOptions + * @see #OPTION_INSERT_MARKS + * @see #INSERT_LRM_FOR_NUMERIC + * @see #REMOVE_BIDI_CONTROLS + * @stable ICU 3.8 + */ + public static final int OPTION_REMOVE_CONTROLS = 2; + + /** + * Option bit for setReorderingOptions: + * process the output as part of a stream to be continued + * + *

      This option must be set or reset before calling + * setPara.

      + * + *

      This option specifies that the caller is interested in processing + * large text object in parts. The results of the successive calls are + * expected to be concatenated by the caller. Only the call for the last + * part will have this option bit off.

      + * + *

      When this option bit is on, setPara() may process + * less than the full source text in order to truncate the text at a + * meaningful boundary. The caller should call + * getProcessedLength() immediately after calling + * setPara() in order to determine how much of the source + * text has been processed. Source text beyond that length should be + * resubmitted in following calls to setPara. The + * processed length may be less than the length of the source text if a + * character preceding the last character of the source text constitutes a + * reasonable boundary (like a block separator) for text to be continued.
      + * If the last character of the source text constitutes a reasonable + * boundary, the whole text will be processed at once.
      + * If nowhere in the source text there exists + * such a reasonable boundary, the processed length will be zero.
      + * The caller should check for such an occurrence and do one of the following: + *

      • submit a larger amount of text with a better chance to include + * a reasonable boundary.
      • + *
      • resubmit the same text after turning off option + * OPTION_STREAMING.
      + * In all cases, this option should be turned off before processing the last + * part of the text.

      + * + *

      When the OPTION_STREAMING option is used, it is + * recommended to call orderParagraphsLTR(true) before calling + * setPara() so that later paragraphs may be concatenated to + * previous paragraphs on the right. + *

      + * + * @see #setReorderingMode + * @see #setReorderingOptions + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public static final int OPTION_STREAMING = 4; + + /** + * Value returned by BidiClassifier when there is no need to + * override the standard Bidi class for a given code point. + * @see BidiClassifier + * @stable ICU 3.8 + */ + public static final int CLASS_DEFAULT = 19; //UCharacterDirection.CHAR_DIRECTION_COUNT; + + /** + * Allocate a Bidi object. + * Such an object is initially empty. It is assigned + * the Bidi properties of a piece of text containing one or more paragraphs + * by setPara() + * or the Bidi properties of a line within a paragraph by + * setLine().

      + * This object can be reused.

      + * setPara() and setLine() will allocate + * additional memory for internal structures as necessary. + * + * @stable ICU 3.8 + */ + public Bidi() + { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Allocate a Bidi object with preallocated memory + * for internal structures. + * This method provides a Bidi object like the default constructor + * but it also preallocates memory for internal structures + * according to the sizings supplied by the caller.

      + * The preallocation can be limited to some of the internal memory + * by setting some values to 0 here. That means that if, e.g., + * maxRunCount cannot be reasonably predetermined and should not + * be set to maxLength (the only failproof value) to avoid + * wasting memory, then maxRunCount could be set to 0 here + * and the internal structures that are associated with it will be allocated + * on demand, just like with the default constructor. + * + * @param maxLength is the maximum text or line length that internal memory + * will be preallocated for. An attempt to associate this object with a + * longer text will fail, unless this value is 0, which leaves the allocation + * up to the implementation. + * + * @param maxRunCount is the maximum anticipated number of same-level runs + * that internal memory will be preallocated for. An attempt to access + * visual runs on an object that was not preallocated for as many runs + * as the text was actually resolved to will fail, + * unless this value is 0, which leaves the allocation up to the implementation.

      + * The number of runs depends on the actual text and maybe anywhere between + * 1 and maxLength. It is typically small. + * + * @throws IllegalArgumentException if maxLength or maxRunCount is less than 0 + * @stable ICU 3.8 + */ + public Bidi(int maxLength, int maxRunCount) + { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Modify the operation of the Bidi algorithm such that it + * approximates an "inverse Bidi" algorithm. This method + * must be called before setPara(). + * + *

      The normal operation of the Bidi algorithm as described + * in the Unicode Technical Report is to take text stored in logical + * (keyboard, typing) order and to determine the reordering of it for visual + * rendering. + * Some legacy systems store text in visual order, and for operations + * with standard, Unicode-based algorithms, the text needs to be transformed + * to logical order. This is effectively the inverse algorithm of the + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi" and that the current implementation provides only an + * approximation of "inverse Bidi".

      + * + *

      With isInversed set to true, + * this method changes the behavior of some of the subsequent methods + * in a way that they can be used for the inverse Bidi algorithm. + * Specifically, runs of text with numeric characters will be treated in a + * special way and may need to be surrounded with LRM characters when they are + * written in reordered sequence.

      + * + *

      Output runs should be retrieved using getVisualRun(). + * Since the actual input for "inverse Bidi" is visually ordered text and + * getVisualRun() gets the reordered runs, these are actually + * the runs of the logically ordered output.

      + * + *

      Calling this method with argument isInverse set to + * true is equivalent to calling setReorderingMode + * with argument reorderingMode + * set to REORDER_INVERSE_NUMBERS_AS_L.
      + * Calling this method with argument isInverse set to + * false is equivalent to calling setReorderingMode + * with argument reorderingMode + * set to REORDER_DEFAULT. + * + * @param isInverse specifies "forward" or "inverse" Bidi operation. + * + * @see #setPara + * @see #writeReordered + * @see #setReorderingMode + * @see #REORDER_INVERSE_NUMBERS_AS_L + * @see #REORDER_DEFAULT + * @stable ICU 3.8 + */ + public void setInverse(boolean isInverse) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Is this Bidi object set to perform the inverse Bidi + * algorithm? + *

      Note: calling this method after setting the reordering mode with + * setReorderingMode will return true if the + * reordering mode was set to + * REORDER_INVERSE_NUMBERS_AS_L, false + * for all other values.

      + * + * @return true if the Bidi object is set to + * perform the inverse Bidi algorithm by handling numbers as L. + * + * @see #setInverse + * @see #setReorderingMode + * @see #REORDER_INVERSE_NUMBERS_AS_L + * @stable ICU 3.8 + */ + public boolean isInverse() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Modify the operation of the Bidi algorithm such that it implements some + * variant to the basic Bidi algorithm or approximates an "inverse Bidi" + * algorithm, depending on different values of the "reordering mode". + * This method must be called before setPara(), and stays in + * effect until called again with a different argument. + * + *

      The normal operation of the Bidi algorithm as described in the Unicode + * Standard Annex #9 is to take text stored in logical (keyboard, typing) + * order and to determine how to reorder it for visual rendering.

      + * + *

      With the reordering mode set to a value other than + * REORDER_DEFAULT, this method changes the behavior of some of + * the subsequent methods in a way such that they implement an inverse Bidi + * algorithm or some other algorithm variants.

      + * + *

      Some legacy systems store text in visual order, and for operations + * with standard, Unicode-based algorithms, the text needs to be transformed + * into logical order. This is effectively the inverse algorithm of the + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi", so a number of variants are implemented here.

      + * + *

      In other cases, it may be desirable to emulate some variant of the + * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a + * Logical to Logical transformation.

      + * + *
        + *
      • When the Reordering Mode is set to + * REORDER_DEFAULT, + * the standard Bidi Logical to Visual algorithm is applied.
      • + * + *
      • When the reordering mode is set to + * REORDER_NUMBERS_SPECIAL, + * the algorithm used to perform Bidi transformations when calling + * setPara should approximate the algorithm used in Microsoft + * Windows XP rather than strictly conform to the Unicode Bidi algorithm. + *
        + * The differences between the basic algorithm and the algorithm addressed + * by this option are as follows: + *
          + *
        • Within text at an even embedding level, the sequence "123AB" + * (where AB represent R or AL letters) is transformed to "123BA" by the + * Unicode algorithm and to "BA123" by the Windows algorithm.
        • + * + *
        • Arabic-Indic numbers (AN) are handled by the Windows algorithm just + * like regular numbers (EN).
        • + *
      • + * + *
      • When the reordering mode is set to + * REORDER_GROUP_NUMBERS_WITH_R, + * numbers located between LTR text and RTL text are associated with the RTL + * text. For instance, an LTR paragraph with content "abc 123 DEF" (where + * upper case letters represent RTL characters) will be transformed to + * "abc FED 123" (and not "abc 123 FED"), "DEF 123 abc" will be transformed + * to "123 FED abc" and "123 FED abc" will be transformed to "DEF 123 abc". + * This makes the algorithm reversible and makes it useful when round trip + * (from visual to logical and back to visual) must be achieved without + * adding LRM characters. However, this is a variation from the standard + * Unicode Bidi algorithm.
        + * The source text should not contain Bidi control characters other than LRM + * or RLM.
      • + * + *
      • When the reordering mode is set to + * REORDER_RUNS_ONLY, + * a "Logical to Logical" transformation must be performed: + *
          + *
        • If the default text level of the source text (argument + * paraLevel in setPara) is even, the source text + * will be handled as LTR logical text and will be transformed to the RTL + * logical text which has the same LTR visual display.
        • + *
        • If the default level of the source text is odd, the source text + * will be handled as RTL logical text and will be transformed to the + * LTR logical text which has the same LTR visual display.
        • + *
        + * This mode may be needed when logical text which is basically Arabic or + * Hebrew, with possible included numbers or phrases in English, has to be + * displayed as if it had an even embedding level (this can happen if the + * displaying application treats all text as if it was basically LTR). + *
        + * This mode may also be needed in the reverse case, when logical text which + * is basically English, with possible included phrases in Arabic or Hebrew, + * has to be displayed as if it had an odd embedding level. + *
        + * Both cases could be handled by adding LRE or RLE at the head of the + * text, if the display subsystem supports these formatting controls. If it + * does not, the problem may be handled by transforming the source text in + * this mode before displaying it, so that it will be displayed properly. + *
        + * The source text should not contain Bidi control characters other than LRM + * or RLM.
      • + * + *
      • When the reordering mode is set to + * REORDER_INVERSE_NUMBERS_AS_L, an "inverse Bidi" + * algorithm is applied. + * Runs of text with numeric characters will be treated like LTR letters and + * may need to be surrounded with LRM characters when they are written in + * reordered sequence (the option INSERT_LRM_FOR_NUMERIC can + * be used with method writeReordered to this end. This mode + * is equivalent to calling setInverse() with + * argument isInverse set to true.
      • + * + *
      • When the reordering mode is set to + * REORDER_INVERSE_LIKE_DIRECT, the "direct" Logical to + * Visual Bidi algorithm is used as an approximation of an "inverse Bidi" + * algorithm. This mode is similar to mode + * REORDER_INVERSE_NUMBERS_AS_L but is closer to the + * regular Bidi algorithm. + *
        + * For example, an LTR paragraph with the content "FED 123 456 CBA" (where + * upper case represents RTL characters) will be transformed to + * "ABC 456 123 DEF", as opposed to "DEF 123 456 ABC" + * with mode REORDER_INVERSE_NUMBERS_AS_L.
        + * When used in conjunction with option + * OPTION_INSERT_MARKS, this mode generally + * adds Bidi marks to the output significantly more sparingly than mode + * REORDER_INVERSE_NUMBERS_AS_L.
        with option + * INSERT_LRM_FOR_NUMERIC in calls to + * writeReordered.
      • + * + *
      • When the reordering mode is set to + * REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the Logical to Visual + * Bidi algorithm used in Windows XP is used as an approximation of an "inverse + * Bidi" algorithm. + *
        + * For example, an LTR paragraph with the content "abc FED123" (where + * upper case represents RTL characters) will be transformed to + * "abc 123DEF.
      • + *
      + * + *

      In all the reordering modes specifying an "inverse Bidi" algorithm + * (i.e. those with a name starting with REORDER_INVERSE), + * output runs should be retrieved using getVisualRun(), and + * the output text with writeReordered(). The caller should + * keep in mind that in "inverse Bidi" modes the input is actually visually + * ordered text and reordered output returned by getVisualRun() + * or writeReordered() are actually runs or character string + * of logically ordered output.
      + * For all the "inverse Bidi" modes, the source text should not contain + * Bidi control characters other than LRM or RLM.

      + * + *

      Note that option OUTPUT_REVERSE of + * writeReordered has no useful meaning and should not be used + * in conjunction with any value of the reordering mode specifying "inverse + * Bidi" or with value REORDER_RUNS_ONLY. + * + * @param reorderingMode specifies the required variant of the Bidi + * algorithm. + * + * @see #setInverse + * @see #setPara + * @see #writeReordered + * @see #INSERT_LRM_FOR_NUMERIC + * @see #OUTPUT_REVERSE + * @see #REORDER_DEFAULT + * @see #REORDER_NUMBERS_SPECIAL + * @see #REORDER_GROUP_NUMBERS_WITH_R + * @see #REORDER_RUNS_ONLY + * @see #REORDER_INVERSE_NUMBERS_AS_L + * @see #REORDER_INVERSE_LIKE_DIRECT + * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 3.8 + */ + public void setReorderingMode(int reorderingMode) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * What is the requested reordering mode for a given Bidi object? + * + * @return the current reordering mode of the Bidi object + * + * @see #setReorderingMode + * @stable ICU 3.8 + */ + public int getReorderingMode() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Specify which of the reordering options should be applied during Bidi + * transformations. + * + * @param options A combination of zero or more of the following + * reordering options: + * OPTION_DEFAULT, OPTION_INSERT_MARKS, + * OPTION_REMOVE_CONTROLS, OPTION_STREAMING. + * + * @see #getReorderingOptions + * @see #OPTION_DEFAULT + * @see #OPTION_INSERT_MARKS + * @see #OPTION_REMOVE_CONTROLS + * @see #OPTION_STREAMING + * @stable ICU 3.8 + */ + public void setReorderingOptions(int options) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * What are the reordering options applied to a given Bidi object? + * + * @return the current reordering options of the Bidi object + * + * @see #setReorderingOptions + * @stable ICU 3.8 + */ + public int getReorderingOptions() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Perform the Unicode Bidi algorithm. It is defined in the + * Unicode Standard Annex #9, + * version 13, + * also described in The Unicode Standard, Version 4.0 .

      + * + * This method takes a piece of plain text containing one or more paragraphs, + * with or without externally specified embedding levels from styled + * text and computes the left-right-directionality of each character.

      + * + * If the entire text is all of the same directionality, then + * the method may not perform all the steps described by the algorithm, + * i.e., some levels may not be the same as if all steps were performed. + * This is not relevant for unidirectional text.
      + * For example, in pure LTR text with numbers the numbers would get + * a resolved level of 2 higher than the surrounding text according to + * the algorithm. This implementation may set all resolved levels to + * the same value in such a case.

      + * + * The text can be composed of multiple paragraphs. Occurrence of a block + * separator in the text terminates a paragraph, and whatever comes next starts + * a new paragraph. The exception to this rule is when a Carriage Return (CR) + * is followed by a Line Feed (LF). Both CR and LF are block separators, but + * in that case, the pair of characters is considered as terminating the + * preceding paragraph, and a new paragraph will be started by a character + * coming after the LF. + * + * Although the text is passed here as a String, it is + * stored internally as an array of characters. Therefore the + * documentation will refer to indexes of the characters in the text. + * + * @param text contains the text that the Bidi algorithm will be performed + * on. This text can be retrieved with getText() or + * getTextAsString.
      + * + * @param paraLevel specifies the default level for the text; + * it is typically 0 (LTR) or 1 (RTL). + * If the method shall determine the paragraph level from the text, + * then paraLevel can be set to + * either LEVEL_DEFAULT_LTR + * or LEVEL_DEFAULT_RTL; if the text contains multiple + * paragraphs, the paragraph level shall be determined separately for + * each paragraph; if a paragraph does not include any strongly typed + * character, then the desired default is used (0 for LTR or 1 for RTL). + * Any other value between 0 and MAX_EXPLICIT_LEVEL + * is also valid, with odd levels indicating RTL. + * + * @param embeddingLevels (in) may be used to preset the embedding and override levels, + * ignoring characters like LRE and PDF in the text. + * A level overrides the directional property of its corresponding + * (same index) character if the level has the + * LEVEL_OVERRIDE bit set.

      + * Except for that bit, it must be + * paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL, + * with one exception: a level of zero may be specified for a + * paragraph separator even if paraLevel>0 when multiple + * paragraphs are submitted in the same call to setPara().

      + * Caution: A reference to this array, not a copy + * of the levels, will be stored in the Bidi object; + * the embeddingLevels + * should not be modified to avoid unexpected results on subsequent + * Bidi operations. However, the setPara() and + * setLine() methods may modify some or all of the + * levels.

      + * Note: the embeddingLevels array must + * have one entry for each character in text. + * + * @throws IllegalArgumentException if the values in embeddingLevels are + * not within the allowed range + * + * @see #LEVEL_DEFAULT_LTR + * @see #LEVEL_DEFAULT_RTL + * @see #LEVEL_OVERRIDE + * @see #MAX_EXPLICIT_LEVEL + * @stable ICU 3.8 + */ + public void setPara(String text, byte paraLevel, byte[] embeddingLevels) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Perform the Unicode Bidi algorithm. It is defined in the + * Unicode Standard Annex #9, + * version 13, + * also described in The Unicode Standard, Version 4.0 .

      + * + * This method takes a piece of plain text containing one or more paragraphs, + * with or without externally specified embedding levels from styled + * text and computes the left-right-directionality of each character.

      + * + * If the entire text is all of the same directionality, then + * the method may not perform all the steps described by the algorithm, + * i.e., some levels may not be the same as if all steps were performed. + * This is not relevant for unidirectional text.
      + * For example, in pure LTR text with numbers the numbers would get + * a resolved level of 2 higher than the surrounding text according to + * the algorithm. This implementation may set all resolved levels to + * the same value in such a case.

      + * + * The text can be composed of multiple paragraphs. Occurrence of a block + * separator in the text terminates a paragraph, and whatever comes next starts + * a new paragraph. The exception to this rule is when a Carriage Return (CR) + * is followed by a Line Feed (LF). Both CR and LF are block separators, but + * in that case, the pair of characters is considered as terminating the + * preceding paragraph, and a new paragraph will be started by a character + * coming after the LF. + * + * The text is stored internally as an array of characters. Therefore the + * documentation will refer to indexes of the characters in the text. + * + * @param chars contains the text that the Bidi algorithm will be performed + * on. This text can be retrieved with getText() or + * getTextAsString.
      + * + * @param paraLevel specifies the default level for the text; + * it is typically 0 (LTR) or 1 (RTL). + * If the method shall determine the paragraph level from the text, + * then paraLevel can be set to + * either LEVEL_DEFAULT_LTR + * or LEVEL_DEFAULT_RTL; if the text contains multiple + * paragraphs, the paragraph level shall be determined separately for + * each paragraph; if a paragraph does not include any strongly typed + * character, then the desired default is used (0 for LTR or 1 for RTL). + * Any other value between 0 and MAX_EXPLICIT_LEVEL + * is also valid, with odd levels indicating RTL. + * + * @param embeddingLevels (in) may be used to preset the embedding and + * override levels, ignoring characters like LRE and PDF in the text. + * A level overrides the directional property of its corresponding + * (same index) character if the level has the + * LEVEL_OVERRIDE bit set.

      + * Except for that bit, it must be + * paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL, + * with one exception: a level of zero may be specified for a + * paragraph separator even if paraLevel>0 when multiple + * paragraphs are submitted in the same call to setPara().

      + * Caution: A reference to this array, not a copy + * of the levels, will be stored in the Bidi object; + * the embeddingLevels + * should not be modified to avoid unexpected results on subsequent + * Bidi operations. However, the setPara() and + * setLine() methods may modify some or all of the + * levels.

      + * Note: the embeddingLevels array must + * have one entry for each character in text. + * + * @throws IllegalArgumentException if the values in embeddingLevels are + * not within the allowed range + * + * @see #LEVEL_DEFAULT_LTR + * @see #LEVEL_DEFAULT_RTL + * @see #LEVEL_OVERRIDE + * @see #MAX_EXPLICIT_LEVEL + * @stable ICU 3.8 + */ + public void setPara(char[] chars, byte paraLevel, byte[] embeddingLevels) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the + * Unicode Standard Annex #9, + * version 13, + * also described in The Unicode Standard, Version 4.0 .

      + * + * This method takes a paragraph of text and computes the + * left-right-directionality of each character. The text should not + * contain any Unicode block separators.

      + * + * The RUN_DIRECTION attribute in the text, if present, determines the base + * direction (left-to-right or right-to-left). If not present, the base + * direction is computed using the Unicode Bidirectional Algorithm, + * defaulting to left-to-right if there are no strong directional characters + * in the text. This attribute, if present, must be applied to all the text + * in the paragraph.

      + * + * The BIDI_EMBEDDING attribute in the text, if present, represents + * embedding level information. Negative values from -1 to -62 indicate + * overrides at the absolute value of the level. Positive values from 1 to + * 62 indicate embeddings. Where values are zero or not defined, the base + * embedding level as determined by the base direction is assumed.

      + * + * The NUMERIC_SHAPING attribute in the text, if present, converts European + * digits to other decimal digits before running the bidi algorithm. This + * attribute, if present, must be applied to all the text in the paragraph. + * + * If the entire text is all of the same directionality, then + * the method may not perform all the steps described by the algorithm, + * i.e., some levels may not be the same as if all steps were performed. + * This is not relevant for unidirectional text.
      + * For example, in pure LTR text with numbers the numbers would get + * a resolved level of 2 higher than the surrounding text according to + * the algorithm. This implementation may set all resolved levels to + * the same value in such a case.

      + * + * @param paragraph a paragraph of text with optional character and + * paragraph attribute information + * @stable ICU 3.8 + */ + public void setPara(AttributedCharacterIterator paragraph) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Specify whether block separators must be allocated level zero, + * so that successive paragraphs will progress from left to right. + * This method must be called before setPara(). + * Paragraph separators (B) may appear in the text. Setting them to level zero + * means that all paragraph separators (including one possibly appearing + * in the last text position) are kept in the reordered text after the text + * that they follow in the source text. + * When this feature is not enabled, a paragraph separator at the last + * position of the text before reordering will go to the first position + * of the reordered text when the paragraph level is odd. + * + * @param ordarParaLTR specifies whether paragraph separators (B) must + * receive level 0, so that successive paragraphs progress from left to right. + * + * @see #setPara + * @stable ICU 3.8 + */ + public void orderParagraphsLTR(boolean ordarParaLTR) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Is this Bidi object set to allocate level 0 to block + * separators so that successive paragraphs progress from left to right? + * + * @return true if the Bidi object is set to + * allocate level 0 to block separators. + * + * @stable ICU 3.8 + */ + public boolean isOrderParagraphsLTR() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the directionality of the text. + * + * @return a value of LTR, RTL or MIXED + * that indicates if the entire text + * represented by this object is unidirectional, + * and which direction, or if it is mixed-directional. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #LTR + * @see #RTL + * @see #MIXED + * @stable ICU 3.8 + */ + public byte getDirection() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the text. + * + * @return A String containing the text that the + * Bidi object was created for. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #setPara + * @see #setLine + * @stable ICU 3.8 + */ + public String getTextAsString() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the text. + * + * @return A char array containing the text that the + * Bidi object was created for. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #setPara + * @see #setLine + * @stable ICU 3.8 + */ + public char[] getText() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the length of the text. + * + * @return The length of the text that the Bidi object was + * created for. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @stable ICU 3.8 + */ + public int getLength() + { + return bidi.getLength(); + } + + /** + * Get the length of the source text processed by the last call to + * setPara(). This length may be different from the length of + * the source text if option OPTION_STREAMING has been + * set. + *
      + * Note that whenever the length of the text affects the execution or the + * result of a method, it is the processed length which must be considered, + * except for setPara (which receives unprocessed source text) + * and getLength (which returns the original length of the + * source text).
      + * In particular, the processed length is the one to consider in the + * following cases: + *

        + *
      • maximum value of the limit argument of + * setLine
      • + *
      • maximum value of the charIndex argument of + * getParagraph
      • + *
      • maximum value of the charIndex argument of + * getLevelAt
      • + *
      • number of elements in the array returned by getLevels + *
      • + *
      • maximum value of the logicalStart argument of + * getLogicalRun
      • + *
      • maximum value of the logicalIndex argument of + * getVisualIndex
      • + *
      • number of elements returned by getLogicalMap
      • + *
      • length of text processed by writeReordered
      • + *
      + * + * @return The length of the part of the source text processed by + * the last call to setPara. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #setPara + * @see #OPTION_STREAMING + * @stable ICU 3.8 + */ + public int getProcessedLength() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the length of the reordered text resulting from the last call to + * setPara(). This length may be different from the length + * of the source text if option OPTION_INSERT_MARKS + * or option OPTION_REMOVE_CONTROLS has been set. + *
      + * This resulting length is the one to consider in the following cases: + *
        + *
      • maximum value of the visualIndex argument of + * getLogicalIndex
      • + *
      • number of elements returned by getVisualMap
      • + *
      + * Note that this length stays identical to the source text length if + * Bidi marks are inserted or removed using option bits of + * writeReordered, or if option + * REORDER_INVERSE_NUMBERS_AS_L has been set. + * + * @return The length of the reordered text resulting from + * the last call to setPara. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #setPara + * @see #OPTION_INSERT_MARKS + * @see #OPTION_REMOVE_CONTROLS + * @see #REORDER_INVERSE_NUMBERS_AS_L + * @stable ICU 3.8 + */ + public int getResultLength() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /* paragraphs API methods ------------------------------------------------- */ + + /** + * Get the paragraph level of the text. + * + * @return The paragraph level. If there are multiple paragraphs, their + * level may vary if the required paraLevel is LEVEL_DEFAULT_LTR or + * LEVEL_DEFAULT_RTL. In that case, the level of the first paragraph + * is returned. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #LEVEL_DEFAULT_LTR + * @see #LEVEL_DEFAULT_RTL + * @see #getParagraph + * @see #getParagraphByIndex + * @stable ICU 3.8 + */ + public byte getParaLevel() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the number of paragraphs. + * + * @return The number of paragraphs. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @stable ICU 3.8 + */ + public int countParagraphs() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get a paragraph, given the index of this paragraph. + * + * This method returns information about a paragraph.

      + * + * @param paraIndex is the number of the paragraph, in the + * range [0..countParagraphs()-1]. + * + * @return a BidiRun object with the details of the paragraph:
      + * start will receive the index of the first character + * of the paragraph in the text.
      + * limit will receive the limit of the paragraph.
      + * embeddingLevel will receive the level of the paragraph. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if paraIndex is not in the range + * [0..countParagraphs()-1] + * + * @see com.ibm.icu.text.BidiRun + * @stable ICU 3.8 + */ + public BidiRun getParagraphByIndex(int paraIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get a paragraph, given a position within the text. + * This method returns information about a paragraph.
      + * Note: if the paragraph index is known, it is more efficient to + * retrieve the paragraph information using getParagraphByIndex().

      + * + * @param charIndex is the index of a character within the text, in the + * range [0..getProcessedLength()-1]. + * + * @return a BidiRun object with the details of the paragraph:
      + * start will receive the index of the first character + * of the paragraph in the text.
      + * limit will receive the limit of the paragraph.
      + * embeddingLevel will receive the level of the paragraph. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if charIndex is not within the legal range + * + * @see com.ibm.icu.text.BidiRun + * @see #getParagraphByIndex + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public BidiRun getParagraph(int charIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the index of a paragraph, given a position within the text.

      + * + * @param charIndex is the index of a character within the text, in the + * range [0..getProcessedLength()-1]. + * + * @return The index of the paragraph containing the specified position, + * starting from 0. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if charIndex is not within the legal range + * + * @see com.ibm.icu.text.BidiRun + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public int getParagraphIndex(int charIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Set a custom Bidi classifier used by the UBA implementation for Bidi + * class determination. + * + * @param classifier A new custom classifier. This can be null. + * + * @see #getCustomClassifier + * @stable ICU 3.8 + */ + public void setCustomClassifier(BidiClassifier classifier) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Gets the current custom class classifier used for Bidi class + * determination. + * + * @return An instance of class BidiClassifier + * + * @see #setCustomClassifier + * @stable ICU 3.8 + */ + public BidiClassifier getCustomClassifier() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Retrieves the Bidi class for a given code point. + *

      If a BidiClassifier is defined and returns a value + * other than CLASS_DEFAULT, that value is used; otherwise + * the default class determination mechanism is invoked.

      + * + * @param c The code point to get a Bidi class for. + * + * @return The Bidi class for the character c that is in effect + * for this Bidi instance. + * + * @see BidiClassifier + * @stable ICU 3.8 + */ + public int getCustomizedClass(int c) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * setLine() returns a Bidi object to + * contain the reordering information, especially the resolved levels, + * for all the characters in a line of text. This line of text is + * specified by referring to a Bidi object representing + * this information for a piece of text containing one or more paragraphs, + * and by specifying a range of indexes in this text.

      + * In the new line object, the indexes will range from 0 to limit-start-1.

      + * + * This is used after calling setPara() + * for a piece of text, and after line-breaking on that text. + * It is not necessary if each paragraph is treated as a single line.

      + * + * After line-breaking, rules (L1) and (L2) for the treatment of + * trailing WS and for reordering are performed on + * a Bidi object that represents a line.

      + * + * Important: the line Bidi object may + * reference data within the global text Bidi object. + * You should not alter the content of the global text object until + * you are finished using the line object. + * + * @param start is the line's first index into the text. + * + * @param limit is just behind the line's last index into the text + * (its last index +1). + * + * @return a Bidi object that will now represent a line of the text. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara + * @throws IllegalArgumentException if start and limit are not in the range + * 0<=start<limit<=getProcessedLength(), + * or if the specified line crosses a paragraph boundary + * + * @see #setPara + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public Bidi setLine(int start, int limit) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the level for one character. + * + * @param charIndex the index of a character. + * + * @return The level for the character at charIndex. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if charIndex is not in the range + * 0<=charIndex<getProcessedLength() + * + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public byte getLevelAt(int charIndex) + { + return (byte)bidi.getLevelAt(charIndex); + } + + /** + * Get an array of levels for each character.

      + * + * Note that this method may allocate memory under some + * circumstances, unlike getLevelAt(). + * + * @return The levels array for the text, + * or null if an error occurs. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @stable ICU 3.8 + */ + public byte[] getLevels() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get a logical run. + * This method returns information about a run and is used + * to retrieve runs in logical order.

      + * This is especially useful for line-breaking on a paragraph. + * + * @param logicalPosition is a logical position within the source text. + * + * @return a BidiRun object filled with start containing + * the first character of the run, limit containing + * the limit of the run, and embeddingLevel containing + * the level of the run. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if logicalPosition is not in the range + * 0<=logicalPosition<getProcessedLength() + * + * @see com.ibm.icu.text.BidiRun + * @see com.ibm.icu.text.BidiRun#getStart() + * @see com.ibm.icu.text.BidiRun#getLimit() + * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel() + * + * @stable ICU 3.8 + */ + public BidiRun getLogicalRun(int logicalPosition) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the number of runs. + * This method may invoke the actual reordering on the + * Bidi object, after setPara() + * may have resolved only the levels of the text. Therefore, + * countRuns() may have to allocate memory, + * and may throw an exception if it fails to do so. + * + * @return The number of runs. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @stable ICU 3.8 + */ + public int countRuns() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * + * Get a BidiRun object according to its index. BidiRun methods + * may be used to retrieve the run's logical start, length and level, + * which can be even for an LTR run or odd for an RTL run. + * In an RTL run, the character at the logical start is + * visually on the right of the displayed run. + * The length is the number of characters in the run.

      + * countRuns() is normally called + * before the runs are retrieved. + * + *

      + * Example: + *

      +     *  Bidi bidi = new Bidi();
      +     *  String text = "abc 123 DEFG xyz";
      +     *  bidi.setPara(text, Bidi.RTL, null);
      +     *  int i, count=bidi.countRuns(), logicalStart, visualIndex=0, length;
      +     *  BidiRun run;
      +     *  for (i = 0; i < count; ++i) {
      +     *      run = bidi.getVisualRun(i);
      +     *      logicalStart = run.getStart();
      +     *      length = run.getLength();
      +     *      if (Bidi.LTR == run.getEmbeddingLevel()) {
      +     *          do { // LTR
      +     *              show_char(text.charAt(logicalStart++), visualIndex++);
      +     *          } while (--length > 0);
      +     *      } else {
      +     *          logicalStart += length;  // logicalLimit
      +     *          do { // RTL
      +     *              show_char(text.charAt(--logicalStart), visualIndex++);
      +     *          } while (--length > 0);
      +     *      }
      +     *  }
      +     * 
      + *

      + * Note that in right-to-left runs, code like this places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + *

      + * Use of {@link #writeReordered}, optionally with the + * {@link #KEEP_BASE_COMBINING} option, can be considered in + * order to avoid these issues. + * + * @param runIndex is the number of the run in visual order, in the + * range [0..countRuns()-1]. + * + * @return a BidiRun object containing the details of the run. The + * directionality of the run is + * LTR==0 or RTL==1, + * never MIXED. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if runIndex is not in + * the range 0<=runIndex<countRuns() + * + * @see #countRuns() + * @see com.ibm.icu.text.BidiRun + * @see com.ibm.icu.text.BidiRun#getStart() + * @see com.ibm.icu.text.BidiRun#getLength() + * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel() + * @stable ICU 3.8 + */ + public BidiRun getVisualRun(int runIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get the visual position from a logical text position. + * If such a mapping is used many times on the same + * Bidi object, then calling + * getLogicalMap() is more efficient. + *

      + * The value returned may be MAP_NOWHERE if there is no + * visual position because the corresponding text character is a Bidi + * control removed from output by the option + * OPTION_REMOVE_CONTROLS. + *

      + * When the visual output is altered by using options of + * writeReordered() such as INSERT_LRM_FOR_NUMERIC, + * KEEP_BASE_COMBINING, OUTPUT_REVERSE, + * REMOVE_BIDI_CONTROLS, the visual position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. + *

      + * Note that in right-to-left runs, this mapping places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of {@link #writeReordered}, optionally with the + * {@link #KEEP_BASE_COMBINING} option can be considered instead + * of using the mapping, in order to avoid these issues. + * + * @param logicalIndex is the index of a character in the text. + * + * @return The visual position of this character. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if logicalIndex is not in + * the range 0<=logicalIndex<getProcessedLength() + * + * @see #getLogicalMap + * @see #getLogicalIndex + * @see #getProcessedLength + * @see #MAP_NOWHERE + * @see #OPTION_REMOVE_CONTROLS + * @see #writeReordered + * @stable ICU 3.8 + */ + public int getVisualIndex(int logicalIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + + /** + * Get the logical text position from a visual position. + * If such a mapping is used many times on the same + * Bidi object, then calling + * getVisualMap() is more efficient. + *

      + * The value returned may be MAP_NOWHERE if there is no + * logical position because the corresponding text character is a Bidi + * mark inserted in the output by option + * OPTION_INSERT_MARKS. + *

      + * This is the inverse method to getVisualIndex(). + *

      + * When the visual output is altered by using options of + * writeReordered() such as INSERT_LRM_FOR_NUMERIC, + * KEEP_BASE_COMBINING, OUTPUT_REVERSE, + * REMOVE_BIDI_CONTROLS, the logical position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. + * + * @param visualIndex is the visual position of a character. + * + * @return The index of this character in the text. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if visualIndex is not in + * the range 0<=visualIndex<getResultLength() + * + * @see #getVisualMap + * @see #getVisualIndex + * @see #getResultLength + * @see #MAP_NOWHERE + * @see #OPTION_INSERT_MARKS + * @see #writeReordered + * @stable ICU 3.8 + */ + public int getLogicalIndex(int visualIndex) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get a logical-to-visual index map (array) for the characters in the + * Bidi (paragraph or line) object. + *

      + * Some values in the map may be MAP_NOWHERE if the + * corresponding text characters are Bidi controls removed from the visual + * output by the option OPTION_REMOVE_CONTROLS. + *

      + * When the visual output is altered by using options of + * writeReordered() such as INSERT_LRM_FOR_NUMERIC, + * KEEP_BASE_COMBINING, OUTPUT_REVERSE, + * REMOVE_BIDI_CONTROLS, the visual positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. + *

      + * Note that in right-to-left runs, this mapping places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of {@link #writeReordered}, optionally with the + * {@link #KEEP_BASE_COMBINING} option can be considered instead + * of using the mapping, in order to avoid these issues. + * + * @return an array of getProcessedLength() + * indexes which will reflect the reordering of the characters.

      + * The index map will result in + * indexMap[logicalIndex]==visualIndex, where + * indexMap represents the returned array. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #getVisualMap + * @see #getVisualIndex + * @see #getProcessedLength + * @see #MAP_NOWHERE + * @see #OPTION_REMOVE_CONTROLS + * @see #writeReordered + * @stable ICU 3.8 + */ + public int[] getLogicalMap() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Get a visual-to-logical index map (array) for the characters in the + * Bidi (paragraph or line) object. + *

      + * Some values in the map may be MAP_NOWHERE if the + * corresponding text characters are Bidi marks inserted in the visual + * output by the option OPTION_INSERT_MARKS. + *

      + * When the visual output is altered by using options of + * writeReordered() such as INSERT_LRM_FOR_NUMERIC, + * KEEP_BASE_COMBINING, OUTPUT_REVERSE, + * REMOVE_BIDI_CONTROLS, the logical positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}. + * + * @return an array of getResultLength() + * indexes which will reflect the reordering of the characters.

      + * The index map will result in + * indexMap[visualIndex]==logicalIndex, where + * indexMap represents the returned array. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #getLogicalMap + * @see #getLogicalIndex + * @see #getResultLength + * @see #MAP_NOWHERE + * @see #OPTION_INSERT_MARKS + * @see #writeReordered + * @stable ICU 3.8 + */ + public int[] getVisualMap() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * This is a convenience method that does not use a Bidi object. + * It is intended to be used for when an application has determined the levels + * of objects (character sequences) and just needs to have them reordered (L2). + * This is equivalent to using getLogicalMap() on a + * Bidi object. + * + * @param levels is an array of levels that have been determined by + * the application. + * + * @return an array of levels.length + * indexes which will reflect the reordering of the characters.

      + * The index map will result in + * indexMap[logicalIndex]==visualIndex, where + * indexMap represents the returned array. + * + * @stable ICU 3.8 + */ + public static int[] reorderLogical(byte[] levels) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * This is a convenience method that does not use a Bidi object. + * It is intended to be used for when an application has determined the levels + * of objects (character sequences) and just needs to have them reordered (L2). + * This is equivalent to using getVisualMap() on a + * Bidi object. + * + * @param levels is an array of levels that have been determined by + * the application. + * + * @return an array of levels.length + * indexes which will reflect the reordering of the characters.

      + * The index map will result in + * indexMap[visualIndex]==logicalIndex, where + * indexMap represents the returned array. + * + * @stable ICU 3.8 + */ + public static int[] reorderVisual(byte[] levels) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Invert an index map. + * The index mapping of the argument map is inverted and returned as + * an array of indexes that we will call the inverse map. + * + * @param srcMap is an array whose elements define the original mapping + * from a source array to a destination array. + * Some elements of the source array may have no mapping in the + * destination array. In that case, their value will be + * the special value MAP_NOWHERE. + * All elements must be >=0 or equal to MAP_NOWHERE. + * Some elements in the source map may have a value greater than the + * srcMap.length if the destination array has more elements than the + * source array. + * There must be no duplicate indexes (two or more elements with the + * same value except MAP_NOWHERE). + * + * @return an array representing the inverse map. + * This array has a number of elements equal to 1 + the highest + * value in srcMap. + * For elements of the result array which have no matching elements + * in the source array, the corresponding elements in the inverse + * map will receive a value equal to MAP_NOWHERE. + * If element with index i in srcMap has a value k different + * from MAP_NOWHERE, this means that element i of + * the source array maps to element k in the destination array. + * The inverse map will have value i in its k-th element. + * For all elements of the destination array which do not map to + * an element in the source array, the corresponding element in the + * inverse map will have a value equal to MAP_NOWHERE. + * + * @see #MAP_NOWHERE + * @stable ICU 3.8 + */ + public static int[] invertMap(int[] srcMap) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /* + * Fields and methods for compatibility with java.text.bidi (Sun implementation) + */ + + /** + * Constant indicating base direction is left-to-right. + * @stable ICU 3.8 + */ + public static final int DIRECTION_LEFT_TO_RIGHT = LTR; + + /** + * Constant indicating base direction is right-to-left. + * @stable ICU 3.8 + */ + public static final int DIRECTION_RIGHT_TO_LEFT = RTL; + + /** + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, the base + * direction is left-to-right. + * @stable ICU 3.8 + */ + public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = LEVEL_DEFAULT_LTR; + + /** + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, the base + * direction is right-to-left. + * @stable ICU 3.8 + */ + public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = LEVEL_DEFAULT_RTL; + + /** + * Create Bidi from the given paragraph of text and base direction. + * + * @param paragraph a paragraph of text + * @param flags a collection of flags that control the algorithm. The + * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, + * DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and + * DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved. + * @see #DIRECTION_LEFT_TO_RIGHT + * @see #DIRECTION_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT + * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT + * @stable ICU 3.8 + */ + public Bidi(String paragraph, int flags) + { + // Note: ICU and Oracle JDK are using the + // same DIRECTION_* flags definitions. + this(new java.text.Bidi(paragraph, flags)); + } + + /** + * Create Bidi from the given paragraph of text.

      + * + * The RUN_DIRECTION attribute in the text, if present, determines the base + * direction (left-to-right or right-to-left). If not present, the base + * direction is computed using the Unicode Bidirectional Algorithm, + * defaulting to left-to-right if there are no strong directional characters + * in the text. This attribute, if present, must be applied to all the text + * in the paragraph.

      + * + * The BIDI_EMBEDDING attribute in the text, if present, represents + * embedding level information. Negative values from -1 to -62 indicate + * overrides at the absolute value of the level. Positive values from 1 to + * 62 indicate embeddings. Where values are zero or not defined, the base + * embedding level as determined by the base direction is assumed.

      + * + * The NUMERIC_SHAPING attribute in the text, if present, converts European + * digits to other decimal digits before running the bidi algorithm. This + * attribute, if present, must be applied to all the text in the paragraph.

      + * + * Note: this constructor calls setPara() internally. + * + * @param paragraph a paragraph of text with optional character and + * paragraph attribute information + * @stable ICU 3.8 + */ + public Bidi(AttributedCharacterIterator paragraph) + { + // ICU does not define its own attributes and just + // use java.awt.font.TextAttribute. Thus, no mappings + // are necessary. + this(new java.text.Bidi(paragraph)); + } + + /** + * Create Bidi from the given text, embedding, and direction information. + * The embeddings array may be null. If present, the values represent + * embedding level information. Negative values from -1 to -61 indicate + * overrides at the absolute value of the level. Positive values from 1 to + * 61 indicate embeddings. Where values are zero, the base embedding level + * as determined by the base direction is assumed.

      + * + * Note: this constructor calls setPara() internally. + * + * @param text an array containing the paragraph of text to process. + * @param textStart the index into the text array of the start of the + * paragraph. + * @param embeddings an array containing embedding values for each character + * in the paragraph. This can be null, in which case it is assumed + * that there is no external embedding information. + * @param embStart the index into the embedding array of the start of the + * paragraph. + * @param paragraphLength the length of the paragraph in the text and + * embeddings arrays. + * @param flags a collection of flags that control the algorithm. The + * algorithm understands the flags DIRECTION_LEFT_TO_RIGHT, + * DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and + * DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved. + * + * @throws IllegalArgumentException if the values in embeddings are + * not within the allowed range + * + * @see #DIRECTION_LEFT_TO_RIGHT + * @see #DIRECTION_RIGHT_TO_LEFT + * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT + * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT + * @stable ICU 3.8 + */ + public Bidi(char[] text, + int textStart, + byte[] embeddings, + int embStart, + int paragraphLength, + int flags) + { + // Note: ICU and Oracle JDK are using the + // same DIRECTION_* flags definitions. + this(new java.text.Bidi(text, textStart, embeddings, embStart, paragraphLength, flags)); + } + + /** + * Create a Bidi object representing the bidi information on a line of text + * within the paragraph represented by the current Bidi. This call is not + * required if the entire paragraph fits on one line. + * + * @param lineStart the offset from the start of the paragraph to the start + * of the line. + * @param lineLimit the offset from the start of the paragraph to the limit + * of the line. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara + * @throws IllegalArgumentException if lineStart and lineLimit are not in the range + * 0<=lineStart<lineLimit<=getProcessedLength(), + * or if the specified line crosses a paragraph boundary + * @stable ICU 3.8 + */ + public Bidi createLineBidi(int lineStart, int lineLimit) + { + return new Bidi(bidi.createLineBidi(lineStart, lineLimit)); + } + + /** + * Return true if the line is not left-to-right or right-to-left. This means + * it either has mixed runs of left-to-right and right-to-left text, or the + * base direction differs from the direction of the only run of text. + * + * @return true if the line is not left-to-right or right-to-left. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara + * @stable ICU 3.8 + */ + public boolean isMixed() + { + return bidi.isMixed(); + } + + /** + * Return true if the line is all left-to-right text and the base direction + * is left-to-right. + * + * @return true if the line is all left-to-right text and the base direction + * is left-to-right. + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara + * @stable ICU 3.8 + */ + public boolean isLeftToRight() + { + return bidi.isLeftToRight(); + } + + /** + * Return true if the line is all right-to-left text, and the base direction + * is right-to-left + * + * @return true if the line is all right-to-left text, and the base + * direction is right-to-left + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara + * @stable ICU 3.8 + */ + public boolean isRightToLeft() + { + return bidi.isRightToLeft(); + } + + /** + * Return true if the base direction is left-to-right + * + * @return true if the base direction is left-to-right + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @stable ICU 3.8 + */ + public boolean baseIsLeftToRight() + { + return bidi.baseIsLeftToRight(); + } + + /** + * Return the base level (0 if left-to-right, 1 if right-to-left). + * + * @return the base level + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @stable ICU 3.8 + */ + public int getBaseLevel() + { + return bidi.getBaseLevel(); + } + + /** + * Return the number of level runs. + * + * @return the number of level runs + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @stable ICU 3.8 + */ + public int getRunCount() + { + return bidi.getRunCount(); + } + + /** + * Return the level of the nth logical run in this line. + * + * @param run the index of the run, between 0 and countRuns()-1 + * + * @return the level of the run + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if run is not in + * the range 0<=run<countRuns() + * @stable ICU 3.8 + */ + public int getRunLevel(int run) + { + return bidi.getRunLevel(run); + } + + /** + * Return the index of the character at the start of the nth logical run in + * this line, as an offset from the start of the line. + * + * @param run the index of the run, between 0 and countRuns() + * + * @return the start of the run + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if run is not in + * the range 0<=run<countRuns() + * @stable ICU 3.8 + */ + public int getRunStart(int run) + { + return bidi.getRunStart(run); + } + + /** + * Return the index of the character past the end of the nth logical run in + * this line, as an offset from the start of the line. For example, this + * will return the length of the line for the last run on the line. + * + * @param run the index of the run, between 0 and countRuns() + * + * @return the limit of the run + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * @throws IllegalArgumentException if run is not in + * the range 0<=run<countRuns() + * @stable ICU 3.8 + */ + public int getRunLimit(int run) + { + return bidi.getRunLimit(run); + } + + /** + * Return true if the specified text requires bidi analysis. If this returns + * false, the text will display left-to-right. Clients can then avoid + * constructing a Bidi object. Text in the Arabic Presentation Forms area of + * Unicode is presumed to already be shaped and ordered for display, and so + * will not cause this method to return true. + * + * @param text the text containing the characters to test + * @param start the start of the range of characters to test + * @param limit the limit of the range of characters to test + * + * @return true if the range of characters requires bidi analysis + * + * @stable ICU 3.8 + */ + public static boolean requiresBidi(char[] text, + int start, + int limit) + { + return java.text.Bidi.requiresBidi(text, start, limit); + } + + /** + * Reorder the objects in the array into visual order based on their levels. + * This is a utility method to use when you have a collection of objects + * representing runs of text in logical order, each run containing text at a + * single level. The elements at index from + * objectStart up to objectStart + count in the + * objects array will be reordered into visual order assuming + * each run of text has the level indicated by the corresponding element in + * the levels array (at index - objectStart + levelStart). + * + * @param levels an array representing the bidi level of each object + * @param levelStart the start position in the levels array + * @param objects the array of objects to be reordered into visual order + * @param objectStart the start position in the objects array + * @param count the number of objects to reorder + * @stable ICU 3.8 + */ + public static void reorderVisually(byte[] levels, + int levelStart, + Object[] objects, + int objectStart, + int count) + { + java.text.Bidi.reorderVisually(levels, levelStart, objects, objectStart, count); + } + + /** + * Take a Bidi object containing the reordering + * information for a piece of text (one or more paragraphs) set by + * setPara() or for a line of text set by setLine() + * and return a string containing the reordered text. + * + *

      The text may have been aliased (only a reference was stored + * without copying the contents), thus it must not have been modified + * since the setPara() call.

      + * + * This method preserves the integrity of characters with multiple + * code units and (optionally) combining characters. + * Characters in RTL runs can be replaced by mirror-image characters + * in the returned string. Note that "real" mirroring has to be done in a + * rendering engine by glyph selection and that for many "mirrored" + * characters there are no Unicode characters as mirror-image equivalents. + * There are also options to insert or remove Bidi control + * characters; see the descriptions of the return value and the + * options parameter, and of the option bit flags. + * + * @param options A bit set of options for the reordering that control + * how the reordered text is written. + * The options include mirroring the characters on a code + * point basis and inserting LRM characters, which is used + * especially for transforming visually stored text + * to logically stored text (although this is still an + * imperfect implementation of an "inverse Bidi" algorithm + * because it uses the "forward Bidi" algorithm at its core). + * The available options are: + * DO_MIRRORING, + * INSERT_LRM_FOR_NUMERIC, + * KEEP_BASE_COMBINING, + * OUTPUT_REVERSE, + * REMOVE_BIDI_CONTROLS, + * STREAMING + * + * @return The reordered text. + * If the INSERT_LRM_FOR_NUMERIC option is set, then + * the length of the returned string could be as large as + * getLength()+2*countRuns().
      + * If the REMOVE_BIDI_CONTROLS option is set, then the + * length of the returned string may be less than + * getLength().
      + * If none of these options is set, then the length of the returned + * string will be exactly getProcessedLength(). + * + * @throws IllegalStateException if this call is not preceded by a successful + * call to setPara or setLine + * + * @see #DO_MIRRORING + * @see #INSERT_LRM_FOR_NUMERIC + * @see #KEEP_BASE_COMBINING + * @see #OUTPUT_REVERSE + * @see #REMOVE_BIDI_CONTROLS + * @see #OPTION_STREAMING + * @see #getProcessedLength + * @stable ICU 3.8 + */ + public String writeReordered(int options) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Reverse a Right-To-Left run of Unicode text. + * + * This method preserves the integrity of characters with multiple + * code units and (optionally) combining characters. + * Characters can be replaced by mirror-image characters + * in the destination buffer. Note that "real" mirroring has + * to be done in a rendering engine by glyph selection + * and that for many "mirrored" characters there are no + * Unicode characters as mirror-image equivalents. + * There are also options to insert or remove Bidi control + * characters. + * + * This method is the implementation for reversing RTL runs as part + * of writeReordered(). For detailed descriptions + * of the parameters, see there. + * Since no Bidi controls are inserted here, the output string length + * will never exceed src.length(). + * + * @see #writeReordered + * + * @param src The RTL run text. + * + * @param options A bit set of options for the reordering that control + * how the reordered text is written. + * See the options parameter in writeReordered(). + * + * @return The reordered text. + * If the REMOVE_BIDI_CONTROLS option + * is set, then the length of the returned string may be less than + * src.length(). If this option is not set, + * then the length of the returned string will be exactly + * src.length(). + * + * @throws IllegalArgumentException if src is null. + * @stable ICU 3.8 + */ + public static String writeReverse(String src, int options) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiClassifier.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiClassifier.java index 5063e7ccde5..39ffdf1411a 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiClassifier.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiClassifier.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -/* - * Empty stub - */ -public class BidiClassifier { - private BidiClassifier() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +/* + * Empty stub + */ +public class BidiClassifier { + private BidiClassifier() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiRun.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiRun.java index 484681654a8..b0a74483aea 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiRun.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BidiRun.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -/* - * Empty stub - */ -public class BidiRun { - private BidiRun() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +/* + * Empty stub + */ +public class BidiRun { + private BidiRun() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java index 5b0922f9e8d..bf915953388 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java @@ -1,833 +1,833 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.text; - -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.Locale; - -import com.ibm.icu.util.ULocale; - -/** - * {@icuenhanced java.text.BreakIterator}.{@icu _usage_} - * - *

      A class that locates boundaries in text. This class defines a protocol for - * objects that break up a piece of natural-language text according to a set - * of criteria. Instances or subclasses of BreakIterator can be provided, for - * example, to break a piece of text into words, sentences, or logical characters - * according to the conventions of some language or group of languages. - * - * We provide five built-in types of BreakIterator: - *

      • getTitleInstance() returns a BreakIterator that locates boundaries - * between title breaks. - *
      • getSentenceInstance() returns a BreakIterator that locates boundaries - * between sentences. This is useful for triple-click selection, for example. - *
      • getWordInstance() returns a BreakIterator that locates boundaries between - * words. This is useful for double-click selection or "find whole words" searches. - * This type of BreakIterator makes sure there is a boundary position at the - * beginning and end of each legal word. (Numbers count as words, too.) Whitespace - * and punctuation are kept separate from real words. - *
      • getLineInstance() returns a BreakIterator that locates positions where it is - * legal for a text editor to wrap lines. This is similar to word breaking, but - * not the same: punctuation and whitespace are generally kept with words (you don't - * want a line to start with whitespace, for example), and some special characters - * can force a position to be considered a line-break position or prevent a position - * from being a line-break position. - *
      • getCharacterInstance() returns a BreakIterator that locates boundaries between - * logical characters. Because of the structure of the Unicode encoding, a logical - * character may be stored internally as more than one Unicode code point. (A with an - * umlaut may be stored as an a followed by a separate combining umlaut character, - * for example, but the user still thinks of it as one character.) This iterator allows - * various processes (especially text editors) to treat as characters the units of text - * that a user would think of as characters, rather than the units of text that the - * computer sees as "characters".
      - * - * BreakIterator's interface follows an "iterator" model (hence the name), meaning it - * has a concept of a "current position" and methods like first(), last(), next(), - * and previous() that update the current position. All BreakIterators uphold the - * following invariants: - *
      • The beginning and end of the text are always treated as boundary positions. - *
      • The current position of the iterator is always a boundary position (random- - * access methods move the iterator to the nearest boundary position before or - * after the specified position, not _to_ the specified position). - *
      • DONE is used as a flag to indicate when iteration has stopped. DONE is only - * returned when the current position is the end of the text and the user calls next(), - * or when the current position is the beginning of the text and the user calls - * previous(). - *
      • Break positions are numbered by the positions of the characters that follow - * them. Thus, under normal circumstances, the position before the first character - * is 0, the position after the first character is 1, and the position after the - * last character is 1 plus the length of the string. - *
      • The client can change the position of an iterator, or the text it analyzes, - * at will, but cannot change the behavior. If the user wants different behavior, he - * must instantiate a new iterator.
      - * - * BreakIterator accesses the text it analyzes through a CharacterIterator, which makes - * it possible to use BreakIterator to analyze text in any text-storage vehicle that - * provides a CharacterIterator interface. - * - * Note: Some types of BreakIterator can take a long time to create, and - * instances of BreakIterator are not currently cached by the system. For - * optimal performance, keep instances of BreakIterator around as long as makes - * sense. For example, when word-wrapping a document, don't create and destroy a - * new BreakIterator for each line. Create one break iterator for the whole document - * (or whatever stretch of text you're wrapping) and use it to do the whole job of - * wrapping the text. - * - *

      - * Examples:

      - * Creating and using text boundaries - *

      - *
      - * public static void main(String args[]) {
      - *      if (args.length == 1) {
      - *          String stringToExamine = args[0];
      - *          //print each word in order
      - *          BreakIterator boundary = BreakIterator.getWordInstance();
      - *          boundary.setText(stringToExamine);
      - *          printEachForward(boundary, stringToExamine);
      - *          //print each sentence in reverse order
      - *          boundary = BreakIterator.getSentenceInstance(Locale.US);
      - *          boundary.setText(stringToExamine);
      - *          printEachBackward(boundary, stringToExamine);
      - *          printFirst(boundary, stringToExamine);
      - *          printLast(boundary, stringToExamine);
      - *      }
      - * }
      - * 
      - *
      - * - * Print each element in order - *
      - *
      - * public static void printEachForward(BreakIterator boundary, String source) {
      - *     int start = boundary.first();
      - *     for (int end = boundary.next();
      - *          end != BreakIterator.DONE;
      - *          start = end, end = boundary.next()) {
      - *          System.out.println(source.substring(start,end));
      - *     }
      - * }
      - * 
      - *
      - * - * Print each element in reverse order - *
      - *
      - * public static void printEachBackward(BreakIterator boundary, String source) {
      - *     int end = boundary.last();
      - *     for (int start = boundary.previous();
      - *          start != BreakIterator.DONE;
      - *          end = start, start = boundary.previous()) {
      - *         System.out.println(source.substring(start,end));
      - *     }
      - * }
      - * 
      - *
      - * - * Print first element - *
      - *
      - * public static void printFirst(BreakIterator boundary, String source) {
      - *     int start = boundary.first();
      - *     int end = boundary.next();
      - *     System.out.println(source.substring(start,end));
      - * }
      - * 
      - *
      - * - * Print last element - *
      - *
      - * public static void printLast(BreakIterator boundary, String source) {
      - *     int end = boundary.last();
      - *     int start = boundary.previous();
      - *     System.out.println(source.substring(start,end));
      - * }
      - * 
      - *
      - * - * Print the element at a specified position - *
      - *
      - * public static void printAt(BreakIterator boundary, int pos, String source) {
      - *     int end = boundary.following(pos);
      - *     int start = boundary.previous();
      - *     System.out.println(source.substring(start,end));
      - * }
      - * 
      - *
      - * - * Find the next word - *
      - *
      - * public static int nextWordStartAfter(int pos, String text) {
      - *     BreakIterator wb = BreakIterator.getWordInstance();
      - *     wb.setText(text);
      - *     int last = wb.following(pos);
      - *     int current = wb.next();
      - *     while (current != BreakIterator.DONE) {
      - *         for (int p = last; p < current; p++) {
      - *             if (Character.isLetter(text.charAt(p)))
      - *                 return last;
      - *         }
      - *         last = current;
      - *         current = wb.next();
      - *     }
      - *     return BreakIterator.DONE;
      - * }
      - * 
      - * (The iterator returned by BreakIterator.getWordInstance() is unique in that - * the break positions it returns don't represent both the start and end of the - * thing being iterated over. That is, a sentence-break iterator returns breaks - * that each represent the end of one sentence and the beginning of the next. - * With the word-break iterator, the characters between two boundaries might be a - * word, or they might be the punctuation or whitespace between two words. The - * above code uses a simple heuristic to determine which boundary is the beginning - * of a word: If the characters between this boundary and the next boundary - * include at least one letter (this can be an alphabetical letter, a CJK ideograph, - * a Hangul syllable, a Kana character, etc.), then the text between this boundary - * and the next is a word; otherwise, it's the material between words.) - *
      - * - * @see CharacterIterator - * @stable ICU 2.0 - * - */ - -public abstract class BreakIterator implements Cloneable -{ - - /** - * Default constructor. There is no state that is carried by this abstract - * base class. - * @stable ICU 2.0 - */ - protected BreakIterator() - { - } - - /** - * Clone method. Creates another BreakIterator with the same behavior and - * current state as this one. - * @return The clone. - * @stable ICU 2.0 - */ - public Object clone() - { - try { - return super.clone(); - } - catch (CloneNotSupportedException e) { - ///CLOVER:OFF - throw new IllegalStateException(); - ///CLOVER:ON - } - } - - /** - * DONE is returned by previous() and next() after all valid - * boundaries have been returned. - * @stable ICU 2.0 - */ - public static final int DONE = -1; - - /** - * Return the first boundary position. This is always the beginning - * index of the text this iterator iterates over. For example, if - * the iterator iterates over a whole string, this function will - * always return 0. This function also updates the iteration position - * to point to the beginning of the text. - * @return The character offset of the beginning of the stretch of text - * being broken. - * @stable ICU 2.0 - */ - public abstract int first(); - - /** - * Return the last boundary position. This is always the "past-the-end" - * index of the text this iterator iterates over. For example, if the - * iterator iterates over a whole string (call it "text"), this function - * will always return text.length(). This function also updated the - * iteration position to point to the end of the text. - * @return The character offset of the end of the stretch of text - * being broken. - * @stable ICU 2.0 - */ - public abstract int last(); - - /** - * Advances the specified number of steps forward in the text (a negative - * number, therefore, advances backwards). If this causes the iterator - * to advance off either end of the text, this function returns DONE; - * otherwise, this function returns the position of the appropriate - * boundary. Calling this function is equivalent to calling next() or - * previous() n times. - * @param n The number of boundaries to advance over (if positive, moves - * forward; if negative, moves backwards). - * @return The position of the boundary n boundaries from the current - * iteration position, or DONE if moving n boundaries causes the iterator - * to advance off either end of the text. - * @stable ICU 2.0 - */ - public abstract int next(int n); - - /** - * Advances the iterator forward one boundary. The current iteration - * position is updated to point to the next boundary position after the - * current position, and this is also the value that is returned. If - * the current position is equal to the value returned by last(), or to - * DONE, this function returns DONE and sets the current position to - * DONE. - * @return The position of the first boundary position following the - * iteration position. - * @stable ICU 2.0 - */ - public abstract int next(); - - /** - * Advances the iterator backward one boundary. The current iteration - * position is updated to point to the last boundary position before - * the current position, and this is also the value that is returned. If - * the current position is equal to the value returned by first(), or to - * DONE, this function returns DONE and sets the current position to - * DONE. - * @return The position of the last boundary position preceding the - * iteration position. - * @stable ICU 2.0 - */ - public abstract int previous(); - - /** - * Sets the iterator's current iteration position to be the first - * boundary position following the specified position. (Whether the - * specified position is itself a boundary position or not doesn't - * matter-- this function always moves the iteration position to the - * first boundary after the specified position.) If the specified - * position is the past-the-end position, returns DONE. - * @param offset The character position to start searching from. - * @return The position of the first boundary position following - * "offset" (whether or not "offset" itself is a boundary position), - * or DONE if "offset" is the past-the-end offset. - * @stable ICU 2.0 - */ - public abstract int following(int offset); - - /** - * Sets the iterator's current iteration position to be the last - * boundary position preceding the specified position. (Whether the - * specified position is itself a boundary position or not doesn't - * matter-- this function always moves the iteration position to the - * last boundary before the specified position.) If the specified - * position is the starting position, returns DONE. - * @param offset The character position to start searching from. - * @return The position of the last boundary position preceding - * "offset" (whether of not "offset" itself is a boundary position), - * or DONE if "offset" is the starting offset of the iterator. - * @stable ICU 2.0 - */ - public int preceding(int offset) { - // NOTE: This implementation is here solely because we can't add new - // abstract methods to an existing class. There is almost ALWAYS a - // better, faster way to do this. - int pos = following(offset); - while (pos >= offset && pos != DONE) - pos = previous(); - return pos; - } - - /** - * Return true if the specfied position is a boundary position. If the - * function returns true, the current iteration position is set to the - * specified position; if the function returns false, the current - * iteration position is set as though following() had been called. - * @param offset the offset to check. - * @return True if "offset" is a boundary position. - * @stable ICU 2.0 - */ - public boolean isBoundary(int offset) { - // Again, this is the default implementation, which is provided solely because - // we couldn't add a new abstract method to an existing class. The real - // implementations will usually need to do a little more work. - if (offset == 0) { - return true; - } - else - return following(offset - 1) == offset; - } - - /** - * Return the iterator's current position. - * @return The iterator's current position. - * @stable ICU 2.0 - */ - public abstract int current(); - - /** - * Returns a CharacterIterator over the text being analyzed. - * For at least some subclasses of BreakIterator, this is a reference - * to the actual iterator being used by the BreakIterator, - * and therefore, this function's return value should be treated as - * const. No guarantees are made about the current position - * of this iterator when it is returned. If you need to move that - * position to examine the text, clone this function's return value first. - * @return A CharacterIterator over the text being analyzed. - * @stable ICU 2.0 - */ - public abstract CharacterIterator getText(); - - /** - * Sets the iterator to analyze a new piece of text. The new - * piece of text is passed in as a String, and the current - * iteration position is reset to the beginning of the string. - * (The old text is dropped.) - * @param newText A String containing the text to analyze with - * this BreakIterator. - * @stable ICU 2.0 - */ - public void setText(String newText) - { - setText(new StringCharacterIterator(newText)); - } - - /** - * Sets the iterator to analyze a new piece of text. The - * BreakIterator is passed a CharacterIterator through which - * it will access the text itself. The current iteration - * position is reset to the CharacterIterator's start index. - * (The old iterator is dropped.) - * @param newText A CharacterIterator referring to the text - * to analyze with this BreakIterator (the iterator's current - * position is ignored, but its other state is significant). - * @stable ICU 2.0 - */ - public abstract void setText(CharacterIterator newText); - - /** - * {@icu} - * @stable ICU 2.4 - */ - public static final int KIND_CHARACTER = 0; - /** - * {@icu} - * @stable ICU 2.4 - */ - public static final int KIND_WORD = 1; - /** - * {@icu} - * @stable ICU 2.4 - */ - public static final int KIND_LINE = 2; - /** - * {@icu} - * @stable ICU 2.4 - */ - public static final int KIND_SENTENCE = 3; - /** - * {@icu} - * @stable ICU 2.4 - */ - public static final int KIND_TITLE = 4; - - /** - * Returns a new instance of BreakIterator that locates word boundaries. - * This function assumes that the text being analyzed is in the default - * locale's language. - * @return An instance of BreakIterator that locates word boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getWordInstance() - { - return getWordInstance(Locale.getDefault()); - } - - /** - * Returns a new instance of BreakIterator that locates word boundaries. - * @param where A locale specifying the language of the text to be - * analyzed. - * @return An instance of BreakIterator that locates word boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getWordInstance(Locale where) - { - return getBreakInstance(where, KIND_WORD); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates word boundaries. - * @param where A locale specifying the language of the text to be - * analyzed. - * @return An instance of BreakIterator that locates word boundaries. - * @stable ICU 3.2 - */ - public static BreakIterator getWordInstance(ULocale where) - { - return getBreakInstance(where.toLocale(), KIND_WORD); - } - - /** - * Returns a new instance of BreakIterator that locates legal line- - * wrapping positions. This function assumes the text being broken - * is in the default locale's language. - * @return A new instance of BreakIterator that locates legal - * line-wrapping positions. - * @stable ICU 2.0 - */ - public static BreakIterator getLineInstance() - { - return getLineInstance(Locale.getDefault()); - } - - /** - * Returns a new instance of BreakIterator that locates legal line- - * wrapping positions. - * @param where A Locale specifying the language of the text being broken. - * @return A new instance of BreakIterator that locates legal - * line-wrapping positions. - * @stable ICU 2.0 - */ - public static BreakIterator getLineInstance(Locale where) - { - return getBreakInstance(where, KIND_LINE); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates legal line- - * wrapping positions. - * @param where A Locale specifying the language of the text being broken. - * @return A new instance of BreakIterator that locates legal - * line-wrapping positions. - * @stable ICU 3.2 - */ - public static BreakIterator getLineInstance(ULocale where) - { - return getBreakInstance(where.toLocale(), KIND_LINE); - } - - /** - * Returns a new instance of BreakIterator that locates logical-character - * boundaries. This function assumes that the text being analyzed is - * in the default locale's language. - * @return A new instance of BreakIterator that locates logical-character - * boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getCharacterInstance() - { - return getCharacterInstance(Locale.getDefault()); - } - - /** - * Returns a new instance of BreakIterator that locates logical-character - * boundaries. - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates logical-character - * boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getCharacterInstance(Locale where) - { - return getBreakInstance(where, KIND_CHARACTER); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates logical-character - * boundaries. - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates logical-character - * boundaries. - * @stable ICU 3.2 - */ - public static BreakIterator getCharacterInstance(ULocale where) - { - return getBreakInstance(where.toLocale(), KIND_CHARACTER); - } - - /** - * Returns a new instance of BreakIterator that locates sentence boundaries. - * This function assumes the text being analyzed is in the default locale's - * language. - * @return A new instance of BreakIterator that locates sentence boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getSentenceInstance() - { - return getSentenceInstance(Locale.getDefault()); - } - - /** - * Returns a new instance of BreakIterator that locates sentence boundaries. - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates sentence boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getSentenceInstance(Locale where) - { - return getBreakInstance(where, KIND_SENTENCE); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates sentence boundaries. - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates sentence boundaries. - * @stable ICU 3.2 - */ - public static BreakIterator getSentenceInstance(ULocale where) - { - return getBreakInstance(where.toLocale(), KIND_SENTENCE); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates title boundaries. - * This function assumes the text being analyzed is in the default locale's - * language. The iterator returned locates title boundaries as described for - * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, - * please use a word boundary iterator. {@link #getWordInstance} - * @return A new instance of BreakIterator that locates title boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getTitleInstance() - { - return getTitleInstance(Locale.getDefault()); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates title boundaries. - * The iterator returned locates title boundaries as described for - * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, - * please use Word Boundary iterator.{@link #getWordInstance} - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates title boundaries. - * @stable ICU 2.0 - */ - public static BreakIterator getTitleInstance(Locale where) - { - return getBreakInstance(where, KIND_TITLE); - } - - /** - * {@icu} Returns a new instance of BreakIterator that locates title boundaries. - * The iterator returned locates title boundaries as described for - * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, - * please use Word Boundary iterator.{@link #getWordInstance} - * @param where A Locale specifying the language of the text being analyzed. - * @return A new instance of BreakIterator that locates title boundaries. - * @stable ICU 3.2 -s */ - public static BreakIterator getTitleInstance(ULocale where) - { - return getBreakInstance(where.toLocale(), KIND_TITLE); - } - - /** - * {@icu} Registers a new break iterator of the indicated kind, to use in the given - * locale. Clones of the iterator will be returned if a request for a break iterator - * of the given kind matches or falls back to this locale. - * @param iter the BreakIterator instance to adopt. - * @param locale the Locale for which this instance is to be registered - * @param kind the type of iterator for which this instance is to be registered - * @return a registry key that can be used to unregister this instance - * @stable ICU 2.4 - */ - public static Object registerInstance(BreakIterator iter, Locale locale, int kind) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Registers a new break iterator of the indicated kind, to use in the given - * locale. Clones of the iterator will be returned if a request for a break iterator - * of the given kind matches or falls back to this locale. - * @param iter the BreakIterator instance to adopt. - * @param locale the Locale for which this instance is to be registered - * @param kind the type of iterator for which this instance is to be registered - * @return a registry key that can be used to unregister this instance - * @stable ICU 3.2 - */ - public static Object registerInstance(BreakIterator iter, ULocale locale, int kind) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Unregisters a previously-registered BreakIterator using the key returned - * from the register call. Key becomes invalid after this call and should not be used - * again. - * @param key the registry key returned by a previous call to registerInstance - * @return true if the iterator for the key was successfully unregistered - * @stable ICU 2.4 - */ - public static boolean unregister(Object key) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - // end of registration - - /** - * Returns a particular kind of BreakIterator for a locale. - * Avoids writing a switch statement with getXYZInstance(where) calls. - * @internal - * @deprecated This API is ICU internal only. - */ - public static BreakIterator getBreakInstance(ULocale where, int kind) { - return getBreakInstance(where.toLocale(), KIND_SENTENCE); - } - - private static BreakIterator getBreakInstance(Locale where, int kind) { - java.text.BreakIterator br = null; - switch(kind) { - case KIND_CHARACTER: br = java.text.BreakIterator.getCharacterInstance(where); break; - case KIND_WORD: br = java.text.BreakIterator.getWordInstance(where); break; - case KIND_LINE: br = java.text.BreakIterator.getLineInstance(where); break; - case KIND_SENTENCE: br = java.text.BreakIterator.getSentenceInstance(where); break; - case KIND_TITLE: throw new UnsupportedOperationException("Title break is not supported by com.ibm.icu.base"); - } - return new BreakIteratorHandle(br); - } - - /** - * Returns a list of locales for which BreakIterators can be used. - * @return An array of Locales. All of the locales in the array can - * be used when creating a BreakIterator. - * @stable ICU 2.6 - */ - public static synchronized Locale[] getAvailableLocales() { - return java.text.BreakIterator.getAvailableLocales(); - } - - /** - * {@icu} Returns a list of locales for which BreakIterators can be used. - * @return An array of Locales. All of the locales in the array can - * be used when creating a BreakIterator. - * @draft ICU 3.2 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static synchronized ULocale[] getAvailableULocales() { - Locale[] locales = java.text.BreakIterator.getAvailableLocales(); - ULocale[] ulocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; ++i) { - ulocales[i] = ULocale.forLocale(locales[i]); - } - return ulocales; - } - - /** - * {@icu} Returns the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: The actual locale is returned correctly, but the valid - * locale is not, in most cases. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - // forwarding implementation class - static final class BreakIteratorHandle extends BreakIterator { - /** - * @internal - */ - public final java.text.BreakIterator breakIterator; - - /** - * @internal - * @param delegate the BreakIterator to which to delegate - */ - public BreakIteratorHandle(java.text.BreakIterator delegate) { - this.breakIterator = delegate; - } - - public int first() { - return breakIterator.first(); - } - public int last() { - return breakIterator.last(); - } - public int next(int n) { - return breakIterator.next(n); - } - public int next() { - return breakIterator.next(); - } - public int previous() { - return breakIterator.previous(); - } - public int following(int offset) { - return breakIterator.following(offset); - } - public int preceding(int offset) { - return breakIterator.preceding(offset); - } - public boolean isBoundary(int offset) { - return breakIterator.isBoundary(offset); - } - public int current() { - return breakIterator.current(); - } - public CharacterIterator getText() { - return breakIterator.getText(); - } - public void setText(CharacterIterator newText) { - breakIterator.setText(newText); - } - - /** - * Return a string suitable for debugging. - * @return a string suitable for debugging - * @stable ICU 3.4.3 - */ - public String toString() { - return breakIterator.toString(); - } - - /** - * Return a clone of this BreakIterator. - * @return a clone of this BreakIterator - * @stable ICU 3.4.3 - */ - public Object clone() { - return new BreakIteratorHandle((java.text.BreakIterator)breakIterator.clone()); - } - - /** - * Return true if rhs is a BreakIterator with the same break behavior as this. - * @return true if rhs equals this - * @stable ICU 3.4.3 - */ - public boolean equals(Object rhs) { - try { - return breakIterator.equals(((BreakIteratorHandle)rhs).breakIterator); - } - catch (Exception e) { - return false; - } - } - - /** - * Return a hashCode. - * @return a hashCode - * @stable ICU 3.4.3 - */ - public int hashCode() { - return breakIterator.hashCode(); - } - } -} +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.text; + +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.Locale; + +import com.ibm.icu.util.ULocale; + +/** + * {@icuenhanced java.text.BreakIterator}.{@icu _usage_} + * + *

      A class that locates boundaries in text. This class defines a protocol for + * objects that break up a piece of natural-language text according to a set + * of criteria. Instances or subclasses of BreakIterator can be provided, for + * example, to break a piece of text into words, sentences, or logical characters + * according to the conventions of some language or group of languages. + * + * We provide five built-in types of BreakIterator: + *

      • getTitleInstance() returns a BreakIterator that locates boundaries + * between title breaks. + *
      • getSentenceInstance() returns a BreakIterator that locates boundaries + * between sentences. This is useful for triple-click selection, for example. + *
      • getWordInstance() returns a BreakIterator that locates boundaries between + * words. This is useful for double-click selection or "find whole words" searches. + * This type of BreakIterator makes sure there is a boundary position at the + * beginning and end of each legal word. (Numbers count as words, too.) Whitespace + * and punctuation are kept separate from real words. + *
      • getLineInstance() returns a BreakIterator that locates positions where it is + * legal for a text editor to wrap lines. This is similar to word breaking, but + * not the same: punctuation and whitespace are generally kept with words (you don't + * want a line to start with whitespace, for example), and some special characters + * can force a position to be considered a line-break position or prevent a position + * from being a line-break position. + *
      • getCharacterInstance() returns a BreakIterator that locates boundaries between + * logical characters. Because of the structure of the Unicode encoding, a logical + * character may be stored internally as more than one Unicode code point. (A with an + * umlaut may be stored as an a followed by a separate combining umlaut character, + * for example, but the user still thinks of it as one character.) This iterator allows + * various processes (especially text editors) to treat as characters the units of text + * that a user would think of as characters, rather than the units of text that the + * computer sees as "characters".
      + * + * BreakIterator's interface follows an "iterator" model (hence the name), meaning it + * has a concept of a "current position" and methods like first(), last(), next(), + * and previous() that update the current position. All BreakIterators uphold the + * following invariants: + *
      • The beginning and end of the text are always treated as boundary positions. + *
      • The current position of the iterator is always a boundary position (random- + * access methods move the iterator to the nearest boundary position before or + * after the specified position, not _to_ the specified position). + *
      • DONE is used as a flag to indicate when iteration has stopped. DONE is only + * returned when the current position is the end of the text and the user calls next(), + * or when the current position is the beginning of the text and the user calls + * previous(). + *
      • Break positions are numbered by the positions of the characters that follow + * them. Thus, under normal circumstances, the position before the first character + * is 0, the position after the first character is 1, and the position after the + * last character is 1 plus the length of the string. + *
      • The client can change the position of an iterator, or the text it analyzes, + * at will, but cannot change the behavior. If the user wants different behavior, he + * must instantiate a new iterator.
      + * + * BreakIterator accesses the text it analyzes through a CharacterIterator, which makes + * it possible to use BreakIterator to analyze text in any text-storage vehicle that + * provides a CharacterIterator interface. + * + * Note: Some types of BreakIterator can take a long time to create, and + * instances of BreakIterator are not currently cached by the system. For + * optimal performance, keep instances of BreakIterator around as long as makes + * sense. For example, when word-wrapping a document, don't create and destroy a + * new BreakIterator for each line. Create one break iterator for the whole document + * (or whatever stretch of text you're wrapping) and use it to do the whole job of + * wrapping the text. + * + *

      + * Examples:

      + * Creating and using text boundaries + *

      + *
      + * public static void main(String args[]) {
      + *      if (args.length == 1) {
      + *          String stringToExamine = args[0];
      + *          //print each word in order
      + *          BreakIterator boundary = BreakIterator.getWordInstance();
      + *          boundary.setText(stringToExamine);
      + *          printEachForward(boundary, stringToExamine);
      + *          //print each sentence in reverse order
      + *          boundary = BreakIterator.getSentenceInstance(Locale.US);
      + *          boundary.setText(stringToExamine);
      + *          printEachBackward(boundary, stringToExamine);
      + *          printFirst(boundary, stringToExamine);
      + *          printLast(boundary, stringToExamine);
      + *      }
      + * }
      + * 
      + *
      + * + * Print each element in order + *
      + *
      + * public static void printEachForward(BreakIterator boundary, String source) {
      + *     int start = boundary.first();
      + *     for (int end = boundary.next();
      + *          end != BreakIterator.DONE;
      + *          start = end, end = boundary.next()) {
      + *          System.out.println(source.substring(start,end));
      + *     }
      + * }
      + * 
      + *
      + * + * Print each element in reverse order + *
      + *
      + * public static void printEachBackward(BreakIterator boundary, String source) {
      + *     int end = boundary.last();
      + *     for (int start = boundary.previous();
      + *          start != BreakIterator.DONE;
      + *          end = start, start = boundary.previous()) {
      + *         System.out.println(source.substring(start,end));
      + *     }
      + * }
      + * 
      + *
      + * + * Print first element + *
      + *
      + * public static void printFirst(BreakIterator boundary, String source) {
      + *     int start = boundary.first();
      + *     int end = boundary.next();
      + *     System.out.println(source.substring(start,end));
      + * }
      + * 
      + *
      + * + * Print last element + *
      + *
      + * public static void printLast(BreakIterator boundary, String source) {
      + *     int end = boundary.last();
      + *     int start = boundary.previous();
      + *     System.out.println(source.substring(start,end));
      + * }
      + * 
      + *
      + * + * Print the element at a specified position + *
      + *
      + * public static void printAt(BreakIterator boundary, int pos, String source) {
      + *     int end = boundary.following(pos);
      + *     int start = boundary.previous();
      + *     System.out.println(source.substring(start,end));
      + * }
      + * 
      + *
      + * + * Find the next word + *
      + *
      + * public static int nextWordStartAfter(int pos, String text) {
      + *     BreakIterator wb = BreakIterator.getWordInstance();
      + *     wb.setText(text);
      + *     int last = wb.following(pos);
      + *     int current = wb.next();
      + *     while (current != BreakIterator.DONE) {
      + *         for (int p = last; p < current; p++) {
      + *             if (Character.isLetter(text.charAt(p)))
      + *                 return last;
      + *         }
      + *         last = current;
      + *         current = wb.next();
      + *     }
      + *     return BreakIterator.DONE;
      + * }
      + * 
      + * (The iterator returned by BreakIterator.getWordInstance() is unique in that + * the break positions it returns don't represent both the start and end of the + * thing being iterated over. That is, a sentence-break iterator returns breaks + * that each represent the end of one sentence and the beginning of the next. + * With the word-break iterator, the characters between two boundaries might be a + * word, or they might be the punctuation or whitespace between two words. The + * above code uses a simple heuristic to determine which boundary is the beginning + * of a word: If the characters between this boundary and the next boundary + * include at least one letter (this can be an alphabetical letter, a CJK ideograph, + * a Hangul syllable, a Kana character, etc.), then the text between this boundary + * and the next is a word; otherwise, it's the material between words.) + *
      + * + * @see CharacterIterator + * @stable ICU 2.0 + * + */ + +public abstract class BreakIterator implements Cloneable +{ + + /** + * Default constructor. There is no state that is carried by this abstract + * base class. + * @stable ICU 2.0 + */ + protected BreakIterator() + { + } + + /** + * Clone method. Creates another BreakIterator with the same behavior and + * current state as this one. + * @return The clone. + * @stable ICU 2.0 + */ + public Object clone() + { + try { + return super.clone(); + } + catch (CloneNotSupportedException e) { + ///CLOVER:OFF + throw new IllegalStateException(); + ///CLOVER:ON + } + } + + /** + * DONE is returned by previous() and next() after all valid + * boundaries have been returned. + * @stable ICU 2.0 + */ + public static final int DONE = -1; + + /** + * Return the first boundary position. This is always the beginning + * index of the text this iterator iterates over. For example, if + * the iterator iterates over a whole string, this function will + * always return 0. This function also updates the iteration position + * to point to the beginning of the text. + * @return The character offset of the beginning of the stretch of text + * being broken. + * @stable ICU 2.0 + */ + public abstract int first(); + + /** + * Return the last boundary position. This is always the "past-the-end" + * index of the text this iterator iterates over. For example, if the + * iterator iterates over a whole string (call it "text"), this function + * will always return text.length(). This function also updated the + * iteration position to point to the end of the text. + * @return The character offset of the end of the stretch of text + * being broken. + * @stable ICU 2.0 + */ + public abstract int last(); + + /** + * Advances the specified number of steps forward in the text (a negative + * number, therefore, advances backwards). If this causes the iterator + * to advance off either end of the text, this function returns DONE; + * otherwise, this function returns the position of the appropriate + * boundary. Calling this function is equivalent to calling next() or + * previous() n times. + * @param n The number of boundaries to advance over (if positive, moves + * forward; if negative, moves backwards). + * @return The position of the boundary n boundaries from the current + * iteration position, or DONE if moving n boundaries causes the iterator + * to advance off either end of the text. + * @stable ICU 2.0 + */ + public abstract int next(int n); + + /** + * Advances the iterator forward one boundary. The current iteration + * position is updated to point to the next boundary position after the + * current position, and this is also the value that is returned. If + * the current position is equal to the value returned by last(), or to + * DONE, this function returns DONE and sets the current position to + * DONE. + * @return The position of the first boundary position following the + * iteration position. + * @stable ICU 2.0 + */ + public abstract int next(); + + /** + * Advances the iterator backward one boundary. The current iteration + * position is updated to point to the last boundary position before + * the current position, and this is also the value that is returned. If + * the current position is equal to the value returned by first(), or to + * DONE, this function returns DONE and sets the current position to + * DONE. + * @return The position of the last boundary position preceding the + * iteration position. + * @stable ICU 2.0 + */ + public abstract int previous(); + + /** + * Sets the iterator's current iteration position to be the first + * boundary position following the specified position. (Whether the + * specified position is itself a boundary position or not doesn't + * matter-- this function always moves the iteration position to the + * first boundary after the specified position.) If the specified + * position is the past-the-end position, returns DONE. + * @param offset The character position to start searching from. + * @return The position of the first boundary position following + * "offset" (whether or not "offset" itself is a boundary position), + * or DONE if "offset" is the past-the-end offset. + * @stable ICU 2.0 + */ + public abstract int following(int offset); + + /** + * Sets the iterator's current iteration position to be the last + * boundary position preceding the specified position. (Whether the + * specified position is itself a boundary position or not doesn't + * matter-- this function always moves the iteration position to the + * last boundary before the specified position.) If the specified + * position is the starting position, returns DONE. + * @param offset The character position to start searching from. + * @return The position of the last boundary position preceding + * "offset" (whether of not "offset" itself is a boundary position), + * or DONE if "offset" is the starting offset of the iterator. + * @stable ICU 2.0 + */ + public int preceding(int offset) { + // NOTE: This implementation is here solely because we can't add new + // abstract methods to an existing class. There is almost ALWAYS a + // better, faster way to do this. + int pos = following(offset); + while (pos >= offset && pos != DONE) + pos = previous(); + return pos; + } + + /** + * Return true if the specfied position is a boundary position. If the + * function returns true, the current iteration position is set to the + * specified position; if the function returns false, the current + * iteration position is set as though following() had been called. + * @param offset the offset to check. + * @return True if "offset" is a boundary position. + * @stable ICU 2.0 + */ + public boolean isBoundary(int offset) { + // Again, this is the default implementation, which is provided solely because + // we couldn't add a new abstract method to an existing class. The real + // implementations will usually need to do a little more work. + if (offset == 0) { + return true; + } + else + return following(offset - 1) == offset; + } + + /** + * Return the iterator's current position. + * @return The iterator's current position. + * @stable ICU 2.0 + */ + public abstract int current(); + + /** + * Returns a CharacterIterator over the text being analyzed. + * For at least some subclasses of BreakIterator, this is a reference + * to the actual iterator being used by the BreakIterator, + * and therefore, this function's return value should be treated as + * const. No guarantees are made about the current position + * of this iterator when it is returned. If you need to move that + * position to examine the text, clone this function's return value first. + * @return A CharacterIterator over the text being analyzed. + * @stable ICU 2.0 + */ + public abstract CharacterIterator getText(); + + /** + * Sets the iterator to analyze a new piece of text. The new + * piece of text is passed in as a String, and the current + * iteration position is reset to the beginning of the string. + * (The old text is dropped.) + * @param newText A String containing the text to analyze with + * this BreakIterator. + * @stable ICU 2.0 + */ + public void setText(String newText) + { + setText(new StringCharacterIterator(newText)); + } + + /** + * Sets the iterator to analyze a new piece of text. The + * BreakIterator is passed a CharacterIterator through which + * it will access the text itself. The current iteration + * position is reset to the CharacterIterator's start index. + * (The old iterator is dropped.) + * @param newText A CharacterIterator referring to the text + * to analyze with this BreakIterator (the iterator's current + * position is ignored, but its other state is significant). + * @stable ICU 2.0 + */ + public abstract void setText(CharacterIterator newText); + + /** + * {@icu} + * @stable ICU 2.4 + */ + public static final int KIND_CHARACTER = 0; + /** + * {@icu} + * @stable ICU 2.4 + */ + public static final int KIND_WORD = 1; + /** + * {@icu} + * @stable ICU 2.4 + */ + public static final int KIND_LINE = 2; + /** + * {@icu} + * @stable ICU 2.4 + */ + public static final int KIND_SENTENCE = 3; + /** + * {@icu} + * @stable ICU 2.4 + */ + public static final int KIND_TITLE = 4; + + /** + * Returns a new instance of BreakIterator that locates word boundaries. + * This function assumes that the text being analyzed is in the default + * locale's language. + * @return An instance of BreakIterator that locates word boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getWordInstance() + { + return getWordInstance(Locale.getDefault()); + } + + /** + * Returns a new instance of BreakIterator that locates word boundaries. + * @param where A locale specifying the language of the text to be + * analyzed. + * @return An instance of BreakIterator that locates word boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getWordInstance(Locale where) + { + return getBreakInstance(where, KIND_WORD); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates word boundaries. + * @param where A locale specifying the language of the text to be + * analyzed. + * @return An instance of BreakIterator that locates word boundaries. + * @stable ICU 3.2 + */ + public static BreakIterator getWordInstance(ULocale where) + { + return getBreakInstance(where.toLocale(), KIND_WORD); + } + + /** + * Returns a new instance of BreakIterator that locates legal line- + * wrapping positions. This function assumes the text being broken + * is in the default locale's language. + * @return A new instance of BreakIterator that locates legal + * line-wrapping positions. + * @stable ICU 2.0 + */ + public static BreakIterator getLineInstance() + { + return getLineInstance(Locale.getDefault()); + } + + /** + * Returns a new instance of BreakIterator that locates legal line- + * wrapping positions. + * @param where A Locale specifying the language of the text being broken. + * @return A new instance of BreakIterator that locates legal + * line-wrapping positions. + * @stable ICU 2.0 + */ + public static BreakIterator getLineInstance(Locale where) + { + return getBreakInstance(where, KIND_LINE); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates legal line- + * wrapping positions. + * @param where A Locale specifying the language of the text being broken. + * @return A new instance of BreakIterator that locates legal + * line-wrapping positions. + * @stable ICU 3.2 + */ + public static BreakIterator getLineInstance(ULocale where) + { + return getBreakInstance(where.toLocale(), KIND_LINE); + } + + /** + * Returns a new instance of BreakIterator that locates logical-character + * boundaries. This function assumes that the text being analyzed is + * in the default locale's language. + * @return A new instance of BreakIterator that locates logical-character + * boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getCharacterInstance() + { + return getCharacterInstance(Locale.getDefault()); + } + + /** + * Returns a new instance of BreakIterator that locates logical-character + * boundaries. + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates logical-character + * boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getCharacterInstance(Locale where) + { + return getBreakInstance(where, KIND_CHARACTER); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates logical-character + * boundaries. + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates logical-character + * boundaries. + * @stable ICU 3.2 + */ + public static BreakIterator getCharacterInstance(ULocale where) + { + return getBreakInstance(where.toLocale(), KIND_CHARACTER); + } + + /** + * Returns a new instance of BreakIterator that locates sentence boundaries. + * This function assumes the text being analyzed is in the default locale's + * language. + * @return A new instance of BreakIterator that locates sentence boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getSentenceInstance() + { + return getSentenceInstance(Locale.getDefault()); + } + + /** + * Returns a new instance of BreakIterator that locates sentence boundaries. + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates sentence boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getSentenceInstance(Locale where) + { + return getBreakInstance(where, KIND_SENTENCE); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates sentence boundaries. + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates sentence boundaries. + * @stable ICU 3.2 + */ + public static BreakIterator getSentenceInstance(ULocale where) + { + return getBreakInstance(where.toLocale(), KIND_SENTENCE); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates title boundaries. + * This function assumes the text being analyzed is in the default locale's + * language. The iterator returned locates title boundaries as described for + * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, + * please use a word boundary iterator. {@link #getWordInstance} + * @return A new instance of BreakIterator that locates title boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getTitleInstance() + { + return getTitleInstance(Locale.getDefault()); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates title boundaries. + * The iterator returned locates title boundaries as described for + * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, + * please use Word Boundary iterator.{@link #getWordInstance} + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates title boundaries. + * @stable ICU 2.0 + */ + public static BreakIterator getTitleInstance(Locale where) + { + return getBreakInstance(where, KIND_TITLE); + } + + /** + * {@icu} Returns a new instance of BreakIterator that locates title boundaries. + * The iterator returned locates title boundaries as described for + * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, + * please use Word Boundary iterator.{@link #getWordInstance} + * @param where A Locale specifying the language of the text being analyzed. + * @return A new instance of BreakIterator that locates title boundaries. + * @stable ICU 3.2 +s */ + public static BreakIterator getTitleInstance(ULocale where) + { + return getBreakInstance(where.toLocale(), KIND_TITLE); + } + + /** + * {@icu} Registers a new break iterator of the indicated kind, to use in the given + * locale. Clones of the iterator will be returned if a request for a break iterator + * of the given kind matches or falls back to this locale. + * @param iter the BreakIterator instance to adopt. + * @param locale the Locale for which this instance is to be registered + * @param kind the type of iterator for which this instance is to be registered + * @return a registry key that can be used to unregister this instance + * @stable ICU 2.4 + */ + public static Object registerInstance(BreakIterator iter, Locale locale, int kind) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Registers a new break iterator of the indicated kind, to use in the given + * locale. Clones of the iterator will be returned if a request for a break iterator + * of the given kind matches or falls back to this locale. + * @param iter the BreakIterator instance to adopt. + * @param locale the Locale for which this instance is to be registered + * @param kind the type of iterator for which this instance is to be registered + * @return a registry key that can be used to unregister this instance + * @stable ICU 3.2 + */ + public static Object registerInstance(BreakIterator iter, ULocale locale, int kind) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Unregisters a previously-registered BreakIterator using the key returned + * from the register call. Key becomes invalid after this call and should not be used + * again. + * @param key the registry key returned by a previous call to registerInstance + * @return true if the iterator for the key was successfully unregistered + * @stable ICU 2.4 + */ + public static boolean unregister(Object key) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + // end of registration + + /** + * Returns a particular kind of BreakIterator for a locale. + * Avoids writing a switch statement with getXYZInstance(where) calls. + * @internal + * @deprecated This API is ICU internal only. + */ + public static BreakIterator getBreakInstance(ULocale where, int kind) { + return getBreakInstance(where.toLocale(), KIND_SENTENCE); + } + + private static BreakIterator getBreakInstance(Locale where, int kind) { + java.text.BreakIterator br = null; + switch(kind) { + case KIND_CHARACTER: br = java.text.BreakIterator.getCharacterInstance(where); break; + case KIND_WORD: br = java.text.BreakIterator.getWordInstance(where); break; + case KIND_LINE: br = java.text.BreakIterator.getLineInstance(where); break; + case KIND_SENTENCE: br = java.text.BreakIterator.getSentenceInstance(where); break; + case KIND_TITLE: throw new UnsupportedOperationException("Title break is not supported by com.ibm.icu.base"); + } + return new BreakIteratorHandle(br); + } + + /** + * Returns a list of locales for which BreakIterators can be used. + * @return An array of Locales. All of the locales in the array can + * be used when creating a BreakIterator. + * @stable ICU 2.6 + */ + public static synchronized Locale[] getAvailableLocales() { + return java.text.BreakIterator.getAvailableLocales(); + } + + /** + * {@icu} Returns a list of locales for which BreakIterators can be used. + * @return An array of Locales. All of the locales in the array can + * be used when creating a BreakIterator. + * @draft ICU 3.2 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static synchronized ULocale[] getAvailableULocales() { + Locale[] locales = java.text.BreakIterator.getAvailableLocales(); + ULocale[] ulocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + ulocales[i] = ULocale.forLocale(locales[i]); + } + return ulocales; + } + + /** + * {@icu} Returns the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: The actual locale is returned correctly, but the valid + * locale is not, in most cases. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + // forwarding implementation class + static final class BreakIteratorHandle extends BreakIterator { + /** + * @internal + */ + public final java.text.BreakIterator breakIterator; + + /** + * @internal + * @param delegate the BreakIterator to which to delegate + */ + public BreakIteratorHandle(java.text.BreakIterator delegate) { + this.breakIterator = delegate; + } + + public int first() { + return breakIterator.first(); + } + public int last() { + return breakIterator.last(); + } + public int next(int n) { + return breakIterator.next(n); + } + public int next() { + return breakIterator.next(); + } + public int previous() { + return breakIterator.previous(); + } + public int following(int offset) { + return breakIterator.following(offset); + } + public int preceding(int offset) { + return breakIterator.preceding(offset); + } + public boolean isBoundary(int offset) { + return breakIterator.isBoundary(offset); + } + public int current() { + return breakIterator.current(); + } + public CharacterIterator getText() { + return breakIterator.getText(); + } + public void setText(CharacterIterator newText) { + breakIterator.setText(newText); + } + + /** + * Return a string suitable for debugging. + * @return a string suitable for debugging + * @stable ICU 3.4.3 + */ + public String toString() { + return breakIterator.toString(); + } + + /** + * Return a clone of this BreakIterator. + * @return a clone of this BreakIterator + * @stable ICU 3.4.3 + */ + public Object clone() { + return new BreakIteratorHandle((java.text.BreakIterator)breakIterator.clone()); + } + + /** + * Return true if rhs is a BreakIterator with the same break behavior as this. + * @return true if rhs equals this + * @stable ICU 3.4.3 + */ + public boolean equals(Object rhs) { + try { + return breakIterator.equals(((BreakIteratorHandle)rhs).breakIterator); + } + catch (Exception e) { + return false; + } + } + + /** + * Return a hashCode. + * @return a hashCode + * @stable ICU 3.4.3 + */ + public int hashCode() { + return breakIterator.hashCode(); + } + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java index 5cdef2f3aeb..7de3a95a73a 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java @@ -1,415 +1,415 @@ -/** -******************************************************************************* -* Copyright (C) 1996-2011, International Business Machines Corporation and * -* others. All Rights Reserved. * -******************************************************************************* -*/ -package com.ibm.icu.text; - -/** - *

      A CollationKey represents a String - * under the rules of a specific Collator - * object. Comparing two CollationKeys returns the - * relative order of the Strings they represent.

      - * - *

      Since the rule set of Collators can differ, the - * sort orders of the same string under two different - * Collators might differ. Hence comparing - * CollationKeys generated from different - * Collators can give incorrect results.

      - - *

      Both the method - * CollationKey.compareTo(CollationKey) and the method - * Collator.compare(String, String) compare two strings - * and returns their relative order. The performance characterictics - * of these two approaches can differ.

      - * - *

      During the construction of a CollationKey, the - * entire source string is examined and processed into a series of - * bits terminated by a null, that are stored in the CollationKey. - * When CollationKey.compareTo(CollationKey) executes, it - * performs bitwise comparison on the bit sequences. This can incurs - * startup cost when creating the CollationKey, but once - * the key is created, binary comparisons are fast. This approach is - * recommended when the same strings are to be compared over and over - * again.

      - * - *

      On the other hand, implementations of - * Collator.compare(String, String) can examine and - * process the strings only until the first characters differing in - * order. This approach is recommended if the strings are to be - * compared only once.

      - * - *

      More information about the composition of the bit sequence can - * be found in the - * - * user guide.

      - * - *

      The following example shows how CollationKeys can be used - * to sort a list of Strings.

      - *
      - *
      - * // Create an array of CollationKeys for the Strings to be sorted.
      - * Collator myCollator = Collator.getInstance();
      - * CollationKey[] keys = new CollationKey[3];
      - * keys[0] = myCollator.getCollationKey("Tom");
      - * keys[1] = myCollator.getCollationKey("Dick");
      - * keys[2] = myCollator.getCollationKey("Harry");
      - * sort( keys );
      - * 
      - * //... - *
      - * // Inside body of sort routine, compare keys this way - * if( keys[i].compareTo( keys[j] ) > 0 ) - * // swap keys[i] and keys[j] - *
      - * //... - *
      - * // Finally, when we've returned from sort. - * System.out.println( keys[0].getSourceString() ); - * System.out.println( keys[1].getSourceString() ); - * System.out.println( keys[2].getSourceString() ); - *
      - *
      - *

      - *

      - * This class is not subclassable - *

      - * @see Collator - * @see RuleBasedCollator - * @author Syn Wee Quek - * @stable ICU 2.8 - */ -public final class CollationKey implements Comparable -{ - /** - * @internal - */ - final java.text.CollationKey key; - - /** - * @internal - */ - CollationKey(java.text.CollationKey delegate) { - this.key = delegate; - } - - // public inner classes ------------------------------------------------- - - /** - * Options that used in the API CollationKey.getBound() for getting a - * CollationKey based on the bound mode requested. - * @stable ICU 2.6 - */ - public static final class BoundMode - { - /* - * do not change the values assigned to the members of this enum. - * Underlying code depends on them having these numbers - */ - - /** - * Lower bound - * @stable ICU 2.6 - */ - public static final int LOWER = 0; - - /** - * Upper bound that will match strings of exact size - * @stable ICU 2.6 - */ - public static final int UPPER = 1; - - /** - * Upper bound that will match all the strings that have the same - * initial substring as the given string - * @stable ICU 2.6 - */ - public static final int UPPER_LONG = 2; - - /** - * Number of bound mode - * @stable ICU 2.6 - */ - public static final int COUNT = 3; - - /** - * Private Constructor - */ - ///CLOVER:OFF - private BoundMode(){} - ///CLOVER:ON - } - - // public constructor --------------------------------------------------- - - /** - * CollationKey constructor. - * This constructor is given public access, unlike the JDK version, to - * allow access to users extending the Collator class. See - * {@link Collator#getCollationKey(String)}. - * @param source string this CollationKey is to represent - * @param key array of bytes that represent the collation order of argument - * source terminated by a null - * @see Collator - * @stable ICU 2.8 - */ - public CollationKey(String source, byte key[]) - { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * CollationKey constructor that forces key to release its internal byte - * array for adoption. key will have a null byte array after this - * construction. - * @param source string this CollationKey is to represent - * @param key RawCollationKey object that represents the collation order of - * argument source. - * @see Collator - * @see RawCollationKey - * @stable ICU 2.8 - */ - public CollationKey(String source, RawCollationKey key) - { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - // public getters ------------------------------------------------------- - - /** - * Return the source string that this CollationKey represents. - * @return source string that this CollationKey represents - * @stable ICU 2.8 - */ - public String getSourceString() - { - return key.getSourceString(); - } - - /** - *

      Duplicates and returns the value of this CollationKey as a sequence - * of big-endian bytes terminated by a null.

      - * - *

      If two CollationKeys can be legitimately compared, then one can - * compare the byte arrays of each to obtain the same result, e.g. - *

      -     * byte key1[] = collationkey1.toByteArray();
      -     * byte key2[] = collationkey2.toByteArray();
      -     * int key, targetkey;
      -     * int i = 0;
      -     * do {
      -     *       key = key1[i] & 0xFF;
      -     *     targetkey = key2[i] & 0xFF;
      -     *     if (key < targetkey) {
      -     *         System.out.println("String 1 is less than string 2");
      -     *         return;
      -     *     }
      -     *     if (targetkey < key) {
      -     *         System.out.println("String 1 is more than string 2");
      -     *     }
      -     *     i ++;
      -     * } while (key != 0 && targetKey != 0);
      -     *
      -     * System.out.println("Strings are equal.");
      -     * 
      - *

      - * @return CollationKey value in a sequence of big-endian byte bytes - * terminated by a null. - * @stable ICU 2.8 - */ - public byte[] toByteArray() - { - return key.toByteArray(); - } - - // public other methods ------------------------------------------------- - - /** - *

      Compare this CollationKey to another CollationKey. The - * collation rules of the Collator that created this key are - * applied.

      - * - *

      Note: Comparison between CollationKeys - * created by different Collators might return incorrect - * results. See class documentation.

      - * - * @param target target CollationKey - * @return an integer value. If the value is less than zero this CollationKey - * is less than than target, if the value is zero they are equal, and - * if the value is greater than zero this CollationKey is greater - * than target. - * @exception NullPointerException is thrown if argument is null. - * @see Collator#compare(String, String) - * @stable ICU 2.8 - */ - public int compareTo(CollationKey target) - { - return key.compareTo(target.key); - } - - /** - *

      Compare this CollationKey and the specified Object for - * equality. The collation rules of the Collator that created - * this key are applied.

      - * - *

      See note in compareTo(CollationKey) for warnings about - * possible incorrect results.

      - * - * @param target the object to compare to. - * @return true if the two keys compare as equal, false otherwise. - * @see #compareTo(CollationKey) - * @exception ClassCastException is thrown when the argument is not - * a CollationKey. NullPointerException is thrown when the argument - * is null. - * @stable ICU 2.8 - */ - public boolean equals(Object target) - { - if (!(target instanceof CollationKey)) { - return false; - } - - return equals((CollationKey)target); - } - - /** - *

      - * Compare this CollationKey and the argument target CollationKey for - * equality. - * The collation - * rules of the Collator object which created these objects are applied. - *

      - *

      - * See note in compareTo(CollationKey) for warnings of incorrect results - *

      - * @param target the CollationKey to compare to. - * @return true if two objects are equal, false otherwise. - * @exception NullPointerException is thrown when the argument is null. - * @stable ICU 2.8 - */ - public boolean equals(CollationKey target) - { - return key.equals(target.key); - } - - /** - *

      Returns a hash code for this CollationKey. The hash value is calculated - * on the key itself, not the String from which the key was created. Thus - * if x and y are CollationKeys, then x.hashCode(x) == y.hashCode() - * if x.equals(y) is true. This allows language-sensitive comparison in a - * hash table. - *

      - * @return the hash value. - * @stable ICU 2.8 - */ - public int hashCode() - { - return key.hashCode(); - } - - /** - *

      - * Produce a bound for the sort order of a given collation key and a - * strength level. This API does not attempt to find a bound for the - * CollationKey String representation, hence null will be returned in its - * place. - *

      - *

      - * Resulting bounds can be used to produce a range of strings that are - * between upper and lower bounds. For example, if bounds are produced - * for a sortkey of string "smith", strings between upper and lower - * bounds with primary strength would include "Smith", "SMITH", "sMiTh". - *

      - *

      - * There are two upper bounds that can be produced. If BoundMode.UPPER - * is produced, strings matched would be as above. However, if a bound - * is produced using BoundMode.UPPER_LONG is used, the above example will - * also match "Smithsonian" and similar. - *

      - *

      - * For more on usage, see example in test procedure - * - * src/com/ibm/icu/dev/test/collator/CollationAPITest/TestBounds. - * - *

      - *

      - * Collation keys produced may be compared using the compare API. - *

      - * @param boundType Mode of bound required. It can be BoundMode.LOWER, which - * produces a lower inclusive bound, BoundMode.UPPER, that - * produces upper bound that matches strings of the same - * length or BoundMode.UPPER_LONG that matches strings that - * have the same starting substring as the source string. - * @param noOfLevels Strength levels required in the resulting bound - * (for most uses, the recommended value is PRIMARY). This - * strength should be less than the maximum strength of - * this CollationKey. - * See users guide for explanation on the strength levels a - * collation key can have. - * @return the result bounded CollationKey with a valid sort order but - * a null String representation. - * @exception IllegalArgumentException thrown when the strength level - * requested is higher than or equal to the strength in this - * CollationKey. - * In the case of an Exception, information - * about the maximum strength to use will be returned in the - * Exception. The user can then call getBound() again with the - * appropriate strength. - * @see CollationKey - * @see CollationKey.BoundMode - * @see Collator#PRIMARY - * @see Collator#SECONDARY - * @see Collator#TERTIARY - * @see Collator#QUATERNARY - * @see Collator#IDENTICAL - * @stable ICU 2.6 - */ - public CollationKey getBound(int boundType, int noOfLevels) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - *

      - * Merges this CollationKey with another. Only the sorting order of the - * CollationKeys will be merged. This API does not attempt to merge the - * String representations of the CollationKeys, hence null will be returned - * as the String representation. - *

      - *

      - * The strength levels are merged with their corresponding counterparts - * (PRIMARIES with PRIMARIES, SECONDARIES with SECONDARIES etc.). - *

      - *

      - * The merged String representation of the result CollationKey will be a - * concatenation of the String representations of the 2 source - * CollationKeys. - *

      - *

      - * Between the values from the same level a separator is inserted. - * example (uncompressed): - *

       
      -     * 191B1D 01 050505 01 910505 00 and 1F2123 01 050505 01 910505 00
      -     * will be merged as 
      -     * 191B1D 02 1F212301 050505 02 050505 01 910505 02 910505 00
      -     * 
      - *

      - *

      - * This allows for concatenating of first and last names for sorting, among - * other things. - *

      - *

      - * @param source CollationKey to merge with - * @return a CollationKey that contains the valid merged sorting order - * with a null String representation, - * i.e. new CollationKey(null, merge_sort_order) - * @exception IllegalArgumentException thrown if source CollationKey - * argument is null or of 0 length. - * @stable ICU 2.6 - */ - public CollationKey merge(CollationKey source) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } -} +/** +******************************************************************************* +* Copyright (C) 1996-2011, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ +package com.ibm.icu.text; + +/** + *

      A CollationKey represents a String + * under the rules of a specific Collator + * object. Comparing two CollationKeys returns the + * relative order of the Strings they represent.

      + * + *

      Since the rule set of Collators can differ, the + * sort orders of the same string under two different + * Collators might differ. Hence comparing + * CollationKeys generated from different + * Collators can give incorrect results.

      + + *

      Both the method + * CollationKey.compareTo(CollationKey) and the method + * Collator.compare(String, String) compare two strings + * and returns their relative order. The performance characterictics + * of these two approaches can differ.

      + * + *

      During the construction of a CollationKey, the + * entire source string is examined and processed into a series of + * bits terminated by a null, that are stored in the CollationKey. + * When CollationKey.compareTo(CollationKey) executes, it + * performs bitwise comparison on the bit sequences. This can incurs + * startup cost when creating the CollationKey, but once + * the key is created, binary comparisons are fast. This approach is + * recommended when the same strings are to be compared over and over + * again.

      + * + *

      On the other hand, implementations of + * Collator.compare(String, String) can examine and + * process the strings only until the first characters differing in + * order. This approach is recommended if the strings are to be + * compared only once.

      + * + *

      More information about the composition of the bit sequence can + * be found in the + * + * user guide.

      + * + *

      The following example shows how CollationKeys can be used + * to sort a list of Strings.

      + *
      + *
      + * // Create an array of CollationKeys for the Strings to be sorted.
      + * Collator myCollator = Collator.getInstance();
      + * CollationKey[] keys = new CollationKey[3];
      + * keys[0] = myCollator.getCollationKey("Tom");
      + * keys[1] = myCollator.getCollationKey("Dick");
      + * keys[2] = myCollator.getCollationKey("Harry");
      + * sort( keys );
      + * 
      + * //... + *
      + * // Inside body of sort routine, compare keys this way + * if( keys[i].compareTo( keys[j] ) > 0 ) + * // swap keys[i] and keys[j] + *
      + * //... + *
      + * // Finally, when we've returned from sort. + * System.out.println( keys[0].getSourceString() ); + * System.out.println( keys[1].getSourceString() ); + * System.out.println( keys[2].getSourceString() ); + *
      + *
      + *

      + *

      + * This class is not subclassable + *

      + * @see Collator + * @see RuleBasedCollator + * @author Syn Wee Quek + * @stable ICU 2.8 + */ +public final class CollationKey implements Comparable +{ + /** + * @internal + */ + final java.text.CollationKey key; + + /** + * @internal + */ + CollationKey(java.text.CollationKey delegate) { + this.key = delegate; + } + + // public inner classes ------------------------------------------------- + + /** + * Options that used in the API CollationKey.getBound() for getting a + * CollationKey based on the bound mode requested. + * @stable ICU 2.6 + */ + public static final class BoundMode + { + /* + * do not change the values assigned to the members of this enum. + * Underlying code depends on them having these numbers + */ + + /** + * Lower bound + * @stable ICU 2.6 + */ + public static final int LOWER = 0; + + /** + * Upper bound that will match strings of exact size + * @stable ICU 2.6 + */ + public static final int UPPER = 1; + + /** + * Upper bound that will match all the strings that have the same + * initial substring as the given string + * @stable ICU 2.6 + */ + public static final int UPPER_LONG = 2; + + /** + * Number of bound mode + * @stable ICU 2.6 + */ + public static final int COUNT = 3; + + /** + * Private Constructor + */ + ///CLOVER:OFF + private BoundMode(){} + ///CLOVER:ON + } + + // public constructor --------------------------------------------------- + + /** + * CollationKey constructor. + * This constructor is given public access, unlike the JDK version, to + * allow access to users extending the Collator class. See + * {@link Collator#getCollationKey(String)}. + * @param source string this CollationKey is to represent + * @param key array of bytes that represent the collation order of argument + * source terminated by a null + * @see Collator + * @stable ICU 2.8 + */ + public CollationKey(String source, byte key[]) + { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * CollationKey constructor that forces key to release its internal byte + * array for adoption. key will have a null byte array after this + * construction. + * @param source string this CollationKey is to represent + * @param key RawCollationKey object that represents the collation order of + * argument source. + * @see Collator + * @see RawCollationKey + * @stable ICU 2.8 + */ + public CollationKey(String source, RawCollationKey key) + { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + // public getters ------------------------------------------------------- + + /** + * Return the source string that this CollationKey represents. + * @return source string that this CollationKey represents + * @stable ICU 2.8 + */ + public String getSourceString() + { + return key.getSourceString(); + } + + /** + *

      Duplicates and returns the value of this CollationKey as a sequence + * of big-endian bytes terminated by a null.

      + * + *

      If two CollationKeys can be legitimately compared, then one can + * compare the byte arrays of each to obtain the same result, e.g. + *

      +     * byte key1[] = collationkey1.toByteArray();
      +     * byte key2[] = collationkey2.toByteArray();
      +     * int key, targetkey;
      +     * int i = 0;
      +     * do {
      +     *       key = key1[i] & 0xFF;
      +     *     targetkey = key2[i] & 0xFF;
      +     *     if (key < targetkey) {
      +     *         System.out.println("String 1 is less than string 2");
      +     *         return;
      +     *     }
      +     *     if (targetkey < key) {
      +     *         System.out.println("String 1 is more than string 2");
      +     *     }
      +     *     i ++;
      +     * } while (key != 0 && targetKey != 0);
      +     *
      +     * System.out.println("Strings are equal.");
      +     * 
      + *

      + * @return CollationKey value in a sequence of big-endian byte bytes + * terminated by a null. + * @stable ICU 2.8 + */ + public byte[] toByteArray() + { + return key.toByteArray(); + } + + // public other methods ------------------------------------------------- + + /** + *

      Compare this CollationKey to another CollationKey. The + * collation rules of the Collator that created this key are + * applied.

      + * + *

      Note: Comparison between CollationKeys + * created by different Collators might return incorrect + * results. See class documentation.

      + * + * @param target target CollationKey + * @return an integer value. If the value is less than zero this CollationKey + * is less than than target, if the value is zero they are equal, and + * if the value is greater than zero this CollationKey is greater + * than target. + * @exception NullPointerException is thrown if argument is null. + * @see Collator#compare(String, String) + * @stable ICU 2.8 + */ + public int compareTo(CollationKey target) + { + return key.compareTo(target.key); + } + + /** + *

      Compare this CollationKey and the specified Object for + * equality. The collation rules of the Collator that created + * this key are applied.

      + * + *

      See note in compareTo(CollationKey) for warnings about + * possible incorrect results.

      + * + * @param target the object to compare to. + * @return true if the two keys compare as equal, false otherwise. + * @see #compareTo(CollationKey) + * @exception ClassCastException is thrown when the argument is not + * a CollationKey. NullPointerException is thrown when the argument + * is null. + * @stable ICU 2.8 + */ + public boolean equals(Object target) + { + if (!(target instanceof CollationKey)) { + return false; + } + + return equals((CollationKey)target); + } + + /** + *

      + * Compare this CollationKey and the argument target CollationKey for + * equality. + * The collation + * rules of the Collator object which created these objects are applied. + *

      + *

      + * See note in compareTo(CollationKey) for warnings of incorrect results + *

      + * @param target the CollationKey to compare to. + * @return true if two objects are equal, false otherwise. + * @exception NullPointerException is thrown when the argument is null. + * @stable ICU 2.8 + */ + public boolean equals(CollationKey target) + { + return key.equals(target.key); + } + + /** + *

      Returns a hash code for this CollationKey. The hash value is calculated + * on the key itself, not the String from which the key was created. Thus + * if x and y are CollationKeys, then x.hashCode(x) == y.hashCode() + * if x.equals(y) is true. This allows language-sensitive comparison in a + * hash table. + *

      + * @return the hash value. + * @stable ICU 2.8 + */ + public int hashCode() + { + return key.hashCode(); + } + + /** + *

      + * Produce a bound for the sort order of a given collation key and a + * strength level. This API does not attempt to find a bound for the + * CollationKey String representation, hence null will be returned in its + * place. + *

      + *

      + * Resulting bounds can be used to produce a range of strings that are + * between upper and lower bounds. For example, if bounds are produced + * for a sortkey of string "smith", strings between upper and lower + * bounds with primary strength would include "Smith", "SMITH", "sMiTh". + *

      + *

      + * There are two upper bounds that can be produced. If BoundMode.UPPER + * is produced, strings matched would be as above. However, if a bound + * is produced using BoundMode.UPPER_LONG is used, the above example will + * also match "Smithsonian" and similar. + *

      + *

      + * For more on usage, see example in test procedure + * + * src/com/ibm/icu/dev/test/collator/CollationAPITest/TestBounds. + * + *

      + *

      + * Collation keys produced may be compared using the compare API. + *

      + * @param boundType Mode of bound required. It can be BoundMode.LOWER, which + * produces a lower inclusive bound, BoundMode.UPPER, that + * produces upper bound that matches strings of the same + * length or BoundMode.UPPER_LONG that matches strings that + * have the same starting substring as the source string. + * @param noOfLevels Strength levels required in the resulting bound + * (for most uses, the recommended value is PRIMARY). This + * strength should be less than the maximum strength of + * this CollationKey. + * See users guide for explanation on the strength levels a + * collation key can have. + * @return the result bounded CollationKey with a valid sort order but + * a null String representation. + * @exception IllegalArgumentException thrown when the strength level + * requested is higher than or equal to the strength in this + * CollationKey. + * In the case of an Exception, information + * about the maximum strength to use will be returned in the + * Exception. The user can then call getBound() again with the + * appropriate strength. + * @see CollationKey + * @see CollationKey.BoundMode + * @see Collator#PRIMARY + * @see Collator#SECONDARY + * @see Collator#TERTIARY + * @see Collator#QUATERNARY + * @see Collator#IDENTICAL + * @stable ICU 2.6 + */ + public CollationKey getBound(int boundType, int noOfLevels) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + *

      + * Merges this CollationKey with another. Only the sorting order of the + * CollationKeys will be merged. This API does not attempt to merge the + * String representations of the CollationKeys, hence null will be returned + * as the String representation. + *

      + *

      + * The strength levels are merged with their corresponding counterparts + * (PRIMARIES with PRIMARIES, SECONDARIES with SECONDARIES etc.). + *

      + *

      + * The merged String representation of the result CollationKey will be a + * concatenation of the String representations of the 2 source + * CollationKeys. + *

      + *

      + * Between the values from the same level a separator is inserted. + * example (uncompressed): + *

       
      +     * 191B1D 01 050505 01 910505 00 and 1F2123 01 050505 01 910505 00
      +     * will be merged as 
      +     * 191B1D 02 1F212301 050505 02 050505 01 910505 02 910505 00
      +     * 
      + *

      + *

      + * This allows for concatenating of first and last names for sorting, among + * other things. + *

      + *

      + * @param source CollationKey to merge with + * @return a CollationKey that contains the valid merged sorting order + * with a null String representation, + * i.e. new CollationKey(null, merge_sort_order) + * @exception IllegalArgumentException thrown if source CollationKey + * argument is null or of 0 length. + * @stable ICU 2.6 + */ + public CollationKey merge(CollationKey source) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java index d9eaaeb8091..2623e467dba 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java @@ -1,932 +1,932 @@ -/** -******************************************************************************* -* Copyright (C) 1996-2011, International Business Machines Corporation and * -* others. All Rights Reserved. * -******************************************************************************* -*/ -package com.ibm.icu.text; - -import java.util.Comparator; -import java.util.Locale; -import java.util.Set; - -import com.ibm.icu.util.ULocale; -import com.ibm.icu.util.VersionInfo; - -/** -* {@icuenhanced java.text.Collator}.{@icu _usage_} -* -*

      Collator performs locale-sensitive string comparison. A concrete -* subclass, RuleBasedCollator, allows customization of the collation -* ordering by the use of rule sets.

      -* -*

      Following the Unicode -* Consortium's specifications for the -* Unicode Collation -* Algorithm (UCA), there are 5 different levels of strength used -* in comparisons: -* -*

        -*
      • PRIMARY strength: Typically, this is used to denote differences between -* base characters (for example, "a" < "b"). -* It is the strongest difference. For example, dictionaries are divided -* into different sections by base character. -*
      • SECONDARY strength: Accents in the characters are considered secondary -* differences (for example, "as" < "às" < "at"). Other -* differences -* between letters can also be considered secondary differences, depending -* on the language. A secondary difference is ignored when there is a -* primary difference anywhere in the strings. -*
      • TERTIARY strength: Upper and lower case differences in characters are -* distinguished at tertiary strength (for example, "ao" < "Ao" < -* "aò"). In addition, a variant of a letter differs from the base -* form on the tertiary strength (such as "A" and "Ⓐ"). Another -* example is the -* difference between large and small Kana. A tertiary difference is ignored -* when there is a primary or secondary difference anywhere in the strings. -*
      • QUATERNARY strength: When punctuation is ignored -* -* (see Ignoring Punctuations in the user guide) at PRIMARY to TERTIARY -* strength, an additional strength level can -* be used to distinguish words with and without punctuation (for example, -* "ab" < "a-b" < "aB"). -* This difference is ignored when there is a PRIMARY, SECONDARY or TERTIARY -* difference. The QUATERNARY strength should only be used if ignoring -* punctuation is required. -*
      • IDENTICAL strength: -* When all other strengths are equal, the IDENTICAL strength is used as a -* tiebreaker. The Unicode code point values of the NFD form of each string -* are compared, just in case there is no difference. -* For example, Hebrew cantellation marks are only distinguished at this -* strength. This strength should be used sparingly, as only code point -* value differences between two strings is an extremely rare occurrence. -* Using this strength substantially decreases the performance for both -* comparison and collation key generation APIs. This strength also -* increases the size of the collation key. -*
      -* -* Unlike the JDK, ICU4J's Collator deals only with 2 decomposition modes, -* the canonical decomposition mode and one that does not use any decomposition. -* The compatibility decomposition mode, java.text.Collator.FULL_DECOMPOSITION -* is not supported here. If the canonical -* decomposition mode is set, the Collator handles un-normalized text properly, -* producing the same results as if the text were normalized in NFD. If -* canonical decomposition is turned off, it is the user's responsibility to -* ensure that all text is already in the appropriate form before performing -* a comparison or before getting a CollationKey.

      -* -*

      For more information about the collation service see the -* users -* guide.

      -* -*

      Examples of use -*

      -* // Get the Collator for US English and set its strength to PRIMARY
      -* Collator usCollator = Collator.getInstance(Locale.US);
      -* usCollator.setStrength(Collator.PRIMARY);
      -* if (usCollator.compare("abc", "ABC") == 0) {
      -*     System.out.println("Strings are equivalent");
      -* }
      -*
      -* The following example shows how to compare two strings using the
      -* Collator for the default locale.
      -*
      -* // Compare two strings in the default locale
      -* Collator myCollator = Collator.getInstance();
      -* myCollator.setDecomposition(NO_DECOMPOSITION);
      -* if (myCollator.compare("à\u0325", "a\u0325̀") != 0) {
      -*     System.out.println("à\u0325 is not equals to a\u0325̀ without decomposition");
      -*     myCollator.setDecomposition(CANONICAL_DECOMPOSITION);
      -*     if (myCollator.compare("à\u0325", "a\u0325̀") != 0) {
      -*         System.out.println("Error: à\u0325 should be equals to a\u0325̀ with decomposition");
      -*     }
      -*     else {
      -*         System.out.println("à\u0325 is equals to a\u0325̀ with decomposition");
      -*     }
      -* }
      -* else {
      -*     System.out.println("Error: à\u0325 should be not equals to a\u0325̀ without decomposition");
      -* }
      -* 
      -*

      -* @see RuleBasedCollator -* @see CollationKey -* @author Syn Wee Quek -* @stable ICU 2.8 -*/ -public class Collator implements Comparator, Cloneable -{ - /** - * @internal - */ - private final java.text.Collator collator; - - /** - * @internal - */ - private Collator(java.text.Collator delegate) { - this.collator = delegate; - } - - /** - * Create a collator with a null delegate. - * For use by possible subclassers. This is present since - * the original Collator is abstract, and so, in theory - * subclassable. All member APIs must be overridden. - */ - protected Collator() { - this.collator = null; - } - - // public data members --------------------------------------------------- - - /** - * Strongest collator strength value. Typically used to denote differences - * between base characters. See class documentation for more explanation. - * @see #setStrength - * @see #getStrength - * @stable ICU 2.8 - */ - public final static int PRIMARY = java.text.Collator.PRIMARY; - - /** - * Second level collator strength value. - * Accents in the characters are considered secondary differences. - * Other differences between letters can also be considered secondary - * differences, depending on the language. - * See class documentation for more explanation. - * @see #setStrength - * @see #getStrength - * @stable ICU 2.8 - */ - public final static int SECONDARY = java.text.Collator.SECONDARY; - - /** - * Third level collator strength value. - * Upper and lower case differences in characters are distinguished at this - * strength level. In addition, a variant of a letter differs from the base - * form on the tertiary level. - * See class documentation for more explanation. - * @see #setStrength - * @see #getStrength - * @stable ICU 2.8 - */ - public final static int TERTIARY = java.text.Collator.TERTIARY; - - /** - * {@icu} Fourth level collator strength value. - * When punctuation is ignored - * - * (see Ignoring Punctuations in the user guide) at PRIMARY to TERTIARY - * strength, an additional strength level can - * be used to distinguish words with and without punctuation. - * See class documentation for more explanation. - * @see #setStrength - * @see #getStrength - * @stable ICU 2.8 - */ - public final static int QUATERNARY = java.text.Collator.IDENTICAL; - - /** - * Smallest Collator strength value. When all other strengths are equal, - * the IDENTICAL strength is used as a tiebreaker. The Unicode code point - * values of the NFD form of each string are compared, just in case there - * is no difference. - * See class documentation for more explanation. - *

      - *

      - * Note this value is different from JDK's - *

      - * @stable ICU 2.8 - */ - public final static int IDENTICAL = java.text.Collator.FULL_DECOMPOSITION; - - /** - * {@icunote} This is for backwards compatibility with Java APIs only. It - * should not be used, IDENTICAL should be used instead. ICU's - * collation does not support Java's FULL_DECOMPOSITION mode. - * @stable ICU 3.4 - */ - public final static int FULL_DECOMPOSITION = java.text.Collator.FULL_DECOMPOSITION; - - /** - * Decomposition mode value. With NO_DECOMPOSITION set, Strings - * will not be decomposed for collation. This is the default - * decomposition setting unless otherwise specified by the locale - * used to create the Collator.

      - * - *

      Note this value is different from the JDK's.

      - * @see #CANONICAL_DECOMPOSITION - * @see #getDecomposition - * @see #setDecomposition - * @stable ICU 2.8 - */ - public final static int NO_DECOMPOSITION = java.text.Collator.NO_DECOMPOSITION; - - /** - * Decomposition mode value. With CANONICAL_DECOMPOSITION set, - * characters that are canonical variants according to the Unicode standard - * will be decomposed for collation.

      - * - *

      CANONICAL_DECOMPOSITION corresponds to Normalization Form D as - * described in - * Unicode Technical Report #15. - *

      - * @see #NO_DECOMPOSITION - * @see #getDecomposition - * @see #setDecomposition - * @stable ICU 2.8 - */ - public final static int CANONICAL_DECOMPOSITION = java.text.Collator.CANONICAL_DECOMPOSITION; - - // public methods -------------------------------------------------------- - - // public setters -------------------------------------------------------- - - /** - * Sets this Collator's strength property. The strength property - * determines the minimum level of difference considered significant - * during comparison.

      - * - *

      The default strength for the Collator is TERTIARY, unless specified - * otherwise by the locale used to create the Collator.

      - * - *

      See the Collator class description for an example of use.

      - * @param newStrength the new strength value. - * @see #getStrength - * @see #PRIMARY - * @see #SECONDARY - * @see #TERTIARY - * @see #QUATERNARY - * @see #IDENTICAL - * @throws IllegalArgumentException if the new strength value is not one - * of PRIMARY, SECONDARY, TERTIARY, QUATERNARY or IDENTICAL. - * @stable ICU 2.8 - */ - public void setStrength(int newStrength) - { - collator.setStrength(newStrength); - } - - /** - * Sets the decomposition mode of this Collator. Setting this - * decomposition property with CANONICAL_DECOMPOSITION allows the - * Collator to handle un-normalized text properly, producing the - * same results as if the text were normalized. If - * NO_DECOMPOSITION is set, it is the user's responsibility to - * insure that all text is already in the appropriate form before - * a comparison or before getting a CollationKey. Adjusting - * decomposition mode allows the user to select between faster and - * more complete collation behavior.

      - * - *

      Since a great many of the world's languages do not require - * text normalization, most locales set NO_DECOMPOSITION as the - * default decomposition mode.

      - * - * The default decompositon mode for the Collator is - * NO_DECOMPOSITON, unless specified otherwise by the locale used - * to create the Collator.

      - * - *

      See getDecomposition for a description of decomposition - * mode.

      - * - * @param decomposition the new decomposition mode - * @see #getDecomposition - * @see #NO_DECOMPOSITION - * @see #CANONICAL_DECOMPOSITION - * @throws IllegalArgumentException If the given value is not a valid - * decomposition mode. - * @stable ICU 2.8 - */ - public void setDecomposition(int decomposition) - { - collator.setDecomposition(decomposition); - } - - // public getters -------------------------------------------------------- - - /** - * Returns the Collator for the current default locale. - * The default locale is determined by java.util.Locale.getDefault(). - * @return the Collator for the default locale (for example, en_US) if it - * is created successfully. Otherwise if there is no Collator - * associated with the current locale, the default UCA collator - * will be returned. - * @see java.util.Locale#getDefault() - * @see #getInstance(Locale) - * @stable ICU 2.8 - */ - public static final Collator getInstance() - { - return new Collator(java.text.Collator.getInstance()); - } - - /** - * Clones the collator. - * @stable ICU 2.6 - * @return a clone of this collator. - */ - public Object clone() throws CloneNotSupportedException { - return new Collator((java.text.Collator)collator.clone()); - } - - // begin registry stuff - - /** - * A factory used with registerFactory to register multiple collators and provide - * display names for them. If standard locale display names are sufficient, - * Collator instances may be registered instead. - *

      Note: as of ICU4J 3.2, the default API for CollatorFactory uses - * ULocale instead of Locale. Instead of overriding createCollator(Locale), - * new implementations should override createCollator(ULocale). Note that - * one of these two methods MUST be overridden or else an infinite - * loop will occur. - * @stable ICU 2.6 - */ - public static abstract class CollatorFactory { - /** - * Return true if this factory will be visible. Default is true. - * If not visible, the locales supported by this factory will not - * be listed by getAvailableLocales. - * - * @return true if this factory is visible - * @stable ICU 2.6 - */ - public boolean visible() { - return true; - } - - /** - * Return an instance of the appropriate collator. If the locale - * is not supported, return null. - * Note: as of ICU4J 3.2, implementations should override - * this method instead of createCollator(Locale). - * @param loc the locale for which this collator is to be created. - * @return the newly created collator. - * @stable ICU 3.2 - */ - public Collator createCollator(ULocale loc) { - return createCollator(loc.toLocale()); - } - - /** - * Return an instance of the appropriate collator. If the locale - * is not supported, return null. - *

      Note: as of ICU4J 3.2, implementations should override - * createCollator(ULocale) instead of this method, and inherit this - * method's implementation. This method is no longer abstract - * and instead delegates to createCollator(ULocale). - * @param loc the locale for which this collator is to be created. - * @return the newly created collator. - * @stable ICU 2.6 - */ - public Collator createCollator(Locale loc) { - return createCollator(ULocale.forLocale(loc)); - } - - /** - * Return the name of the collator for the objectLocale, localized for the displayLocale. - * If objectLocale is not visible or not defined by the factory, return null. - * @param objectLocale the locale identifying the collator - * @param displayLocale the locale for which the display name of the collator should be localized - * @return the display name - * @stable ICU 2.6 - */ - public String getDisplayName(Locale objectLocale, Locale displayLocale) { - return getDisplayName(ULocale.forLocale(objectLocale), ULocale.forLocale(displayLocale)); - } - - /** - * Return the name of the collator for the objectLocale, localized for the displayLocale. - * If objectLocale is not visible or not defined by the factory, return null. - * @param objectLocale the locale identifying the collator - * @param displayLocale the locale for which the display name of the collator should be localized - * @return the display name - * @stable ICU 3.2 - */ - public String getDisplayName(ULocale objectLocale, ULocale displayLocale) { - if (visible()) { - Set supported = getSupportedLocaleIDs(); - String name = objectLocale.getBaseName(); - if (supported.contains(name)) { - return objectLocale.getDisplayName(displayLocale); - } - } - return null; - } - - /** - * Return an unmodifiable collection of the locale names directly - * supported by this factory. - * - * @return the set of supported locale IDs. - * @stable ICU 2.6 - */ - public abstract Set getSupportedLocaleIDs(); - - /** - * Empty default constructor. - * @stable ICU 2.6 - */ - protected CollatorFactory() { - } - } - - /** - * {@icu} Returns the Collator for the desired locale. - * @param locale the desired locale. - * @return Collator for the desired locale if it is created successfully. - * Otherwise if there is no Collator - * associated with the current locale, a default UCA collator will - * be returned. - * @see java.util.Locale - * @see java.util.ResourceBundle - * @see #getInstance(Locale) - * @see #getInstance() - * @stable ICU 3.0 - */ - public static final Collator getInstance(ULocale locale) { - return getInstance(locale.toLocale()); - } - - /** - * Returns the Collator for the desired locale. - * @param locale the desired locale. - * @return Collator for the desired locale if it is created successfully. - * Otherwise if there is no Collator - * associated with the current locale, a default UCA collator will - * be returned. - * @see java.util.Locale - * @see java.util.ResourceBundle - * @see #getInstance(ULocale) - * @see #getInstance() - * @stable ICU 2.8 - */ - public static final Collator getInstance(Locale locale) { - return new Collator(java.text.Collator.getInstance(locale)); - } - - /** - * {@icu} Registers a collator as the default collator for the provided locale. The - * collator should not be modified after it is registered. - * - * @param collator the collator to register - * @param locale the locale for which this is the default collator - * @return an object that can be used to unregister the registered collator. - * - * @stable ICU 3.2 - */ - public static final Object registerInstance(Collator collator, ULocale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Registers a collator factory. - * - * @param factory the factory to register - * @return an object that can be used to unregister the registered factory. - * - * @stable ICU 2.6 - */ - public static final Object registerFactory(CollatorFactory factory) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Unregisters a collator previously registered using registerInstance. - * @param registryKey the object previously returned by registerInstance. - * @return true if the collator was successfully unregistered. - * @stable ICU 2.6 - */ - public static final boolean unregister(Object registryKey) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the set of locales, as Locale objects, for which collators - * are installed. Note that Locale objects do not support RFC 3066. - * @return the list of locales in which collators are installed. - * This list includes any that have been registered, in addition to - * those that are installed with ICU4J. - * @stable ICU 2.4 - */ - public static Locale[] getAvailableLocales() { - return java.text.Collator.getAvailableLocales(); - } - - /** - * {@icu} Returns the set of locales, as ULocale objects, for which collators - * are installed. ULocale objects support RFC 3066. - * @return the list of locales in which collators are installed. - * This list includes any that have been registered, in addition to - * those that are installed with ICU4J. - * @stable ICU 3.0 - */ - public static final ULocale[] getAvailableULocales() { - Locale[] locales = java.text.Collator.getAvailableLocales(); - ULocale[] ulocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; ++i) { - ulocales[i] = ULocale.forLocale(locales[i]); - } - return ulocales; - } - - /** - * {@icu} Returns an array of all possible keywords that are relevant to - * collation. At this point, the only recognized keyword for this - * service is "collation". - * @return an array of valid collation keywords. - * @see #getKeywordValues - * @stable ICU 3.0 - */ - public static final String[] getKeywords() { - // No keywords support in com.ibm.icu.base - return new String[0]; - } - - /** - * {@icu} Given a keyword, returns an array of all values for - * that keyword that are currently in use. - * @param keyword one of the keywords returned by getKeywords. - * @see #getKeywords - * @stable ICU 3.0 - */ - public static final String[] getKeywordValues(String keyword) { - // No keywords support in com.ibm.icu.base - return new String[0]; - } - - /** - * {@icu} Given a key and a locale, returns an array of string values in a preferred - * order that would make a difference. These are all and only those values where - * the open (creation) of the service with the locale formed from the input locale - * plus input keyword and that value has different behavior than creation with the - * input locale alone. - * @param key one of the keys supported by this service. For now, only - * "collation" is supported. - * @param locale the locale - * @param commonlyUsed if set to true it will return only commonly used values - * with the given locale in preferred order. Otherwise, - * it will return all the available values for the locale. - * @return an array of string values for the given key and the locale. - * @stable ICU 4.2 - */ - public static final String[] getKeywordValuesForLocale(String key, ULocale locale, - boolean commonlyUsed) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the functionally equivalent locale for the given - * requested locale, with respect to given keyword, for the - * collation service. If two locales return the same result, then - * collators instantiated for these locales will behave - * equivalently. The converse is not always true; two collators - * may in fact be equivalent, but return different results, due to - * internal details. The return result has no other meaning than - * that stated above, and implies nothing as to the relationship - * between the two locales. This is intended for use by - * applications who wish to cache collators, or otherwise reuse - * collators when possible. The functional equivalent may change - * over time. For more information, please see the - * Locales and Services section of the ICU User Guide. - * @param keyword a particular keyword as enumerated by - * getKeywords. - * @param locID The requested locale - * @param isAvailable If non-null, isAvailable[0] will receive and - * output boolean that indicates whether the requested locale was - * 'available' to the collation service. If non-null, isAvailable - * must have length >= 1. - * @return the locale - * @stable ICU 3.0 - */ - public static final ULocale getFunctionalEquivalent(String keyword, - ULocale locID, - boolean isAvailable[]) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the functionally equivalent locale for the given - * requested locale, with respect to given keyword, for the - * collation service. - * @param keyword a particular keyword as enumerated by - * getKeywords. - * @param locID The requested locale - * @return the locale - * @see #getFunctionalEquivalent(String,ULocale,boolean[]) - * @stable ICU 3.0 - */ - public static final ULocale getFunctionalEquivalent(String keyword, - ULocale locID) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the name of the collator for the objectLocale, localized for the - * displayLocale. - * @param objectLocale the locale of the collator - * @param displayLocale the locale for the collator's display name - * @return the display name - * @stable ICU 2.6 - */ - static public String getDisplayName(Locale objectLocale, Locale displayLocale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the name of the collator for the objectLocale, localized for the - * displayLocale. - * @param objectLocale the locale of the collator - * @param displayLocale the locale for the collator's display name - * @return the display name - * @stable ICU 3.2 - */ - static public String getDisplayName(ULocale objectLocale, ULocale displayLocale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the name of the collator for the objectLocale, localized for the - * current locale. - * @param objectLocale the locale of the collator - * @return the display name - * @stable ICU 2.6 - */ - static public String getDisplayName(Locale objectLocale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the name of the collator for the objectLocale, localized for the - * current locale. - * @param objectLocale the locale of the collator - * @return the display name - * @stable ICU 3.2 - */ - static public String getDisplayName(ULocale objectLocale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns this Collator's strength property. The strength property - * determines the minimum level of difference considered significant. - *

      - * {@icunote} This can return QUATERNARY strength, which is not supported by the - * JDK version. - *

      - * See the Collator class description for more details. - *

      - * @return this Collator's current strength property. - * @see #setStrength - * @see #PRIMARY - * @see #SECONDARY - * @see #TERTIARY - * @see #QUATERNARY - * @see #IDENTICAL - * @stable ICU 2.8 - */ - public int getStrength() - { - return collator.getStrength(); - } - - /** - * Returns the decomposition mode of this Collator. The decomposition mode - * determines how Unicode composed characters are handled. - *

      - *

      - * See the Collator class description for more details. - *

      - * @return the decomposition mode - * @see #setDecomposition - * @see #NO_DECOMPOSITION - * @see #CANONICAL_DECOMPOSITION - * @stable ICU 2.8 - */ - public int getDecomposition() - { - return collator.getDecomposition(); - } - - // public other methods ------------------------------------------------- - - /** - * Compares the equality of two text Strings using - * this Collator's rules, strength and decomposition mode. Convenience method. - * @param source the source string to be compared. - * @param target the target string to be compared. - * @return true if the strings are equal according to the collation - * rules, otherwise false. - * @see #compare - * @throws NullPointerException thrown if either arguments is null. - * @stable ICU 2.8 - */ - public boolean equals(String source, String target) - { - return (compare(source, target) == 0); - } - - /** - * {@icu} Returns a UnicodeSet that contains all the characters and sequences tailored - * in this collator. - * @return a pointer to a UnicodeSet object containing all the - * code points and sequences that may sort differently than - * in the UCA. - * @stable ICU 2.4 - */ - public UnicodeSet getTailoredSet() - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Compares the source text String to the target text String according to - * this Collator's rules, strength and decomposition mode. - * Returns an integer less than, - * equal to or greater than zero depending on whether the source String is - * less than, equal to or greater than the target String. See the Collator - * class description for an example of use. - *

      - * @param source the source String. - * @param target the target String. - * @return Returns an integer value. Value is less than zero if source is - * less than target, value is zero if source and target are equal, - * value is greater than zero if source is greater than target. - * @see CollationKey - * @see #getCollationKey - * @throws NullPointerException thrown if either argument is null. - * @stable ICU 2.8 - */ - public int compare(String source, String target) { - return collator.compare(source, target); - } - - /** - * Compares the source Object to the target Object. - *

      - * @param source the source Object. - * @param target the target Object. - * @return Returns an integer value. Value is less than zero if source is - * less than target, value is zero if source and target are equal, - * value is greater than zero if source is greater than target. - * @throws ClassCastException thrown if either arguments cannot be cast to String. - * @stable ICU 4.2 - */ - public int compare(Object source, Object target) { - return compare((String)source, (String)target); - } - - /** - *

      - * Transforms the String into a CollationKey suitable for efficient - * repeated comparison. The resulting key depends on the collator's - * rules, strength and decomposition mode. - *

      - *

      See the CollationKey class documentation for more information.

      - * @param source the string to be transformed into a CollationKey. - * @return the CollationKey for the given String based on this Collator's - * collation rules. If the source String is null, a null - * CollationKey is returned. - * @see CollationKey - * @see #compare(String, String) - * @see #getRawCollationKey - * @stable ICU 2.8 - */ - public CollationKey getCollationKey(String source) { - return new CollationKey(collator.getCollationKey(source)); - } - - /** - * {@icu} Returns the simpler form of a CollationKey for the String source following - * the rules of this Collator and stores the result into the user provided argument - * key. If key has a internal byte array of length that's too small for the result, - * the internal byte array will be grown to the exact required size. - * @param source the text String to be transformed into a RawCollationKey - * @return If key is null, a new instance of RawCollationKey will be - * created and returned, otherwise the user provided key will be - * returned. - * @see #compare(String, String) - * @see #getCollationKey - * @see RawCollationKey - * @stable ICU 2.8 - */ - public RawCollationKey getRawCollationKey(String source, RawCollationKey key) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Variable top is a two byte primary value which causes all the codepoints - * with primary values that are less or equal than the variable top to be - * shifted when alternate handling is set to SHIFTED. - *

      - *

      - * Sets the variable top to a collation element value of a string supplied. - *

      - * @param varTop one or more (if contraction) characters to which the - * variable top should be set - * @return a int value containing the value of the variable top in upper 16 - * bits. Lower 16 bits are undefined. - * @throws IllegalArgumentException is thrown if varTop argument is not - * a valid variable top element. A variable top element is - * invalid when it is a contraction that does not exist in the - * Collation order or when the PRIMARY strength collation - * element for the variable top has more than two bytes - * @see #getVariableTop - * @see RuleBasedCollator#setAlternateHandlingShifted - * @stable ICU 2.6 - */ - public int setVariableTop(String varTop) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the variable top value of a Collator. - * Lower 16 bits are undefined and should be ignored. - * @return the variable top value of a Collator. - * @see #setVariableTop - * @stable ICU 2.6 - */ - public int getVariableTop() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the variable top to a collation element value supplied. - * Variable top is set to the upper 16 bits. - * Lower 16 bits are ignored. - * @param varTop Collation element value, as returned by setVariableTop or - * getVariableTop - * @see #getVariableTop - * @see #setVariableTop - * @stable ICU 2.6 - */ - public void setVariableTop(int varTop) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the version of this collator object. - * @return the version object associated with this collator - * @stable ICU 2.8 - */ - public VersionInfo getVersion() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the UCA version of this collator object. - * @return the version object associated with this collator - * @stable ICU 2.8 - */ - public VersionInfo getUCAVersion() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 - * contains a partial preview implementation. The * actual - * locale is returned correctly, but the valid locale is - * not, in most cases. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - // com.ibm.icu.base specific overrides - public String toString() { - return collator.toString(); - } - - public boolean equals(Object rhs) { - try { - return collator.equals(((Collator)rhs).collator); - } - catch (Exception e) { - return false; - } - } - - public int hashCode() { - return collator.hashCode(); - } -} +/** +******************************************************************************* +* Copyright (C) 1996-2011, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ +package com.ibm.icu.text; + +import java.util.Comparator; +import java.util.Locale; +import java.util.Set; + +import com.ibm.icu.util.ULocale; +import com.ibm.icu.util.VersionInfo; + +/** +* {@icuenhanced java.text.Collator}.{@icu _usage_} +* +*

      Collator performs locale-sensitive string comparison. A concrete +* subclass, RuleBasedCollator, allows customization of the collation +* ordering by the use of rule sets.

      +* +*

      Following the Unicode +* Consortium's specifications for the +* Unicode Collation +* Algorithm (UCA), there are 5 different levels of strength used +* in comparisons: +* +*

        +*
      • PRIMARY strength: Typically, this is used to denote differences between +* base characters (for example, "a" < "b"). +* It is the strongest difference. For example, dictionaries are divided +* into different sections by base character. +*
      • SECONDARY strength: Accents in the characters are considered secondary +* differences (for example, "as" < "às" < "at"). Other +* differences +* between letters can also be considered secondary differences, depending +* on the language. A secondary difference is ignored when there is a +* primary difference anywhere in the strings. +*
      • TERTIARY strength: Upper and lower case differences in characters are +* distinguished at tertiary strength (for example, "ao" < "Ao" < +* "aò"). In addition, a variant of a letter differs from the base +* form on the tertiary strength (such as "A" and "Ⓐ"). Another +* example is the +* difference between large and small Kana. A tertiary difference is ignored +* when there is a primary or secondary difference anywhere in the strings. +*
      • QUATERNARY strength: When punctuation is ignored +* +* (see Ignoring Punctuations in the user guide) at PRIMARY to TERTIARY +* strength, an additional strength level can +* be used to distinguish words with and without punctuation (for example, +* "ab" < "a-b" < "aB"). +* This difference is ignored when there is a PRIMARY, SECONDARY or TERTIARY +* difference. The QUATERNARY strength should only be used if ignoring +* punctuation is required. +*
      • IDENTICAL strength: +* When all other strengths are equal, the IDENTICAL strength is used as a +* tiebreaker. The Unicode code point values of the NFD form of each string +* are compared, just in case there is no difference. +* For example, Hebrew cantellation marks are only distinguished at this +* strength. This strength should be used sparingly, as only code point +* value differences between two strings is an extremely rare occurrence. +* Using this strength substantially decreases the performance for both +* comparison and collation key generation APIs. This strength also +* increases the size of the collation key. +*
      +* +* Unlike the JDK, ICU4J's Collator deals only with 2 decomposition modes, +* the canonical decomposition mode and one that does not use any decomposition. +* The compatibility decomposition mode, java.text.Collator.FULL_DECOMPOSITION +* is not supported here. If the canonical +* decomposition mode is set, the Collator handles un-normalized text properly, +* producing the same results as if the text were normalized in NFD. If +* canonical decomposition is turned off, it is the user's responsibility to +* ensure that all text is already in the appropriate form before performing +* a comparison or before getting a CollationKey.

      +* +*

      For more information about the collation service see the +* users +* guide.

      +* +*

      Examples of use +*

      +* // Get the Collator for US English and set its strength to PRIMARY
      +* Collator usCollator = Collator.getInstance(Locale.US);
      +* usCollator.setStrength(Collator.PRIMARY);
      +* if (usCollator.compare("abc", "ABC") == 0) {
      +*     System.out.println("Strings are equivalent");
      +* }
      +*
      +* The following example shows how to compare two strings using the
      +* Collator for the default locale.
      +*
      +* // Compare two strings in the default locale
      +* Collator myCollator = Collator.getInstance();
      +* myCollator.setDecomposition(NO_DECOMPOSITION);
      +* if (myCollator.compare("à\u0325", "a\u0325̀") != 0) {
      +*     System.out.println("à\u0325 is not equals to a\u0325̀ without decomposition");
      +*     myCollator.setDecomposition(CANONICAL_DECOMPOSITION);
      +*     if (myCollator.compare("à\u0325", "a\u0325̀") != 0) {
      +*         System.out.println("Error: à\u0325 should be equals to a\u0325̀ with decomposition");
      +*     }
      +*     else {
      +*         System.out.println("à\u0325 is equals to a\u0325̀ with decomposition");
      +*     }
      +* }
      +* else {
      +*     System.out.println("Error: à\u0325 should be not equals to a\u0325̀ without decomposition");
      +* }
      +* 
      +*

      +* @see RuleBasedCollator +* @see CollationKey +* @author Syn Wee Quek +* @stable ICU 2.8 +*/ +public class Collator implements Comparator, Cloneable +{ + /** + * @internal + */ + private final java.text.Collator collator; + + /** + * @internal + */ + private Collator(java.text.Collator delegate) { + this.collator = delegate; + } + + /** + * Create a collator with a null delegate. + * For use by possible subclassers. This is present since + * the original Collator is abstract, and so, in theory + * subclassable. All member APIs must be overridden. + */ + protected Collator() { + this.collator = null; + } + + // public data members --------------------------------------------------- + + /** + * Strongest collator strength value. Typically used to denote differences + * between base characters. See class documentation for more explanation. + * @see #setStrength + * @see #getStrength + * @stable ICU 2.8 + */ + public final static int PRIMARY = java.text.Collator.PRIMARY; + + /** + * Second level collator strength value. + * Accents in the characters are considered secondary differences. + * Other differences between letters can also be considered secondary + * differences, depending on the language. + * See class documentation for more explanation. + * @see #setStrength + * @see #getStrength + * @stable ICU 2.8 + */ + public final static int SECONDARY = java.text.Collator.SECONDARY; + + /** + * Third level collator strength value. + * Upper and lower case differences in characters are distinguished at this + * strength level. In addition, a variant of a letter differs from the base + * form on the tertiary level. + * See class documentation for more explanation. + * @see #setStrength + * @see #getStrength + * @stable ICU 2.8 + */ + public final static int TERTIARY = java.text.Collator.TERTIARY; + + /** + * {@icu} Fourth level collator strength value. + * When punctuation is ignored + * + * (see Ignoring Punctuations in the user guide) at PRIMARY to TERTIARY + * strength, an additional strength level can + * be used to distinguish words with and without punctuation. + * See class documentation for more explanation. + * @see #setStrength + * @see #getStrength + * @stable ICU 2.8 + */ + public final static int QUATERNARY = java.text.Collator.IDENTICAL; + + /** + * Smallest Collator strength value. When all other strengths are equal, + * the IDENTICAL strength is used as a tiebreaker. The Unicode code point + * values of the NFD form of each string are compared, just in case there + * is no difference. + * See class documentation for more explanation. + *

      + *

      + * Note this value is different from JDK's + *

      + * @stable ICU 2.8 + */ + public final static int IDENTICAL = java.text.Collator.FULL_DECOMPOSITION; + + /** + * {@icunote} This is for backwards compatibility with Java APIs only. It + * should not be used, IDENTICAL should be used instead. ICU's + * collation does not support Java's FULL_DECOMPOSITION mode. + * @stable ICU 3.4 + */ + public final static int FULL_DECOMPOSITION = java.text.Collator.FULL_DECOMPOSITION; + + /** + * Decomposition mode value. With NO_DECOMPOSITION set, Strings + * will not be decomposed for collation. This is the default + * decomposition setting unless otherwise specified by the locale + * used to create the Collator.

      + * + *

      Note this value is different from the JDK's.

      + * @see #CANONICAL_DECOMPOSITION + * @see #getDecomposition + * @see #setDecomposition + * @stable ICU 2.8 + */ + public final static int NO_DECOMPOSITION = java.text.Collator.NO_DECOMPOSITION; + + /** + * Decomposition mode value. With CANONICAL_DECOMPOSITION set, + * characters that are canonical variants according to the Unicode standard + * will be decomposed for collation.

      + * + *

      CANONICAL_DECOMPOSITION corresponds to Normalization Form D as + * described in + * Unicode Technical Report #15. + *

      + * @see #NO_DECOMPOSITION + * @see #getDecomposition + * @see #setDecomposition + * @stable ICU 2.8 + */ + public final static int CANONICAL_DECOMPOSITION = java.text.Collator.CANONICAL_DECOMPOSITION; + + // public methods -------------------------------------------------------- + + // public setters -------------------------------------------------------- + + /** + * Sets this Collator's strength property. The strength property + * determines the minimum level of difference considered significant + * during comparison.

      + * + *

      The default strength for the Collator is TERTIARY, unless specified + * otherwise by the locale used to create the Collator.

      + * + *

      See the Collator class description for an example of use.

      + * @param newStrength the new strength value. + * @see #getStrength + * @see #PRIMARY + * @see #SECONDARY + * @see #TERTIARY + * @see #QUATERNARY + * @see #IDENTICAL + * @throws IllegalArgumentException if the new strength value is not one + * of PRIMARY, SECONDARY, TERTIARY, QUATERNARY or IDENTICAL. + * @stable ICU 2.8 + */ + public void setStrength(int newStrength) + { + collator.setStrength(newStrength); + } + + /** + * Sets the decomposition mode of this Collator. Setting this + * decomposition property with CANONICAL_DECOMPOSITION allows the + * Collator to handle un-normalized text properly, producing the + * same results as if the text were normalized. If + * NO_DECOMPOSITION is set, it is the user's responsibility to + * insure that all text is already in the appropriate form before + * a comparison or before getting a CollationKey. Adjusting + * decomposition mode allows the user to select between faster and + * more complete collation behavior.

      + * + *

      Since a great many of the world's languages do not require + * text normalization, most locales set NO_DECOMPOSITION as the + * default decomposition mode.

      + * + * The default decompositon mode for the Collator is + * NO_DECOMPOSITON, unless specified otherwise by the locale used + * to create the Collator.

      + * + *

      See getDecomposition for a description of decomposition + * mode.

      + * + * @param decomposition the new decomposition mode + * @see #getDecomposition + * @see #NO_DECOMPOSITION + * @see #CANONICAL_DECOMPOSITION + * @throws IllegalArgumentException If the given value is not a valid + * decomposition mode. + * @stable ICU 2.8 + */ + public void setDecomposition(int decomposition) + { + collator.setDecomposition(decomposition); + } + + // public getters -------------------------------------------------------- + + /** + * Returns the Collator for the current default locale. + * The default locale is determined by java.util.Locale.getDefault(). + * @return the Collator for the default locale (for example, en_US) if it + * is created successfully. Otherwise if there is no Collator + * associated with the current locale, the default UCA collator + * will be returned. + * @see java.util.Locale#getDefault() + * @see #getInstance(Locale) + * @stable ICU 2.8 + */ + public static final Collator getInstance() + { + return new Collator(java.text.Collator.getInstance()); + } + + /** + * Clones the collator. + * @stable ICU 2.6 + * @return a clone of this collator. + */ + public Object clone() throws CloneNotSupportedException { + return new Collator((java.text.Collator)collator.clone()); + } + + // begin registry stuff + + /** + * A factory used with registerFactory to register multiple collators and provide + * display names for them. If standard locale display names are sufficient, + * Collator instances may be registered instead. + *

      Note: as of ICU4J 3.2, the default API for CollatorFactory uses + * ULocale instead of Locale. Instead of overriding createCollator(Locale), + * new implementations should override createCollator(ULocale). Note that + * one of these two methods MUST be overridden or else an infinite + * loop will occur. + * @stable ICU 2.6 + */ + public static abstract class CollatorFactory { + /** + * Return true if this factory will be visible. Default is true. + * If not visible, the locales supported by this factory will not + * be listed by getAvailableLocales. + * + * @return true if this factory is visible + * @stable ICU 2.6 + */ + public boolean visible() { + return true; + } + + /** + * Return an instance of the appropriate collator. If the locale + * is not supported, return null. + * Note: as of ICU4J 3.2, implementations should override + * this method instead of createCollator(Locale). + * @param loc the locale for which this collator is to be created. + * @return the newly created collator. + * @stable ICU 3.2 + */ + public Collator createCollator(ULocale loc) { + return createCollator(loc.toLocale()); + } + + /** + * Return an instance of the appropriate collator. If the locale + * is not supported, return null. + *

      Note: as of ICU4J 3.2, implementations should override + * createCollator(ULocale) instead of this method, and inherit this + * method's implementation. This method is no longer abstract + * and instead delegates to createCollator(ULocale). + * @param loc the locale for which this collator is to be created. + * @return the newly created collator. + * @stable ICU 2.6 + */ + public Collator createCollator(Locale loc) { + return createCollator(ULocale.forLocale(loc)); + } + + /** + * Return the name of the collator for the objectLocale, localized for the displayLocale. + * If objectLocale is not visible or not defined by the factory, return null. + * @param objectLocale the locale identifying the collator + * @param displayLocale the locale for which the display name of the collator should be localized + * @return the display name + * @stable ICU 2.6 + */ + public String getDisplayName(Locale objectLocale, Locale displayLocale) { + return getDisplayName(ULocale.forLocale(objectLocale), ULocale.forLocale(displayLocale)); + } + + /** + * Return the name of the collator for the objectLocale, localized for the displayLocale. + * If objectLocale is not visible or not defined by the factory, return null. + * @param objectLocale the locale identifying the collator + * @param displayLocale the locale for which the display name of the collator should be localized + * @return the display name + * @stable ICU 3.2 + */ + public String getDisplayName(ULocale objectLocale, ULocale displayLocale) { + if (visible()) { + Set supported = getSupportedLocaleIDs(); + String name = objectLocale.getBaseName(); + if (supported.contains(name)) { + return objectLocale.getDisplayName(displayLocale); + } + } + return null; + } + + /** + * Return an unmodifiable collection of the locale names directly + * supported by this factory. + * + * @return the set of supported locale IDs. + * @stable ICU 2.6 + */ + public abstract Set getSupportedLocaleIDs(); + + /** + * Empty default constructor. + * @stable ICU 2.6 + */ + protected CollatorFactory() { + } + } + + /** + * {@icu} Returns the Collator for the desired locale. + * @param locale the desired locale. + * @return Collator for the desired locale if it is created successfully. + * Otherwise if there is no Collator + * associated with the current locale, a default UCA collator will + * be returned. + * @see java.util.Locale + * @see java.util.ResourceBundle + * @see #getInstance(Locale) + * @see #getInstance() + * @stable ICU 3.0 + */ + public static final Collator getInstance(ULocale locale) { + return getInstance(locale.toLocale()); + } + + /** + * Returns the Collator for the desired locale. + * @param locale the desired locale. + * @return Collator for the desired locale if it is created successfully. + * Otherwise if there is no Collator + * associated with the current locale, a default UCA collator will + * be returned. + * @see java.util.Locale + * @see java.util.ResourceBundle + * @see #getInstance(ULocale) + * @see #getInstance() + * @stable ICU 2.8 + */ + public static final Collator getInstance(Locale locale) { + return new Collator(java.text.Collator.getInstance(locale)); + } + + /** + * {@icu} Registers a collator as the default collator for the provided locale. The + * collator should not be modified after it is registered. + * + * @param collator the collator to register + * @param locale the locale for which this is the default collator + * @return an object that can be used to unregister the registered collator. + * + * @stable ICU 3.2 + */ + public static final Object registerInstance(Collator collator, ULocale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Registers a collator factory. + * + * @param factory the factory to register + * @return an object that can be used to unregister the registered factory. + * + * @stable ICU 2.6 + */ + public static final Object registerFactory(CollatorFactory factory) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Unregisters a collator previously registered using registerInstance. + * @param registryKey the object previously returned by registerInstance. + * @return true if the collator was successfully unregistered. + * @stable ICU 2.6 + */ + public static final boolean unregister(Object registryKey) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the set of locales, as Locale objects, for which collators + * are installed. Note that Locale objects do not support RFC 3066. + * @return the list of locales in which collators are installed. + * This list includes any that have been registered, in addition to + * those that are installed with ICU4J. + * @stable ICU 2.4 + */ + public static Locale[] getAvailableLocales() { + return java.text.Collator.getAvailableLocales(); + } + + /** + * {@icu} Returns the set of locales, as ULocale objects, for which collators + * are installed. ULocale objects support RFC 3066. + * @return the list of locales in which collators are installed. + * This list includes any that have been registered, in addition to + * those that are installed with ICU4J. + * @stable ICU 3.0 + */ + public static final ULocale[] getAvailableULocales() { + Locale[] locales = java.text.Collator.getAvailableLocales(); + ULocale[] ulocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + ulocales[i] = ULocale.forLocale(locales[i]); + } + return ulocales; + } + + /** + * {@icu} Returns an array of all possible keywords that are relevant to + * collation. At this point, the only recognized keyword for this + * service is "collation". + * @return an array of valid collation keywords. + * @see #getKeywordValues + * @stable ICU 3.0 + */ + public static final String[] getKeywords() { + // No keywords support in com.ibm.icu.base + return new String[0]; + } + + /** + * {@icu} Given a keyword, returns an array of all values for + * that keyword that are currently in use. + * @param keyword one of the keywords returned by getKeywords. + * @see #getKeywords + * @stable ICU 3.0 + */ + public static final String[] getKeywordValues(String keyword) { + // No keywords support in com.ibm.icu.base + return new String[0]; + } + + /** + * {@icu} Given a key and a locale, returns an array of string values in a preferred + * order that would make a difference. These are all and only those values where + * the open (creation) of the service with the locale formed from the input locale + * plus input keyword and that value has different behavior than creation with the + * input locale alone. + * @param key one of the keys supported by this service. For now, only + * "collation" is supported. + * @param locale the locale + * @param commonlyUsed if set to true it will return only commonly used values + * with the given locale in preferred order. Otherwise, + * it will return all the available values for the locale. + * @return an array of string values for the given key and the locale. + * @stable ICU 4.2 + */ + public static final String[] getKeywordValuesForLocale(String key, ULocale locale, + boolean commonlyUsed) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the functionally equivalent locale for the given + * requested locale, with respect to given keyword, for the + * collation service. If two locales return the same result, then + * collators instantiated for these locales will behave + * equivalently. The converse is not always true; two collators + * may in fact be equivalent, but return different results, due to + * internal details. The return result has no other meaning than + * that stated above, and implies nothing as to the relationship + * between the two locales. This is intended for use by + * applications who wish to cache collators, or otherwise reuse + * collators when possible. The functional equivalent may change + * over time. For more information, please see the + * Locales and Services section of the ICU User Guide. + * @param keyword a particular keyword as enumerated by + * getKeywords. + * @param locID The requested locale + * @param isAvailable If non-null, isAvailable[0] will receive and + * output boolean that indicates whether the requested locale was + * 'available' to the collation service. If non-null, isAvailable + * must have length >= 1. + * @return the locale + * @stable ICU 3.0 + */ + public static final ULocale getFunctionalEquivalent(String keyword, + ULocale locID, + boolean isAvailable[]) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the functionally equivalent locale for the given + * requested locale, with respect to given keyword, for the + * collation service. + * @param keyword a particular keyword as enumerated by + * getKeywords. + * @param locID The requested locale + * @return the locale + * @see #getFunctionalEquivalent(String,ULocale,boolean[]) + * @stable ICU 3.0 + */ + public static final ULocale getFunctionalEquivalent(String keyword, + ULocale locID) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the name of the collator for the objectLocale, localized for the + * displayLocale. + * @param objectLocale the locale of the collator + * @param displayLocale the locale for the collator's display name + * @return the display name + * @stable ICU 2.6 + */ + static public String getDisplayName(Locale objectLocale, Locale displayLocale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the name of the collator for the objectLocale, localized for the + * displayLocale. + * @param objectLocale the locale of the collator + * @param displayLocale the locale for the collator's display name + * @return the display name + * @stable ICU 3.2 + */ + static public String getDisplayName(ULocale objectLocale, ULocale displayLocale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the name of the collator for the objectLocale, localized for the + * current locale. + * @param objectLocale the locale of the collator + * @return the display name + * @stable ICU 2.6 + */ + static public String getDisplayName(Locale objectLocale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the name of the collator for the objectLocale, localized for the + * current locale. + * @param objectLocale the locale of the collator + * @return the display name + * @stable ICU 3.2 + */ + static public String getDisplayName(ULocale objectLocale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns this Collator's strength property. The strength property + * determines the minimum level of difference considered significant. + *

      + * {@icunote} This can return QUATERNARY strength, which is not supported by the + * JDK version. + *

      + * See the Collator class description for more details. + *

      + * @return this Collator's current strength property. + * @see #setStrength + * @see #PRIMARY + * @see #SECONDARY + * @see #TERTIARY + * @see #QUATERNARY + * @see #IDENTICAL + * @stable ICU 2.8 + */ + public int getStrength() + { + return collator.getStrength(); + } + + /** + * Returns the decomposition mode of this Collator. The decomposition mode + * determines how Unicode composed characters are handled. + *

      + *

      + * See the Collator class description for more details. + *

      + * @return the decomposition mode + * @see #setDecomposition + * @see #NO_DECOMPOSITION + * @see #CANONICAL_DECOMPOSITION + * @stable ICU 2.8 + */ + public int getDecomposition() + { + return collator.getDecomposition(); + } + + // public other methods ------------------------------------------------- + + /** + * Compares the equality of two text Strings using + * this Collator's rules, strength and decomposition mode. Convenience method. + * @param source the source string to be compared. + * @param target the target string to be compared. + * @return true if the strings are equal according to the collation + * rules, otherwise false. + * @see #compare + * @throws NullPointerException thrown if either arguments is null. + * @stable ICU 2.8 + */ + public boolean equals(String source, String target) + { + return (compare(source, target) == 0); + } + + /** + * {@icu} Returns a UnicodeSet that contains all the characters and sequences tailored + * in this collator. + * @return a pointer to a UnicodeSet object containing all the + * code points and sequences that may sort differently than + * in the UCA. + * @stable ICU 2.4 + */ + public UnicodeSet getTailoredSet() + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Compares the source text String to the target text String according to + * this Collator's rules, strength and decomposition mode. + * Returns an integer less than, + * equal to or greater than zero depending on whether the source String is + * less than, equal to or greater than the target String. See the Collator + * class description for an example of use. + *

      + * @param source the source String. + * @param target the target String. + * @return Returns an integer value. Value is less than zero if source is + * less than target, value is zero if source and target are equal, + * value is greater than zero if source is greater than target. + * @see CollationKey + * @see #getCollationKey + * @throws NullPointerException thrown if either argument is null. + * @stable ICU 2.8 + */ + public int compare(String source, String target) { + return collator.compare(source, target); + } + + /** + * Compares the source Object to the target Object. + *

      + * @param source the source Object. + * @param target the target Object. + * @return Returns an integer value. Value is less than zero if source is + * less than target, value is zero if source and target are equal, + * value is greater than zero if source is greater than target. + * @throws ClassCastException thrown if either arguments cannot be cast to String. + * @stable ICU 4.2 + */ + public int compare(Object source, Object target) { + return compare((String)source, (String)target); + } + + /** + *

      + * Transforms the String into a CollationKey suitable for efficient + * repeated comparison. The resulting key depends on the collator's + * rules, strength and decomposition mode. + *

      + *

      See the CollationKey class documentation for more information.

      + * @param source the string to be transformed into a CollationKey. + * @return the CollationKey for the given String based on this Collator's + * collation rules. If the source String is null, a null + * CollationKey is returned. + * @see CollationKey + * @see #compare(String, String) + * @see #getRawCollationKey + * @stable ICU 2.8 + */ + public CollationKey getCollationKey(String source) { + return new CollationKey(collator.getCollationKey(source)); + } + + /** + * {@icu} Returns the simpler form of a CollationKey for the String source following + * the rules of this Collator and stores the result into the user provided argument + * key. If key has a internal byte array of length that's too small for the result, + * the internal byte array will be grown to the exact required size. + * @param source the text String to be transformed into a RawCollationKey + * @return If key is null, a new instance of RawCollationKey will be + * created and returned, otherwise the user provided key will be + * returned. + * @see #compare(String, String) + * @see #getCollationKey + * @see RawCollationKey + * @stable ICU 2.8 + */ + public RawCollationKey getRawCollationKey(String source, RawCollationKey key) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Variable top is a two byte primary value which causes all the codepoints + * with primary values that are less or equal than the variable top to be + * shifted when alternate handling is set to SHIFTED. + *

      + *

      + * Sets the variable top to a collation element value of a string supplied. + *

      + * @param varTop one or more (if contraction) characters to which the + * variable top should be set + * @return a int value containing the value of the variable top in upper 16 + * bits. Lower 16 bits are undefined. + * @throws IllegalArgumentException is thrown if varTop argument is not + * a valid variable top element. A variable top element is + * invalid when it is a contraction that does not exist in the + * Collation order or when the PRIMARY strength collation + * element for the variable top has more than two bytes + * @see #getVariableTop + * @see RuleBasedCollator#setAlternateHandlingShifted + * @stable ICU 2.6 + */ + public int setVariableTop(String varTop) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the variable top value of a Collator. + * Lower 16 bits are undefined and should be ignored. + * @return the variable top value of a Collator. + * @see #setVariableTop + * @stable ICU 2.6 + */ + public int getVariableTop() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the variable top to a collation element value supplied. + * Variable top is set to the upper 16 bits. + * Lower 16 bits are ignored. + * @param varTop Collation element value, as returned by setVariableTop or + * getVariableTop + * @see #getVariableTop + * @see #setVariableTop + * @stable ICU 2.6 + */ + public void setVariableTop(int varTop) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the version of this collator object. + * @return the version object associated with this collator + * @stable ICU 2.8 + */ + public VersionInfo getVersion() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the UCA version of this collator object. + * @return the version object associated with this collator + * @stable ICU 2.8 + */ + public VersionInfo getUCAVersion() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 + * contains a partial preview implementation. The * actual + * locale is returned correctly, but the valid locale is + * not, in most cases. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + // com.ibm.icu.base specific overrides + public String toString() { + return collator.toString(); + } + + public boolean equals(Object rhs) { + try { + return collator.equals(((Collator)rhs).collator); + } + catch (Exception e) { + return false; + } + } + + public int hashCode() { + return collator.hashCode(); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CurrencyPluralInfo.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CurrencyPluralInfo.java index 39f1fd123f4..40289fd940d 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CurrencyPluralInfo.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CurrencyPluralInfo.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -/* - * Empty stub - */ -public class CurrencyPluralInfo { - private CurrencyPluralInfo() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +/* + * Empty stub + */ +public class CurrencyPluralInfo { + private CurrencyPluralInfo() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java index 686d1dd3508..730d3f7df4e 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java @@ -1,1949 +1,1949 @@ -/* - * Copyright (C) 1996-2011, International Business Machines - * Corporation and others. All Rights Reserved. - */ - -package com.ibm.icu.text; - -import java.io.InvalidObjectException; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -/** - * {@icuenhanced java.text.DateFormat}.{@icu _usage_} - * - *

      DateFormat is an abstract class for date/time formatting subclasses which - * formats and parses dates or time in a language-independent manner. - * The date/time formatting subclass, such as SimpleDateFormat, allows for - * formatting (i.e., date -> text), parsing (text -> date), and - * normalization. The date is represented as a Date object or - * as the milliseconds since January 1, 1970, 00:00:00 GMT. - * - *

      DateFormat provides many class methods for obtaining default date/time - * formatters based on the default or a given locale and a number of formatting - * styles. The formatting styles include FULL, LONG, MEDIUM, and SHORT. More - * detail and examples of using these styles are provided in the method - * descriptions. - * - *

      DateFormat helps you to format and parse dates for any locale. - * Your code can be completely independent of the locale conventions for - * months, days of the week, or even the calendar format: lunar vs. solar. - * - *

      To format a date for the current Locale, use one of the - * static factory methods: - *

      - *  myString = DateFormat.getDateInstance().format(myDate);
      - * 
      - *

      If you are formatting multiple numbers, it is - * more efficient to get the format and use it multiple times so that - * the system doesn't have to fetch the information about the local - * language and country conventions multiple times. - *

      - *  DateFormat df = DateFormat.getDateInstance();
      - *  for (int i = 0; i < a.length; ++i) {
      - *    output.println(df.format(myDate[i]) + "; ");
      - *  }
      - * 
      - *

      To format a number for a different Locale, specify it in the - * call to getDateInstance(). - *

      - *  DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
      - * 
      - *

      You can use a DateFormat to parse also. - *

      - *  myDate = df.parse(myString);
      - * 
      - *

      Use getDateInstance to get the normal date format for that country. - * There are other static factory methods available. - * Use getTimeInstance to get the time format for that country. - * Use getDateTimeInstance to get a date and time format. You can pass in - * different options to these factory methods to control the length of the - * result; from SHORT to MEDIUM to LONG to FULL. The exact result depends - * on the locale, but generally: - *

      • SHORT is completely numeric, such as 12.13.52 or 3:30pm - *
      • MEDIUM is longer, such as Jan 12, 1952 - *
      • LONG is longer, such as January 12, 1952 or 3:30:32pm - *
      • FULL is pretty completely specified, such as - * Tuesday, April 12, 1952 AD or 3:30:42pm PST. - *
      - * - *

      You can also set the time zone on the format if you wish. - * If you want even more control over the format or parsing, - * (or want to give your users more control), - * you can try casting the DateFormat you get from the factory methods - * to a SimpleDateFormat. This will work for the majority - * of countries; just remember to put it in a try block in case you - * encounter an unusual one. - * - *

      You can also use forms of the parse and format methods with - * ParsePosition and FieldPosition to - * allow you to - *

      • progressively parse through pieces of a string. - *
      • align any particular field, or find out where it is for selection - * on the screen. - *
      - * - *

      Synchronization

      - * - * Date formats are not synchronized. It is recommended to create separate - * format instances for each thread. If multiple threads access a format - * concurrently, it must be synchronized externally. - * - * @see UFormat - * @see NumberFormat - * @see SimpleDateFormat - * @see com.ibm.icu.util.Calendar - * @see com.ibm.icu.util.GregorianCalendar - * @see com.ibm.icu.util.TimeZone - * @author Mark Davis, Chen-Lieh Huang, Alan Liu - * @stable ICU 2.0 - */ -public class DateFormat extends Format { - - private static final long serialVersionUID = 1L; - - /** - * @internal - */ - public final java.text.DateFormat dateFormat; - - /** - * @internal - * @param delegate the DateFormat to which to delegate - */ - public DateFormat(java.text.DateFormat delegate) { - this.dateFormat = delegate; - } - - /** - * For subclass use. Subclasses will generally not - * work correctly unless they manipulate the delegate. - */ - protected DateFormat() { - this.dateFormat = java.text.DateFormat.getInstance(); - } - - /** - * FieldPosition selector for 'G' field alignment, - * corresponding to the {@link Calendar#ERA} field. - * @stable ICU 2.0 - */ - public final static int ERA_FIELD = 0; - - /** - * FieldPosition selector for 'y' field alignment, - * corresponding to the {@link Calendar#YEAR} field. - * @stable ICU 2.0 - */ - public final static int YEAR_FIELD = 1; - - /** - * FieldPosition selector for 'M' field alignment, - * corresponding to the {@link Calendar#MONTH} field. - * @stable ICU 2.0 - */ - public final static int MONTH_FIELD = 2; - - /** - * FieldPosition selector for 'd' field alignment, - * corresponding to the {@link Calendar#DATE} field. - * @stable ICU 2.0 - */ - public final static int DATE_FIELD = 3; - - /** - * FieldPosition selector for 'k' field alignment, - * corresponding to the {@link Calendar#HOUR_OF_DAY} field. - * HOUR_OF_DAY1_FIELD is used for the one-based 24-hour clock. - * For example, 23:59 + 01:00 results in 24:59. - * @stable ICU 2.0 - */ - public final static int HOUR_OF_DAY1_FIELD = 4; - - /** - * FieldPosition selector for 'H' field alignment, - * corresponding to the {@link Calendar#HOUR_OF_DAY} field. - * HOUR_OF_DAY0_FIELD is used for the zero-based 24-hour clock. - * For example, 23:59 + 01:00 results in 00:59. - * @stable ICU 2.0 - */ - public final static int HOUR_OF_DAY0_FIELD = 5; - - /** - * FieldPosition selector for 'm' field alignment, - * corresponding to the {@link Calendar#MINUTE} field. - * @stable ICU 2.0 - */ - public final static int MINUTE_FIELD = 6; - - /** - * FieldPosition selector for 's' field alignment, - * corresponding to the {@link Calendar#SECOND} field. - * @stable ICU 2.0 - */ - public final static int SECOND_FIELD = 7; - - /** - * {@icu} FieldPosition selector for 'S' field alignment, - * corresponding to the {@link Calendar#MILLISECOND} field. - * @stable ICU 3.0 - */ - public final static int FRACTIONAL_SECOND_FIELD = 8; - - /** - * Alias for FRACTIONAL_SECOND_FIELD. - * @deprecated ICU 3.0 use FRACTIONAL_SECOND_FIELD. - */ - public final static int MILLISECOND_FIELD = FRACTIONAL_SECOND_FIELD; - - /** - * FieldPosition selector for 'E' field alignment, - * corresponding to the {@link Calendar#DAY_OF_WEEK} field. - * @stable ICU 2.0 - */ - public final static int DAY_OF_WEEK_FIELD = 9; - - /** - * FieldPosition selector for 'D' field alignment, - * corresponding to the {@link Calendar#DAY_OF_YEAR} field. - * @stable ICU 2.0 - */ - public final static int DAY_OF_YEAR_FIELD = 10; - - /** - * FieldPosition selector for 'F' field alignment, - * corresponding to the {@link Calendar#DAY_OF_WEEK_IN_MONTH} field. - * @stable ICU 2.0 - */ - public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11; - - /** - * FieldPosition selector for 'w' field alignment, - * corresponding to the {@link Calendar#WEEK_OF_YEAR} field. - * @stable ICU 2.0 - */ - public final static int WEEK_OF_YEAR_FIELD = 12; - - /** - * FieldPosition selector for 'W' field alignment, - * corresponding to the {@link Calendar#WEEK_OF_MONTH} field. - * @stable ICU 2.0 - */ - public final static int WEEK_OF_MONTH_FIELD = 13; - - /** - * FieldPosition selector for 'a' field alignment, - * corresponding to the {@link Calendar#AM_PM} field. - * @stable ICU 2.0 - */ - public final static int AM_PM_FIELD = 14; - - /** - * FieldPosition selector for 'h' field alignment, - * corresponding to the {@link Calendar#HOUR} field. - * HOUR1_FIELD is used for the one-based 12-hour clock. - * For example, 11:30 PM + 1 hour results in 12:30 AM. - * @stable ICU 2.0 - */ - public final static int HOUR1_FIELD = 15; - - /** - * FieldPosition selector for 'K' field alignment, - * corresponding to the {@link Calendar#HOUR} field. - * HOUR0_FIELD is used for the zero-based 12-hour clock. - * For example, 11:30 PM + 1 hour results in 00:30 AM. - * @stable ICU 2.0 - */ - public final static int HOUR0_FIELD = 16; - - /** - * FieldPosition selector for 'z' field alignment, - * corresponding to the {@link Calendar#ZONE_OFFSET} and - * {@link Calendar#DST_OFFSET} fields. - * @stable ICU 2.0 - */ - public final static int TIMEZONE_FIELD = 17; - - /** - * {@icu} FieldPosition selector for 'Y' field alignment, - * corresponding to the {@link Calendar#YEAR_WOY} field. - * @stable ICU 3.0 - */ - public final static int YEAR_WOY_FIELD = 18; - - /** - * {@icu} FieldPosition selector for 'e' field alignment, - * corresponding to the {@link Calendar#DOW_LOCAL} field. - * @stable ICU 3.0 - */ - public final static int DOW_LOCAL_FIELD = 19; - - /** - * {@icu} FieldPosition selector for 'u' field alignment, - * corresponding to the {@link Calendar#EXTENDED_YEAR} field. - * @stable ICU 3.0 - */ - public final static int EXTENDED_YEAR_FIELD = 20; - - /** - * {@icu} FieldPosition selector for 'g' field alignment, - * corresponding to the {@link Calendar#JULIAN_DAY} field. - * @stable ICU 3.0 - */ - public final static int JULIAN_DAY_FIELD = 21; - - /** - * {@icu} FieldPosition selector for 'A' field alignment, - * corresponding to the {@link Calendar#MILLISECONDS_IN_DAY} field. - * @stable ICU 3.0 - */ - public final static int MILLISECONDS_IN_DAY_FIELD = 22; - - /** - * {@icu} FieldPosition selector for 'Z' field alignment, - * corresponding to the {@link Calendar#ZONE_OFFSET} and - * {@link Calendar#DST_OFFSET} fields. - * @stable ICU 3.0 - */ - public final static int TIMEZONE_RFC_FIELD = 23; - - /** - * {@icu} FieldPosition selector for 'v' field alignment, - * corresponding to the {@link Calendar#ZONE_OFFSET} and - * {@link Calendar#DST_OFFSET} fields. This displays the generic zone - * name, if available. - * @stable ICU 3.4 - */ - public final static int TIMEZONE_GENERIC_FIELD = 24; - - /** - * {@icu} FieldPosition selector for 'c' field alignment, - * corresponding to the {@link Calendar#DAY_OF_WEEK} field. - * This displays the stand alone day name, if available. - * @stable ICU 3.4 - */ - public final static int STANDALONE_DAY_FIELD = 25; - - /** - * {@icu} FieldPosition selector for 'L' field alignment, - * corresponding to the {@link Calendar#MONTH} field. - * This displays the stand alone month name, if available. - * @stable ICU 3.4 - */ - public final static int STANDALONE_MONTH_FIELD = 26; - - /** - * {@icu} FieldPosition selector for 'Q' field alignment, - * corresponding to the {@link Calendar#MONTH} field. - * This displays the quarter. - * @stable ICU 3.6 - */ - public final static int QUARTER_FIELD = 27; - - /** - * {@icu} FieldPosition selector for 'q' field alignment, - * corresponding to the {@link Calendar#MONTH} field. - * This displays the stand alone quarter, if available. - * @stable ICU 3.6 - */ - public final static int STANDALONE_QUARTER_FIELD = 28; - - /** - * {@icu} FieldPosition selector for 'V' field alignment, - * corresponding to the {@link Calendar#ZONE_OFFSET} and - * {@link Calendar#DST_OFFSET} fields. This displays the fallback timezone - * name when VVVV is specified, and the short standard or daylight - * timezone name ignoring commonlyUsed when a single V is specified. - * @stable ICU 3.8 - */ - public final static int TIMEZONE_SPECIAL_FIELD = 29; - - /** - * {@icu} Number of FieldPosition selectors for DateFormat. - * Valid selectors range from 0 to FIELD_COUNT-1. - * @stable ICU 3.0 - */ - public final static int FIELD_COUNT = 30; // must == DateFormatSymbols.patternChars.length() - - /** - * Formats a time object into a time string. Examples of time objects - * are a time value expressed in milliseconds and a Date object. - * @param obj must be a Number or a Date or a Calendar. - * @param toAppendTo the string buffer for the returning time string. - * @return the formatted time string. - * @param fieldPosition keeps track of the position of the field - * within the returned string. - * On input: an alignment field, - * if desired. On output: the offsets of the alignment field. For - * example, given a time text "1996.07.10 AD at 15:08:56 PDT", - * if the given fieldPosition is DateFormat.YEAR_FIELD, the - * begin index and end index of fieldPosition will be set to - * 0 and 4, respectively. - * Notice that if the same time field appears - * more than once in a pattern, the fieldPosition will be set for the first - * occurrence of that time field. For instance, formatting a Date to - * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern - * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, - * the begin index and end index of fieldPosition will be set to - * 5 and 8, respectively, for the first occurrence of the timezone - * pattern character 'z'. - * @see java.text.Format - * @stable ICU 2.0 - */ - public final StringBuffer format(Object obj, StringBuffer toAppendTo, - FieldPosition fieldPosition) - { - if (obj instanceof Calendar) { - return format((Calendar)obj, toAppendTo, fieldPosition); - } else if (obj instanceof Date) { - return format((Date)obj, toAppendTo, fieldPosition); - } else if (obj instanceof Number) { - return format(new Date(((Number)obj).longValue()), toAppendTo, fieldPosition ); - } - - throw new IllegalArgumentException("Cannot format given Object (" + - obj.getClass().getName() + ") as a Date"); - } - - /** - * Formats a date into a date/time string. - * @param cal a Calendar set to the date and time to be formatted - * into a date/time string. When the calendar type is different from - * the internal calendar held by this DateFormat instance, the date - * and the time zone will be inherited from the input calendar, but - * other calendar field values will be calculated by the internal calendar. - * @param toAppendTo the string buffer for the returning date/time string. - * @param fieldPosition keeps track of the position of the field - * within the returned string. - * On input: an alignment field, - * if desired. On output: the offsets of the alignment field. For - * example, given a time text "1996.07.10 AD at 15:08:56 PDT", - * if the given fieldPosition is DateFormat.YEAR_FIELD, the - * begin index and end index of fieldPosition will be set to - * 0 and 4, respectively. - * Notice that if the same time field appears - * more than once in a pattern, the fieldPosition will be set for the first - * occurrence of that time field. For instance, formatting a Date to - * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern - * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, - * the begin index and end index of fieldPosition will be set to - * 5 and 8, respectively, for the first occurrence of the timezone - * pattern character 'z'. - * @return the formatted date/time string. - * @stable ICU 2.0 - */ - public StringBuffer format(Calendar cal, StringBuffer toAppendTo, - FieldPosition fieldPosition) { - return format(cal.getTime(), toAppendTo, fieldPosition); - } - - /** - * Formats a Date into a date/time string. - * @param date a Date to be formatted into a date/time string. - * @param toAppendTo the string buffer for the returning date/time string. - * @param fieldPosition keeps track of the position of the field - * within the returned string. - * On input: an alignment field, - * if desired. On output: the offsets of the alignment field. For - * example, given a time text "1996.07.10 AD at 15:08:56 PDT", - * if the given fieldPosition is DateFormat.YEAR_FIELD, the - * begin index and end index of fieldPosition will be set to - * 0 and 4, respectively. - * Notice that if the same time field appears - * more than once in a pattern, the fieldPosition will be set for the first - * occurrence of that time field. For instance, formatting a Date to - * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern - * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, - * the begin index and end index of fieldPosition will be set to - * 5 and 8, respectively, for the first occurrence of the timezone - * pattern character 'z'. - * @return the formatted date/time string. - * @stable ICU 2.0 - */ - public StringBuffer format(Date date, StringBuffer toAppendTo, - FieldPosition fieldPosition) { - FieldPosition jdkPos = toJDKFieldPosition(fieldPosition); - StringBuffer buf = dateFormat.format(date, toAppendTo, jdkPos); - if (jdkPos != null) { - fieldPosition.setBeginIndex(jdkPos.getBeginIndex()); - fieldPosition.setEndIndex(jdkPos.getEndIndex()); - } - return buf; - } - - /** - * Formats a Date into a date/time string. - * @param date the time value to be formatted into a time string. - * @return the formatted time string. - * @stable ICU 2.0 - */ - public final String format(Date date) - { - return dateFormat.format(date); - } - - /** - * Parses a date/time string. - * - * @param text The date/time string to be parsed - * - * @return A Date, or null if the input could not be parsed - * - * @exception ParseException If the given string cannot be parsed as a date. - * - * @see #parse(String, ParsePosition) - * @stable ICU 2.0 - */ - public Date parse(String text) throws ParseException - { - return dateFormat.parse(text); - } - - /** - * Parses a date/time string according to the given parse position. - * For example, a time text "07/10/96 4:5 PM, PDT" will be parsed - * into a Calendar that is equivalent to Date(837039928046). The - * caller should clear the calendar before calling this method, - * unless existing field information is to be kept. - * - *

      By default, parsing is lenient: If the input is not in the form used - * by this object's format method but can still be parsed as a date, then - * the parse succeeds. Clients may insist on strict adherence to the - * format by calling setLenient(false). - * - * @see #setLenient(boolean) - * - * @param text The date/time string to be parsed - * - * @param cal The calendar into which parsed data will be stored. - * In general, this should be cleared before calling this - * method. If this parse fails, the calendar may still - * have been modified. When the calendar type is different - * from the internal calendar held by this DateFormat - * instance, calendar field values will be parsed based - * on the internal calendar initialized with the time and - * the time zone taken from this calendar, then the - * parse result (time in milliseconds and time zone) will - * be set back to this calendar. - * - * @param pos On input, the position at which to start parsing; on - * output, the position at which parsing terminated, or the - * start position if the parse failed. - * @stable ICU 2.0 - */ - public void parse(String text, Calendar cal, ParsePosition pos) { - Date result = dateFormat.parse(text, pos); - cal.setTime(result); - } - - /** - * Parses a date/time string according to the given parse position. For - * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date - * that is equivalent to Date(837039928046). - * - *

      By default, parsing is lenient: If the input is not in the form used - * by this object's format method but can still be parsed as a date, then - * the parse succeeds. Clients may insist on strict adherence to the - * format by calling setLenient(false). - * - * @see #setLenient(boolean) - * - * @param text The date/time string to be parsed - * - * @param pos On input, the position at which to start parsing; on - * output, the position at which parsing terminated, or the - * start position if the parse failed. - * - * @return A Date, or null if the input could not be parsed - * @stable ICU 2.0 - */ - public Date parse(String text, ParsePosition pos) { - return dateFormat.parse(text, pos); - } - - /** - * Parses a date/time string into an Object. This convenience method simply - * calls parse(String, ParsePosition). - * - * @see #parse(String, ParsePosition) - * @stable ICU 2.0 - */ - public Object parseObject (String source, ParsePosition pos) - { - return parse(source, pos); - } - - /** - * {@icu} Constant for empty style pattern. - * @stable ICU 3.8 - */ - public static final int NONE = -1; - - /** - * Constant for full style pattern. - * @stable ICU 2.0 - */ - public static final int FULL = 0; - - /** - * Constant for long style pattern. - * @stable ICU 2.0 - */ - public static final int LONG = 1; - - /** - * Constant for medium style pattern. - * @stable ICU 2.0 - */ - public static final int MEDIUM = 2; - - /** - * Constant for short style pattern. - * @stable ICU 2.0 - */ - public static final int SHORT = 3; - - /** - * Constant for default style pattern. Its value is MEDIUM. - * @stable ICU 2.0 - */ - public static final int DEFAULT = MEDIUM; - - /** - * {@icu} Constant for relative style mask. - * @stable ICU 3.8 - */ - public static final int RELATIVE = (1 << 7); - - /** - * {@icu} Constant for relative full style pattern. - * @stable ICU 3.8 - */ - public static final int RELATIVE_FULL = RELATIVE | FULL; - - /** - * {@icu} Constant for relative style pattern. - * @stable ICU 3.8 - */ - public static final int RELATIVE_LONG = RELATIVE | LONG; - - /** - * {@icu} Constant for relative style pattern. - * @stable ICU 3.8 - */ - public static final int RELATIVE_MEDIUM = RELATIVE | MEDIUM; - - /** - * {@icu} Constant for relative style pattern. - * @stable ICU 3.8 - */ - public static final int RELATIVE_SHORT = RELATIVE | SHORT; - - /** - * {@icu} Constant for relative default style pattern. - * @stable ICU 3.8 - */ - public static final int RELATIVE_DEFAULT = RELATIVE | DEFAULT; - - /* Below are pre-defined skeletons - * - *

      - * A skeleton - *

        - *
      • - * 1. only keeps the field pattern letter and ignores all other parts - * in a pattern, such as space, punctuations, and string literals. - *
      • - * 2. hides the order of fields. - *
      • - * 3. might hide a field's pattern letter length. - * - * For those non-digit calendar fields, the pattern letter length is - * important, such as MMM, MMMM, and MMMMM; E and EEEE, - * and the field's pattern letter length is honored. - * - * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, - * the field pattern length is ignored and the best match, which is - * defined in date time patterns, will be returned without honor - * the field pattern letter length in skeleton. - *
      - */ - /** - * {@icu} Constant for date pattern with minute and second. - * @stable ICU 4.0 - */ - public static final String MINUTE_SECOND = "ms"; - - /** - * {@icu} Constant for date pattern with hour and minute in 24-hour presentation. - * @stable ICU 4.0 - */ - public static final String HOUR24_MINUTE = "Hm"; - - /** - * {@icu} Constant for date pattern with hour, minute, and second in - * 24-hour presentation. - * @stable ICU 4.0 - */ - public static final String HOUR24_MINUTE_SECOND = "Hms"; - - /** - * {@icu} Constant for date pattern with hour, minute, and second. - * @stable ICU 4.0 - */ - public static final String HOUR_MINUTE_SECOND = "hms"; - - /** - * {@icu} Constant for date pattern with standalone month. - * @stable ICU 4.0 - */ - public static final String STANDALONE_MONTH = "LLLL"; - - /** - * {@icu} Constant for date pattern with standalone abbreviated month. - * @stable ICU 4.0 - */ - public static final String ABBR_STANDALONE_MONTH = "LLL"; - - /** - * {@icu} Constant for date pattern with year and quarter. - * @stable ICU 4.0 - */ - public static final String YEAR_QUARTER = "yQQQ"; - - /** - * {@icu} Constant for date pattern with year and abbreviated quarter. - * @stable ICU 4.0 - */ - public static final String YEAR_ABBR_QUARTER = "yQ"; - - - /* Below are skeletons that date interval pre-defined in resource file. - * Users are encouraged to use them in date interval format factory methods. - */ - /** - * {@icu} Constant for date pattern with hour and minute. - * @stable ICU 4.0 - */ - public static final String HOUR_MINUTE = "hm"; - - /** - * {@icu} Constant for date pattern with year. - * @stable ICU 4.0 - */ - public static final String YEAR = "y"; - - /** - * {@icu} Constant for date pattern with day. - * @stable ICU 4.0 - */ - public static final String DAY = "d"; - - /** - * {@icu} Constant for date pattern with numeric month, weekday, and day. - * @stable ICU 4.0 - */ - public static final String NUM_MONTH_WEEKDAY_DAY = "MEd"; - - /** - * {@icu} Constant for date pattern with year and numeric month. - * @stable ICU 4.0 - */ - public static final String YEAR_NUM_MONTH = "yM"; - - /** - * {@icu} Constant for date pattern with numeric month and day. - * @stable ICU 4.0 - */ - public static final String NUM_MONTH_DAY = "Md"; - - /** - * {@icu} Constant for date pattern with year, numeric month, weekday, and day. - * @stable ICU 4.0 - */ - public static final String YEAR_NUM_MONTH_WEEKDAY_DAY = "yMEd"; - - /** - * {@icu} Constant for date pattern with abbreviated month, weekday, and day. - * @stable ICU 4.0 - */ - public static final String ABBR_MONTH_WEEKDAY_DAY = "MMMEd"; - - /** - * {@icu} Constant for date pattern with year and month. - * @stable ICU 4.0 - */ - public static final String YEAR_MONTH = "yMMMM"; - - /** - * {@icu} Constant for date pattern with year and abbreviated month. - * @stable ICU 4.0 - */ - public static final String YEAR_ABBR_MONTH = "yMMM"; - - /** - * {@icu} Constant for date pattern having month and day. - * @stable ICU 4.0 - */ - public static final String MONTH_DAY = "MMMMd"; - - /** - * {@icu} Constant for date pattern with abbreviated month and day. - * @stable ICU 4.0 - */ - public static final String ABBR_MONTH_DAY = "MMMd"; - - /** - * {@icu} Constant for date pattern with month, weekday, and day. - * @stable ICU 4.0 - */ - public static final String MONTH_WEEKDAY_DAY = "MMMMEEEEd"; - - /** - * {@icu} Constant for date pattern with year, abbreviated month, weekday, - * and day. - * @stable ICU 4.0 - */ - public static final String YEAR_ABBR_MONTH_WEEKDAY_DAY = "yMMMEd"; - - /** - * {@icu} Constant for date pattern with year, month, weekday, and day. - * @stable ICU 4.0 - */ - public static final String YEAR_MONTH_WEEKDAY_DAY = "yMMMMEEEEd"; - - /** - * {@icu} Constant for date pattern with year, month, and day. - * @stable ICU 4.0 - */ - public static final String YEAR_MONTH_DAY = "yMMMMd"; - - /** - * {@icu} Constant for date pattern with year, abbreviated month, and day. - * @stable ICU 4.0 - */ - public static final String YEAR_ABBR_MONTH_DAY = "yMMMd"; - - /** - * {@icu} Constant for date pattern with year, numeric month, and day. - * @stable ICU 4.0 - */ - public static final String YEAR_NUM_MONTH_DAY = "yMd"; - - /** - * {@icu} Constant for date pattern with numeric month. - * @stable ICU 4.0 - */ - public static final String NUM_MONTH = "M"; - - /** - * {@icu} Constant for date pattern with abbreviated month. - * @stable ICU 4.0 - */ - public static final String ABBR_MONTH = "MMM"; - - /** - * {@icu} Constant for date pattern with month. - * @stable ICU 4.0 - */ - public static final String MONTH = "MMMM"; - - /** - * {@icu} Constant for date pattern with hour, minute, and generic timezone. - * @stable ICU 4.0 - */ - public static final String HOUR_MINUTE_GENERIC_TZ = "hmv"; - - /** - * {@icu} Constant for date pattern with hour, minute, and timezone. - * @stable ICU 4.0 - */ - public static final String HOUR_MINUTE_TZ = "hmz"; - - /** - * {@icu} Constant for date pattern with hour. - * @stable ICU 4.0 - */ - public static final String HOUR = "h"; - - /** - * {@icu} Constant for date pattern with hour and generic timezone. - * @stable ICU 4.0 - */ - public static final String HOUR_GENERIC_TZ = "hv"; - - /** - * {@icu} Constant for date pattern with hour and timezone. - * @stable ICU 4.0 - */ - public static final String HOUR_TZ = "hz"; - - /** - * Gets the time formatter with the default formatting style - * for the default locale. - * @return a time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getTimeInstance() - { - return new DateFormat(java.text.DateFormat.getTimeInstance()); - } - - /** - * Returns the time formatter with the given formatting style - * for the default locale. - * @param style the given formatting style. For example, - * SHORT for "h:mm a" in the US locale. - * @return a time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getTimeInstance(int style) - { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style))); - } - - /** - * Returns the time formatter with the given formatting style - * for the given locale. - * @param style the given formatting style. For example, - * SHORT for "h:mm a" in the US locale. - * @param aLocale the given locale. - * @return a time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getTimeInstance(int style, - Locale aLocale) - { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), aLocale)); - } - - /** - * Returns the time formatter with the given formatting style - * for the given locale. - * @param style the given formatting style. For example, - * SHORT for "h:mm a" in the US locale. - * @param locale the given ulocale. - * @return a time formatter. - * @stable ICU 3.2 - */ - public final static DateFormat getTimeInstance(int style, - ULocale locale) - { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), locale.toLocale())); - } - - /** - * Returns the date formatter with the default formatting style - * for the default locale. - * @return a date formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateInstance() - { - return new DateFormat(java.text.DateFormat.getDateInstance()); - } - - /** - * Returns the date formatter with the given formatting style - * for the default locale. - * @param style the given formatting style. For example, - * SHORT for "M/d/yy" in the US locale. - * @return a date formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateInstance(int style) - { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style))); - } - - /** - * Returns the date formatter with the given formatting style - * for the given locale. - * @param style the given formatting style. For example, - * SHORT for "M/d/yy" in the US locale. - * @param aLocale the given locale. - * @return a date formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateInstance(int style, - Locale aLocale) - { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), aLocale)); - } - - /** - * Returns the date formatter with the given formatting style - * for the given locale. - * @param style the given formatting style. For example, - * SHORT for "M/d/yy" in the US locale. - * @param locale the given ulocale. - * @return a date formatter. - * @stable ICU 3.2 - */ - public final static DateFormat getDateInstance(int style, - ULocale locale) - { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), locale.toLocale())); - } - - /** - * Returns the date/time formatter with the default formatting style - * for the default locale. - * @return a date/time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateTimeInstance() - { - return new DateFormat(java.text.DateFormat.getDateTimeInstance()); - } - - /** - * Returns the date/time formatter with the given date and time - * formatting styles for the default locale. - * @param dateStyle the given date formatting style. For example, - * SHORT for "M/d/yy" in the US locale. - * @param timeStyle the given time formatting style. For example, - * SHORT for "h:mm a" in the US locale. - * @return a date/time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateTimeInstance(int dateStyle, - int timeStyle) - { - if (dateStyle != NONE) { - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle))); - } else { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle))); - } - } - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle))); - } - return null; - } - - /** - * Returns the date/time formatter with the given formatting styles - * for the given locale. - * @param dateStyle the given date formatting style. - * @param timeStyle the given time formatting style. - * @param aLocale the given locale. - * @return a date/time formatter. - * @stable ICU 2.0 - */ - public final static DateFormat getDateTimeInstance( - int dateStyle, int timeStyle, Locale aLocale) - { - if (dateStyle != NONE) { - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), aLocale)); - } else { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), aLocale)); - } - } - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), aLocale)); - } - return null; - } - - /** - * Returns the date/time formatter with the given formatting styles - * for the given locale. - * @param dateStyle the given date formatting style. - * @param timeStyle the given time formatting style. - * @param locale the given ulocale. - * @return a date/time formatter. - * @stable ICU 3.2 - */ - public final static DateFormat getDateTimeInstance( - int dateStyle, int timeStyle, ULocale locale) - { - if (dateStyle != NONE) { - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), locale.toLocale())); - } else { - return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), locale.toLocale())); - } - } - if (timeStyle != NONE) { - return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), locale.toLocale())); - } - return null; - } - - /** - * Returns a default date/time formatter that uses the SHORT style for both the - * date and the time. - * @stable ICU 2.0 - */ - public final static DateFormat getInstance() { - return new DateFormat(java.text.DateFormat.getInstance()); - } - - /** - * Returns the set of locales for which DateFormats are installed. - * @return the set of locales for which DateFormats are installed. - * @stable ICU 2.0 - */ - public static Locale[] getAvailableLocales() - { - return java.text.DateFormat.getAvailableLocales(); - } - - /** - * {@icu} Returns the set of locales for which DateFormats are installed. - * @return the set of locales for which DateFormats are installed. - * @draft ICU 3.2 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static ULocale[] getAvailableULocales() - { - if (availableULocales == null) { - synchronized(DateFormat.class) { - if (availableULocales == null) { - Locale[] locales = java.text.DateFormat.getAvailableLocales(); - availableULocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; ++i) { - availableULocales[i] = ULocale.forLocale(locales[i]); - } - } - } - } - return availableULocales; - } - private static volatile ULocale[] availableULocales; - - /** - * Sets the calendar to be used by this date format. Initially, the default - * calendar for the specified or default locale is used. - * @param newCalendar the new Calendar to be used by the date format - * @stable ICU 2.0 - */ - public void setCalendar(Calendar newCalendar) - { - dateFormat.setCalendar(newCalendar.calendar); - } - - /** - * Returns the calendar associated with this date/time formatter. - * @return the calendar associated with this date/time formatter. - * @stable ICU 2.0 - */ - public Calendar getCalendar() - { - return new Calendar(dateFormat.getCalendar()); - } - - /** - * Sets the number formatter. - * @param newNumberFormat the given new NumberFormat. - * @stable ICU 2.0 - */ - public void setNumberFormat(NumberFormat newNumberFormat) - { - dateFormat.setNumberFormat(newNumberFormat.numberFormat); - } - - /** - * Returns the number formatter which this date/time formatter uses to - * format and parse a time. - * @return the number formatter which this date/time formatter uses. - * @stable ICU 2.0 - */ - public NumberFormat getNumberFormat() - { - return new NumberFormat(dateFormat.getNumberFormat()); - } - - /** - * Sets the time zone for the calendar of this DateFormat object. - * @param zone the given new time zone. - * @stable ICU 2.0 - */ - public void setTimeZone(TimeZone zone) - { - dateFormat.setTimeZone(zone.timeZone); - } - - /** - * Returns the time zone. - * @return the time zone associated with the calendar of DateFormat. - * @stable ICU 2.0 - */ - public TimeZone getTimeZone() - { - return new TimeZone(dateFormat.getTimeZone()); - } - - /** - * Specifies whether date/time parsing is to be lenient. With - * lenient parsing, the parser may use heuristics to interpret inputs that - * do not precisely match this object's format. With strict parsing, - * inputs must match this object's format. - * @param lenient when true, parsing is lenient - * @see com.ibm.icu.util.Calendar#setLenient - * @stable ICU 2.0 - */ - public void setLenient(boolean lenient) - { - dateFormat.setLenient(lenient); - } - - /** - * Returns whether date/time parsing is lenient. - * @stable ICU 2.0 - */ - public boolean isLenient() - { - return dateFormat.isLenient(); - } - - /** - * Overrides hashCode. - * @stable ICU 2.0 - */ - public int hashCode() { - return dateFormat.hashCode(); - } - - /** - * Overrides equals. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) { - try { - return dateFormat.equals(((DateFormat)obj).dateFormat); - } - catch (Exception e) { - return false; - } - } - - /** - * Overrides clone. - * @stable ICU 2.0 - */ - public Object clone() - { - return new DateFormat((java.text.DateFormat)dateFormat.clone()); - } - - //------------------------------------------------------------------------- - // Public static interface for creating custon DateFormats for different - // types of Calendars. - //------------------------------------------------------------------------- - - /** - * Creates a {@link DateFormat} object that can be used to format dates in - * the calendar system specified by cal. - *

      - * @param cal The calendar system for which a date format is desired. - * - * @param dateStyle The type of date format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the date format is desired. - * @stable ICU 2.0 - */ - static final public DateFormat getDateInstance(Calendar cal, int dateStyle, Locale locale) - { - DateFormat df = getDateInstance(dateStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Creates a {@link DateFormat} object that can be used to format dates in - * the calendar system specified by cal. - *

      - * @param cal The calendar system for which a date format is desired. - * - * @param dateStyle The type of date format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the date format is desired. - * @stable ICU 3.2 - */ - static final public DateFormat getDateInstance(Calendar cal, int dateStyle, ULocale locale) - { - DateFormat df = getDateInstance(dateStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Creates a {@link DateFormat} object that can be used to format times in - * the calendar system specified by cal. - *

      - * Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - *

      - * @param cal The calendar system for which a time format is desired. - * - * @param timeStyle The type of time format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the time format is desired. - * - * @see DateFormat#getTimeInstance - * @stable ICU 2.0 - */ - static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, Locale locale) - { - DateFormat df = getTimeInstance(timeStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Creates a {@link DateFormat} object that can be used to format times in - * the calendar system specified by cal. - *

      - * Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - *

      - * @param cal The calendar system for which a time format is desired. - * - * @param timeStyle The type of time format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the time format is desired. - * - * @see DateFormat#getTimeInstance - * @stable ICU 3.2 - */ - static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, ULocale locale) - { - DateFormat df = getTimeInstance(timeStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Creates a {@link DateFormat} object that can be used to format dates and times in - * the calendar system specified by cal. - *

      - * Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - *

      - * @param cal The calendar system for which a date/time format is desired. - * - * @param dateStyle The type of date format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param timeStyle The type of time format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the date/time format is desired. - * - * @see DateFormat#getDateTimeInstance - * @stable ICU 2.0 - */ - static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, - int timeStyle, Locale locale) - { - DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Creates a {@link DateFormat} object that can be used to format dates and times in - * the calendar system specified by cal. - *

      - * Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - *

      - * @param cal The calendar system for which a date/time format is desired. - * - * @param dateStyle The type of date format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param timeStyle The type of time format desired. This can be - * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, - * etc. - * - * @param locale The locale for which the date/time format is desired. - * - * @see DateFormat#getDateTimeInstance - * @stable ICU 3.2 - */ - static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, - int timeStyle, ULocale locale) - { - DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale); - df.setCalendar(cal); - return df; - } - - /** - * Convenience overload. - * @stable ICU 2.0 - */ - static final public DateFormat getInstance(Calendar cal, Locale locale) { - return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale); - } - - /** - * Convenience overload. - * @stable ICU 3.2 - * @provisional This API might change or be removed in a future release. - */ - static final public DateFormat getInstance(Calendar cal, ULocale locale) { - return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale); - } - - /** - * Convenience overload. - * @stable ICU 2.0 - */ - static final public DateFormat getInstance(Calendar cal) { - return getInstance(cal, ULocale.getDefault()); - } - - /** - * Convenience overload. - * @stable ICU 2.0 - */ - static final public DateFormat getDateInstance(Calendar cal, int dateStyle) { - return getDateInstance(cal, dateStyle, ULocale.getDefault()); - } - - /** - * Convenience overload. - * @stable ICU 2.0 - */ - static final public DateFormat getTimeInstance(Calendar cal, int timeStyle) { - return getTimeInstance(cal, timeStyle, ULocale.getDefault()); - } - - /** - * Convenience overload. - * @stable ICU 2.0 - */ - static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, int timeStyle) { - return getDateTimeInstance(cal, dateStyle, timeStyle, ULocale.getDefault()); - } - - /** - * {@icu} Convenience overload. - * @stable ICU 4.0 - */ - public final static DateFormat getPatternInstance(String pattern) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Convenience overload. - * @stable ICU 4.0 - */ - public final static DateFormat getPatternInstance(String pattern, Locale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in - * the given locale. - *

      - * Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - *

      - * - * @param pattern The pattern that selects the fields to be formatted. (Uses the - * {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH}, - * {@link DateFormat#MONTH_WEEKDAY_DAY}, etc. - * - * @param locale The locale for which the date/time format is desired. - * - * @stable ICU 4.0 - */ - public final static DateFormat getPatternInstance(String pattern, ULocale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Convenience overload. - * @stable ICU 4.0 - */ - public final static DateFormat getPatternInstance(Calendar cal, String pattern, Locale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Creates a {@link DateFormat} object that can be used to format dates and - * times in the calendar system specified by cal. - * - *

      Note: When this functionality is moved into the core JDK, this method - * will probably be replaced by a new overload of {@link DateFormat#getInstance}. - * - * @param cal The calendar system for which a date/time format is desired. - * - * @param pattern The pattern that selects the fields to be formatted. (Uses the - * {@link DateTimePatternGenerator}.) This can be - * {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY}, - * etc. - * - * @param locale The locale for which the date/time format is desired. - * - * @stable ICU 4.0 - */ - public final static DateFormat getPatternInstance( - Calendar cal, String pattern, ULocale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * The instances of this inner class are used as attribute keys and values - * in AttributedCharacterIterator that - * DateFormat.formatToCharacterIterator() method returns. - * - *

      There is no public constructor to this class, the only instances are the - * constants defined here. - *

      - * @stable ICU 3.8 - */ - public static class Field extends Format.Field { - - private static final long serialVersionUID = -3627456821000730829L; - - // Max number of calendar fields - private static final int CAL_FIELD_COUNT; - - // Table for mapping calendar field number to DateFormat.Field - private static final Field[] CAL_FIELDS; - - // Map for resolving DateFormat.Field by name - private static final Map FIELD_NAME_MAP; - - static { - Calendar cal = Calendar.getInstance(); - CAL_FIELD_COUNT = cal.getFieldCount(); - CAL_FIELDS = new Field[CAL_FIELD_COUNT]; - FIELD_NAME_MAP = new HashMap(CAL_FIELD_COUNT); - } - - // Java fields ------------------- - - /** - * Constant identifying the time of day indicator(am/pm). - * @stable ICU 3.8 - */ - public static final Field AM_PM = new Field("am pm", Calendar.AM_PM); - - /** - * Constant identifying the day of month field. - * @stable ICU 3.8 - */ - public static final Field DAY_OF_MONTH = new Field("day of month", Calendar.DAY_OF_MONTH); - - /** - * Constant identifying the day of week field. - * @stable ICU 3.8 - */ - public static final Field DAY_OF_WEEK = new Field("day of week", Calendar.DAY_OF_WEEK); - - /** - * Constant identifying the day of week in month field. - * @stable ICU 3.8 - */ - public static final Field DAY_OF_WEEK_IN_MONTH = - new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH); - - /** - * Constant identifying the day of year field. - * @stable ICU 3.8 - */ - public static final Field DAY_OF_YEAR = new Field("day of year", Calendar.DAY_OF_YEAR); - - /** - * Constant identifying the era field. - * @stable ICU 3.8 - */ - public static final Field ERA = new Field("era", Calendar.ERA); - - /** - * Constant identifying the hour(0-23) of day field. - * @stable ICU 3.8 - */ - public static final Field HOUR_OF_DAY0 = new Field("hour of day", Calendar.HOUR_OF_DAY); - - /** - * Constant identifying the hour(1-24) of day field. - * @stable ICU 3.8 - */ - public static final Field HOUR_OF_DAY1 = new Field("hour of day 1", -1); - - /** - * Constant identifying the hour(0-11) field. - * @stable ICU 3.8 - */ - public static final Field HOUR0 = new Field("hour", Calendar.HOUR); - - /** - * Constant identifying the hour(1-12) field. - * @stable ICU 3.8 - */ - public static final Field HOUR1 = new Field("hour 1", -1); - - /** - * Constant identifying the millisecond field. - * @stable ICU 3.8 - */ - public static final Field MILLISECOND = new Field("millisecond", Calendar.MILLISECOND); - - /** - * Constant identifying the minute field. - * @stable ICU 3.8 - */ - public static final Field MINUTE = new Field("minute", Calendar.MINUTE); - - /** - * Constant identifying the month field. - * @stable ICU 3.8 - */ - public static final Field MONTH = new Field("month", Calendar.MONTH); - - /** - * Constant identifying the second field. - * @stable ICU 3.8 - */ - public static final Field SECOND = new Field("second", Calendar.SECOND); - - /** - * Constant identifying the time zone field. - * @stable ICU 3.8 - */ - public static final Field TIME_ZONE = new Field("time zone", -1); - - /** - * Constant identifying the week of month field. - * @stable ICU 3.8 - */ - public static final Field WEEK_OF_MONTH = - new Field("week of month", Calendar.WEEK_OF_MONTH); - - /** - * Constant identifying the week of year field. - * @stable ICU 3.8 - */ - public static final Field WEEK_OF_YEAR = new Field("week of year", Calendar.WEEK_OF_YEAR); - - /** - * Constant identifying the year field. - * @stable ICU 3.8 - */ - public static final Field YEAR = new Field("year", Calendar.YEAR); - - - // ICU only fields ------------------- - - /** - * Constant identifying the local day of week field. - * @stable ICU 3.8 - */ - public static final Field DOW_LOCAL = new Field("local day of week", Calendar.DOW_LOCAL); - - /** - * Constant identifying the extended year field. - * @stable ICU 3.8 - */ - public static final Field EXTENDED_YEAR = new Field("extended year", - Calendar.EXTENDED_YEAR); - - /** - * Constant identifying the Julian day field. - * @stable ICU 3.8 - */ - public static final Field JULIAN_DAY = new Field("Julian day", Calendar.JULIAN_DAY); - - /** - * Constant identifying the milliseconds in day field. - * @stable ICU 3.8 - */ - public static final Field MILLISECONDS_IN_DAY = - new Field("milliseconds in day", Calendar.MILLISECONDS_IN_DAY); - - /** - * Constant identifying the year used with week of year field. - * @stable ICU 3.8 - */ - public static final Field YEAR_WOY = new Field("year for week of year", Calendar.YEAR_WOY); - - /** - * Constant identifying the quarter field. - * @stable ICU 3.8 - */ - public static final Field QUARTER = new Field("quarter", -1); - - // Stand alone types are variants for its base types. So we do not define Field for - // them. - /* - public static final Field STANDALONE_DAY = - new Field("stand alone day of week", Calendar.DAY_OF_WEEK); - public static final Field STANDALONE_MONTH = new Field("stand alone month", Calendar.MONTH); - public static final Field STANDALONE_QUARTER = new Field("stand alone quarter", -1); - */ - - // Corresponding calendar field - private final int calendarField; - - /** - * Constructs a DateFormat.Field with the given name and - * the Calendar field which this attribute represents. Use -1 for - * calendarField if this field does not have a corresponding - * Calendar field. - * - * @param name Name of the attribute - * @param calendarField Calendar field constant - * - * @stable ICU 3.8 - */ - protected Field(String name, int calendarField) { - super(name); - this.calendarField = calendarField; - if (this.getClass() == DateFormat.Field.class) { - FIELD_NAME_MAP.put(name, this); - if (calendarField >= 0 && calendarField < CAL_FIELD_COUNT) { - CAL_FIELDS[calendarField] = this; - } - } - } - - /** - * Returns the Field constant that corresponds to the - * Calendar field calendarField. If there is no - * corresponding Field is available, null is returned. - * - * @param calendarField Calendar field constant - * @return Field associated with the calendarField, - * or null if no associated Field is available. - * @throws IllegalArgumentException if calendarField is not - * a valid Calendar field constant. - * - * @stable ICU 3.8 - */ - public static DateFormat.Field ofCalendarField(int calendarField) { - if (calendarField < 0 || calendarField >= CAL_FIELD_COUNT) { - throw new IllegalArgumentException("Calendar field number is out of range"); - } - return CAL_FIELDS[calendarField]; - } - - /** - * Returns the Calendar field associated with this attribute. - * If there is no corresponding Calendar available, this will - * return -1. - * - * @return Calendar constant for this attribute. - * - * @stable ICU 3.8 - */ - public int getCalendarField() { - return calendarField; - } - - /** - * Resolves instances being deserialized to the predefined constants. - * - * @throws InvalidObjectException if the constant could not be resolved. - * - * @stable ICU 3.8 - */ - protected Object readResolve() throws InvalidObjectException { - ///CLOVER:OFF - if (this.getClass() != DateFormat.Field.class) { - throw new InvalidObjectException( - "A subclass of DateFormat.Field must implement readResolve."); - } - ///CLOVER:ON - Object o = FIELD_NAME_MAP.get(this.getName()); - ///CLOVER:OFF - if (o == null) { - throw new InvalidObjectException("Unknown attribute name."); - } - ///CLOVER:ON - return o; - } - } - - private static int getJDKFormatStyle(int icuFormatStyle) { - switch (icuFormatStyle) { - case DateFormat.FULL: - return java.text.DateFormat.FULL; - case DateFormat.LONG: - return java.text.DateFormat.LONG; - case DateFormat.MEDIUM: - return java.text.DateFormat.MEDIUM; - case DateFormat.SHORT: - return java.text.DateFormat.SHORT; - default: - throw new UnsupportedOperationException("Style not supported by com.ibm.icu.base"); - } - } - - - protected static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { - if (icuPos == null) { - return null; - } - - int fieldID = icuPos.getField(); - Format.Field fieldAttribute = icuPos.getFieldAttribute(); - - FieldPosition jdkPos = null; - - if (fieldID >= 0) { - switch (fieldID) { - case ERA_FIELD: - fieldID = java.text.DateFormat.ERA_FIELD; - break; - case YEAR_FIELD: - fieldID = java.text.DateFormat.YEAR_FIELD; - break; - case MONTH_FIELD: - fieldID = java.text.DateFormat.MONTH_FIELD; - break; - case DATE_FIELD: - fieldID = java.text.DateFormat.DATE_FIELD; - break; - case HOUR_OF_DAY1_FIELD: - fieldID = java.text.DateFormat.HOUR_OF_DAY1_FIELD; - break; - case HOUR_OF_DAY0_FIELD: - fieldID = java.text.DateFormat.HOUR_OF_DAY0_FIELD; - break; - case MINUTE_FIELD: - fieldID = java.text.DateFormat.MINUTE_FIELD; - break; - case SECOND_FIELD: - fieldID = java.text.DateFormat.SECOND_FIELD; - break; - case FRACTIONAL_SECOND_FIELD: // MILLISECOND_FIELD - fieldID = java.text.DateFormat.MILLISECOND_FIELD; - break; - case DAY_OF_WEEK_FIELD: - fieldID = java.text.DateFormat.DAY_OF_WEEK_FIELD; - break; - case DAY_OF_YEAR_FIELD: - fieldID = java.text.DateFormat.DAY_OF_YEAR_FIELD; - break; - case DAY_OF_WEEK_IN_MONTH_FIELD: - fieldID = java.text.DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD; - break; - case WEEK_OF_YEAR_FIELD: - fieldID = java.text.DateFormat.WEEK_OF_YEAR_FIELD; - break; - case WEEK_OF_MONTH_FIELD: - fieldID = java.text.DateFormat.WEEK_OF_MONTH_FIELD; - break; - case AM_PM_FIELD: - fieldID = java.text.DateFormat.AM_PM_FIELD; - break; - case HOUR1_FIELD: - fieldID = java.text.DateFormat.HOUR1_FIELD; - break; - case HOUR0_FIELD: - fieldID = java.text.DateFormat.HOUR0_FIELD; - break; - case TIMEZONE_FIELD: - fieldID = java.text.DateFormat.TIMEZONE_FIELD; - break; - - case YEAR_WOY_FIELD: - case DOW_LOCAL_FIELD: - case EXTENDED_YEAR_FIELD: - case JULIAN_DAY_FIELD: - case MILLISECONDS_IN_DAY_FIELD: - case TIMEZONE_RFC_FIELD: - case TIMEZONE_GENERIC_FIELD: - case STANDALONE_DAY_FIELD: - case STANDALONE_MONTH_FIELD: - case QUARTER_FIELD: - case STANDALONE_QUARTER_FIELD: - case TIMEZONE_SPECIAL_FIELD: - throw new UnsupportedOperationException("Format Field ID not supported by com.ibm.icu.base"); - - default: - // just let it go - break; - } - } - - if (fieldAttribute != null) { - // map field - if (fieldAttribute.equals(Field.AM_PM)) { - fieldAttribute = java.text.DateFormat.Field.AM_PM; - } else if (fieldAttribute.equals(Field.DAY_OF_MONTH)) { - fieldAttribute = java.text.DateFormat.Field.DAY_OF_MONTH; - } else if (fieldAttribute.equals(Field.DAY_OF_WEEK)) { - fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK; - } else if (fieldAttribute.equals(Field.DAY_OF_WEEK_IN_MONTH)) { - fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH; - } else if (fieldAttribute.equals(Field.DAY_OF_YEAR)) { - fieldAttribute = java.text.DateFormat.Field.DAY_OF_YEAR; - } else if (fieldAttribute.equals(Field.ERA)) { - fieldAttribute = java.text.DateFormat.Field.ERA; - } else if (fieldAttribute.equals(Field.HOUR_OF_DAY0)) { - fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY0; - } else if (fieldAttribute.equals(Field.HOUR_OF_DAY1)) { - fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY1; - } else if (fieldAttribute.equals(Field.HOUR0)) { - fieldAttribute = java.text.DateFormat.Field.HOUR0; - } else if (fieldAttribute.equals(Field.HOUR1)) { - fieldAttribute = java.text.DateFormat.Field.HOUR1; - } else if (fieldAttribute.equals(Field.MILLISECOND)) { - fieldAttribute = java.text.DateFormat.Field.MILLISECOND; - } else if (fieldAttribute.equals(Field.MINUTE)) { - fieldAttribute = java.text.DateFormat.Field.MINUTE; - } else if (fieldAttribute.equals(Field.MONTH)) { - fieldAttribute = java.text.DateFormat.Field.MONTH; - } else if (fieldAttribute.equals(Field.SECOND)) { - fieldAttribute = java.text.DateFormat.Field.SECOND; - } else if (fieldAttribute.equals(Field.TIME_ZONE)) { - fieldAttribute = java.text.DateFormat.Field.TIME_ZONE; - } else if (fieldAttribute.equals(Field.WEEK_OF_MONTH)) { - fieldAttribute = java.text.DateFormat.Field.WEEK_OF_MONTH; - } else if (fieldAttribute.equals(Field.WEEK_OF_YEAR)) { - fieldAttribute = java.text.DateFormat.Field.WEEK_OF_YEAR; - } else if (fieldAttribute.equals(Field.YEAR)) { - fieldAttribute = java.text.DateFormat.Field.YEAR; - } else if (fieldAttribute.equals(Field.DOW_LOCAL) - || fieldAttribute.equals(Field.EXTENDED_YEAR) - || fieldAttribute.equals(Field.JULIAN_DAY) - || fieldAttribute.equals(Field.MILLISECONDS_IN_DAY) - || fieldAttribute.equals(Field.YEAR_WOY) - || fieldAttribute.equals(Field.QUARTER)) { - // Not supported - throw new UnsupportedOperationException("Format Field not supported by com.ibm.icu.base"); - } - - jdkPos = new FieldPosition(fieldAttribute, fieldID); - } else { - jdkPos = new FieldPosition(fieldID); - } - - jdkPos.setBeginIndex(icuPos.getBeginIndex()); - jdkPos.setEndIndex(icuPos.getEndIndex()); - - return jdkPos; - } -} +/* + * Copyright (C) 1996-2011, International Business Machines + * Corporation and others. All Rights Reserved. + */ + +package com.ibm.icu.text; + +import java.io.InvalidObjectException; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; + +/** + * {@icuenhanced java.text.DateFormat}.{@icu _usage_} + * + *

      DateFormat is an abstract class for date/time formatting subclasses which + * formats and parses dates or time in a language-independent manner. + * The date/time formatting subclass, such as SimpleDateFormat, allows for + * formatting (i.e., date -> text), parsing (text -> date), and + * normalization. The date is represented as a Date object or + * as the milliseconds since January 1, 1970, 00:00:00 GMT. + * + *

      DateFormat provides many class methods for obtaining default date/time + * formatters based on the default or a given locale and a number of formatting + * styles. The formatting styles include FULL, LONG, MEDIUM, and SHORT. More + * detail and examples of using these styles are provided in the method + * descriptions. + * + *

      DateFormat helps you to format and parse dates for any locale. + * Your code can be completely independent of the locale conventions for + * months, days of the week, or even the calendar format: lunar vs. solar. + * + *

      To format a date for the current Locale, use one of the + * static factory methods: + *

      + *  myString = DateFormat.getDateInstance().format(myDate);
      + * 
      + *

      If you are formatting multiple numbers, it is + * more efficient to get the format and use it multiple times so that + * the system doesn't have to fetch the information about the local + * language and country conventions multiple times. + *

      + *  DateFormat df = DateFormat.getDateInstance();
      + *  for (int i = 0; i < a.length; ++i) {
      + *    output.println(df.format(myDate[i]) + "; ");
      + *  }
      + * 
      + *

      To format a number for a different Locale, specify it in the + * call to getDateInstance(). + *

      + *  DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
      + * 
      + *

      You can use a DateFormat to parse also. + *

      + *  myDate = df.parse(myString);
      + * 
      + *

      Use getDateInstance to get the normal date format for that country. + * There are other static factory methods available. + * Use getTimeInstance to get the time format for that country. + * Use getDateTimeInstance to get a date and time format. You can pass in + * different options to these factory methods to control the length of the + * result; from SHORT to MEDIUM to LONG to FULL. The exact result depends + * on the locale, but generally: + *

      • SHORT is completely numeric, such as 12.13.52 or 3:30pm + *
      • MEDIUM is longer, such as Jan 12, 1952 + *
      • LONG is longer, such as January 12, 1952 or 3:30:32pm + *
      • FULL is pretty completely specified, such as + * Tuesday, April 12, 1952 AD or 3:30:42pm PST. + *
      + * + *

      You can also set the time zone on the format if you wish. + * If you want even more control over the format or parsing, + * (or want to give your users more control), + * you can try casting the DateFormat you get from the factory methods + * to a SimpleDateFormat. This will work for the majority + * of countries; just remember to put it in a try block in case you + * encounter an unusual one. + * + *

      You can also use forms of the parse and format methods with + * ParsePosition and FieldPosition to + * allow you to + *

      • progressively parse through pieces of a string. + *
      • align any particular field, or find out where it is for selection + * on the screen. + *
      + * + *

      Synchronization

      + * + * Date formats are not synchronized. It is recommended to create separate + * format instances for each thread. If multiple threads access a format + * concurrently, it must be synchronized externally. + * + * @see UFormat + * @see NumberFormat + * @see SimpleDateFormat + * @see com.ibm.icu.util.Calendar + * @see com.ibm.icu.util.GregorianCalendar + * @see com.ibm.icu.util.TimeZone + * @author Mark Davis, Chen-Lieh Huang, Alan Liu + * @stable ICU 2.0 + */ +public class DateFormat extends Format { + + private static final long serialVersionUID = 1L; + + /** + * @internal + */ + public final java.text.DateFormat dateFormat; + + /** + * @internal + * @param delegate the DateFormat to which to delegate + */ + public DateFormat(java.text.DateFormat delegate) { + this.dateFormat = delegate; + } + + /** + * For subclass use. Subclasses will generally not + * work correctly unless they manipulate the delegate. + */ + protected DateFormat() { + this.dateFormat = java.text.DateFormat.getInstance(); + } + + /** + * FieldPosition selector for 'G' field alignment, + * corresponding to the {@link Calendar#ERA} field. + * @stable ICU 2.0 + */ + public final static int ERA_FIELD = 0; + + /** + * FieldPosition selector for 'y' field alignment, + * corresponding to the {@link Calendar#YEAR} field. + * @stable ICU 2.0 + */ + public final static int YEAR_FIELD = 1; + + /** + * FieldPosition selector for 'M' field alignment, + * corresponding to the {@link Calendar#MONTH} field. + * @stable ICU 2.0 + */ + public final static int MONTH_FIELD = 2; + + /** + * FieldPosition selector for 'd' field alignment, + * corresponding to the {@link Calendar#DATE} field. + * @stable ICU 2.0 + */ + public final static int DATE_FIELD = 3; + + /** + * FieldPosition selector for 'k' field alignment, + * corresponding to the {@link Calendar#HOUR_OF_DAY} field. + * HOUR_OF_DAY1_FIELD is used for the one-based 24-hour clock. + * For example, 23:59 + 01:00 results in 24:59. + * @stable ICU 2.0 + */ + public final static int HOUR_OF_DAY1_FIELD = 4; + + /** + * FieldPosition selector for 'H' field alignment, + * corresponding to the {@link Calendar#HOUR_OF_DAY} field. + * HOUR_OF_DAY0_FIELD is used for the zero-based 24-hour clock. + * For example, 23:59 + 01:00 results in 00:59. + * @stable ICU 2.0 + */ + public final static int HOUR_OF_DAY0_FIELD = 5; + + /** + * FieldPosition selector for 'm' field alignment, + * corresponding to the {@link Calendar#MINUTE} field. + * @stable ICU 2.0 + */ + public final static int MINUTE_FIELD = 6; + + /** + * FieldPosition selector for 's' field alignment, + * corresponding to the {@link Calendar#SECOND} field. + * @stable ICU 2.0 + */ + public final static int SECOND_FIELD = 7; + + /** + * {@icu} FieldPosition selector for 'S' field alignment, + * corresponding to the {@link Calendar#MILLISECOND} field. + * @stable ICU 3.0 + */ + public final static int FRACTIONAL_SECOND_FIELD = 8; + + /** + * Alias for FRACTIONAL_SECOND_FIELD. + * @deprecated ICU 3.0 use FRACTIONAL_SECOND_FIELD. + */ + public final static int MILLISECOND_FIELD = FRACTIONAL_SECOND_FIELD; + + /** + * FieldPosition selector for 'E' field alignment, + * corresponding to the {@link Calendar#DAY_OF_WEEK} field. + * @stable ICU 2.0 + */ + public final static int DAY_OF_WEEK_FIELD = 9; + + /** + * FieldPosition selector for 'D' field alignment, + * corresponding to the {@link Calendar#DAY_OF_YEAR} field. + * @stable ICU 2.0 + */ + public final static int DAY_OF_YEAR_FIELD = 10; + + /** + * FieldPosition selector for 'F' field alignment, + * corresponding to the {@link Calendar#DAY_OF_WEEK_IN_MONTH} field. + * @stable ICU 2.0 + */ + public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11; + + /** + * FieldPosition selector for 'w' field alignment, + * corresponding to the {@link Calendar#WEEK_OF_YEAR} field. + * @stable ICU 2.0 + */ + public final static int WEEK_OF_YEAR_FIELD = 12; + + /** + * FieldPosition selector for 'W' field alignment, + * corresponding to the {@link Calendar#WEEK_OF_MONTH} field. + * @stable ICU 2.0 + */ + public final static int WEEK_OF_MONTH_FIELD = 13; + + /** + * FieldPosition selector for 'a' field alignment, + * corresponding to the {@link Calendar#AM_PM} field. + * @stable ICU 2.0 + */ + public final static int AM_PM_FIELD = 14; + + /** + * FieldPosition selector for 'h' field alignment, + * corresponding to the {@link Calendar#HOUR} field. + * HOUR1_FIELD is used for the one-based 12-hour clock. + * For example, 11:30 PM + 1 hour results in 12:30 AM. + * @stable ICU 2.0 + */ + public final static int HOUR1_FIELD = 15; + + /** + * FieldPosition selector for 'K' field alignment, + * corresponding to the {@link Calendar#HOUR} field. + * HOUR0_FIELD is used for the zero-based 12-hour clock. + * For example, 11:30 PM + 1 hour results in 00:30 AM. + * @stable ICU 2.0 + */ + public final static int HOUR0_FIELD = 16; + + /** + * FieldPosition selector for 'z' field alignment, + * corresponding to the {@link Calendar#ZONE_OFFSET} and + * {@link Calendar#DST_OFFSET} fields. + * @stable ICU 2.0 + */ + public final static int TIMEZONE_FIELD = 17; + + /** + * {@icu} FieldPosition selector for 'Y' field alignment, + * corresponding to the {@link Calendar#YEAR_WOY} field. + * @stable ICU 3.0 + */ + public final static int YEAR_WOY_FIELD = 18; + + /** + * {@icu} FieldPosition selector for 'e' field alignment, + * corresponding to the {@link Calendar#DOW_LOCAL} field. + * @stable ICU 3.0 + */ + public final static int DOW_LOCAL_FIELD = 19; + + /** + * {@icu} FieldPosition selector for 'u' field alignment, + * corresponding to the {@link Calendar#EXTENDED_YEAR} field. + * @stable ICU 3.0 + */ + public final static int EXTENDED_YEAR_FIELD = 20; + + /** + * {@icu} FieldPosition selector for 'g' field alignment, + * corresponding to the {@link Calendar#JULIAN_DAY} field. + * @stable ICU 3.0 + */ + public final static int JULIAN_DAY_FIELD = 21; + + /** + * {@icu} FieldPosition selector for 'A' field alignment, + * corresponding to the {@link Calendar#MILLISECONDS_IN_DAY} field. + * @stable ICU 3.0 + */ + public final static int MILLISECONDS_IN_DAY_FIELD = 22; + + /** + * {@icu} FieldPosition selector for 'Z' field alignment, + * corresponding to the {@link Calendar#ZONE_OFFSET} and + * {@link Calendar#DST_OFFSET} fields. + * @stable ICU 3.0 + */ + public final static int TIMEZONE_RFC_FIELD = 23; + + /** + * {@icu} FieldPosition selector for 'v' field alignment, + * corresponding to the {@link Calendar#ZONE_OFFSET} and + * {@link Calendar#DST_OFFSET} fields. This displays the generic zone + * name, if available. + * @stable ICU 3.4 + */ + public final static int TIMEZONE_GENERIC_FIELD = 24; + + /** + * {@icu} FieldPosition selector for 'c' field alignment, + * corresponding to the {@link Calendar#DAY_OF_WEEK} field. + * This displays the stand alone day name, if available. + * @stable ICU 3.4 + */ + public final static int STANDALONE_DAY_FIELD = 25; + + /** + * {@icu} FieldPosition selector for 'L' field alignment, + * corresponding to the {@link Calendar#MONTH} field. + * This displays the stand alone month name, if available. + * @stable ICU 3.4 + */ + public final static int STANDALONE_MONTH_FIELD = 26; + + /** + * {@icu} FieldPosition selector for 'Q' field alignment, + * corresponding to the {@link Calendar#MONTH} field. + * This displays the quarter. + * @stable ICU 3.6 + */ + public final static int QUARTER_FIELD = 27; + + /** + * {@icu} FieldPosition selector for 'q' field alignment, + * corresponding to the {@link Calendar#MONTH} field. + * This displays the stand alone quarter, if available. + * @stable ICU 3.6 + */ + public final static int STANDALONE_QUARTER_FIELD = 28; + + /** + * {@icu} FieldPosition selector for 'V' field alignment, + * corresponding to the {@link Calendar#ZONE_OFFSET} and + * {@link Calendar#DST_OFFSET} fields. This displays the fallback timezone + * name when VVVV is specified, and the short standard or daylight + * timezone name ignoring commonlyUsed when a single V is specified. + * @stable ICU 3.8 + */ + public final static int TIMEZONE_SPECIAL_FIELD = 29; + + /** + * {@icu} Number of FieldPosition selectors for DateFormat. + * Valid selectors range from 0 to FIELD_COUNT-1. + * @stable ICU 3.0 + */ + public final static int FIELD_COUNT = 30; // must == DateFormatSymbols.patternChars.length() + + /** + * Formats a time object into a time string. Examples of time objects + * are a time value expressed in milliseconds and a Date object. + * @param obj must be a Number or a Date or a Calendar. + * @param toAppendTo the string buffer for the returning time string. + * @return the formatted time string. + * @param fieldPosition keeps track of the position of the field + * within the returned string. + * On input: an alignment field, + * if desired. On output: the offsets of the alignment field. For + * example, given a time text "1996.07.10 AD at 15:08:56 PDT", + * if the given fieldPosition is DateFormat.YEAR_FIELD, the + * begin index and end index of fieldPosition will be set to + * 0 and 4, respectively. + * Notice that if the same time field appears + * more than once in a pattern, the fieldPosition will be set for the first + * occurrence of that time field. For instance, formatting a Date to + * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern + * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, + * the begin index and end index of fieldPosition will be set to + * 5 and 8, respectively, for the first occurrence of the timezone + * pattern character 'z'. + * @see java.text.Format + * @stable ICU 2.0 + */ + public final StringBuffer format(Object obj, StringBuffer toAppendTo, + FieldPosition fieldPosition) + { + if (obj instanceof Calendar) { + return format((Calendar)obj, toAppendTo, fieldPosition); + } else if (obj instanceof Date) { + return format((Date)obj, toAppendTo, fieldPosition); + } else if (obj instanceof Number) { + return format(new Date(((Number)obj).longValue()), toAppendTo, fieldPosition ); + } + + throw new IllegalArgumentException("Cannot format given Object (" + + obj.getClass().getName() + ") as a Date"); + } + + /** + * Formats a date into a date/time string. + * @param cal a Calendar set to the date and time to be formatted + * into a date/time string. When the calendar type is different from + * the internal calendar held by this DateFormat instance, the date + * and the time zone will be inherited from the input calendar, but + * other calendar field values will be calculated by the internal calendar. + * @param toAppendTo the string buffer for the returning date/time string. + * @param fieldPosition keeps track of the position of the field + * within the returned string. + * On input: an alignment field, + * if desired. On output: the offsets of the alignment field. For + * example, given a time text "1996.07.10 AD at 15:08:56 PDT", + * if the given fieldPosition is DateFormat.YEAR_FIELD, the + * begin index and end index of fieldPosition will be set to + * 0 and 4, respectively. + * Notice that if the same time field appears + * more than once in a pattern, the fieldPosition will be set for the first + * occurrence of that time field. For instance, formatting a Date to + * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern + * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, + * the begin index and end index of fieldPosition will be set to + * 5 and 8, respectively, for the first occurrence of the timezone + * pattern character 'z'. + * @return the formatted date/time string. + * @stable ICU 2.0 + */ + public StringBuffer format(Calendar cal, StringBuffer toAppendTo, + FieldPosition fieldPosition) { + return format(cal.getTime(), toAppendTo, fieldPosition); + } + + /** + * Formats a Date into a date/time string. + * @param date a Date to be formatted into a date/time string. + * @param toAppendTo the string buffer for the returning date/time string. + * @param fieldPosition keeps track of the position of the field + * within the returned string. + * On input: an alignment field, + * if desired. On output: the offsets of the alignment field. For + * example, given a time text "1996.07.10 AD at 15:08:56 PDT", + * if the given fieldPosition is DateFormat.YEAR_FIELD, the + * begin index and end index of fieldPosition will be set to + * 0 and 4, respectively. + * Notice that if the same time field appears + * more than once in a pattern, the fieldPosition will be set for the first + * occurrence of that time field. For instance, formatting a Date to + * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern + * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD, + * the begin index and end index of fieldPosition will be set to + * 5 and 8, respectively, for the first occurrence of the timezone + * pattern character 'z'. + * @return the formatted date/time string. + * @stable ICU 2.0 + */ + public StringBuffer format(Date date, StringBuffer toAppendTo, + FieldPosition fieldPosition) { + FieldPosition jdkPos = toJDKFieldPosition(fieldPosition); + StringBuffer buf = dateFormat.format(date, toAppendTo, jdkPos); + if (jdkPos != null) { + fieldPosition.setBeginIndex(jdkPos.getBeginIndex()); + fieldPosition.setEndIndex(jdkPos.getEndIndex()); + } + return buf; + } + + /** + * Formats a Date into a date/time string. + * @param date the time value to be formatted into a time string. + * @return the formatted time string. + * @stable ICU 2.0 + */ + public final String format(Date date) + { + return dateFormat.format(date); + } + + /** + * Parses a date/time string. + * + * @param text The date/time string to be parsed + * + * @return A Date, or null if the input could not be parsed + * + * @exception ParseException If the given string cannot be parsed as a date. + * + * @see #parse(String, ParsePosition) + * @stable ICU 2.0 + */ + public Date parse(String text) throws ParseException + { + return dateFormat.parse(text); + } + + /** + * Parses a date/time string according to the given parse position. + * For example, a time text "07/10/96 4:5 PM, PDT" will be parsed + * into a Calendar that is equivalent to Date(837039928046). The + * caller should clear the calendar before calling this method, + * unless existing field information is to be kept. + * + *

      By default, parsing is lenient: If the input is not in the form used + * by this object's format method but can still be parsed as a date, then + * the parse succeeds. Clients may insist on strict adherence to the + * format by calling setLenient(false). + * + * @see #setLenient(boolean) + * + * @param text The date/time string to be parsed + * + * @param cal The calendar into which parsed data will be stored. + * In general, this should be cleared before calling this + * method. If this parse fails, the calendar may still + * have been modified. When the calendar type is different + * from the internal calendar held by this DateFormat + * instance, calendar field values will be parsed based + * on the internal calendar initialized with the time and + * the time zone taken from this calendar, then the + * parse result (time in milliseconds and time zone) will + * be set back to this calendar. + * + * @param pos On input, the position at which to start parsing; on + * output, the position at which parsing terminated, or the + * start position if the parse failed. + * @stable ICU 2.0 + */ + public void parse(String text, Calendar cal, ParsePosition pos) { + Date result = dateFormat.parse(text, pos); + cal.setTime(result); + } + + /** + * Parses a date/time string according to the given parse position. For + * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date + * that is equivalent to Date(837039928046). + * + *

      By default, parsing is lenient: If the input is not in the form used + * by this object's format method but can still be parsed as a date, then + * the parse succeeds. Clients may insist on strict adherence to the + * format by calling setLenient(false). + * + * @see #setLenient(boolean) + * + * @param text The date/time string to be parsed + * + * @param pos On input, the position at which to start parsing; on + * output, the position at which parsing terminated, or the + * start position if the parse failed. + * + * @return A Date, or null if the input could not be parsed + * @stable ICU 2.0 + */ + public Date parse(String text, ParsePosition pos) { + return dateFormat.parse(text, pos); + } + + /** + * Parses a date/time string into an Object. This convenience method simply + * calls parse(String, ParsePosition). + * + * @see #parse(String, ParsePosition) + * @stable ICU 2.0 + */ + public Object parseObject (String source, ParsePosition pos) + { + return parse(source, pos); + } + + /** + * {@icu} Constant for empty style pattern. + * @stable ICU 3.8 + */ + public static final int NONE = -1; + + /** + * Constant for full style pattern. + * @stable ICU 2.0 + */ + public static final int FULL = 0; + + /** + * Constant for long style pattern. + * @stable ICU 2.0 + */ + public static final int LONG = 1; + + /** + * Constant for medium style pattern. + * @stable ICU 2.0 + */ + public static final int MEDIUM = 2; + + /** + * Constant for short style pattern. + * @stable ICU 2.0 + */ + public static final int SHORT = 3; + + /** + * Constant for default style pattern. Its value is MEDIUM. + * @stable ICU 2.0 + */ + public static final int DEFAULT = MEDIUM; + + /** + * {@icu} Constant for relative style mask. + * @stable ICU 3.8 + */ + public static final int RELATIVE = (1 << 7); + + /** + * {@icu} Constant for relative full style pattern. + * @stable ICU 3.8 + */ + public static final int RELATIVE_FULL = RELATIVE | FULL; + + /** + * {@icu} Constant for relative style pattern. + * @stable ICU 3.8 + */ + public static final int RELATIVE_LONG = RELATIVE | LONG; + + /** + * {@icu} Constant for relative style pattern. + * @stable ICU 3.8 + */ + public static final int RELATIVE_MEDIUM = RELATIVE | MEDIUM; + + /** + * {@icu} Constant for relative style pattern. + * @stable ICU 3.8 + */ + public static final int RELATIVE_SHORT = RELATIVE | SHORT; + + /** + * {@icu} Constant for relative default style pattern. + * @stable ICU 3.8 + */ + public static final int RELATIVE_DEFAULT = RELATIVE | DEFAULT; + + /* Below are pre-defined skeletons + * + *

      + * A skeleton + *

        + *
      • + * 1. only keeps the field pattern letter and ignores all other parts + * in a pattern, such as space, punctuations, and string literals. + *
      • + * 2. hides the order of fields. + *
      • + * 3. might hide a field's pattern letter length. + * + * For those non-digit calendar fields, the pattern letter length is + * important, such as MMM, MMMM, and MMMMM; E and EEEE, + * and the field's pattern letter length is honored. + * + * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, + * the field pattern length is ignored and the best match, which is + * defined in date time patterns, will be returned without honor + * the field pattern letter length in skeleton. + *
      + */ + /** + * {@icu} Constant for date pattern with minute and second. + * @stable ICU 4.0 + */ + public static final String MINUTE_SECOND = "ms"; + + /** + * {@icu} Constant for date pattern with hour and minute in 24-hour presentation. + * @stable ICU 4.0 + */ + public static final String HOUR24_MINUTE = "Hm"; + + /** + * {@icu} Constant for date pattern with hour, minute, and second in + * 24-hour presentation. + * @stable ICU 4.0 + */ + public static final String HOUR24_MINUTE_SECOND = "Hms"; + + /** + * {@icu} Constant for date pattern with hour, minute, and second. + * @stable ICU 4.0 + */ + public static final String HOUR_MINUTE_SECOND = "hms"; + + /** + * {@icu} Constant for date pattern with standalone month. + * @stable ICU 4.0 + */ + public static final String STANDALONE_MONTH = "LLLL"; + + /** + * {@icu} Constant for date pattern with standalone abbreviated month. + * @stable ICU 4.0 + */ + public static final String ABBR_STANDALONE_MONTH = "LLL"; + + /** + * {@icu} Constant for date pattern with year and quarter. + * @stable ICU 4.0 + */ + public static final String YEAR_QUARTER = "yQQQ"; + + /** + * {@icu} Constant for date pattern with year and abbreviated quarter. + * @stable ICU 4.0 + */ + public static final String YEAR_ABBR_QUARTER = "yQ"; + + + /* Below are skeletons that date interval pre-defined in resource file. + * Users are encouraged to use them in date interval format factory methods. + */ + /** + * {@icu} Constant for date pattern with hour and minute. + * @stable ICU 4.0 + */ + public static final String HOUR_MINUTE = "hm"; + + /** + * {@icu} Constant for date pattern with year. + * @stable ICU 4.0 + */ + public static final String YEAR = "y"; + + /** + * {@icu} Constant for date pattern with day. + * @stable ICU 4.0 + */ + public static final String DAY = "d"; + + /** + * {@icu} Constant for date pattern with numeric month, weekday, and day. + * @stable ICU 4.0 + */ + public static final String NUM_MONTH_WEEKDAY_DAY = "MEd"; + + /** + * {@icu} Constant for date pattern with year and numeric month. + * @stable ICU 4.0 + */ + public static final String YEAR_NUM_MONTH = "yM"; + + /** + * {@icu} Constant for date pattern with numeric month and day. + * @stable ICU 4.0 + */ + public static final String NUM_MONTH_DAY = "Md"; + + /** + * {@icu} Constant for date pattern with year, numeric month, weekday, and day. + * @stable ICU 4.0 + */ + public static final String YEAR_NUM_MONTH_WEEKDAY_DAY = "yMEd"; + + /** + * {@icu} Constant for date pattern with abbreviated month, weekday, and day. + * @stable ICU 4.0 + */ + public static final String ABBR_MONTH_WEEKDAY_DAY = "MMMEd"; + + /** + * {@icu} Constant for date pattern with year and month. + * @stable ICU 4.0 + */ + public static final String YEAR_MONTH = "yMMMM"; + + /** + * {@icu} Constant for date pattern with year and abbreviated month. + * @stable ICU 4.0 + */ + public static final String YEAR_ABBR_MONTH = "yMMM"; + + /** + * {@icu} Constant for date pattern having month and day. + * @stable ICU 4.0 + */ + public static final String MONTH_DAY = "MMMMd"; + + /** + * {@icu} Constant for date pattern with abbreviated month and day. + * @stable ICU 4.0 + */ + public static final String ABBR_MONTH_DAY = "MMMd"; + + /** + * {@icu} Constant for date pattern with month, weekday, and day. + * @stable ICU 4.0 + */ + public static final String MONTH_WEEKDAY_DAY = "MMMMEEEEd"; + + /** + * {@icu} Constant for date pattern with year, abbreviated month, weekday, + * and day. + * @stable ICU 4.0 + */ + public static final String YEAR_ABBR_MONTH_WEEKDAY_DAY = "yMMMEd"; + + /** + * {@icu} Constant for date pattern with year, month, weekday, and day. + * @stable ICU 4.0 + */ + public static final String YEAR_MONTH_WEEKDAY_DAY = "yMMMMEEEEd"; + + /** + * {@icu} Constant for date pattern with year, month, and day. + * @stable ICU 4.0 + */ + public static final String YEAR_MONTH_DAY = "yMMMMd"; + + /** + * {@icu} Constant for date pattern with year, abbreviated month, and day. + * @stable ICU 4.0 + */ + public static final String YEAR_ABBR_MONTH_DAY = "yMMMd"; + + /** + * {@icu} Constant for date pattern with year, numeric month, and day. + * @stable ICU 4.0 + */ + public static final String YEAR_NUM_MONTH_DAY = "yMd"; + + /** + * {@icu} Constant for date pattern with numeric month. + * @stable ICU 4.0 + */ + public static final String NUM_MONTH = "M"; + + /** + * {@icu} Constant for date pattern with abbreviated month. + * @stable ICU 4.0 + */ + public static final String ABBR_MONTH = "MMM"; + + /** + * {@icu} Constant for date pattern with month. + * @stable ICU 4.0 + */ + public static final String MONTH = "MMMM"; + + /** + * {@icu} Constant for date pattern with hour, minute, and generic timezone. + * @stable ICU 4.0 + */ + public static final String HOUR_MINUTE_GENERIC_TZ = "hmv"; + + /** + * {@icu} Constant for date pattern with hour, minute, and timezone. + * @stable ICU 4.0 + */ + public static final String HOUR_MINUTE_TZ = "hmz"; + + /** + * {@icu} Constant for date pattern with hour. + * @stable ICU 4.0 + */ + public static final String HOUR = "h"; + + /** + * {@icu} Constant for date pattern with hour and generic timezone. + * @stable ICU 4.0 + */ + public static final String HOUR_GENERIC_TZ = "hv"; + + /** + * {@icu} Constant for date pattern with hour and timezone. + * @stable ICU 4.0 + */ + public static final String HOUR_TZ = "hz"; + + /** + * Gets the time formatter with the default formatting style + * for the default locale. + * @return a time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getTimeInstance() + { + return new DateFormat(java.text.DateFormat.getTimeInstance()); + } + + /** + * Returns the time formatter with the given formatting style + * for the default locale. + * @param style the given formatting style. For example, + * SHORT for "h:mm a" in the US locale. + * @return a time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getTimeInstance(int style) + { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style))); + } + + /** + * Returns the time formatter with the given formatting style + * for the given locale. + * @param style the given formatting style. For example, + * SHORT for "h:mm a" in the US locale. + * @param aLocale the given locale. + * @return a time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getTimeInstance(int style, + Locale aLocale) + { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), aLocale)); + } + + /** + * Returns the time formatter with the given formatting style + * for the given locale. + * @param style the given formatting style. For example, + * SHORT for "h:mm a" in the US locale. + * @param locale the given ulocale. + * @return a time formatter. + * @stable ICU 3.2 + */ + public final static DateFormat getTimeInstance(int style, + ULocale locale) + { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), locale.toLocale())); + } + + /** + * Returns the date formatter with the default formatting style + * for the default locale. + * @return a date formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateInstance() + { + return new DateFormat(java.text.DateFormat.getDateInstance()); + } + + /** + * Returns the date formatter with the given formatting style + * for the default locale. + * @param style the given formatting style. For example, + * SHORT for "M/d/yy" in the US locale. + * @return a date formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateInstance(int style) + { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style))); + } + + /** + * Returns the date formatter with the given formatting style + * for the given locale. + * @param style the given formatting style. For example, + * SHORT for "M/d/yy" in the US locale. + * @param aLocale the given locale. + * @return a date formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateInstance(int style, + Locale aLocale) + { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), aLocale)); + } + + /** + * Returns the date formatter with the given formatting style + * for the given locale. + * @param style the given formatting style. For example, + * SHORT for "M/d/yy" in the US locale. + * @param locale the given ulocale. + * @return a date formatter. + * @stable ICU 3.2 + */ + public final static DateFormat getDateInstance(int style, + ULocale locale) + { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), locale.toLocale())); + } + + /** + * Returns the date/time formatter with the default formatting style + * for the default locale. + * @return a date/time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateTimeInstance() + { + return new DateFormat(java.text.DateFormat.getDateTimeInstance()); + } + + /** + * Returns the date/time formatter with the given date and time + * formatting styles for the default locale. + * @param dateStyle the given date formatting style. For example, + * SHORT for "M/d/yy" in the US locale. + * @param timeStyle the given time formatting style. For example, + * SHORT for "h:mm a" in the US locale. + * @return a date/time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateTimeInstance(int dateStyle, + int timeStyle) + { + if (dateStyle != NONE) { + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle))); + } else { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle))); + } + } + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle))); + } + return null; + } + + /** + * Returns the date/time formatter with the given formatting styles + * for the given locale. + * @param dateStyle the given date formatting style. + * @param timeStyle the given time formatting style. + * @param aLocale the given locale. + * @return a date/time formatter. + * @stable ICU 2.0 + */ + public final static DateFormat getDateTimeInstance( + int dateStyle, int timeStyle, Locale aLocale) + { + if (dateStyle != NONE) { + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), aLocale)); + } else { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), aLocale)); + } + } + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), aLocale)); + } + return null; + } + + /** + * Returns the date/time formatter with the given formatting styles + * for the given locale. + * @param dateStyle the given date formatting style. + * @param timeStyle the given time formatting style. + * @param locale the given ulocale. + * @return a date/time formatter. + * @stable ICU 3.2 + */ + public final static DateFormat getDateTimeInstance( + int dateStyle, int timeStyle, ULocale locale) + { + if (dateStyle != NONE) { + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), locale.toLocale())); + } else { + return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), locale.toLocale())); + } + } + if (timeStyle != NONE) { + return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), locale.toLocale())); + } + return null; + } + + /** + * Returns a default date/time formatter that uses the SHORT style for both the + * date and the time. + * @stable ICU 2.0 + */ + public final static DateFormat getInstance() { + return new DateFormat(java.text.DateFormat.getInstance()); + } + + /** + * Returns the set of locales for which DateFormats are installed. + * @return the set of locales for which DateFormats are installed. + * @stable ICU 2.0 + */ + public static Locale[] getAvailableLocales() + { + return java.text.DateFormat.getAvailableLocales(); + } + + /** + * {@icu} Returns the set of locales for which DateFormats are installed. + * @return the set of locales for which DateFormats are installed. + * @draft ICU 3.2 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static ULocale[] getAvailableULocales() + { + if (availableULocales == null) { + synchronized(DateFormat.class) { + if (availableULocales == null) { + Locale[] locales = java.text.DateFormat.getAvailableLocales(); + availableULocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + availableULocales[i] = ULocale.forLocale(locales[i]); + } + } + } + } + return availableULocales; + } + private static volatile ULocale[] availableULocales; + + /** + * Sets the calendar to be used by this date format. Initially, the default + * calendar for the specified or default locale is used. + * @param newCalendar the new Calendar to be used by the date format + * @stable ICU 2.0 + */ + public void setCalendar(Calendar newCalendar) + { + dateFormat.setCalendar(newCalendar.calendar); + } + + /** + * Returns the calendar associated with this date/time formatter. + * @return the calendar associated with this date/time formatter. + * @stable ICU 2.0 + */ + public Calendar getCalendar() + { + return new Calendar(dateFormat.getCalendar()); + } + + /** + * Sets the number formatter. + * @param newNumberFormat the given new NumberFormat. + * @stable ICU 2.0 + */ + public void setNumberFormat(NumberFormat newNumberFormat) + { + dateFormat.setNumberFormat(newNumberFormat.numberFormat); + } + + /** + * Returns the number formatter which this date/time formatter uses to + * format and parse a time. + * @return the number formatter which this date/time formatter uses. + * @stable ICU 2.0 + */ + public NumberFormat getNumberFormat() + { + return new NumberFormat(dateFormat.getNumberFormat()); + } + + /** + * Sets the time zone for the calendar of this DateFormat object. + * @param zone the given new time zone. + * @stable ICU 2.0 + */ + public void setTimeZone(TimeZone zone) + { + dateFormat.setTimeZone(zone.timeZone); + } + + /** + * Returns the time zone. + * @return the time zone associated with the calendar of DateFormat. + * @stable ICU 2.0 + */ + public TimeZone getTimeZone() + { + return new TimeZone(dateFormat.getTimeZone()); + } + + /** + * Specifies whether date/time parsing is to be lenient. With + * lenient parsing, the parser may use heuristics to interpret inputs that + * do not precisely match this object's format. With strict parsing, + * inputs must match this object's format. + * @param lenient when true, parsing is lenient + * @see com.ibm.icu.util.Calendar#setLenient + * @stable ICU 2.0 + */ + public void setLenient(boolean lenient) + { + dateFormat.setLenient(lenient); + } + + /** + * Returns whether date/time parsing is lenient. + * @stable ICU 2.0 + */ + public boolean isLenient() + { + return dateFormat.isLenient(); + } + + /** + * Overrides hashCode. + * @stable ICU 2.0 + */ + public int hashCode() { + return dateFormat.hashCode(); + } + + /** + * Overrides equals. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) { + try { + return dateFormat.equals(((DateFormat)obj).dateFormat); + } + catch (Exception e) { + return false; + } + } + + /** + * Overrides clone. + * @stable ICU 2.0 + */ + public Object clone() + { + return new DateFormat((java.text.DateFormat)dateFormat.clone()); + } + + //------------------------------------------------------------------------- + // Public static interface for creating custon DateFormats for different + // types of Calendars. + //------------------------------------------------------------------------- + + /** + * Creates a {@link DateFormat} object that can be used to format dates in + * the calendar system specified by cal. + *

      + * @param cal The calendar system for which a date format is desired. + * + * @param dateStyle The type of date format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the date format is desired. + * @stable ICU 2.0 + */ + static final public DateFormat getDateInstance(Calendar cal, int dateStyle, Locale locale) + { + DateFormat df = getDateInstance(dateStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Creates a {@link DateFormat} object that can be used to format dates in + * the calendar system specified by cal. + *

      + * @param cal The calendar system for which a date format is desired. + * + * @param dateStyle The type of date format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the date format is desired. + * @stable ICU 3.2 + */ + static final public DateFormat getDateInstance(Calendar cal, int dateStyle, ULocale locale) + { + DateFormat df = getDateInstance(dateStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Creates a {@link DateFormat} object that can be used to format times in + * the calendar system specified by cal. + *

      + * Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + *

      + * @param cal The calendar system for which a time format is desired. + * + * @param timeStyle The type of time format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the time format is desired. + * + * @see DateFormat#getTimeInstance + * @stable ICU 2.0 + */ + static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, Locale locale) + { + DateFormat df = getTimeInstance(timeStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Creates a {@link DateFormat} object that can be used to format times in + * the calendar system specified by cal. + *

      + * Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + *

      + * @param cal The calendar system for which a time format is desired. + * + * @param timeStyle The type of time format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the time format is desired. + * + * @see DateFormat#getTimeInstance + * @stable ICU 3.2 + */ + static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, ULocale locale) + { + DateFormat df = getTimeInstance(timeStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Creates a {@link DateFormat} object that can be used to format dates and times in + * the calendar system specified by cal. + *

      + * Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + *

      + * @param cal The calendar system for which a date/time format is desired. + * + * @param dateStyle The type of date format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param timeStyle The type of time format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the date/time format is desired. + * + * @see DateFormat#getDateTimeInstance + * @stable ICU 2.0 + */ + static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, + int timeStyle, Locale locale) + { + DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Creates a {@link DateFormat} object that can be used to format dates and times in + * the calendar system specified by cal. + *

      + * Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + *

      + * @param cal The calendar system for which a date/time format is desired. + * + * @param dateStyle The type of date format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param timeStyle The type of time format desired. This can be + * {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM}, + * etc. + * + * @param locale The locale for which the date/time format is desired. + * + * @see DateFormat#getDateTimeInstance + * @stable ICU 3.2 + */ + static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, + int timeStyle, ULocale locale) + { + DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale); + df.setCalendar(cal); + return df; + } + + /** + * Convenience overload. + * @stable ICU 2.0 + */ + static final public DateFormat getInstance(Calendar cal, Locale locale) { + return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale); + } + + /** + * Convenience overload. + * @stable ICU 3.2 + * @provisional This API might change or be removed in a future release. + */ + static final public DateFormat getInstance(Calendar cal, ULocale locale) { + return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale); + } + + /** + * Convenience overload. + * @stable ICU 2.0 + */ + static final public DateFormat getInstance(Calendar cal) { + return getInstance(cal, ULocale.getDefault()); + } + + /** + * Convenience overload. + * @stable ICU 2.0 + */ + static final public DateFormat getDateInstance(Calendar cal, int dateStyle) { + return getDateInstance(cal, dateStyle, ULocale.getDefault()); + } + + /** + * Convenience overload. + * @stable ICU 2.0 + */ + static final public DateFormat getTimeInstance(Calendar cal, int timeStyle) { + return getTimeInstance(cal, timeStyle, ULocale.getDefault()); + } + + /** + * Convenience overload. + * @stable ICU 2.0 + */ + static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, int timeStyle) { + return getDateTimeInstance(cal, dateStyle, timeStyle, ULocale.getDefault()); + } + + /** + * {@icu} Convenience overload. + * @stable ICU 4.0 + */ + public final static DateFormat getPatternInstance(String pattern) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Convenience overload. + * @stable ICU 4.0 + */ + public final static DateFormat getPatternInstance(String pattern, Locale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in + * the given locale. + *

      + * Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + *

      + * + * @param pattern The pattern that selects the fields to be formatted. (Uses the + * {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH}, + * {@link DateFormat#MONTH_WEEKDAY_DAY}, etc. + * + * @param locale The locale for which the date/time format is desired. + * + * @stable ICU 4.0 + */ + public final static DateFormat getPatternInstance(String pattern, ULocale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Convenience overload. + * @stable ICU 4.0 + */ + public final static DateFormat getPatternInstance(Calendar cal, String pattern, Locale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Creates a {@link DateFormat} object that can be used to format dates and + * times in the calendar system specified by cal. + * + *

      Note: When this functionality is moved into the core JDK, this method + * will probably be replaced by a new overload of {@link DateFormat#getInstance}. + * + * @param cal The calendar system for which a date/time format is desired. + * + * @param pattern The pattern that selects the fields to be formatted. (Uses the + * {@link DateTimePatternGenerator}.) This can be + * {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY}, + * etc. + * + * @param locale The locale for which the date/time format is desired. + * + * @stable ICU 4.0 + */ + public final static DateFormat getPatternInstance( + Calendar cal, String pattern, ULocale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * The instances of this inner class are used as attribute keys and values + * in AttributedCharacterIterator that + * DateFormat.formatToCharacterIterator() method returns. + * + *

      There is no public constructor to this class, the only instances are the + * constants defined here. + *

      + * @stable ICU 3.8 + */ + public static class Field extends Format.Field { + + private static final long serialVersionUID = -3627456821000730829L; + + // Max number of calendar fields + private static final int CAL_FIELD_COUNT; + + // Table for mapping calendar field number to DateFormat.Field + private static final Field[] CAL_FIELDS; + + // Map for resolving DateFormat.Field by name + private static final Map FIELD_NAME_MAP; + + static { + Calendar cal = Calendar.getInstance(); + CAL_FIELD_COUNT = cal.getFieldCount(); + CAL_FIELDS = new Field[CAL_FIELD_COUNT]; + FIELD_NAME_MAP = new HashMap(CAL_FIELD_COUNT); + } + + // Java fields ------------------- + + /** + * Constant identifying the time of day indicator(am/pm). + * @stable ICU 3.8 + */ + public static final Field AM_PM = new Field("am pm", Calendar.AM_PM); + + /** + * Constant identifying the day of month field. + * @stable ICU 3.8 + */ + public static final Field DAY_OF_MONTH = new Field("day of month", Calendar.DAY_OF_MONTH); + + /** + * Constant identifying the day of week field. + * @stable ICU 3.8 + */ + public static final Field DAY_OF_WEEK = new Field("day of week", Calendar.DAY_OF_WEEK); + + /** + * Constant identifying the day of week in month field. + * @stable ICU 3.8 + */ + public static final Field DAY_OF_WEEK_IN_MONTH = + new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH); + + /** + * Constant identifying the day of year field. + * @stable ICU 3.8 + */ + public static final Field DAY_OF_YEAR = new Field("day of year", Calendar.DAY_OF_YEAR); + + /** + * Constant identifying the era field. + * @stable ICU 3.8 + */ + public static final Field ERA = new Field("era", Calendar.ERA); + + /** + * Constant identifying the hour(0-23) of day field. + * @stable ICU 3.8 + */ + public static final Field HOUR_OF_DAY0 = new Field("hour of day", Calendar.HOUR_OF_DAY); + + /** + * Constant identifying the hour(1-24) of day field. + * @stable ICU 3.8 + */ + public static final Field HOUR_OF_DAY1 = new Field("hour of day 1", -1); + + /** + * Constant identifying the hour(0-11) field. + * @stable ICU 3.8 + */ + public static final Field HOUR0 = new Field("hour", Calendar.HOUR); + + /** + * Constant identifying the hour(1-12) field. + * @stable ICU 3.8 + */ + public static final Field HOUR1 = new Field("hour 1", -1); + + /** + * Constant identifying the millisecond field. + * @stable ICU 3.8 + */ + public static final Field MILLISECOND = new Field("millisecond", Calendar.MILLISECOND); + + /** + * Constant identifying the minute field. + * @stable ICU 3.8 + */ + public static final Field MINUTE = new Field("minute", Calendar.MINUTE); + + /** + * Constant identifying the month field. + * @stable ICU 3.8 + */ + public static final Field MONTH = new Field("month", Calendar.MONTH); + + /** + * Constant identifying the second field. + * @stable ICU 3.8 + */ + public static final Field SECOND = new Field("second", Calendar.SECOND); + + /** + * Constant identifying the time zone field. + * @stable ICU 3.8 + */ + public static final Field TIME_ZONE = new Field("time zone", -1); + + /** + * Constant identifying the week of month field. + * @stable ICU 3.8 + */ + public static final Field WEEK_OF_MONTH = + new Field("week of month", Calendar.WEEK_OF_MONTH); + + /** + * Constant identifying the week of year field. + * @stable ICU 3.8 + */ + public static final Field WEEK_OF_YEAR = new Field("week of year", Calendar.WEEK_OF_YEAR); + + /** + * Constant identifying the year field. + * @stable ICU 3.8 + */ + public static final Field YEAR = new Field("year", Calendar.YEAR); + + + // ICU only fields ------------------- + + /** + * Constant identifying the local day of week field. + * @stable ICU 3.8 + */ + public static final Field DOW_LOCAL = new Field("local day of week", Calendar.DOW_LOCAL); + + /** + * Constant identifying the extended year field. + * @stable ICU 3.8 + */ + public static final Field EXTENDED_YEAR = new Field("extended year", + Calendar.EXTENDED_YEAR); + + /** + * Constant identifying the Julian day field. + * @stable ICU 3.8 + */ + public static final Field JULIAN_DAY = new Field("Julian day", Calendar.JULIAN_DAY); + + /** + * Constant identifying the milliseconds in day field. + * @stable ICU 3.8 + */ + public static final Field MILLISECONDS_IN_DAY = + new Field("milliseconds in day", Calendar.MILLISECONDS_IN_DAY); + + /** + * Constant identifying the year used with week of year field. + * @stable ICU 3.8 + */ + public static final Field YEAR_WOY = new Field("year for week of year", Calendar.YEAR_WOY); + + /** + * Constant identifying the quarter field. + * @stable ICU 3.8 + */ + public static final Field QUARTER = new Field("quarter", -1); + + // Stand alone types are variants for its base types. So we do not define Field for + // them. + /* + public static final Field STANDALONE_DAY = + new Field("stand alone day of week", Calendar.DAY_OF_WEEK); + public static final Field STANDALONE_MONTH = new Field("stand alone month", Calendar.MONTH); + public static final Field STANDALONE_QUARTER = new Field("stand alone quarter", -1); + */ + + // Corresponding calendar field + private final int calendarField; + + /** + * Constructs a DateFormat.Field with the given name and + * the Calendar field which this attribute represents. Use -1 for + * calendarField if this field does not have a corresponding + * Calendar field. + * + * @param name Name of the attribute + * @param calendarField Calendar field constant + * + * @stable ICU 3.8 + */ + protected Field(String name, int calendarField) { + super(name); + this.calendarField = calendarField; + if (this.getClass() == DateFormat.Field.class) { + FIELD_NAME_MAP.put(name, this); + if (calendarField >= 0 && calendarField < CAL_FIELD_COUNT) { + CAL_FIELDS[calendarField] = this; + } + } + } + + /** + * Returns the Field constant that corresponds to the + * Calendar field calendarField. If there is no + * corresponding Field is available, null is returned. + * + * @param calendarField Calendar field constant + * @return Field associated with the calendarField, + * or null if no associated Field is available. + * @throws IllegalArgumentException if calendarField is not + * a valid Calendar field constant. + * + * @stable ICU 3.8 + */ + public static DateFormat.Field ofCalendarField(int calendarField) { + if (calendarField < 0 || calendarField >= CAL_FIELD_COUNT) { + throw new IllegalArgumentException("Calendar field number is out of range"); + } + return CAL_FIELDS[calendarField]; + } + + /** + * Returns the Calendar field associated with this attribute. + * If there is no corresponding Calendar available, this will + * return -1. + * + * @return Calendar constant for this attribute. + * + * @stable ICU 3.8 + */ + public int getCalendarField() { + return calendarField; + } + + /** + * Resolves instances being deserialized to the predefined constants. + * + * @throws InvalidObjectException if the constant could not be resolved. + * + * @stable ICU 3.8 + */ + protected Object readResolve() throws InvalidObjectException { + ///CLOVER:OFF + if (this.getClass() != DateFormat.Field.class) { + throw new InvalidObjectException( + "A subclass of DateFormat.Field must implement readResolve."); + } + ///CLOVER:ON + Object o = FIELD_NAME_MAP.get(this.getName()); + ///CLOVER:OFF + if (o == null) { + throw new InvalidObjectException("Unknown attribute name."); + } + ///CLOVER:ON + return o; + } + } + + private static int getJDKFormatStyle(int icuFormatStyle) { + switch (icuFormatStyle) { + case DateFormat.FULL: + return java.text.DateFormat.FULL; + case DateFormat.LONG: + return java.text.DateFormat.LONG; + case DateFormat.MEDIUM: + return java.text.DateFormat.MEDIUM; + case DateFormat.SHORT: + return java.text.DateFormat.SHORT; + default: + throw new UnsupportedOperationException("Style not supported by com.ibm.icu.base"); + } + } + + + protected static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { + if (icuPos == null) { + return null; + } + + int fieldID = icuPos.getField(); + Format.Field fieldAttribute = icuPos.getFieldAttribute(); + + FieldPosition jdkPos = null; + + if (fieldID >= 0) { + switch (fieldID) { + case ERA_FIELD: + fieldID = java.text.DateFormat.ERA_FIELD; + break; + case YEAR_FIELD: + fieldID = java.text.DateFormat.YEAR_FIELD; + break; + case MONTH_FIELD: + fieldID = java.text.DateFormat.MONTH_FIELD; + break; + case DATE_FIELD: + fieldID = java.text.DateFormat.DATE_FIELD; + break; + case HOUR_OF_DAY1_FIELD: + fieldID = java.text.DateFormat.HOUR_OF_DAY1_FIELD; + break; + case HOUR_OF_DAY0_FIELD: + fieldID = java.text.DateFormat.HOUR_OF_DAY0_FIELD; + break; + case MINUTE_FIELD: + fieldID = java.text.DateFormat.MINUTE_FIELD; + break; + case SECOND_FIELD: + fieldID = java.text.DateFormat.SECOND_FIELD; + break; + case FRACTIONAL_SECOND_FIELD: // MILLISECOND_FIELD + fieldID = java.text.DateFormat.MILLISECOND_FIELD; + break; + case DAY_OF_WEEK_FIELD: + fieldID = java.text.DateFormat.DAY_OF_WEEK_FIELD; + break; + case DAY_OF_YEAR_FIELD: + fieldID = java.text.DateFormat.DAY_OF_YEAR_FIELD; + break; + case DAY_OF_WEEK_IN_MONTH_FIELD: + fieldID = java.text.DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD; + break; + case WEEK_OF_YEAR_FIELD: + fieldID = java.text.DateFormat.WEEK_OF_YEAR_FIELD; + break; + case WEEK_OF_MONTH_FIELD: + fieldID = java.text.DateFormat.WEEK_OF_MONTH_FIELD; + break; + case AM_PM_FIELD: + fieldID = java.text.DateFormat.AM_PM_FIELD; + break; + case HOUR1_FIELD: + fieldID = java.text.DateFormat.HOUR1_FIELD; + break; + case HOUR0_FIELD: + fieldID = java.text.DateFormat.HOUR0_FIELD; + break; + case TIMEZONE_FIELD: + fieldID = java.text.DateFormat.TIMEZONE_FIELD; + break; + + case YEAR_WOY_FIELD: + case DOW_LOCAL_FIELD: + case EXTENDED_YEAR_FIELD: + case JULIAN_DAY_FIELD: + case MILLISECONDS_IN_DAY_FIELD: + case TIMEZONE_RFC_FIELD: + case TIMEZONE_GENERIC_FIELD: + case STANDALONE_DAY_FIELD: + case STANDALONE_MONTH_FIELD: + case QUARTER_FIELD: + case STANDALONE_QUARTER_FIELD: + case TIMEZONE_SPECIAL_FIELD: + throw new UnsupportedOperationException("Format Field ID not supported by com.ibm.icu.base"); + + default: + // just let it go + break; + } + } + + if (fieldAttribute != null) { + // map field + if (fieldAttribute.equals(Field.AM_PM)) { + fieldAttribute = java.text.DateFormat.Field.AM_PM; + } else if (fieldAttribute.equals(Field.DAY_OF_MONTH)) { + fieldAttribute = java.text.DateFormat.Field.DAY_OF_MONTH; + } else if (fieldAttribute.equals(Field.DAY_OF_WEEK)) { + fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK; + } else if (fieldAttribute.equals(Field.DAY_OF_WEEK_IN_MONTH)) { + fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH; + } else if (fieldAttribute.equals(Field.DAY_OF_YEAR)) { + fieldAttribute = java.text.DateFormat.Field.DAY_OF_YEAR; + } else if (fieldAttribute.equals(Field.ERA)) { + fieldAttribute = java.text.DateFormat.Field.ERA; + } else if (fieldAttribute.equals(Field.HOUR_OF_DAY0)) { + fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY0; + } else if (fieldAttribute.equals(Field.HOUR_OF_DAY1)) { + fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY1; + } else if (fieldAttribute.equals(Field.HOUR0)) { + fieldAttribute = java.text.DateFormat.Field.HOUR0; + } else if (fieldAttribute.equals(Field.HOUR1)) { + fieldAttribute = java.text.DateFormat.Field.HOUR1; + } else if (fieldAttribute.equals(Field.MILLISECOND)) { + fieldAttribute = java.text.DateFormat.Field.MILLISECOND; + } else if (fieldAttribute.equals(Field.MINUTE)) { + fieldAttribute = java.text.DateFormat.Field.MINUTE; + } else if (fieldAttribute.equals(Field.MONTH)) { + fieldAttribute = java.text.DateFormat.Field.MONTH; + } else if (fieldAttribute.equals(Field.SECOND)) { + fieldAttribute = java.text.DateFormat.Field.SECOND; + } else if (fieldAttribute.equals(Field.TIME_ZONE)) { + fieldAttribute = java.text.DateFormat.Field.TIME_ZONE; + } else if (fieldAttribute.equals(Field.WEEK_OF_MONTH)) { + fieldAttribute = java.text.DateFormat.Field.WEEK_OF_MONTH; + } else if (fieldAttribute.equals(Field.WEEK_OF_YEAR)) { + fieldAttribute = java.text.DateFormat.Field.WEEK_OF_YEAR; + } else if (fieldAttribute.equals(Field.YEAR)) { + fieldAttribute = java.text.DateFormat.Field.YEAR; + } else if (fieldAttribute.equals(Field.DOW_LOCAL) + || fieldAttribute.equals(Field.EXTENDED_YEAR) + || fieldAttribute.equals(Field.JULIAN_DAY) + || fieldAttribute.equals(Field.MILLISECONDS_IN_DAY) + || fieldAttribute.equals(Field.YEAR_WOY) + || fieldAttribute.equals(Field.QUARTER)) { + // Not supported + throw new UnsupportedOperationException("Format Field not supported by com.ibm.icu.base"); + } + + jdkPos = new FieldPosition(fieldAttribute, fieldID); + } else { + jdkPos = new FieldPosition(fieldID); + } + + jdkPos.setBeginIndex(icuPos.getBeginIndex()); + jdkPos.setEndIndex(icuPos.getEndIndex()); + + return jdkPos; + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java index ab0f9c95885..7077e4ba689 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java @@ -1,840 +1,840 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.text; - -import java.io.Serializable; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.ULocale; - -/** - * {@icuenhanced java.text.DateFormatSymbols}.{@icu _usage_} - * - *

      DateFormatSymbols is a public class for encapsulating - * localizable date-time formatting data, such as the names of the - * months, the names of the days of the week, and the time zone data. - * DateFormat and SimpleDateFormat both use - * DateFormatSymbols to encapsulate this information. - * - *

      Typically you shouldn't use DateFormatSymbols directly. - * Rather, you are encouraged to create a date-time formatter with the - * DateFormat class's factory methods: getTimeInstance, - * getDateInstance, or getDateTimeInstance. - * These methods automatically create a DateFormatSymbols for - * the formatter so that you don't have to. After the - * formatter is created, you may modify its format pattern using the - * setPattern method. For more information about - * creating formatters using DateFormat's factory methods, - * see {@link DateFormat}. - * - *

      If you decide to create a date-time formatter with a specific - * format pattern for a specific locale, you can do so with: - *

      - *
      - * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).
      - * 
      - *
      - * - *

      DateFormatSymbols objects are clonable. When you obtain - * a DateFormatSymbols object, feel free to modify the - * date-time formatting data. For instance, you can replace the localized - * date-time format pattern characters with the ones that you feel easy - * to remember. Or you can change the representative cities - * to your favorite ones. - * - *

      New DateFormatSymbols subclasses may be added to support - * SimpleDateFormat for date-time formatting for additional locales. - * - * @see DateFormat - * @see SimpleDateFormat - * @see com.ibm.icu.util.SimpleTimeZone - * @author Chen-Lieh Huang - * @stable ICU 2.0 - */ -public class DateFormatSymbols implements Serializable, Cloneable { - - private static final long serialVersionUID = 1L; - - /** @internal */ - public java.text.DateFormatSymbols dfs; - - /** @internal */ - public DateFormatSymbols(java.text.DateFormatSymbols delegate) { - this.dfs = delegate; - } - - // TODO make sure local pattern char string is 18 characters long, - // that is, that it encompasses the new 'u' char for - // EXTENDED_YEAR. Two options: 1. Make sure resource data is - // correct; 2. Make code add in 'u' at end if len == 17. - - // Constants for context - /** - * {@icu} Constant for context. - * @stable ICU 3.6 - */ - public static final int FORMAT = 0; - - /** - * {@icu} Constant for context. - * @stable ICU 3.6 - */ - public static final int STANDALONE = 1; - - /** - * {@icu} Constant for context. - * @internal - * @deprecated This API is ICU internal only. - */ - public static final int DT_CONTEXT_COUNT = 2; - - // Constants for width - - /** - * {@icu} Constant for width. - * @stable ICU 3.6 - */ - public static final int ABBREVIATED = 0; - - /** - * {@icu} Constant for width. - * @stable ICU 3.6 - */ - public static final int WIDE = 1; - - /** - * {@icu} Constant for width. - * @stable ICU 3.6 - */ - public static final int NARROW = 2; - - /** - * {@icu} Constant for width. - * @internal - * @deprecated This API is ICU internal only. - */ - public static final int DT_WIDTH_COUNT = 3; - - /** - * Constructs a DateFormatSymbols object by loading format data from - * resources for the default locale. - * - * @throws java.util.MissingResourceException if the resources for the default locale - * cannot be found or cannot be loaded. - * @stable ICU 2.0 - */ - public DateFormatSymbols() - { - this(new java.text.DateFormatSymbols()); - } - - /** - * Constructs a DateFormatSymbols object by loading format data from - * resources for the given locale. - * - * @throws java.util.MissingResourceException if the resources for the specified - * locale cannot be found or cannot be loaded. - * @stable ICU 2.0 - */ - public DateFormatSymbols(Locale locale) - { - this(new java.text.DateFormatSymbols(locale)); - } - - /** - * {@icu} Constructs a DateFormatSymbols object by loading format data from - * resources for the given ulocale. - * - * @throws java.util.MissingResourceException if the resources for the specified - * locale cannot be found or cannot be loaded. - * @stable ICU 3.2 - */ - public DateFormatSymbols(ULocale locale) - { - this(new java.text.DateFormatSymbols(locale.toLocale())); - } - - /** - * Returns a DateFormatSymbols instance for the default locale. - * - * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, - * this method simply returns new com.ibm.icu.text.DateFormatSymbols(). - * ICU does not support DateFormatSymbolsProvider introduced in Java 6 - * or its equivalent implementation for now. - * - * @return A DateFormatSymbols instance. - * @stable ICU 3.8 - */ - public static DateFormatSymbols getInstance() { - return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance()); - } - - /** - * Returns a DateFormatSymbols instance for the given locale. - * - * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, - * this method simply returns new com.ibm.icu.text.DateFormatSymbols(locale). - * ICU does not support DateFormatSymbolsProvider introduced in Java 6 - * or its equivalent implementation for now. - * - * @param locale the locale. - * @return A DateFormatSymbols instance. - * @stable ICU 3.8 - */ - public static DateFormatSymbols getInstance(Locale locale) { - return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance(locale)); - } - - /** - * {@icu} Returns a DateFormatSymbols instance for the given locale. - * - * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, - * this method simply returns new com.ibm.icu.text.DateFormatSymbols(locale). - * ICU does not support DateFormatSymbolsProvider introduced in Java 6 - * or its equivalent implementation for now. - * - * @param locale the locale. - * @return A DateFormatSymbols instance. - * @stable ICU 3.8 - */ - public static DateFormatSymbols getInstance(ULocale locale) { - return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance(locale.toLocale())); - } - - /** - * Returns an array of all locales for which the getInstance methods of - * this class can return localized instances. - * - * {@icunote} Unlike java.text.DateFormatSymbols#getAvailableLocales, - * this method simply returns the array of Locales available in this - * class. ICU does not support DateFormatSymbolsProvider introduced in - * Java 6 or its equivalent implementation for now. - * - * @return An array of Locales for which localized - * DateFormatSymbols instances are available. - * @stable ICU 3.8 - */ - public static Locale[] getAvailableLocales() { - return java.text.DateFormatSymbols.getAvailableLocales(); - } - - /** - * {@icu} Returns an array of all locales for which the getInstance - * methods of this class can return localized instances. - * - * {@icunote} Unlike java.text.DateFormatSymbols#getAvailableLocales, - * this method simply returns the array of ULocales available in this - * class. ICU does not support DateFormatSymbolsProvider introduced in - * Java 6 or its equivalent implementation for now. - * - * @return An array of ULocales for which localized - * DateFormatSymbols instances are available. - * @draft ICU 3.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static ULocale[] getAvailableULocales() { - Locale[] locales = java.text.DateFormatSymbols.getAvailableLocales(); - ULocale[] ulocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; ++i) { - ulocales[i] = ULocale.forLocale(locales[i]); - } - return ulocales; - } - - /** - * Returns era strings. For example: "AD" and "BC". - * @return the era strings. - * @stable ICU 2.0 - */ - public String[] getEras() { - return dfs.getEras(); - } - - /** - * Sets era strings. For example: "AD" and "BC". - * @param newEras the new era strings. - * @stable ICU 2.0 - */ - public void setEras(String[] newEras) { - dfs.setEras(newEras); - } - - /** - * {@icu} Returns era name strings. For example: "Anno Domini" and "Before Christ". - * @return the era strings. - * @stable ICU 3.4 - */ - public String[] getEraNames() { - return getEras(); // Java has no distinction between era strings and era name strings - } - - /** - * {@icu} Sets era name strings. For example: "Anno Domini" and "Before Christ". - * @param newEraNames the new era strings. - * @stable ICU 3.8 - */ - public void setEraNames(String[] newEraNames) { - setEras(newEraNames); // Java has no distinction between era strings and era name strings - } - - /** - * Returns month strings. For example: "January", "February", etc. - * @return the month strings. - * @stable ICU 2.0 - */ - public String[] getMonths() { - return dfs.getMonths(); - } - - /** - * Returns month strings. For example: "January", "February", etc. - * @param context The month context, FORMAT or STANDALONE. - * @param width The width or the returned month string, - * either WIDE, ABBREVIATED, or NARROW. - * @return the month strings. - * @stable ICU 3.4 - */ - public String[] getMonths(int context, int width) { - // JDK does not support context / narrow months - switch (width) { - case WIDE: - return dfs.getMonths(); - - case ABBREVIATED: - case NARROW: - return dfs.getShortMonths(); - - default: - throw new IllegalArgumentException("Unsupported width argument value"); - } - } - - /** - * Sets month strings. For example: "January", "February", etc. - * @param newMonths the new month strings. - * @stable ICU 2.0 - */ - public void setMonths(String[] newMonths) { - dfs.setMonths(newMonths); - } - - /** - * Sets month strings. For example: "January", "February", etc. - * @param newMonths the new month strings. - * @param context The formatting context, FORMAT or STANDALONE. - * @param width The width of the month string, - * either WIDE, ABBREVIATED, or NARROW. - * @stable ICU 3.8 - */ - public void setMonths(String[] newMonths, int context, int width) { - // JDK does not support context / narrow months - switch (width) { - case WIDE: - dfs.setMonths(newMonths); - break; - - case ABBREVIATED: - case NARROW: - dfs.setShortMonths(newMonths); - break; - - default: - throw new IllegalArgumentException("Unsupported width argument value"); - } - } - - /** - * Returns short month strings. For example: "Jan", "Feb", etc. - * @return the short month strings. - * @stable ICU 2.0 - */ - public String[] getShortMonths() { - return dfs.getShortMonths(); - } - - /** - * Sets short month strings. For example: "Jan", "Feb", etc. - * @param newShortMonths the new short month strings. - * @stable ICU 2.0 - */ - public void setShortMonths(String[] newShortMonths) { - dfs.setShortMonths(newShortMonths); - } - - /** - * Returns weekday strings. For example: "Sunday", "Monday", etc. - * @return the weekday strings. Use Calendar.SUNDAY, - * Calendar.MONDAY, etc. to index the result array. - * @stable ICU 2.0 - */ - public String[] getWeekdays() { - return dfs.getWeekdays(); - } - - /** - * Returns weekday strings. For example: "Sunday", "Monday", etc. - * @return the weekday strings. Use Calendar.SUNDAY, - * Calendar.MONDAY, etc. to index the result array. - * @param context Formatting context, either FORMAT or STANDALONE. - * @param width Width of strings to be returned, either - * WIDE, ABBREVIATED, or NARROW - * @stable ICU 3.4 - */ - public String[] getWeekdays(int context, int width) { - // JDK does not support context / narrow weekdays - switch (width) { - case WIDE: - return dfs.getWeekdays(); - - case ABBREVIATED: - case NARROW: - return dfs.getShortWeekdays(); - - default: - throw new IllegalArgumentException("Unsupported width argument value"); - } - } - - /** - * Sets weekday strings. For example: "Sunday", "Monday", etc. - * @param newWeekdays The new weekday strings. - * @param context The formatting context, FORMAT or STANDALONE. - * @param width The width of the strings, - * either WIDE, ABBREVIATED, or NARROW. - * @stable ICU 3.8 - */ - public void setWeekdays(String[] newWeekdays, int context, int width) { - // JDK does not support context / narrow weekdays - switch (width) { - case WIDE: - dfs.setWeekdays(newWeekdays); - break; - - case ABBREVIATED: - case NARROW: - dfs.setShortWeekdays(newWeekdays); - break; - - default: - throw new IllegalArgumentException("Unsupported width argument value"); - } - } - - /** - * Sets weekday strings. For example: "Sunday", "Monday", etc. - * @param newWeekdays the new weekday strings. The array should - * be indexed by Calendar.SUNDAY, - * Calendar.MONDAY, etc. - * @stable ICU 2.0 - */ - public void setWeekdays(String[] newWeekdays) { - dfs.setWeekdays(newWeekdays); - } - - /** - * Returns short weekday strings. For example: "Sun", "Mon", etc. - * @return the short weekday strings. Use Calendar.SUNDAY, - * Calendar.MONDAY, etc. to index the result array. - * @stable ICU 2.0 - */ - public String[] getShortWeekdays() { - return dfs.getShortWeekdays(); - } - - /** - * Sets short weekday strings. For example: "Sun", "Mon", etc. - * @param newShortWeekdays the new short weekday strings. The array should - * be indexed by Calendar.SUNDAY, - * Calendar.MONDAY, etc. - * @stable ICU 2.0 - */ - public void setShortWeekdays(String[] newShortWeekdays) { - dfs.setShortWeekdays(newShortWeekdays); - } - /** - * {@icu} Returns quarter strings. For example: "1st Quarter", "2nd Quarter", etc. - * @param context The quarter context, FORMAT or STANDALONE. - * @param width The width or the returned quarter string, - * either WIDE or ABBREVIATED. There are no NARROW quarters. - * @return the quarter strings. - * @stable ICU 3.6 - */ - public String[] getQuarters(int context, int width) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets quarter strings. For example: "1st Quarter", "2nd Quarter", etc. - * @param newQuarters the new quarter strings. - * @param context The formatting context, FORMAT or STANDALONE. - * @param width The width of the quarter string, - * either WIDE or ABBREVIATED. There are no NARROW quarters. - * @stable ICU 3.8 - */ - public void setQuarters(String[] newQuarters, int context, int width) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns am/pm strings. For example: "AM" and "PM". - * @return the weekday strings. - * @stable ICU 2.0 - */ - public String[] getAmPmStrings() { - return dfs.getAmPmStrings(); - } - - /** - * Sets am/pm strings. For example: "AM" and "PM". - * @param newAmpms the new ampm strings. - * @stable ICU 2.0 - */ - public void setAmPmStrings(String[] newAmpms) { - dfs.setAmPmStrings(newAmpms); - } - - /** - * Returns timezone strings. - * @return the timezone strings. - * @stable ICU 2.0 - */ - public String[][] getZoneStrings() { - return dfs.getZoneStrings(); - } - - /** - * Sets timezone strings. - * @param newZoneStrings the new timezone strings. - * @stable ICU 2.0 - */ - public void setZoneStrings(String[][] newZoneStrings) { - dfs.setZoneStrings(newZoneStrings); - } - - /** - * Returns localized date-time pattern characters. For example: 'u', 't', etc. - * - *

      Note: ICU no longer provides localized date-time pattern characters for a locale - * starting ICU 3.8. This method returns the non-localized date-time pattern - * characters unless user defined localized data is set by setLocalPatternChars. - * @return the localized date-time pattern characters. - * @stable ICU 2.0 - */ - public String getLocalPatternChars() { - return dfs.getLocalPatternChars(); - } - - /** - * Sets localized date-time pattern characters. For example: 'u', 't', etc. - * @param newLocalPatternChars the new localized date-time - * pattern characters. - * @stable ICU 2.0 - */ - public void setLocalPatternChars(String newLocalPatternChars) { - dfs.setLocalPatternChars(newLocalPatternChars); - } - - /** - * Overrides clone. - * @stable ICU 2.0 - */ - public Object clone() - { - return new DateFormatSymbols((java.text.DateFormatSymbols)dfs.clone()); - } - - /** - * Override hashCode. - * Generates a hash code for the DateFormatSymbols object. - * @stable ICU 2.0 - */ - public int hashCode() { - return dfs.hashCode(); - } - - /** - * Overrides equals. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) - { - try { - return dfs.equals(((DateFormatSymbols)obj).dfs); - } - catch (Exception e) { - return false; - } - } - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Returns the {@link DateFormatSymbols} object that should be used to format a - * calendar system's dates in the given locale. - *

      - * Subclassing:
      - * When creating a new Calendar subclass, you must create the - * {@link ResourceBundle ResourceBundle} - * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place. - * The resource bundle name is based on the calendar's fully-specified - * class name, with ".resources" inserted at the end of the package name - * (just before the class name) and "Symbols" appended to the end. - * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" - * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". - *

      - * Within the ResourceBundle, this method searches for five keys: - *

        - *
      • DayNames - - * An array of strings corresponding to each possible - * value of the DAY_OF_WEEK field. Even though - * DAY_OF_WEEK starts with SUNDAY = 1, - * This array is 0-based; the name for Sunday goes in the - * first position, at index 0. If this key is not found - * in the bundle, the day names are inherited from the - * default DateFormatSymbols for the requested locale. - * - *
      • DayAbbreviations - - * An array of abbreviated day names corresponding - * to the values in the "DayNames" array. If this key - * is not found in the resource bundle, the "DayNames" - * values are used instead. If neither key is found, - * the day abbreviations are inherited from the default - * DateFormatSymbols for the locale. - * - *
      • MonthNames - - * An array of strings corresponding to each possible - * value of the MONTH field. If this key is not found - * in the bundle, the month names are inherited from the - * default DateFormatSymbols for the requested locale. - * - *
      • MonthAbbreviations - - * An array of abbreviated day names corresponding - * to the values in the "MonthNames" array. If this key - * is not found in the resource bundle, the "MonthNames" - * values are used instead. If neither key is found, - * the day abbreviations are inherited from the default - * DateFormatSymbols for the locale. - * - *
      • Eras - - * An array of strings corresponding to each possible - * value of the ERA field. If this key is not found - * in the bundle, the era names are inherited from the - * default DateFormatSymbols for the requested locale. - *
      - *

      - * @param cal The calendar system whose date format symbols are desired. - * @param locale The locale whose symbols are desired. - * - * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) - * @stable ICU 2.0 - */ - public DateFormatSymbols(Calendar cal, Locale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Returns the {@link DateFormatSymbols} object that should be used to format a - * calendar system's dates in the given locale. - *

      - * Subclassing:
      - * When creating a new Calendar subclass, you must create the - * {@link ResourceBundle ResourceBundle} - * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place. - * The resource bundle name is based on the calendar's fully-specified - * class name, with ".resources" inserted at the end of the package name - * (just before the class name) and "Symbols" appended to the end. - * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" - * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". - *

      - * Within the ResourceBundle, this method searches for five keys: - *

        - *
      • DayNames - - * An array of strings corresponding to each possible - * value of the DAY_OF_WEEK field. Even though - * DAY_OF_WEEK starts with SUNDAY = 1, - * This array is 0-based; the name for Sunday goes in the - * first position, at index 0. If this key is not found - * in the bundle, the day names are inherited from the - * default DateFormatSymbols for the requested locale. - * - *
      • DayAbbreviations - - * An array of abbreviated day names corresponding - * to the values in the "DayNames" array. If this key - * is not found in the resource bundle, the "DayNames" - * values are used instead. If neither key is found, - * the day abbreviations are inherited from the default - * DateFormatSymbols for the locale. - * - *
      • MonthNames - - * An array of strings corresponding to each possible - * value of the MONTH field. If this key is not found - * in the bundle, the month names are inherited from the - * default DateFormatSymbols for the requested locale. - * - *
      • MonthAbbreviations - - * An array of abbreviated day names corresponding - * to the values in the "MonthNames" array. If this key - * is not found in the resource bundle, the "MonthNames" - * values are used instead. If neither key is found, - * the day abbreviations are inherited from the default - * DateFormatSymbols for the locale. - * - *
      • Eras - - * An array of strings corresponding to each possible - * value of the ERA field. If this key is not found - * in the bundle, the era names are inherited from the - * default DateFormatSymbols for the requested locale. - *
      - *

      - * @param cal The calendar system whose date format symbols are desired. - * @param locale The ulocale whose symbols are desired. - * - * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) - * @stable ICU 3.2 - */ - public DateFormatSymbols(Calendar cal, ULocale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Variant of DateFormatSymbols(Calendar, Locale) that takes the Calendar class - * instead of a Calandar instance. - * @see #DateFormatSymbols(Calendar, Locale) - * @stable ICU 2.2 - */ - public DateFormatSymbols(Class calendarClass, Locale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Variant of DateFormatSymbols(Calendar, ULocale) that takes the Calendar class - * instead of a Calandar instance. - * @see #DateFormatSymbols(Calendar, Locale) - * @stable ICU 3.2 - */ - public DateFormatSymbols(Class calendarClass, ULocale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Fetches a custom calendar's DateFormatSymbols out of the given resource - * bundle. Symbols that are not overridden are inherited from the - * default DateFormatSymbols for the locale. - * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) - * @stable ICU 2.0 - */ - public DateFormatSymbols(ResourceBundle bundle, Locale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Fetches a custom calendar's DateFormatSymbols out of the given resource - * bundle. Symbols that are not overridden are inherited from the - * default DateFormatSymbols for the locale. - * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) - * @stable ICU 3.2 - */ - public DateFormatSymbols(ResourceBundle bundle, ULocale locale) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Finds the ResourceBundle containing the date format information for - * a specified calendar subclass in a given locale. - *

      - * The resource bundle name is based on the calendar's fully-specified - * class name, with ".resources" inserted at the end of the package name - * (just before the class name) and "Symbols" appended to the end. - * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" - * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". - *

      - * Note:Because of the structural changes in the ICU locale bundle, - * this API no longer works as described. This method always returns null. - * @deprecated ICU 4.0 - */ - // This API was formerly @stable ICU 2.0 - static public ResourceBundle getDateFormatBundle(Class calendarClass, - Locale locale) throws MissingResourceException { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } - - /** - * Finds the ResourceBundle containing the date format information for - * a specified calendar subclass in a given locale. - *

      - * The resource bundle name is based on the calendar's fully-specified - * class name, with ".resources" inserted at the end of the package name - * (just before the class name) and "Symbols" appended to the end. - * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" - * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". - *

      - * Note:Because of the structural changes in the ICU locale bundle, - * this API no longer works as described. This method always returns null. - * @deprecated ICU 4.0 - */ - // This API was formerly @stable ICU 3.2 - static public ResourceBundle getDateFormatBundle(Class calendarClass, - ULocale locale) throws MissingResourceException { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } - - /** - * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes - * a Calendar instance instead of a Calendar class. - *

      - * Note:Because of the structural changes in the ICU locale bundle, - * this API no longer works as described. This method always returns null. - * @see #getDateFormatBundle(java.lang.Class, java.util.Locale) - * @deprecated ICU 4.0 - */ - // This API was formerly @stable ICU 2.2 - public static ResourceBundle getDateFormatBundle(Calendar cal, Locale locale) throws MissingResourceException { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } - - /** - * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes - * a Calendar instance instead of a Calendar class. - *

      - * Note:Because of the structural changes in the ICU locale bundle, - * this API no longer works as described. This method always returns null. - * @see #getDateFormatBundle(java.lang.Class, java.util.Locale) - * @deprecated ICU 4.0 - */ - // This API was formerly @stable ICU 3.2 - public static ResourceBundle getDateFormatBundle(Calendar cal, ULocale locale) throws MissingResourceException { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } - - /** - * Returns the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 - * contains a partial preview implementation. The * actual - * locale is returned correctly, but the valid locale is - * not, in most cases. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } -} +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.text; + +import java.io.Serializable; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.ULocale; + +/** + * {@icuenhanced java.text.DateFormatSymbols}.{@icu _usage_} + * + *

      DateFormatSymbols is a public class for encapsulating + * localizable date-time formatting data, such as the names of the + * months, the names of the days of the week, and the time zone data. + * DateFormat and SimpleDateFormat both use + * DateFormatSymbols to encapsulate this information. + * + *

      Typically you shouldn't use DateFormatSymbols directly. + * Rather, you are encouraged to create a date-time formatter with the + * DateFormat class's factory methods: getTimeInstance, + * getDateInstance, or getDateTimeInstance. + * These methods automatically create a DateFormatSymbols for + * the formatter so that you don't have to. After the + * formatter is created, you may modify its format pattern using the + * setPattern method. For more information about + * creating formatters using DateFormat's factory methods, + * see {@link DateFormat}. + * + *

      If you decide to create a date-time formatter with a specific + * format pattern for a specific locale, you can do so with: + *

      + *
      + * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).
      + * 
      + *
      + * + *

      DateFormatSymbols objects are clonable. When you obtain + * a DateFormatSymbols object, feel free to modify the + * date-time formatting data. For instance, you can replace the localized + * date-time format pattern characters with the ones that you feel easy + * to remember. Or you can change the representative cities + * to your favorite ones. + * + *

      New DateFormatSymbols subclasses may be added to support + * SimpleDateFormat for date-time formatting for additional locales. + * + * @see DateFormat + * @see SimpleDateFormat + * @see com.ibm.icu.util.SimpleTimeZone + * @author Chen-Lieh Huang + * @stable ICU 2.0 + */ +public class DateFormatSymbols implements Serializable, Cloneable { + + private static final long serialVersionUID = 1L; + + /** @internal */ + public java.text.DateFormatSymbols dfs; + + /** @internal */ + public DateFormatSymbols(java.text.DateFormatSymbols delegate) { + this.dfs = delegate; + } + + // TODO make sure local pattern char string is 18 characters long, + // that is, that it encompasses the new 'u' char for + // EXTENDED_YEAR. Two options: 1. Make sure resource data is + // correct; 2. Make code add in 'u' at end if len == 17. + + // Constants for context + /** + * {@icu} Constant for context. + * @stable ICU 3.6 + */ + public static final int FORMAT = 0; + + /** + * {@icu} Constant for context. + * @stable ICU 3.6 + */ + public static final int STANDALONE = 1; + + /** + * {@icu} Constant for context. + * @internal + * @deprecated This API is ICU internal only. + */ + public static final int DT_CONTEXT_COUNT = 2; + + // Constants for width + + /** + * {@icu} Constant for width. + * @stable ICU 3.6 + */ + public static final int ABBREVIATED = 0; + + /** + * {@icu} Constant for width. + * @stable ICU 3.6 + */ + public static final int WIDE = 1; + + /** + * {@icu} Constant for width. + * @stable ICU 3.6 + */ + public static final int NARROW = 2; + + /** + * {@icu} Constant for width. + * @internal + * @deprecated This API is ICU internal only. + */ + public static final int DT_WIDTH_COUNT = 3; + + /** + * Constructs a DateFormatSymbols object by loading format data from + * resources for the default locale. + * + * @throws java.util.MissingResourceException if the resources for the default locale + * cannot be found or cannot be loaded. + * @stable ICU 2.0 + */ + public DateFormatSymbols() + { + this(new java.text.DateFormatSymbols()); + } + + /** + * Constructs a DateFormatSymbols object by loading format data from + * resources for the given locale. + * + * @throws java.util.MissingResourceException if the resources for the specified + * locale cannot be found or cannot be loaded. + * @stable ICU 2.0 + */ + public DateFormatSymbols(Locale locale) + { + this(new java.text.DateFormatSymbols(locale)); + } + + /** + * {@icu} Constructs a DateFormatSymbols object by loading format data from + * resources for the given ulocale. + * + * @throws java.util.MissingResourceException if the resources for the specified + * locale cannot be found or cannot be loaded. + * @stable ICU 3.2 + */ + public DateFormatSymbols(ULocale locale) + { + this(new java.text.DateFormatSymbols(locale.toLocale())); + } + + /** + * Returns a DateFormatSymbols instance for the default locale. + * + * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, + * this method simply returns new com.ibm.icu.text.DateFormatSymbols(). + * ICU does not support DateFormatSymbolsProvider introduced in Java 6 + * or its equivalent implementation for now. + * + * @return A DateFormatSymbols instance. + * @stable ICU 3.8 + */ + public static DateFormatSymbols getInstance() { + return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance()); + } + + /** + * Returns a DateFormatSymbols instance for the given locale. + * + * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, + * this method simply returns new com.ibm.icu.text.DateFormatSymbols(locale). + * ICU does not support DateFormatSymbolsProvider introduced in Java 6 + * or its equivalent implementation for now. + * + * @param locale the locale. + * @return A DateFormatSymbols instance. + * @stable ICU 3.8 + */ + public static DateFormatSymbols getInstance(Locale locale) { + return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance(locale)); + } + + /** + * {@icu} Returns a DateFormatSymbols instance for the given locale. + * + * {@icunote} Unlike java.text.DateFormatSymbols#getInstance, + * this method simply returns new com.ibm.icu.text.DateFormatSymbols(locale). + * ICU does not support DateFormatSymbolsProvider introduced in Java 6 + * or its equivalent implementation for now. + * + * @param locale the locale. + * @return A DateFormatSymbols instance. + * @stable ICU 3.8 + */ + public static DateFormatSymbols getInstance(ULocale locale) { + return new DateFormatSymbols(java.text.DateFormatSymbols.getInstance(locale.toLocale())); + } + + /** + * Returns an array of all locales for which the getInstance methods of + * this class can return localized instances. + * + * {@icunote} Unlike java.text.DateFormatSymbols#getAvailableLocales, + * this method simply returns the array of Locales available in this + * class. ICU does not support DateFormatSymbolsProvider introduced in + * Java 6 or its equivalent implementation for now. + * + * @return An array of Locales for which localized + * DateFormatSymbols instances are available. + * @stable ICU 3.8 + */ + public static Locale[] getAvailableLocales() { + return java.text.DateFormatSymbols.getAvailableLocales(); + } + + /** + * {@icu} Returns an array of all locales for which the getInstance + * methods of this class can return localized instances. + * + * {@icunote} Unlike java.text.DateFormatSymbols#getAvailableLocales, + * this method simply returns the array of ULocales available in this + * class. ICU does not support DateFormatSymbolsProvider introduced in + * Java 6 or its equivalent implementation for now. + * + * @return An array of ULocales for which localized + * DateFormatSymbols instances are available. + * @draft ICU 3.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static ULocale[] getAvailableULocales() { + Locale[] locales = java.text.DateFormatSymbols.getAvailableLocales(); + ULocale[] ulocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + ulocales[i] = ULocale.forLocale(locales[i]); + } + return ulocales; + } + + /** + * Returns era strings. For example: "AD" and "BC". + * @return the era strings. + * @stable ICU 2.0 + */ + public String[] getEras() { + return dfs.getEras(); + } + + /** + * Sets era strings. For example: "AD" and "BC". + * @param newEras the new era strings. + * @stable ICU 2.0 + */ + public void setEras(String[] newEras) { + dfs.setEras(newEras); + } + + /** + * {@icu} Returns era name strings. For example: "Anno Domini" and "Before Christ". + * @return the era strings. + * @stable ICU 3.4 + */ + public String[] getEraNames() { + return getEras(); // Java has no distinction between era strings and era name strings + } + + /** + * {@icu} Sets era name strings. For example: "Anno Domini" and "Before Christ". + * @param newEraNames the new era strings. + * @stable ICU 3.8 + */ + public void setEraNames(String[] newEraNames) { + setEras(newEraNames); // Java has no distinction between era strings and era name strings + } + + /** + * Returns month strings. For example: "January", "February", etc. + * @return the month strings. + * @stable ICU 2.0 + */ + public String[] getMonths() { + return dfs.getMonths(); + } + + /** + * Returns month strings. For example: "January", "February", etc. + * @param context The month context, FORMAT or STANDALONE. + * @param width The width or the returned month string, + * either WIDE, ABBREVIATED, or NARROW. + * @return the month strings. + * @stable ICU 3.4 + */ + public String[] getMonths(int context, int width) { + // JDK does not support context / narrow months + switch (width) { + case WIDE: + return dfs.getMonths(); + + case ABBREVIATED: + case NARROW: + return dfs.getShortMonths(); + + default: + throw new IllegalArgumentException("Unsupported width argument value"); + } + } + + /** + * Sets month strings. For example: "January", "February", etc. + * @param newMonths the new month strings. + * @stable ICU 2.0 + */ + public void setMonths(String[] newMonths) { + dfs.setMonths(newMonths); + } + + /** + * Sets month strings. For example: "January", "February", etc. + * @param newMonths the new month strings. + * @param context The formatting context, FORMAT or STANDALONE. + * @param width The width of the month string, + * either WIDE, ABBREVIATED, or NARROW. + * @stable ICU 3.8 + */ + public void setMonths(String[] newMonths, int context, int width) { + // JDK does not support context / narrow months + switch (width) { + case WIDE: + dfs.setMonths(newMonths); + break; + + case ABBREVIATED: + case NARROW: + dfs.setShortMonths(newMonths); + break; + + default: + throw new IllegalArgumentException("Unsupported width argument value"); + } + } + + /** + * Returns short month strings. For example: "Jan", "Feb", etc. + * @return the short month strings. + * @stable ICU 2.0 + */ + public String[] getShortMonths() { + return dfs.getShortMonths(); + } + + /** + * Sets short month strings. For example: "Jan", "Feb", etc. + * @param newShortMonths the new short month strings. + * @stable ICU 2.0 + */ + public void setShortMonths(String[] newShortMonths) { + dfs.setShortMonths(newShortMonths); + } + + /** + * Returns weekday strings. For example: "Sunday", "Monday", etc. + * @return the weekday strings. Use Calendar.SUNDAY, + * Calendar.MONDAY, etc. to index the result array. + * @stable ICU 2.0 + */ + public String[] getWeekdays() { + return dfs.getWeekdays(); + } + + /** + * Returns weekday strings. For example: "Sunday", "Monday", etc. + * @return the weekday strings. Use Calendar.SUNDAY, + * Calendar.MONDAY, etc. to index the result array. + * @param context Formatting context, either FORMAT or STANDALONE. + * @param width Width of strings to be returned, either + * WIDE, ABBREVIATED, or NARROW + * @stable ICU 3.4 + */ + public String[] getWeekdays(int context, int width) { + // JDK does not support context / narrow weekdays + switch (width) { + case WIDE: + return dfs.getWeekdays(); + + case ABBREVIATED: + case NARROW: + return dfs.getShortWeekdays(); + + default: + throw new IllegalArgumentException("Unsupported width argument value"); + } + } + + /** + * Sets weekday strings. For example: "Sunday", "Monday", etc. + * @param newWeekdays The new weekday strings. + * @param context The formatting context, FORMAT or STANDALONE. + * @param width The width of the strings, + * either WIDE, ABBREVIATED, or NARROW. + * @stable ICU 3.8 + */ + public void setWeekdays(String[] newWeekdays, int context, int width) { + // JDK does not support context / narrow weekdays + switch (width) { + case WIDE: + dfs.setWeekdays(newWeekdays); + break; + + case ABBREVIATED: + case NARROW: + dfs.setShortWeekdays(newWeekdays); + break; + + default: + throw new IllegalArgumentException("Unsupported width argument value"); + } + } + + /** + * Sets weekday strings. For example: "Sunday", "Monday", etc. + * @param newWeekdays the new weekday strings. The array should + * be indexed by Calendar.SUNDAY, + * Calendar.MONDAY, etc. + * @stable ICU 2.0 + */ + public void setWeekdays(String[] newWeekdays) { + dfs.setWeekdays(newWeekdays); + } + + /** + * Returns short weekday strings. For example: "Sun", "Mon", etc. + * @return the short weekday strings. Use Calendar.SUNDAY, + * Calendar.MONDAY, etc. to index the result array. + * @stable ICU 2.0 + */ + public String[] getShortWeekdays() { + return dfs.getShortWeekdays(); + } + + /** + * Sets short weekday strings. For example: "Sun", "Mon", etc. + * @param newShortWeekdays the new short weekday strings. The array should + * be indexed by Calendar.SUNDAY, + * Calendar.MONDAY, etc. + * @stable ICU 2.0 + */ + public void setShortWeekdays(String[] newShortWeekdays) { + dfs.setShortWeekdays(newShortWeekdays); + } + /** + * {@icu} Returns quarter strings. For example: "1st Quarter", "2nd Quarter", etc. + * @param context The quarter context, FORMAT or STANDALONE. + * @param width The width or the returned quarter string, + * either WIDE or ABBREVIATED. There are no NARROW quarters. + * @return the quarter strings. + * @stable ICU 3.6 + */ + public String[] getQuarters(int context, int width) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets quarter strings. For example: "1st Quarter", "2nd Quarter", etc. + * @param newQuarters the new quarter strings. + * @param context The formatting context, FORMAT or STANDALONE. + * @param width The width of the quarter string, + * either WIDE or ABBREVIATED. There are no NARROW quarters. + * @stable ICU 3.8 + */ + public void setQuarters(String[] newQuarters, int context, int width) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns am/pm strings. For example: "AM" and "PM". + * @return the weekday strings. + * @stable ICU 2.0 + */ + public String[] getAmPmStrings() { + return dfs.getAmPmStrings(); + } + + /** + * Sets am/pm strings. For example: "AM" and "PM". + * @param newAmpms the new ampm strings. + * @stable ICU 2.0 + */ + public void setAmPmStrings(String[] newAmpms) { + dfs.setAmPmStrings(newAmpms); + } + + /** + * Returns timezone strings. + * @return the timezone strings. + * @stable ICU 2.0 + */ + public String[][] getZoneStrings() { + return dfs.getZoneStrings(); + } + + /** + * Sets timezone strings. + * @param newZoneStrings the new timezone strings. + * @stable ICU 2.0 + */ + public void setZoneStrings(String[][] newZoneStrings) { + dfs.setZoneStrings(newZoneStrings); + } + + /** + * Returns localized date-time pattern characters. For example: 'u', 't', etc. + * + *

      Note: ICU no longer provides localized date-time pattern characters for a locale + * starting ICU 3.8. This method returns the non-localized date-time pattern + * characters unless user defined localized data is set by setLocalPatternChars. + * @return the localized date-time pattern characters. + * @stable ICU 2.0 + */ + public String getLocalPatternChars() { + return dfs.getLocalPatternChars(); + } + + /** + * Sets localized date-time pattern characters. For example: 'u', 't', etc. + * @param newLocalPatternChars the new localized date-time + * pattern characters. + * @stable ICU 2.0 + */ + public void setLocalPatternChars(String newLocalPatternChars) { + dfs.setLocalPatternChars(newLocalPatternChars); + } + + /** + * Overrides clone. + * @stable ICU 2.0 + */ + public Object clone() + { + return new DateFormatSymbols((java.text.DateFormatSymbols)dfs.clone()); + } + + /** + * Override hashCode. + * Generates a hash code for the DateFormatSymbols object. + * @stable ICU 2.0 + */ + public int hashCode() { + return dfs.hashCode(); + } + + /** + * Overrides equals. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) + { + try { + return dfs.equals(((DateFormatSymbols)obj).dfs); + } + catch (Exception e) { + return false; + } + } + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Returns the {@link DateFormatSymbols} object that should be used to format a + * calendar system's dates in the given locale. + *

      + * Subclassing:
      + * When creating a new Calendar subclass, you must create the + * {@link ResourceBundle ResourceBundle} + * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place. + * The resource bundle name is based on the calendar's fully-specified + * class name, with ".resources" inserted at the end of the package name + * (just before the class name) and "Symbols" appended to the end. + * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" + * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". + *

      + * Within the ResourceBundle, this method searches for five keys: + *

        + *
      • DayNames - + * An array of strings corresponding to each possible + * value of the DAY_OF_WEEK field. Even though + * DAY_OF_WEEK starts with SUNDAY = 1, + * This array is 0-based; the name for Sunday goes in the + * first position, at index 0. If this key is not found + * in the bundle, the day names are inherited from the + * default DateFormatSymbols for the requested locale. + * + *
      • DayAbbreviations - + * An array of abbreviated day names corresponding + * to the values in the "DayNames" array. If this key + * is not found in the resource bundle, the "DayNames" + * values are used instead. If neither key is found, + * the day abbreviations are inherited from the default + * DateFormatSymbols for the locale. + * + *
      • MonthNames - + * An array of strings corresponding to each possible + * value of the MONTH field. If this key is not found + * in the bundle, the month names are inherited from the + * default DateFormatSymbols for the requested locale. + * + *
      • MonthAbbreviations - + * An array of abbreviated day names corresponding + * to the values in the "MonthNames" array. If this key + * is not found in the resource bundle, the "MonthNames" + * values are used instead. If neither key is found, + * the day abbreviations are inherited from the default + * DateFormatSymbols for the locale. + * + *
      • Eras - + * An array of strings corresponding to each possible + * value of the ERA field. If this key is not found + * in the bundle, the era names are inherited from the + * default DateFormatSymbols for the requested locale. + *
      + *

      + * @param cal The calendar system whose date format symbols are desired. + * @param locale The locale whose symbols are desired. + * + * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) + * @stable ICU 2.0 + */ + public DateFormatSymbols(Calendar cal, Locale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Returns the {@link DateFormatSymbols} object that should be used to format a + * calendar system's dates in the given locale. + *

      + * Subclassing:
      + * When creating a new Calendar subclass, you must create the + * {@link ResourceBundle ResourceBundle} + * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place. + * The resource bundle name is based on the calendar's fully-specified + * class name, with ".resources" inserted at the end of the package name + * (just before the class name) and "Symbols" appended to the end. + * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" + * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". + *

      + * Within the ResourceBundle, this method searches for five keys: + *

        + *
      • DayNames - + * An array of strings corresponding to each possible + * value of the DAY_OF_WEEK field. Even though + * DAY_OF_WEEK starts with SUNDAY = 1, + * This array is 0-based; the name for Sunday goes in the + * first position, at index 0. If this key is not found + * in the bundle, the day names are inherited from the + * default DateFormatSymbols for the requested locale. + * + *
      • DayAbbreviations - + * An array of abbreviated day names corresponding + * to the values in the "DayNames" array. If this key + * is not found in the resource bundle, the "DayNames" + * values are used instead. If neither key is found, + * the day abbreviations are inherited from the default + * DateFormatSymbols for the locale. + * + *
      • MonthNames - + * An array of strings corresponding to each possible + * value of the MONTH field. If this key is not found + * in the bundle, the month names are inherited from the + * default DateFormatSymbols for the requested locale. + * + *
      • MonthAbbreviations - + * An array of abbreviated day names corresponding + * to the values in the "MonthNames" array. If this key + * is not found in the resource bundle, the "MonthNames" + * values are used instead. If neither key is found, + * the day abbreviations are inherited from the default + * DateFormatSymbols for the locale. + * + *
      • Eras - + * An array of strings corresponding to each possible + * value of the ERA field. If this key is not found + * in the bundle, the era names are inherited from the + * default DateFormatSymbols for the requested locale. + *
      + *

      + * @param cal The calendar system whose date format symbols are desired. + * @param locale The ulocale whose symbols are desired. + * + * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) + * @stable ICU 3.2 + */ + public DateFormatSymbols(Calendar cal, ULocale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Variant of DateFormatSymbols(Calendar, Locale) that takes the Calendar class + * instead of a Calandar instance. + * @see #DateFormatSymbols(Calendar, Locale) + * @stable ICU 2.2 + */ + public DateFormatSymbols(Class calendarClass, Locale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Variant of DateFormatSymbols(Calendar, ULocale) that takes the Calendar class + * instead of a Calandar instance. + * @see #DateFormatSymbols(Calendar, Locale) + * @stable ICU 3.2 + */ + public DateFormatSymbols(Class calendarClass, ULocale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Fetches a custom calendar's DateFormatSymbols out of the given resource + * bundle. Symbols that are not overridden are inherited from the + * default DateFormatSymbols for the locale. + * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) + * @stable ICU 2.0 + */ + public DateFormatSymbols(ResourceBundle bundle, Locale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Fetches a custom calendar's DateFormatSymbols out of the given resource + * bundle. Symbols that are not overridden are inherited from the + * default DateFormatSymbols for the locale. + * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale) + * @stable ICU 3.2 + */ + public DateFormatSymbols(ResourceBundle bundle, ULocale locale) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Finds the ResourceBundle containing the date format information for + * a specified calendar subclass in a given locale. + *

      + * The resource bundle name is based on the calendar's fully-specified + * class name, with ".resources" inserted at the end of the package name + * (just before the class name) and "Symbols" appended to the end. + * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" + * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". + *

      + * Note:Because of the structural changes in the ICU locale bundle, + * this API no longer works as described. This method always returns null. + * @deprecated ICU 4.0 + */ + // This API was formerly @stable ICU 2.0 + static public ResourceBundle getDateFormatBundle(Class calendarClass, + Locale locale) throws MissingResourceException { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } + + /** + * Finds the ResourceBundle containing the date format information for + * a specified calendar subclass in a given locale. + *

      + * The resource bundle name is based on the calendar's fully-specified + * class name, with ".resources" inserted at the end of the package name + * (just before the class name) and "Symbols" appended to the end. + * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar" + * is "com.ibm.icu.impl.data.HebrewCalendarSymbols". + *

      + * Note:Because of the structural changes in the ICU locale bundle, + * this API no longer works as described. This method always returns null. + * @deprecated ICU 4.0 + */ + // This API was formerly @stable ICU 3.2 + static public ResourceBundle getDateFormatBundle(Class calendarClass, + ULocale locale) throws MissingResourceException { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } + + /** + * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes + * a Calendar instance instead of a Calendar class. + *

      + * Note:Because of the structural changes in the ICU locale bundle, + * this API no longer works as described. This method always returns null. + * @see #getDateFormatBundle(java.lang.Class, java.util.Locale) + * @deprecated ICU 4.0 + */ + // This API was formerly @stable ICU 2.2 + public static ResourceBundle getDateFormatBundle(Calendar cal, Locale locale) throws MissingResourceException { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } + + /** + * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes + * a Calendar instance instead of a Calendar class. + *

      + * Note:Because of the structural changes in the ICU locale bundle, + * this API no longer works as described. This method always returns null. + * @see #getDateFormatBundle(java.lang.Class, java.util.Locale) + * @deprecated ICU 4.0 + */ + // This API was formerly @stable ICU 3.2 + public static ResourceBundle getDateFormatBundle(Calendar cal, ULocale locale) throws MissingResourceException { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); } + + /** + * Returns the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 + * contains a partial preview implementation. The * actual + * locale is returned correctly, but the valid locale is + * not, in most cases. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java index 21021b02dd2..14eea149402 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java @@ -1,1762 +1,1762 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -import java.math.BigInteger; -import java.text.AttributedCharacterIterator; -import java.text.AttributedCharacterIterator.Attribute; -import java.text.AttributedString; -import java.text.CharacterIterator; -import java.text.FieldPosition; -import java.text.ParsePosition; -import java.util.Map; -import java.util.Map.Entry; - -import com.ibm.icu.math.BigDecimal; -import com.ibm.icu.math.MathContext; -import com.ibm.icu.util.Currency; -import com.ibm.icu.util.CurrencyAmount; - -/** - * {@icuenhanced java.text.DecimalFormat}.{@icu _usage_} - * - * DecimalFormat is a concrete subclass of {@link NumberFormat} that formats - * decimal numbers. It has a variety of features designed to make it possible to parse and - * format numbers in any locale, including support for Western, Arabic, or Indic digits. - * It also supports different flavors of numbers, including integers ("123"), fixed-point - * numbers ("123.4"), scientific notation ("1.23E4"), percentages ("12%"), and currency - * amounts ("$123.00", "USD123.00", "123.00 US dollars"). All of these flavors can be - * easily localized. - * - *

      To obtain a {@link NumberFormat} for a specific locale (including the default - * locale) call one of NumberFormat's factory methods such as {@link - * NumberFormat#getInstance}. Do not call the DecimalFormat constructors - * directly, unless you know what you are doing, since the {@link NumberFormat} factory - * methods may return subclasses other than DecimalFormat. If you need to - * customize the format object, do something like this: - * - *

      - * NumberFormat f = NumberFormat.getInstance(loc);
      - * if (f instanceof DecimalFormat) {
      - *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
      - * }
      - * - *

      Example Usage - * - * Print out a number using the localized number, currency, and percent - * format for each locale. - * - *

      - * Locale[] locales = NumberFormat.getAvailableLocales();
      - * double myNumber = -1234.56;
      - * NumberFormat format;
      - * for (int j=0; j<3; ++j) {
      - *     System.out.println("FORMAT");
      - *     for (int i = 0; i < locales.length; ++i) {
      - *         if (locales[i].getCountry().length() == 0) {
      - *            // Skip language-only locales
      - *            continue;
      - *         }
      - *         System.out.print(locales[i].getDisplayName());
      - *         switch (j) {
      - *         case 0:
      - *             format = NumberFormat.getInstance(locales[i]); break;
      - *         case 1:
      - *             format = NumberFormat.getCurrencyInstance(locales[i]); break;
      - *         default:
      - *             format = NumberFormat.getPercentInstance(locales[i]); break;
      - *         }
      - *         try {
      - *             // Assume format is a DecimalFormat
      - *             System.out.print(": " + ((DecimalFormat) format).toPattern()
      - *                              + " -> " + form.format(myNumber));
      - *         } catch (Exception e) {}
      - *         try {
      - *             System.out.println(" -> " + format.parse(form.format(myNumber)));
      - *         } catch (ParseException e) {}
      - *     }
      - * }
      - * - *

      Another example use getInstance(style).
      - * Print out a number using the localized number, currency, percent, - * scientific, integer, iso currency, and plural currency format for each locale. - * - *

      - * ULocale locale = new ULocale("en_US");
      - * double myNumber = 1234.56;
      - * for (int j=NumberFormat.NUMBERSTYLE; j<=NumberFormat.PLURALCURRENCYSTYLE; ++j) {
      - *     NumberFormat format = NumberFormat.getInstance(locale, j);
      - *     try {
      - *         // Assume format is a DecimalFormat
      - *         System.out.print(": " + ((DecimalFormat) format).toPattern()
      - *                          + " -> " + form.format(myNumber));
      - *     } catch (Exception e) {}
      - *     try {
      - *         System.out.println(" -> " + format.parse(form.format(myNumber)));
      - *     } catch (ParseException e) {}
      - * }
      - * - *

      Patterns

      - * - *

      A DecimalFormat consists of a pattern and a set of - * symbols. The pattern may be set directly using {@link #applyPattern}, or - * indirectly using other API methods which manipulate aspects of the pattern, such as the - * minimum number of integer digits. The symbols are stored in a {@link - * DecimalFormatSymbols} object. When using the {@link NumberFormat} factory methods, the - * pattern and symbols are read from ICU's locale data. - * - *

      Special Pattern Characters

      - * - *

      Many characters in a pattern are taken literally; they are matched during parsing - * and output unchanged during formatting. Special characters, on the other hand, stand - * for other characters, strings, or classes of characters. For example, the '#' - * character is replaced by a localized digit. Often the replacement character is the - * same as the pattern character; in the U.S. locale, the ',' grouping character is - * replaced by ','. However, the replacement is still happening, and if the symbols are - * modified, the grouping character changes. Some special characters affect the behavior - * of the formatter by their presence; for example, if the percent character is seen, then - * the value is multiplied by 100 before being displayed. - * - *

      To insert a special character in a pattern as a literal, that is, without any - * special meaning, the character must be quoted. There are some exceptions to this which - * are noted below. - * - *

      The characters listed here are used in non-localized patterns. Localized patterns - * use the corresponding characters taken from this formatter's {@link - * DecimalFormatSymbols} object instead, and these characters lose their special status. - * Two exceptions are the currency sign and quote, which are not localized. - * - *

      - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      Symbol - * Location - * Localized? - * Meaning - *
      0 - * Number - * Yes - * Digit - *
      1-9 - * Number - * Yes - * '1' through '9' indicate rounding. - *
      @ - * Number - * No - * Significant digit - *
      # - * Number - * Yes - * Digit, zero shows as absent - *
      . - * Number - * Yes - * Decimal separator or monetary decimal separator - *
      - - * Number - * Yes - * Minus sign - *
      , - * Number - * Yes - * Grouping separator - *
      E - * Number - * Yes - * Separates mantissa and exponent in scientific notation. - * Need not be quoted in prefix or suffix. - *
      + - * Exponent - * Yes - * Prefix positive exponents with localized plus sign. - * Need not be quoted in prefix or suffix. - *
      ; - * Subpattern boundary - * Yes - * Separates positive and negative subpatterns - *
      % - * Prefix or suffix - * Yes - * Multiply by 100 and show as percentage - *
      \u2030 - * Prefix or suffix - * Yes - * Multiply by 1000 and show as per mille - *
      ¤ (\u00A4) - * Prefix or suffix - * No - * Currency sign, replaced by currency symbol. If - * doubled, replaced by international currency symbol. - * If tripled, replaced by currency plural names, for example, - * "US dollar" or "US dollars" for America. - * If present in a pattern, the monetary decimal separator - * is used instead of the decimal separator. - *
      ' - * Prefix or suffix - * No - * Used to quote special characters in a prefix or suffix, - * for example, "'#'#" formats 123 to - * "#123". To create a single quote - * itself, use two in a row: "# o''clock". - *
      * - * Prefix or suffix boundary - * Yes - * Pad escape, precedes pad character - *
      - *
      - * - *

      A DecimalFormat pattern contains a postive and negative subpattern, for - * example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric part, and a - * suffix. If there is no explicit negative subpattern, the negative subpattern is the - * localized minus sign prefixed to the positive subpattern. That is, "0.00" alone is - * equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves - * only to specify the negative prefix and suffix; the number of digits, minimal digits, - * and other characteristics are ignored in the negative subpattern. That means that - * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)". - * - *

      The prefixes, suffixes, and various symbols used for infinity, digits, thousands - * separators, decimal separators, etc. may be set to arbitrary values, and they will - * appear properly during formatting. However, care must be taken that the symbols and - * strings do not conflict, or parsing will be unreliable. For example, either the - * positive and negative prefixes or the suffixes must be distinct for {@link #parse} to - * be able to distinguish positive from negative values. Another example is that the - * decimal separator and thousands separator should be distinct characters, or parsing - * will be impossible. - * - *

      The grouping separator is a character that separates clusters of integer - * digits to make large numbers more legible. It commonly used for thousands, but in some - * locales it separates ten-thousands. The grouping size is the number of digits - * between the grouping separators, such as 3 for "100,000,000" or 4 for "1 0000 - * 0000". There are actually two different grouping sizes: One used for the least - * significant integer digits, the primary grouping size, and one used for all - * others, the secondary grouping size. In most locales these are the same, but - * sometimes they are different. For example, if the primary grouping interval is 3, and - * the secondary is 2, then this corresponds to the pattern "#,##,##0", and the number - * 123456789 is formatted as "12,34,56,789". If a pattern contains multiple grouping - * separators, the interval between the last one and the end of the integer defines the - * primary grouping size, and the interval between the last two defines the secondary - * grouping size. All others are ignored, so "#,##,###,####" == "###,###,####" == - * "##,#,###,####". - * - *

      Illegal patterns, such as "#.#.#" or "#.###,###", will cause - * DecimalFormat to throw an {@link IllegalArgumentException} with a message - * that describes the problem. - * - *

      Pattern BNF

      - * - *
      - * pattern    := subpattern (';' subpattern)?
      - * subpattern := prefix? number exponent? suffix?
      - * number     := (integer ('.' fraction)?) | sigDigits
      - * prefix     := '\u0000'..'\uFFFD' - specialCharacters
      - * suffix     := '\u0000'..'\uFFFD' - specialCharacters
      - * integer    := '#'* '0'* '0'
      - * fraction   := '0'* '#'*
      - * sigDigits  := '#'* '@' '@'* '#'*
      - * exponent   := 'E' '+'? '0'* '0'
      - * padSpec    := '*' padChar
      - * padChar    := '\u0000'..'\uFFFD' - quote
      - *  
      - * Notation:
      - *   X*       0 or more instances of X
      - *   X?       0 or 1 instances of X
      - *   X|Y      either X or Y
      - *   C..D     any character from C up to D, inclusive
      - *   S-T      characters in S, except those in T
      - * 
      - * The first subpattern is for positive numbers. The second (optional) - * subpattern is for negative numbers. - * - *

      Not indicated in the BNF syntax above: - * - *

        - * - *
      • The grouping separator ',' can occur inside the integer and sigDigits - * elements, between any two pattern characters of that element, as long as the integer or - * sigDigits element is not followed by the exponent element. - * - *
      • Two grouping intervals are recognized: That between the decimal point and the first - * grouping symbol, and that between the first and second grouping symbols. These - * intervals are identical in most locales, but in some locales they differ. For example, - * the pattern "#,##,###" formats the number 123456789 as - * "12,34,56,789". - * - *
      • The pad specifier padSpec may appear before the prefix, after the - * prefix, before the suffix, after the suffix, or not at all. - * - *
      • In place of '0', the digits '1' through '9' may be used to indicate a rounding - * increment. - * - *
      - * - *

      Parsing

      - * - *

      DecimalFormat parses all Unicode characters that represent decimal - * digits, as defined by {@link UCharacter#digit}. In addition, - * DecimalFormat also recognizes as digits the ten consecutive characters - * starting with the localized zero digit defined in the {@link DecimalFormatSymbols} - * object. During formatting, the {@link DecimalFormatSymbols}-based digits are output. - * - *

      During parsing, grouping separators are ignored. - * - *

      For currency parsing, the formatter is able to parse every currency style formats no - * matter which style the formatter is constructed with. For example, a formatter - * instance gotten from NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can - * parse formats such as "USD1.00" and "3.00 US dollars". - * - *

      If {@link #parse(String, ParsePosition)} fails to parse a string, it returns - * null and leaves the parse position unchanged. The convenience method - * {@link #parse(String)} indicates parse failure by throwing a {@link - * java.text.ParseException}. - * - *

      Formatting

      - * - *

      Formatting is guided by several parameters, all of which can be specified either - * using a pattern or using the API. The following description applies to formats that do - * not use scientific notation or significant - * digits. - * - *

      • If the number of actual integer digits exceeds the maximum integer - * digits, then only the least significant digits are shown. For example, 1997 is - * formatted as "97" if the maximum integer digits is set to 2. - * - *
      • If the number of actual integer digits is less than the minimum integer - * digits, then leading zeros are added. For example, 1997 is formatted as "01997" - * if the minimum integer digits is set to 5. - * - *
      • If the number of actual fraction digits exceeds the maximum fraction - * digits, then half-even rounding it performed to the maximum fraction digits. For - * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2. This - * behavior can be changed by specifying a rounding increment and a rounding mode. - * - *
      • If the number of actual fraction digits is less than the minimum fraction - * digits, then trailing zeros are added. For example, 0.125 is formatted as - * "0.1250" if the mimimum fraction digits is set to 4. - * - *
      • Trailing fractional zeros are not displayed if they occur j positions - * after the decimal, where j is less than the maximum fraction digits. For - * example, 0.10004 is formatted as "0.1" if the maximum fraction digits is four or less. - *
      - * - *

      Special Values - * - *

      NaN is represented as a single character, typically - * \uFFFD. This character is determined by the {@link - * DecimalFormatSymbols} object. This is the only value for which the prefixes and - * suffixes are not used. - * - *

      Infinity is represented as a single character, typically \u221E, - * with the positive or negative prefixes and suffixes applied. The infinity character is - * determined by the {@link DecimalFormatSymbols} object. - * - *

      Scientific Notation

      - * - *

      Numbers in scientific notation are expressed as the product of a mantissa and a - * power of ten, for example, 1234 can be expressed as 1.234 x 103. The - * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0), - * but it need not be. DecimalFormat supports arbitrary mantissas. - * DecimalFormat can be instructed to use scientific notation through the API - * or through the pattern. In a pattern, the exponent character immediately followed by - * one or more digit characters indicates scientific notation. Example: "0.###E0" formats - * the number 1234 as "1.234E3". - * - *

        - * - *
      • The number of digit characters after the exponent character gives the minimum - * exponent digit count. There is no maximum. Negative exponents are formatted using the - * localized minus sign, not the prefix and suffix from the pattern. This allows - * patterns such as "0.###E0 m/s". To prefix positive exponents with a localized plus - * sign, specify '+' between the exponent and the digits: "0.###E+0" will produce formats - * "1E+1", "1E+0", "1E-1", etc. (In localized patterns, use the localized plus sign - * rather than '+'.) - * - *
      • The minimum number of integer digits is achieved by adjusting the exponent. - * Example: 0.00123 formatted with "00.###E0" yields "12.3E-4". This only happens if - * there is no maximum number of integer digits. If there is a maximum, then the minimum - * number of integer digits is fixed at one. - * - *
      • The maximum number of integer digits, if present, specifies the exponent grouping. - * The most common use of this is to generate engineering notation, in which the - * exponent is a multiple of three, e.g., "##0.###E0". The number 12345 is formatted - * using "##0.####E0" as "12.345E3". - * - *
      • When using scientific notation, the formatter controls the digit counts using - * significant digits logic. The maximum number of significant digits limits the total - * number of integer and fraction digits that will be shown in the mantissa; it does not - * affect parsing. For example, 12345 formatted with "##0.##E0" is "12.3E3". See the - * section on significant digits for more details. - * - *
      • The number of significant digits shown is determined as follows: If - * areSignificantDigitsUsed() returns false, then the minimum number of significant digits - * shown is one, and the maximum number of significant digits shown is the sum of the - * minimum integer and maximum fraction digits, and is unaffected by the - * maximum integer digits. If this sum is zero, then all significant digits are shown. - * If areSignificantDigitsUsed() returns true, then the significant digit counts are - * specified by getMinimumSignificantDigits() and getMaximumSignificantDigits(). In this - * case, the number of integer digits is fixed at one, and there is no exponent grouping. - * - *
      • Exponential patterns may not contain grouping separators. - * - *
      - * - *

      Significant Digits

      - * - * DecimalFormat has two ways of controlling how many digits are shows: (a) - * significant digits counts, or (b) integer and fraction digit counts. Integer and - * fraction digit counts are described above. When a formatter is using significant - * digits counts, the number of integer and fraction digits is not specified directly, and - * the formatter settings for these counts are ignored. Instead, the formatter uses - * however many integer and fraction digits are required to display the specified number - * of significant digits. Examples: - * - *
      - * - * - * - * - * - * - *
      Pattern - * Minimum significant digits - * Maximum significant digits - * Number - * Output of format() - *
      @@@ - * 3 - * 3 - * 12345 - * 12300 - *
      @@@ - * 3 - * 3 - * 0.12345 - * 0.123 - *
      @@## - * 2 - * 4 - * 3.14159 - * 3.142 - *
      @@## - * 2 - * 4 - * 1.23004 - * 1.23 - *
      - *
      - * - *
        - * - *
      • Significant digit counts may be expressed using patterns that specify a minimum and - * maximum number of significant digits. These are indicated by the '@' and - * '#' characters. The minimum number of significant digits is the number of - * '@' characters. The maximum number of significant digits is the number of - * '@' characters plus the number of '#' characters following on - * the right. For example, the pattern "@@@" indicates exactly 3 significant - * digits. The pattern "@##" indicates from 1 to 3 significant digits. - * Trailing zero digits to the right of the decimal separator are suppressed after the - * minimum number of significant digits have been shown. For example, the pattern - * "@##" formats the number 0.1203 as "0.12". - * - *
      • If a pattern uses significant digits, it may not contain a decimal separator, nor - * the '0' pattern character. Patterns such as "@00" or - * "@.###" are disallowed. - * - *
      • Any number of '#' characters may be prepended to the left of the - * leftmost '@' character. These have no effect on the minimum and maximum - * significant digits counts, but may be used to position grouping separators. For - * example, "#,#@#" indicates a minimum of one significant digits, a maximum - * of two significant digits, and a grouping size of three. - * - *
      • In order to enable significant digits formatting, use a pattern containing the - * '@' pattern character. Alternatively, call {@link - * #setSignificantDigitsUsed setSignificantDigitsUsed(true)}. - * - *
      • In order to disable significant digits formatting, use a pattern that does not - * contain the '@' pattern character. Alternatively, call {@link - * #setSignificantDigitsUsed setSignificantDigitsUsed(false)}. - * - *
      • The number of significant digits has no effect on parsing. - * - *
      • Significant digits may be used together with exponential notation. Such patterns - * are equivalent to a normal exponential pattern with a minimum and maximum integer digit - * count of one, a minimum fraction digit count of getMinimumSignificantDigits() - - * 1, and a maximum fraction digit count of getMaximumSignificantDigits() - - * 1. For example, the pattern "@@###E0" is equivalent to - * "0.0###E0". - * - *
      • If signficant digits are in use, then the integer and fraction digit counts, as set - * via the API, are ignored. If significant digits are not in use, then the signficant - * digit counts, as set via the API, are ignored. - * - *
      - * - *

      Padding

      - * - *

      DecimalFormat supports padding the result of {@link #format} to a - * specific width. Padding may be specified either through the API or through the pattern - * syntax. In a pattern the pad escape character, followed by a single pad character, - * causes padding to be parsed and formatted. The pad escape character is '*' in - * unlocalized patterns, and can be localized using {@link - * DecimalFormatSymbols#setPadEscape}. For example, "$*x#,##0.00" formats - * 123 to "$xx123.00", and 1234 to "$1,234.00". - * - *

        - * - *
      • When padding is in effect, the width of the positive subpattern, including prefix - * and suffix, determines the format width. For example, in the pattern "* #0 - * o''clock", the format width is 10. - * - *
      • The width is counted in 16-bit code units (Java chars). - * - *
      • Some parameters which usually do not matter have meaning when padding is used, - * because the pattern width is significant with padding. In the pattern "* - * ##,##,#,##0.##", the format width is 14. The initial characters "##,##," do not affect - * the grouping size or maximum integer digits, but they do affect the format width. - * - *
      • Padding may be inserted at one of four locations: before the prefix, after the - * prefix, before the suffix, or after the suffix. If padding is specified in any other - * location, {@link #applyPattern} throws an {@link IllegalArgumentException}. If there - * is no prefix, before the prefix and after the prefix are equivalent, likewise for the - * suffix. - * - *
      • When specified in a pattern, the 16-bit char immediately following the - * pad escape is the pad character. This may be any character, including a special pattern - * character. That is, the pad escape escapes the following character. If there - * is no character after the pad escape, then the pattern is illegal. - * - *
      - * - *

      - * Rounding - * - *

      DecimalFormat supports rounding to a specific increment. For example, - * 1230 rounded to the nearest 50 is 1250. 1.234 rounded to the nearest 0.65 is 1.3. The - * rounding increment may be specified through the API or in a pattern. To specify a - * rounding increment in a pattern, include the increment in the pattern itself. "#,#50" - * specifies a rounding increment of 50. "#,##0.05" specifies a rounding increment of - * 0.05. - * - *

        - * - *
      • Rounding only affects the string produced by formatting. It does not affect - * parsing or change any numerical values. - * - *
      • A rounding mode determines how values are rounded; see the {@link - * com.ibm.icu.math.BigDecimal} documentation for a description of the modes. Rounding - * increments specified in patterns use the default mode, {@link - * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}. - * - *
      • Some locales use rounding in their currency formats to reflect the smallest - * currency denomination. - * - *
      • In a pattern, digits '1' through '9' specify rounding, but otherwise behave - * identically to digit '0'. - * - *
      - * - *

      Synchronization

      - * - *

      DecimalFormat objects are not synchronized. Multiple threads should - * not access one formatter concurrently. - * - * @see java.text.Format - * @see NumberFormat - * @author Mark Davis - * @author Alan Liu - * @stable ICU 2.0 - */ -public class DecimalFormat extends NumberFormat { - - private static final long serialVersionUID = 1L; - /** - * @internal - * @param delegate the NumberFormat to which to delegate - */ - public DecimalFormat(java.text.DecimalFormat delegate) { - super(delegate); - } - - /** - * Creates a DecimalFormat using the default pattern and symbols for the default - * locale. This is a convenient way to obtain a DecimalFormat when - * internationalization is not the main concern. - * - *

      To obtain standard formats for a given locale, use the factory methods on - * NumberFormat such as getNumberInstance. These factories will return the most - * appropriate sub-class of NumberFormat for a given locale. - * - * @see NumberFormat#getInstance - * @see NumberFormat#getNumberInstance - * @see NumberFormat#getCurrencyInstance - * @see NumberFormat#getPercentInstance - * @stable ICU 2.0 - */ - public DecimalFormat() { - this(new java.text.DecimalFormat()); - } - - /** - * Creates a DecimalFormat from the given pattern and the symbols for the default - * locale. This is a convenient way to obtain a DecimalFormat when - * internationalization is not the main concern. - * - *

      To obtain standard formats for a given locale, use the factory methods on - * NumberFormat such as getNumberInstance. These factories will return the most - * appropriate sub-class of NumberFormat for a given locale. - * - * @param pattern A non-localized pattern string. - * @throws IllegalArgumentException if the given pattern is invalid. - * @see NumberFormat#getInstance - * @see NumberFormat#getNumberInstance - * @see NumberFormat#getCurrencyInstance - * @see NumberFormat#getPercentInstance - * @stable ICU 2.0 - */ - public DecimalFormat(String pattern) { - this(new java.text.DecimalFormat(pattern)); - } - - /** - * Creates a DecimalFormat from the given pattern and symbols. Use this constructor - * when you need to completely customize the behavior of the format. - * - *

      To obtain standard formats for a given locale, use the factory methods on - * NumberFormat such as getInstance or getCurrencyInstance. If you need only minor - * adjustments to a standard format, you can modify the format returned by a - * NumberFormat factory method. - * - * @param pattern a non-localized pattern string - * @param symbols the set of symbols to be used - * @exception IllegalArgumentException if the given pattern is invalid - * @see NumberFormat#getInstance - * @see NumberFormat#getNumberInstance - * @see NumberFormat#getCurrencyInstance - * @see NumberFormat#getPercentInstance - * @see DecimalFormatSymbols - * @stable ICU 2.0 - */ - public DecimalFormat(String pattern, DecimalFormatSymbols symbols) { - this(new java.text.DecimalFormat(pattern, symbols.dfs)); - } - - /** - * Creates a DecimalFormat from the given pattern, symbols, information used for - * currency plural format, and format style. Use this constructor when you need to - * completely customize the behavior of the format. - * - *

      To obtain standard formats for a given locale, use the factory methods on - * NumberFormat such as getInstance or getCurrencyInstance. - * - *

      If you need only minor adjustments to a standard format, you can modify the - * format returned by a NumberFormat factory method using the setters. - * - *

      If you want to completely customize a decimal format, using your own - * DecimalFormatSymbols (such as group separators) and your own information for - * currency plural formatting (such as plural rule and currency plural patterns), you - * can use this constructor. - * - * @param pattern a non-localized pattern string - * @param symbols the set of symbols to be used - * @param infoInput the information used for currency plural format, including - * currency plural patterns and plural rules. - * @param style the decimal formatting style, it is one of the following values: - * NumberFormat.NUMBERSTYLE; NumberFormat.CURRENCYSTYLE; NumberFormat.PERCENTSTYLE; - * NumberFormat.SCIENTIFICSTYLE; NumberFormat.INTEGERSTYLE; - * NumberFormat.ISOCURRENCYSTYLE; NumberFormat.PLURALCURRENCYSTYLE; - * @stable ICU 4.2 - */ - public DecimalFormat(String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput, - int style) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * {@inheritDoc} - * @stable ICU 2.0 - */ - public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) { - return super.format(number, result, fieldPosition); - } - - /** - * @stable ICU 2.0 - */ - // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean - public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) { - return super.format(number, result, fieldPosition); - } - - /** - * Formats a BigInteger number. - * - * @stable ICU 2.0 - */ - public StringBuffer format(BigInteger number, StringBuffer result, - FieldPosition fieldPosition) { - return super.format(number, result, fieldPosition); - } - - /** - * Formats a BigDecimal number. - * - * @stable ICU 2.0 - */ - public StringBuffer format(java.math.BigDecimal number, StringBuffer result, - FieldPosition fieldPosition) { - return super.format(number, result, fieldPosition); - } - - /** - * Formats a BigDecimal number. - * - * @stable ICU 2.0 - */ - public StringBuffer format(BigDecimal number, StringBuffer result, - FieldPosition fieldPosition) { - return super.format(number, result, fieldPosition); - } - - /** - * Parses the given string, returning a Number object to represent the - * parsed value. Double objects are returned to represent non-integral - * values which cannot be stored in a BigDecimal. These are - * NaN, infinity, -infinity, and -0.0. If {@link #isParseBigDecimal()} is - * false (the default), all other values are returned as Long, - * BigInteger, or BigDecimal values, in that order of - * preference. If {@link #isParseBigDecimal()} is true, all other values are returned - * as BigDecimal valuse. If the parse fails, null is returned. - * - * @param text the string to be parsed - * @param parsePosition defines the position where parsing is to begin, and upon - * return, the position where parsing left off. If the position has not changed upon - * return, then parsing failed. - * @return a Number object with the parsed value or - * null if the parse failed - * @stable ICU 2.0 - */ - public Number parse(String text, ParsePosition parsePosition) { - return super.parse(text, parsePosition); - } - - /** - * Parses text from the given string as a CurrencyAmount. Unlike the parse() method, - * this method will attempt to parse a generic currency name, searching for a match of - * this object's locale's currency display names, or for a 3-letter ISO currency - * code. This method will fail if this format is not a currency format, that is, if it - * does not contain the currency pattern symbol (U+00A4) in its prefix or suffix. - * - * @param text the string to parse - * @param pos input-output position; on input, the position within text to match; must - * have 0 <= pos.getIndex() < text.length(); on output, the position after the last - * matched character. If the parse fails, the position in unchanged upon output. - * @return a CurrencyAmount, or null upon failure - */ - CurrencyAmount parseCurrency(String text, ParsePosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns a copy of the decimal format symbols used by this format. - * - * @return desired DecimalFormatSymbols - * @see DecimalFormatSymbols - * @stable ICU 2.0 - */ - public DecimalFormatSymbols getDecimalFormatSymbols() { - return new DecimalFormatSymbols(((java.text.DecimalFormat)numberFormat).getDecimalFormatSymbols()); - } - - /** - * Sets the decimal format symbols used by this format. The format uses a copy of the - * provided symbols. - * - * @param newSymbols desired DecimalFormatSymbols - * @see DecimalFormatSymbols - * @stable ICU 2.0 - */ - public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { - ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(newSymbols.dfs); - } - - /** - * Returns the positive prefix. - * - *

      Examples: +123, $123, sFr123 - * @return the prefix - * @stable ICU 2.0 - */ - public String getPositivePrefix() { - return ((java.text.DecimalFormat)numberFormat).getPositivePrefix(); - } - - /** - * Sets the positive prefix. - * - *

      Examples: +123, $123, sFr123 - * @param newValue the prefix - * @stable ICU 2.0 - */ - public void setPositivePrefix(String newValue) { - ((java.text.DecimalFormat)numberFormat).setPositivePrefix(newValue); - } - - /** - * Returns the negative prefix. - * - *

      Examples: -123, ($123) (with negative suffix), sFr-123 - * - * @return the prefix - * @stable ICU 2.0 - */ - public String getNegativePrefix() { - return ((java.text.DecimalFormat)numberFormat).getNegativePrefix(); - } - - /** - * Sets the negative prefix. - * - *

      Examples: -123, ($123) (with negative suffix), sFr-123 - * @param newValue the prefix - * @stable ICU 2.0 - */ - public void setNegativePrefix(String newValue) { - ((java.text.DecimalFormat)numberFormat).setNegativePrefix(newValue); - } - - /** - * Returns the positive suffix. - * - *

      Example: 123% - * - * @return the suffix - * @stable ICU 2.0 - */ - public String getPositiveSuffix() { - return ((java.text.DecimalFormat)numberFormat).getPositiveSuffix(); - } - - /** - * Sets the positive suffix. - * - *

      Example: 123% - * @param newValue the suffix - * @stable ICU 2.0 - */ - public void setPositiveSuffix(String newValue) { - ((java.text.DecimalFormat)numberFormat).setPositiveSuffix(newValue); - } - - /** - * Returns the negative suffix. - * - *

      Examples: -123%, ($123) (with positive suffixes) - * - * @return the suffix - * @stable ICU 2.0 - */ - public String getNegativeSuffix() { - return ((java.text.DecimalFormat)numberFormat).getNegativeSuffix(); - } - - /** - * Sets the positive suffix. - * - *

      Examples: 123% - * @param newValue the suffix - * @stable ICU 2.0 - */ - public void setNegativeSuffix(String newValue) { - ((java.text.DecimalFormat)numberFormat).setNegativeSuffix(newValue); - } - - /** - * Returns the multiplier for use in percent, permill, etc. For a percentage, set the - * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent - * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be - * 1000. - * - *

      Examples: with 100, 1.23 -> "123", and "123" -> 1.23 - * - * @return the multiplier - * @stable ICU 2.0 - */ - public int getMultiplier() { - return ((java.text.DecimalFormat)numberFormat).getMultiplier(); - } - - /** - * Sets the multiplier for use in percent, permill, etc. For a percentage, set the - * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent - * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be - * 1000. - * - *

      Examples: with 100, 1.23 -> "123", and "123" -> 1.23 - * - * @param newValue the multiplier - * @stable ICU 2.0 - */ - public void setMultiplier(int newValue) { - ((java.text.DecimalFormat)numberFormat).setMultiplier(newValue); - } - - /** - * {@icu} Returns the rounding increment. - * - * @return A positive rounding increment, or null if rounding is not in - * effect. - * @see #setRoundingIncrement - * @see #getRoundingMode - * @see #setRoundingMode - * @stable ICU 2.0 - */ - public BigDecimal getRoundingIncrement() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the rounding increment. This method also controls whether rounding is - * enabled. - * - * @param newValue A positive rounding increment, or null or - * BigDecimal(0.0) to disable rounding. - * @throws IllegalArgumentException if newValue is < 0.0 - * @see #getRoundingIncrement - * @see #getRoundingMode - * @see #setRoundingMode - * @stable ICU 2.0 - */ - public void setRoundingIncrement(java.math.BigDecimal newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the rounding increment. This method also controls whether rounding is - * enabled. - * - * @param newValue A positive rounding increment, or null or - * BigDecimal(0.0) to disable rounding. - * @throws IllegalArgumentException if newValue is < 0.0 - * @see #getRoundingIncrement - * @see #getRoundingMode - * @see #setRoundingMode - * @stable ICU 3.6 - */ - public void setRoundingIncrement(BigDecimal newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the rounding increment. This method also controls whether rounding is - * enabled. - * - * @param newValue A positive rounding increment, or 0.0 to disable rounding. - * @throws IllegalArgumentException if newValue is < 0.0 - * @see #getRoundingIncrement - * @see #getRoundingMode - * @see #setRoundingMode - * @stable ICU 2.0 - */ - public void setRoundingIncrement(double newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the rounding mode. - * - * @return A rounding mode, between BigDecimal.ROUND_UP and - * BigDecimal.ROUND_UNNECESSARY. - * @see #setRoundingIncrement - * @see #getRoundingIncrement - * @see #setRoundingMode - * @see java.math.BigDecimal - * @stable ICU 2.0 - */ - public int getRoundingMode() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the rounding mode. This has no effect unless the rounding increment is greater - * than zero. - * - * @param roundingMode A rounding mode, between BigDecimal.ROUND_UP and - * BigDecimal.ROUND_UNNECESSARY. - * @exception IllegalArgumentException if roundingMode is unrecognized. - * @see #setRoundingIncrement - * @see #getRoundingIncrement - * @see #getRoundingMode - * @see java.math.BigDecimal - * @stable ICU 2.0 - */ - public void setRoundingMode(int roundingMode) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the width to which the output of format() is padded. The width is - * counted in 16-bit code units. - * - * @return the format width, or zero if no padding is in effect - * @see #setFormatWidth - * @see #getPadCharacter - * @see #setPadCharacter - * @see #getPadPosition - * @see #setPadPosition - * @stable ICU 2.0 - */ - public int getFormatWidth() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the width to which the output of format() is - * padded. The width is counted in 16-bit code units. This method - * also controls whether padding is enabled. - * - * @param width the width to which to pad the result of - * format(), or zero to disable padding - * @exception IllegalArgumentException if width is < 0 - * @see #getFormatWidth - * @see #getPadCharacter - * @see #setPadCharacter - * @see #getPadPosition - * @see #setPadPosition - * @stable ICU 2.0 - */ - public void setFormatWidth(int width) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the character used to pad to the format width. The default is ' '. - * - * @return the pad character - * @see #setFormatWidth - * @see #getFormatWidth - * @see #setPadCharacter - * @see #getPadPosition - * @see #setPadPosition - * @stable ICU 2.0 - */ - public char getPadCharacter() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the character used to pad to the format width. If padding is not - * enabled, then this will take effect if padding is later enabled. - * - * @param padChar the pad character - * @see #setFormatWidth - * @see #getFormatWidth - * @see #getPadCharacter - * @see #getPadPosition - * @see #setPadPosition - * @stable ICU 2.0 - */ - public void setPadCharacter(char padChar) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the position at which padding will take place. This is the location at - * which padding will be inserted if the result of format() is shorter - * than the format width. - * - * @return the pad position, one of PAD_BEFORE_PREFIX, - * PAD_AFTER_PREFIX, PAD_BEFORE_SUFFIX, or - * PAD_AFTER_SUFFIX. - * @see #setFormatWidth - * @see #getFormatWidth - * @see #setPadCharacter - * @see #getPadCharacter - * @see #setPadPosition - * @see #PAD_BEFORE_PREFIX - * @see #PAD_AFTER_PREFIX - * @see #PAD_BEFORE_SUFFIX - * @see #PAD_AFTER_SUFFIX - * @stable ICU 2.0 - */ - public int getPadPosition() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the position at which padding will take place. This is the location at - * which padding will be inserted if the result of format() is shorter - * than the format width. This has no effect unless padding is enabled. - * - * @param padPos the pad position, one of PAD_BEFORE_PREFIX, - * PAD_AFTER_PREFIX, PAD_BEFORE_SUFFIX, or - * PAD_AFTER_SUFFIX. - * @exception IllegalArgumentException if the pad position in unrecognized - * @see #setFormatWidth - * @see #getFormatWidth - * @see #setPadCharacter - * @see #getPadCharacter - * @see #getPadPosition - * @see #PAD_BEFORE_PREFIX - * @see #PAD_AFTER_PREFIX - * @see #PAD_BEFORE_SUFFIX - * @see #PAD_AFTER_SUFFIX - * @stable ICU 2.0 - */ - public void setPadPosition(int padPos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns whether or not scientific notation is used. - * - * @return true if this object formats and parses scientific notation - * @see #setScientificNotation - * @see #getMinimumExponentDigits - * @see #setMinimumExponentDigits - * @see #isExponentSignAlwaysShown - * @see #setExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public boolean isScientificNotation() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets whether or not scientific notation is used. When scientific notation is - * used, the effective maximum number of integer digits is <= 8. If the maximum number - * of integer digits is set to more than 8, the effective maximum will be 1. This - * allows this call to generate a 'default' scientific number format without - * additional changes. - * - * @param useScientific true if this object formats and parses scientific notation - * @see #isScientificNotation - * @see #getMinimumExponentDigits - * @see #setMinimumExponentDigits - * @see #isExponentSignAlwaysShown - * @see #setExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public void setScientificNotation(boolean useScientific) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the minimum exponent digits that will be shown. - * - * @return the minimum exponent digits that will be shown - * @see #setScientificNotation - * @see #isScientificNotation - * @see #setMinimumExponentDigits - * @see #isExponentSignAlwaysShown - * @see #setExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public byte getMinimumExponentDigits() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the minimum exponent digits that will be shown. This has no effect - * unless scientific notation is in use. - * - * @param minExpDig a value >= 1 indicating the fewest exponent - * digits that will be shown - * @exception IllegalArgumentException if minExpDig < 1 - * @see #setScientificNotation - * @see #isScientificNotation - * @see #getMinimumExponentDigits - * @see #isExponentSignAlwaysShown - * @see #setExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public void setMinimumExponentDigits(byte minExpDig) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns whether the exponent sign is always shown. - * - * @return true if the exponent is always prefixed with either the localized minus - * sign or the localized plus sign, false if only negative exponents are prefixed with - * the localized minus sign. - * @see #setScientificNotation - * @see #isScientificNotation - * @see #setMinimumExponentDigits - * @see #getMinimumExponentDigits - * @see #setExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public boolean isExponentSignAlwaysShown() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets whether the exponent sign is always shown. This has no effect unless - * scientific notation is in use. - * - * @param expSignAlways true if the exponent is always prefixed with either the - * localized minus sign or the localized plus sign, false if only negative exponents - * are prefixed with the localized minus sign. - * @see #setScientificNotation - * @see #isScientificNotation - * @see #setMinimumExponentDigits - * @see #getMinimumExponentDigits - * @see #isExponentSignAlwaysShown - * @stable ICU 2.0 - */ - public void setExponentSignAlwaysShown(boolean expSignAlways) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the grouping size. Grouping size is the number of digits between grouping - * separators in the integer portion of a number. For example, in the number - * "123,456.78", the grouping size is 3. - * - * @see #setGroupingSize - * @see NumberFormat#isGroupingUsed - * @see DecimalFormatSymbols#getGroupingSeparator - * @stable ICU 2.0 - */ - public int getGroupingSize() { - return ((java.text.DecimalFormat)numberFormat).getGroupingSize(); - } - - /** - * Sets the grouping size. Grouping size is the number of digits between grouping - * separators in the integer portion of a number. For example, in the number - * "123,456.78", the grouping size is 3. - * - * @see #getGroupingSize - * @see NumberFormat#setGroupingUsed - * @see DecimalFormatSymbols#setGroupingSeparator - * @stable ICU 2.0 - */ - public void setGroupingSize(int newValue) { - ((java.text.DecimalFormat)numberFormat).setGroupingSize(newValue); - } - - /** - * {@icu} Returns the secondary grouping size. In some locales one grouping interval - * is used for the least significant integer digits (the primary grouping size), and - * another is used for all others (the secondary grouping size). A formatter - * supporting a secondary grouping size will return a positive integer unequal to the - * primary grouping size returned by getGroupingSize(). For example, if - * the primary grouping size is 4, and the secondary grouping size is 2, then the - * number 123456789 formats as "1,23,45,6789", and the pattern appears as "#,##,###0". - * - * @return the secondary grouping size, or a value less than one if there is none - * @see #setSecondaryGroupingSize - * @see NumberFormat#isGroupingUsed - * @see DecimalFormatSymbols#getGroupingSeparator - * @stable ICU 2.0 - */ - public int getSecondaryGroupingSize() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the secondary grouping size. If set to a value less than 1, then - * secondary grouping is turned off, and the primary grouping size is used for all - * intervals, not just the least significant. - * - * @see #getSecondaryGroupingSize - * @see NumberFormat#setGroupingUsed - * @see DecimalFormatSymbols#setGroupingSeparator - * @stable ICU 2.0 - */ - public void setSecondaryGroupingSize(int newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the MathContext used by this format. - * - * @return desired MathContext - * @see #getMathContext - * @stable ICU 4.2 - */ - public MathContext getMathContextICU() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the MathContext used by this format. - * - * @return desired MathContext - * @see #getMathContext - * @stable ICU 4.2 - */ - public java.math.MathContext getMathContext() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the MathContext used by this format. - * - * @param newValue desired MathContext - * @see #getMathContext - * @stable ICU 4.2 - */ - public void setMathContextICU(MathContext newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the MathContext used by this format. - * - * @param newValue desired MathContext - * @see #getMathContext - * @stable ICU 4.2 - */ - public void setMathContext(java.math.MathContext newValue) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the behavior of the decimal separator with integers. (The decimal - * separator will always appear with decimals.)

      Example: Decimal ON: 12345 -> - * 12345.; OFF: 12345 -> 12345 - * - * @stable ICU 2.0 - */ - public boolean isDecimalSeparatorAlwaysShown() { - return ((java.text.DecimalFormat)numberFormat).isDecimalSeparatorAlwaysShown(); - } - - /** - * Sets the behavior of the decimal separator with integers. (The decimal separator - * will always appear with decimals.) - * - *

      This only affects formatting, and only where there might be no digits after the - * decimal point, e.g., if true, 3456.00 -> "3,456." if false, 3456.00 -> "3456" This - * is independent of parsing. If you want parsing to stop at the decimal point, use - * setParseIntegerOnly. - * - *

      - * Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 - * - * @stable ICU 2.0 - */ - public void setDecimalSeparatorAlwaysShown(boolean newValue) { - ((java.text.DecimalFormat)numberFormat).setDecimalSeparatorAlwaysShown(newValue); - } - - /** - * {@icu} Returns a copy of the CurrencyPluralInfo used by this format. It might - * return null if the decimal format is not a plural type currency decimal - * format. Plural type currency decimal format means either the pattern in the decimal - * format contains 3 currency signs, or the decimal format is initialized with - * PLURALCURRENCYSTYLE. - * - * @return desired CurrencyPluralInfo - * @see CurrencyPluralInfo - * @stable ICU 4.2 - */ - public CurrencyPluralInfo getCurrencyPluralInfo() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the CurrencyPluralInfo used by this format. The format uses a copy of - * the provided information. - * - * @param newInfo desired CurrencyPluralInfo - * @see CurrencyPluralInfo - * @stable ICU 4.2 - */ - public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Overrides clone. - * @stable ICU 2.0 - */ - public Object clone() { - return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)numberFormat.clone()); - } - - /** - * Overrides equals. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) { - return super.equals(obj); - } - - /** - * Overrides hashCode. - * @stable ICU 2.0 - */ - public int hashCode() { - return super.hashCode(); - } - - /** - * Synthesizes a pattern string that represents the current state of this Format - * object. - * - * @see #applyPattern - * @stable ICU 2.0 - */ - public String toPattern() { - return ((java.text.DecimalFormat)numberFormat).toPattern(); - } - - /** - * Synthesizes a localized pattern string that represents the current state of this - * Format object. - * - * @see #applyPattern - * @stable ICU 2.0 - */ - public String toLocalizedPattern() { - return ((java.text.DecimalFormat)numberFormat).toLocalizedPattern(); - } - - /** - * Formats the object to an attributed string, and return the corresponding iterator. - * - * @stable ICU 3.6 - */ - public AttributedCharacterIterator formatToCharacterIterator(Object obj) { - AttributedCharacterIterator it = numberFormat.formatToCharacterIterator(obj); - - // Extract formatted String first - StringBuilder sb = new StringBuilder(); - for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { - sb.append(c); - } - - // Create AttributedString - AttributedString attrstr = new AttributedString(sb.toString()); - - // Map JDK Field to ICU Field - int idx = 0; - it.first(); - while (idx < it.getEndIndex()) { - int end = it.getRunLimit(); - Map attributes = it.getAttributes(); - if (attributes != null) { - for (Entry entry : attributes.entrySet()) { - Attribute attr = entry.getKey(); - Object val = entry.getValue(); - if (attr.equals(java.text.NumberFormat.Field.CURRENCY)) { - val = attr = Field.CURRENCY; - } else if (attr.equals(java.text.NumberFormat.Field.DECIMAL_SEPARATOR)) { - val = attr = Field.DECIMAL_SEPARATOR; - } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT)) { - val = attr = Field.EXPONENT; - } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SIGN)) { - val = attr = Field.EXPONENT_SIGN; - } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SYMBOL)) { - val = attr = Field.EXPONENT_SYMBOL; - } else if (attr.equals(java.text.NumberFormat.Field.FRACTION)) { - val = attr = Field.FRACTION; - } else if (attr.equals(java.text.NumberFormat.Field.GROUPING_SEPARATOR)) { - val = attr = Field.GROUPING_SEPARATOR; - } else if (attr.equals(java.text.NumberFormat.Field.INTEGER)) { - val = attr = Field.INTEGER; - } else if (attr.equals(java.text.NumberFormat.Field.PERCENT)) { - val = attr = Field.PERCENT; - } else if (attr.equals(java.text.NumberFormat.Field.PERMILLE)) { - val = attr = Field.PERMILLE; - } else if (attr.equals(java.text.NumberFormat.Field.SIGN)) { - val = attr = Field.SIGN; - } - attrstr.addAttribute(attr, val, idx, end); - } - } - idx = end; - while (it.getIndex() < idx) { - it.next(); - } - } - - return attrstr.getIterator(); - } - - /** - * Applies the given pattern to this Format object. A pattern is a short-hand - * specification for the various formatting properties. These properties can also be - * changed individually through the various setter methods. - * - *

      There is no limit to integer digits are set by this routine, since that is the - * typical end-user desire; use setMaximumInteger if you want to set a real value. For - * negative numbers, use a second pattern, separated by a semicolon - * - *

      Example "#,#00.0#" -> 1,234.56 - * - *

      This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 - * fraction digits. - * - *

      Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses. - * - *

      In negative patterns, the minimum and maximum counts are ignored; these are - * presumed to be set in the positive pattern. - * - * @stable ICU 2.0 - */ - public void applyPattern(String pattern) { - ((java.text.DecimalFormat)numberFormat).applyPattern(pattern); - } - - /** - * Applies the given pattern to this Format object. The pattern is assumed to be in a - * localized notation. A pattern is a short-hand specification for the various - * formatting properties. These properties can also be changed individually through - * the various setter methods. - * - *

      There is no limit to integer digits are set by this routine, since that is the - * typical end-user desire; use setMaximumInteger if you want to set a real value. For - * negative numbers, use a second pattern, separated by a semicolon - * - *

      Example "#,#00.0#" -> 1,234.56 - * - *

      This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 - * fraction digits. - * - *

      Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses. - * - *

      In negative patterns, the minimum and maximum counts are ignored; these are - * presumed to be set in the positive pattern. - * - * @stable ICU 2.0 - */ - public void applyLocalizedPattern(String pattern) { - ((java.text.DecimalFormat)numberFormat).applyLocalizedPattern(pattern); - } - - /** - * Sets the maximum number of digits allowed in the integer portion of a number. This - * override limits the integer digit count to 309. - * - * @see NumberFormat#setMaximumIntegerDigits - * @stable ICU 2.0 - */ - public void setMaximumIntegerDigits(int newValue) { - super.setMaximumIntegerDigits(newValue); - } - - /** - * Sets the minimum number of digits allowed in the integer portion of a number. This - * override limits the integer digit count to 309. - * - * @see NumberFormat#setMinimumIntegerDigits - * @stable ICU 2.0 - */ - public void setMinimumIntegerDigits(int newValue) { - super.setMinimumIntegerDigits(newValue); - } - - /** - * {@icu} Returns the minimum number of significant digits that will be - * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()} - * returns true. - * - * @return the fewest significant digits that will be shown - * @stable ICU 3.0 - */ - public int getMinimumSignificantDigits() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the maximum number of significant digits that will be - * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()} - * returns true. - * - * @return the most significant digits that will be shown - * @stable ICU 3.0 - */ - public int getMaximumSignificantDigits() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the minimum number of significant digits that will be displayed. If - * min is less than one then it is set to one. If the maximum significant - * digits count is less than min, then it is set to - * min. This value has no effect unless {@link #areSignificantDigitsUsed()} - * returns true. - * - * @param min the fewest significant digits to be shown - * @stable ICU 3.0 - */ - public void setMinimumSignificantDigits(int min) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets the maximum number of significant digits that will be displayed. If - * max is less than one then it is set to one. If the minimum significant - * digits count is greater than max, then it is set to - * max. This value has no effect unless {@link #areSignificantDigitsUsed()} - * returns true. - * - * @param max the most significant digits to be shown - * @stable ICU 3.0 - */ - public void setMaximumSignificantDigits(int max) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns true if significant digits are in use or false if integer and - * fraction digit counts are in use. - * - * @return true if significant digits are in use - * @stable ICU 3.0 - */ - public boolean areSignificantDigitsUsed() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Sets whether significant digits are in use, or integer and fraction digit - * counts are in use. - * - * @param useSignificantDigits true to use significant digits, or false to use integer - * and fraction digit counts - * @stable ICU 3.0 - */ - public void setSignificantDigitsUsed(boolean useSignificantDigits) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the Currency object used to display currency amounts. This takes - * effect immediately, if this format is a currency format. If this format is not a - * currency format, then the currency object is used if and when this object becomes a - * currency format through the application of a new pattern. - * - * @param theCurrency new currency object to use. Must not be null. - * @stable ICU 2.2 - */ - public void setCurrency(Currency theCurrency) { - super.setCurrency(theCurrency); - } - - /** - * Sets the maximum number of digits allowed in the fraction portion of a number. This - * override limits the fraction digit count to 340. - * - * @see NumberFormat#setMaximumFractionDigits - * @stable ICU 2.0 - */ - public void setMaximumFractionDigits(int newValue) { - super.setMaximumFractionDigits(newValue); - } - - /** - * Sets the minimum number of digits allowed in the fraction portion of a number. This - * override limits the fraction digit count to 340. - * - * @see NumberFormat#setMinimumFractionDigits - * @stable ICU 2.0 - */ - public void setMinimumFractionDigits(int newValue) { - super.setMinimumFractionDigits(newValue); - } - - /** - * Sets whether {@link #parse(String, ParsePosition)} returns BigDecimal. The - * default value is false. - * - * @param value true if {@link #parse(String, ParsePosition)} - * returns BigDecimal. - * @stable ICU 3.6 - */ - public void setParseBigDecimal(boolean value) { - ((java.text.DecimalFormat)numberFormat).setParseBigDecimal(value); - } - - /** - * Returns whether {@link #parse(String, ParsePosition)} returns BigDecimal. - * - * @return true if {@link #parse(String, ParsePosition)} returns BigDecimal. - * @stable ICU 3.6 - */ - public boolean isParseBigDecimal() { - return ((java.text.DecimalFormat)numberFormat).isParseBigDecimal(); - } - - // ---------------------------------------------------------------------- - // CONSTANTS - // ---------------------------------------------------------------------- - - /** - * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to - * specify pad characters inserted before the prefix. - * - * @see #setPadPosition - * @see #getPadPosition - * @see #PAD_AFTER_PREFIX - * @see #PAD_BEFORE_SUFFIX - * @see #PAD_AFTER_SUFFIX - * @stable ICU 2.0 - */ - public static final int PAD_BEFORE_PREFIX = 0; - - /** - * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to - * specify pad characters inserted after the prefix. - * - * @see #setPadPosition - * @see #getPadPosition - * @see #PAD_BEFORE_PREFIX - * @see #PAD_BEFORE_SUFFIX - * @see #PAD_AFTER_SUFFIX - * @stable ICU 2.0 - */ - public static final int PAD_AFTER_PREFIX = 1; - - /** - * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to - * specify pad characters inserted before the suffix. - * - * @see #setPadPosition - * @see #getPadPosition - * @see #PAD_BEFORE_PREFIX - * @see #PAD_AFTER_PREFIX - * @see #PAD_AFTER_SUFFIX - * @stable ICU 2.0 - */ - public static final int PAD_BEFORE_SUFFIX = 2; - - /** - * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to - * specify pad characters inserted after the suffix. - * - * @see #setPadPosition - * @see #getPadPosition - * @see #PAD_BEFORE_PREFIX - * @see #PAD_AFTER_PREFIX - * @see #PAD_BEFORE_SUFFIX - * @stable ICU 2.0 - */ - public static final int PAD_AFTER_SUFFIX = 3; -} - -// eof +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +import java.math.BigInteger; +import java.text.AttributedCharacterIterator; +import java.text.AttributedCharacterIterator.Attribute; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Map; +import java.util.Map.Entry; + +import com.ibm.icu.math.BigDecimal; +import com.ibm.icu.math.MathContext; +import com.ibm.icu.util.Currency; +import com.ibm.icu.util.CurrencyAmount; + +/** + * {@icuenhanced java.text.DecimalFormat}.{@icu _usage_} + * + * DecimalFormat is a concrete subclass of {@link NumberFormat} that formats + * decimal numbers. It has a variety of features designed to make it possible to parse and + * format numbers in any locale, including support for Western, Arabic, or Indic digits. + * It also supports different flavors of numbers, including integers ("123"), fixed-point + * numbers ("123.4"), scientific notation ("1.23E4"), percentages ("12%"), and currency + * amounts ("$123.00", "USD123.00", "123.00 US dollars"). All of these flavors can be + * easily localized. + * + *

      To obtain a {@link NumberFormat} for a specific locale (including the default + * locale) call one of NumberFormat's factory methods such as {@link + * NumberFormat#getInstance}. Do not call the DecimalFormat constructors + * directly, unless you know what you are doing, since the {@link NumberFormat} factory + * methods may return subclasses other than DecimalFormat. If you need to + * customize the format object, do something like this: + * + *

      + * NumberFormat f = NumberFormat.getInstance(loc);
      + * if (f instanceof DecimalFormat) {
      + *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
      + * }
      + * + *

      Example Usage + * + * Print out a number using the localized number, currency, and percent + * format for each locale. + * + *

      + * Locale[] locales = NumberFormat.getAvailableLocales();
      + * double myNumber = -1234.56;
      + * NumberFormat format;
      + * for (int j=0; j<3; ++j) {
      + *     System.out.println("FORMAT");
      + *     for (int i = 0; i < locales.length; ++i) {
      + *         if (locales[i].getCountry().length() == 0) {
      + *            // Skip language-only locales
      + *            continue;
      + *         }
      + *         System.out.print(locales[i].getDisplayName());
      + *         switch (j) {
      + *         case 0:
      + *             format = NumberFormat.getInstance(locales[i]); break;
      + *         case 1:
      + *             format = NumberFormat.getCurrencyInstance(locales[i]); break;
      + *         default:
      + *             format = NumberFormat.getPercentInstance(locales[i]); break;
      + *         }
      + *         try {
      + *             // Assume format is a DecimalFormat
      + *             System.out.print(": " + ((DecimalFormat) format).toPattern()
      + *                              + " -> " + form.format(myNumber));
      + *         } catch (Exception e) {}
      + *         try {
      + *             System.out.println(" -> " + format.parse(form.format(myNumber)));
      + *         } catch (ParseException e) {}
      + *     }
      + * }
      + * + *

      Another example use getInstance(style).
      + * Print out a number using the localized number, currency, percent, + * scientific, integer, iso currency, and plural currency format for each locale. + * + *

      + * ULocale locale = new ULocale("en_US");
      + * double myNumber = 1234.56;
      + * for (int j=NumberFormat.NUMBERSTYLE; j<=NumberFormat.PLURALCURRENCYSTYLE; ++j) {
      + *     NumberFormat format = NumberFormat.getInstance(locale, j);
      + *     try {
      + *         // Assume format is a DecimalFormat
      + *         System.out.print(": " + ((DecimalFormat) format).toPattern()
      + *                          + " -> " + form.format(myNumber));
      + *     } catch (Exception e) {}
      + *     try {
      + *         System.out.println(" -> " + format.parse(form.format(myNumber)));
      + *     } catch (ParseException e) {}
      + * }
      + * + *

      Patterns

      + * + *

      A DecimalFormat consists of a pattern and a set of + * symbols. The pattern may be set directly using {@link #applyPattern}, or + * indirectly using other API methods which manipulate aspects of the pattern, such as the + * minimum number of integer digits. The symbols are stored in a {@link + * DecimalFormatSymbols} object. When using the {@link NumberFormat} factory methods, the + * pattern and symbols are read from ICU's locale data. + * + *

      Special Pattern Characters

      + * + *

      Many characters in a pattern are taken literally; they are matched during parsing + * and output unchanged during formatting. Special characters, on the other hand, stand + * for other characters, strings, or classes of characters. For example, the '#' + * character is replaced by a localized digit. Often the replacement character is the + * same as the pattern character; in the U.S. locale, the ',' grouping character is + * replaced by ','. However, the replacement is still happening, and if the symbols are + * modified, the grouping character changes. Some special characters affect the behavior + * of the formatter by their presence; for example, if the percent character is seen, then + * the value is multiplied by 100 before being displayed. + * + *

      To insert a special character in a pattern as a literal, that is, without any + * special meaning, the character must be quoted. There are some exceptions to this which + * are noted below. + * + *

      The characters listed here are used in non-localized patterns. Localized patterns + * use the corresponding characters taken from this formatter's {@link + * DecimalFormatSymbols} object instead, and these characters lose their special status. + * Two exceptions are the currency sign and quote, which are not localized. + * + *

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Symbol + * Location + * Localized? + * Meaning + *
      0 + * Number + * Yes + * Digit + *
      1-9 + * Number + * Yes + * '1' through '9' indicate rounding. + *
      @ + * Number + * No + * Significant digit + *
      # + * Number + * Yes + * Digit, zero shows as absent + *
      . + * Number + * Yes + * Decimal separator or monetary decimal separator + *
      - + * Number + * Yes + * Minus sign + *
      , + * Number + * Yes + * Grouping separator + *
      E + * Number + * Yes + * Separates mantissa and exponent in scientific notation. + * Need not be quoted in prefix or suffix. + *
      + + * Exponent + * Yes + * Prefix positive exponents with localized plus sign. + * Need not be quoted in prefix or suffix. + *
      ; + * Subpattern boundary + * Yes + * Separates positive and negative subpatterns + *
      % + * Prefix or suffix + * Yes + * Multiply by 100 and show as percentage + *
      \u2030 + * Prefix or suffix + * Yes + * Multiply by 1000 and show as per mille + *
      ¤ (\u00A4) + * Prefix or suffix + * No + * Currency sign, replaced by currency symbol. If + * doubled, replaced by international currency symbol. + * If tripled, replaced by currency plural names, for example, + * "US dollar" or "US dollars" for America. + * If present in a pattern, the monetary decimal separator + * is used instead of the decimal separator. + *
      ' + * Prefix or suffix + * No + * Used to quote special characters in a prefix or suffix, + * for example, "'#'#" formats 123 to + * "#123". To create a single quote + * itself, use two in a row: "# o''clock". + *
      * + * Prefix or suffix boundary + * Yes + * Pad escape, precedes pad character + *
      + *
      + * + *

      A DecimalFormat pattern contains a postive and negative subpattern, for + * example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric part, and a + * suffix. If there is no explicit negative subpattern, the negative subpattern is the + * localized minus sign prefixed to the positive subpattern. That is, "0.00" alone is + * equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves + * only to specify the negative prefix and suffix; the number of digits, minimal digits, + * and other characteristics are ignored in the negative subpattern. That means that + * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)". + * + *

      The prefixes, suffixes, and various symbols used for infinity, digits, thousands + * separators, decimal separators, etc. may be set to arbitrary values, and they will + * appear properly during formatting. However, care must be taken that the symbols and + * strings do not conflict, or parsing will be unreliable. For example, either the + * positive and negative prefixes or the suffixes must be distinct for {@link #parse} to + * be able to distinguish positive from negative values. Another example is that the + * decimal separator and thousands separator should be distinct characters, or parsing + * will be impossible. + * + *

      The grouping separator is a character that separates clusters of integer + * digits to make large numbers more legible. It commonly used for thousands, but in some + * locales it separates ten-thousands. The grouping size is the number of digits + * between the grouping separators, such as 3 for "100,000,000" or 4 for "1 0000 + * 0000". There are actually two different grouping sizes: One used for the least + * significant integer digits, the primary grouping size, and one used for all + * others, the secondary grouping size. In most locales these are the same, but + * sometimes they are different. For example, if the primary grouping interval is 3, and + * the secondary is 2, then this corresponds to the pattern "#,##,##0", and the number + * 123456789 is formatted as "12,34,56,789". If a pattern contains multiple grouping + * separators, the interval between the last one and the end of the integer defines the + * primary grouping size, and the interval between the last two defines the secondary + * grouping size. All others are ignored, so "#,##,###,####" == "###,###,####" == + * "##,#,###,####". + * + *

      Illegal patterns, such as "#.#.#" or "#.###,###", will cause + * DecimalFormat to throw an {@link IllegalArgumentException} with a message + * that describes the problem. + * + *

      Pattern BNF

      + * + *
      + * pattern    := subpattern (';' subpattern)?
      + * subpattern := prefix? number exponent? suffix?
      + * number     := (integer ('.' fraction)?) | sigDigits
      + * prefix     := '\u0000'..'\uFFFD' - specialCharacters
      + * suffix     := '\u0000'..'\uFFFD' - specialCharacters
      + * integer    := '#'* '0'* '0'
      + * fraction   := '0'* '#'*
      + * sigDigits  := '#'* '@' '@'* '#'*
      + * exponent   := 'E' '+'? '0'* '0'
      + * padSpec    := '*' padChar
      + * padChar    := '\u0000'..'\uFFFD' - quote
      + *  
      + * Notation:
      + *   X*       0 or more instances of X
      + *   X?       0 or 1 instances of X
      + *   X|Y      either X or Y
      + *   C..D     any character from C up to D, inclusive
      + *   S-T      characters in S, except those in T
      + * 
      + * The first subpattern is for positive numbers. The second (optional) + * subpattern is for negative numbers. + * + *

      Not indicated in the BNF syntax above: + * + *

        + * + *
      • The grouping separator ',' can occur inside the integer and sigDigits + * elements, between any two pattern characters of that element, as long as the integer or + * sigDigits element is not followed by the exponent element. + * + *
      • Two grouping intervals are recognized: That between the decimal point and the first + * grouping symbol, and that between the first and second grouping symbols. These + * intervals are identical in most locales, but in some locales they differ. For example, + * the pattern "#,##,###" formats the number 123456789 as + * "12,34,56,789". + * + *
      • The pad specifier padSpec may appear before the prefix, after the + * prefix, before the suffix, after the suffix, or not at all. + * + *
      • In place of '0', the digits '1' through '9' may be used to indicate a rounding + * increment. + * + *
      + * + *

      Parsing

      + * + *

      DecimalFormat parses all Unicode characters that represent decimal + * digits, as defined by {@link UCharacter#digit}. In addition, + * DecimalFormat also recognizes as digits the ten consecutive characters + * starting with the localized zero digit defined in the {@link DecimalFormatSymbols} + * object. During formatting, the {@link DecimalFormatSymbols}-based digits are output. + * + *

      During parsing, grouping separators are ignored. + * + *

      For currency parsing, the formatter is able to parse every currency style formats no + * matter which style the formatter is constructed with. For example, a formatter + * instance gotten from NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can + * parse formats such as "USD1.00" and "3.00 US dollars". + * + *

      If {@link #parse(String, ParsePosition)} fails to parse a string, it returns + * null and leaves the parse position unchanged. The convenience method + * {@link #parse(String)} indicates parse failure by throwing a {@link + * java.text.ParseException}. + * + *

      Formatting

      + * + *

      Formatting is guided by several parameters, all of which can be specified either + * using a pattern or using the API. The following description applies to formats that do + * not use scientific notation or significant + * digits. + * + *

      • If the number of actual integer digits exceeds the maximum integer + * digits, then only the least significant digits are shown. For example, 1997 is + * formatted as "97" if the maximum integer digits is set to 2. + * + *
      • If the number of actual integer digits is less than the minimum integer + * digits, then leading zeros are added. For example, 1997 is formatted as "01997" + * if the minimum integer digits is set to 5. + * + *
      • If the number of actual fraction digits exceeds the maximum fraction + * digits, then half-even rounding it performed to the maximum fraction digits. For + * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2. This + * behavior can be changed by specifying a rounding increment and a rounding mode. + * + *
      • If the number of actual fraction digits is less than the minimum fraction + * digits, then trailing zeros are added. For example, 0.125 is formatted as + * "0.1250" if the mimimum fraction digits is set to 4. + * + *
      • Trailing fractional zeros are not displayed if they occur j positions + * after the decimal, where j is less than the maximum fraction digits. For + * example, 0.10004 is formatted as "0.1" if the maximum fraction digits is four or less. + *
      + * + *

      Special Values + * + *

      NaN is represented as a single character, typically + * \uFFFD. This character is determined by the {@link + * DecimalFormatSymbols} object. This is the only value for which the prefixes and + * suffixes are not used. + * + *

      Infinity is represented as a single character, typically \u221E, + * with the positive or negative prefixes and suffixes applied. The infinity character is + * determined by the {@link DecimalFormatSymbols} object. + * + *

      Scientific Notation

      + * + *

      Numbers in scientific notation are expressed as the product of a mantissa and a + * power of ten, for example, 1234 can be expressed as 1.234 x 103. The + * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0), + * but it need not be. DecimalFormat supports arbitrary mantissas. + * DecimalFormat can be instructed to use scientific notation through the API + * or through the pattern. In a pattern, the exponent character immediately followed by + * one or more digit characters indicates scientific notation. Example: "0.###E0" formats + * the number 1234 as "1.234E3". + * + *

        + * + *
      • The number of digit characters after the exponent character gives the minimum + * exponent digit count. There is no maximum. Negative exponents are formatted using the + * localized minus sign, not the prefix and suffix from the pattern. This allows + * patterns such as "0.###E0 m/s". To prefix positive exponents with a localized plus + * sign, specify '+' between the exponent and the digits: "0.###E+0" will produce formats + * "1E+1", "1E+0", "1E-1", etc. (In localized patterns, use the localized plus sign + * rather than '+'.) + * + *
      • The minimum number of integer digits is achieved by adjusting the exponent. + * Example: 0.00123 formatted with "00.###E0" yields "12.3E-4". This only happens if + * there is no maximum number of integer digits. If there is a maximum, then the minimum + * number of integer digits is fixed at one. + * + *
      • The maximum number of integer digits, if present, specifies the exponent grouping. + * The most common use of this is to generate engineering notation, in which the + * exponent is a multiple of three, e.g., "##0.###E0". The number 12345 is formatted + * using "##0.####E0" as "12.345E3". + * + *
      • When using scientific notation, the formatter controls the digit counts using + * significant digits logic. The maximum number of significant digits limits the total + * number of integer and fraction digits that will be shown in the mantissa; it does not + * affect parsing. For example, 12345 formatted with "##0.##E0" is "12.3E3". See the + * section on significant digits for more details. + * + *
      • The number of significant digits shown is determined as follows: If + * areSignificantDigitsUsed() returns false, then the minimum number of significant digits + * shown is one, and the maximum number of significant digits shown is the sum of the + * minimum integer and maximum fraction digits, and is unaffected by the + * maximum integer digits. If this sum is zero, then all significant digits are shown. + * If areSignificantDigitsUsed() returns true, then the significant digit counts are + * specified by getMinimumSignificantDigits() and getMaximumSignificantDigits(). In this + * case, the number of integer digits is fixed at one, and there is no exponent grouping. + * + *
      • Exponential patterns may not contain grouping separators. + * + *
      + * + *

      Significant Digits

      + * + * DecimalFormat has two ways of controlling how many digits are shows: (a) + * significant digits counts, or (b) integer and fraction digit counts. Integer and + * fraction digit counts are described above. When a formatter is using significant + * digits counts, the number of integer and fraction digits is not specified directly, and + * the formatter settings for these counts are ignored. Instead, the formatter uses + * however many integer and fraction digits are required to display the specified number + * of significant digits. Examples: + * + *
      + * + * + * + * + * + * + *
      Pattern + * Minimum significant digits + * Maximum significant digits + * Number + * Output of format() + *
      @@@ + * 3 + * 3 + * 12345 + * 12300 + *
      @@@ + * 3 + * 3 + * 0.12345 + * 0.123 + *
      @@## + * 2 + * 4 + * 3.14159 + * 3.142 + *
      @@## + * 2 + * 4 + * 1.23004 + * 1.23 + *
      + *
      + * + *
        + * + *
      • Significant digit counts may be expressed using patterns that specify a minimum and + * maximum number of significant digits. These are indicated by the '@' and + * '#' characters. The minimum number of significant digits is the number of + * '@' characters. The maximum number of significant digits is the number of + * '@' characters plus the number of '#' characters following on + * the right. For example, the pattern "@@@" indicates exactly 3 significant + * digits. The pattern "@##" indicates from 1 to 3 significant digits. + * Trailing zero digits to the right of the decimal separator are suppressed after the + * minimum number of significant digits have been shown. For example, the pattern + * "@##" formats the number 0.1203 as "0.12". + * + *
      • If a pattern uses significant digits, it may not contain a decimal separator, nor + * the '0' pattern character. Patterns such as "@00" or + * "@.###" are disallowed. + * + *
      • Any number of '#' characters may be prepended to the left of the + * leftmost '@' character. These have no effect on the minimum and maximum + * significant digits counts, but may be used to position grouping separators. For + * example, "#,#@#" indicates a minimum of one significant digits, a maximum + * of two significant digits, and a grouping size of three. + * + *
      • In order to enable significant digits formatting, use a pattern containing the + * '@' pattern character. Alternatively, call {@link + * #setSignificantDigitsUsed setSignificantDigitsUsed(true)}. + * + *
      • In order to disable significant digits formatting, use a pattern that does not + * contain the '@' pattern character. Alternatively, call {@link + * #setSignificantDigitsUsed setSignificantDigitsUsed(false)}. + * + *
      • The number of significant digits has no effect on parsing. + * + *
      • Significant digits may be used together with exponential notation. Such patterns + * are equivalent to a normal exponential pattern with a minimum and maximum integer digit + * count of one, a minimum fraction digit count of getMinimumSignificantDigits() - + * 1, and a maximum fraction digit count of getMaximumSignificantDigits() - + * 1. For example, the pattern "@@###E0" is equivalent to + * "0.0###E0". + * + *
      • If signficant digits are in use, then the integer and fraction digit counts, as set + * via the API, are ignored. If significant digits are not in use, then the signficant + * digit counts, as set via the API, are ignored. + * + *
      + * + *

      Padding

      + * + *

      DecimalFormat supports padding the result of {@link #format} to a + * specific width. Padding may be specified either through the API or through the pattern + * syntax. In a pattern the pad escape character, followed by a single pad character, + * causes padding to be parsed and formatted. The pad escape character is '*' in + * unlocalized patterns, and can be localized using {@link + * DecimalFormatSymbols#setPadEscape}. For example, "$*x#,##0.00" formats + * 123 to "$xx123.00", and 1234 to "$1,234.00". + * + *

        + * + *
      • When padding is in effect, the width of the positive subpattern, including prefix + * and suffix, determines the format width. For example, in the pattern "* #0 + * o''clock", the format width is 10. + * + *
      • The width is counted in 16-bit code units (Java chars). + * + *
      • Some parameters which usually do not matter have meaning when padding is used, + * because the pattern width is significant with padding. In the pattern "* + * ##,##,#,##0.##", the format width is 14. The initial characters "##,##," do not affect + * the grouping size or maximum integer digits, but they do affect the format width. + * + *
      • Padding may be inserted at one of four locations: before the prefix, after the + * prefix, before the suffix, or after the suffix. If padding is specified in any other + * location, {@link #applyPattern} throws an {@link IllegalArgumentException}. If there + * is no prefix, before the prefix and after the prefix are equivalent, likewise for the + * suffix. + * + *
      • When specified in a pattern, the 16-bit char immediately following the + * pad escape is the pad character. This may be any character, including a special pattern + * character. That is, the pad escape escapes the following character. If there + * is no character after the pad escape, then the pattern is illegal. + * + *
      + * + *

      + * Rounding + * + *

      DecimalFormat supports rounding to a specific increment. For example, + * 1230 rounded to the nearest 50 is 1250. 1.234 rounded to the nearest 0.65 is 1.3. The + * rounding increment may be specified through the API or in a pattern. To specify a + * rounding increment in a pattern, include the increment in the pattern itself. "#,#50" + * specifies a rounding increment of 50. "#,##0.05" specifies a rounding increment of + * 0.05. + * + *

        + * + *
      • Rounding only affects the string produced by formatting. It does not affect + * parsing or change any numerical values. + * + *
      • A rounding mode determines how values are rounded; see the {@link + * com.ibm.icu.math.BigDecimal} documentation for a description of the modes. Rounding + * increments specified in patterns use the default mode, {@link + * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}. + * + *
      • Some locales use rounding in their currency formats to reflect the smallest + * currency denomination. + * + *
      • In a pattern, digits '1' through '9' specify rounding, but otherwise behave + * identically to digit '0'. + * + *
      + * + *

      Synchronization

      + * + *

      DecimalFormat objects are not synchronized. Multiple threads should + * not access one formatter concurrently. + * + * @see java.text.Format + * @see NumberFormat + * @author Mark Davis + * @author Alan Liu + * @stable ICU 2.0 + */ +public class DecimalFormat extends NumberFormat { + + private static final long serialVersionUID = 1L; + /** + * @internal + * @param delegate the NumberFormat to which to delegate + */ + public DecimalFormat(java.text.DecimalFormat delegate) { + super(delegate); + } + + /** + * Creates a DecimalFormat using the default pattern and symbols for the default + * locale. This is a convenient way to obtain a DecimalFormat when + * internationalization is not the main concern. + * + *

      To obtain standard formats for a given locale, use the factory methods on + * NumberFormat such as getNumberInstance. These factories will return the most + * appropriate sub-class of NumberFormat for a given locale. + * + * @see NumberFormat#getInstance + * @see NumberFormat#getNumberInstance + * @see NumberFormat#getCurrencyInstance + * @see NumberFormat#getPercentInstance + * @stable ICU 2.0 + */ + public DecimalFormat() { + this(new java.text.DecimalFormat()); + } + + /** + * Creates a DecimalFormat from the given pattern and the symbols for the default + * locale. This is a convenient way to obtain a DecimalFormat when + * internationalization is not the main concern. + * + *

      To obtain standard formats for a given locale, use the factory methods on + * NumberFormat such as getNumberInstance. These factories will return the most + * appropriate sub-class of NumberFormat for a given locale. + * + * @param pattern A non-localized pattern string. + * @throws IllegalArgumentException if the given pattern is invalid. + * @see NumberFormat#getInstance + * @see NumberFormat#getNumberInstance + * @see NumberFormat#getCurrencyInstance + * @see NumberFormat#getPercentInstance + * @stable ICU 2.0 + */ + public DecimalFormat(String pattern) { + this(new java.text.DecimalFormat(pattern)); + } + + /** + * Creates a DecimalFormat from the given pattern and symbols. Use this constructor + * when you need to completely customize the behavior of the format. + * + *

      To obtain standard formats for a given locale, use the factory methods on + * NumberFormat such as getInstance or getCurrencyInstance. If you need only minor + * adjustments to a standard format, you can modify the format returned by a + * NumberFormat factory method. + * + * @param pattern a non-localized pattern string + * @param symbols the set of symbols to be used + * @exception IllegalArgumentException if the given pattern is invalid + * @see NumberFormat#getInstance + * @see NumberFormat#getNumberInstance + * @see NumberFormat#getCurrencyInstance + * @see NumberFormat#getPercentInstance + * @see DecimalFormatSymbols + * @stable ICU 2.0 + */ + public DecimalFormat(String pattern, DecimalFormatSymbols symbols) { + this(new java.text.DecimalFormat(pattern, symbols.dfs)); + } + + /** + * Creates a DecimalFormat from the given pattern, symbols, information used for + * currency plural format, and format style. Use this constructor when you need to + * completely customize the behavior of the format. + * + *

      To obtain standard formats for a given locale, use the factory methods on + * NumberFormat such as getInstance or getCurrencyInstance. + * + *

      If you need only minor adjustments to a standard format, you can modify the + * format returned by a NumberFormat factory method using the setters. + * + *

      If you want to completely customize a decimal format, using your own + * DecimalFormatSymbols (such as group separators) and your own information for + * currency plural formatting (such as plural rule and currency plural patterns), you + * can use this constructor. + * + * @param pattern a non-localized pattern string + * @param symbols the set of symbols to be used + * @param infoInput the information used for currency plural format, including + * currency plural patterns and plural rules. + * @param style the decimal formatting style, it is one of the following values: + * NumberFormat.NUMBERSTYLE; NumberFormat.CURRENCYSTYLE; NumberFormat.PERCENTSTYLE; + * NumberFormat.SCIENTIFICSTYLE; NumberFormat.INTEGERSTYLE; + * NumberFormat.ISOCURRENCYSTYLE; NumberFormat.PLURALCURRENCYSTYLE; + * @stable ICU 4.2 + */ + public DecimalFormat(String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput, + int style) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * {@inheritDoc} + * @stable ICU 2.0 + */ + public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) { + return super.format(number, result, fieldPosition); + } + + /** + * @stable ICU 2.0 + */ + // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean + public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) { + return super.format(number, result, fieldPosition); + } + + /** + * Formats a BigInteger number. + * + * @stable ICU 2.0 + */ + public StringBuffer format(BigInteger number, StringBuffer result, + FieldPosition fieldPosition) { + return super.format(number, result, fieldPosition); + } + + /** + * Formats a BigDecimal number. + * + * @stable ICU 2.0 + */ + public StringBuffer format(java.math.BigDecimal number, StringBuffer result, + FieldPosition fieldPosition) { + return super.format(number, result, fieldPosition); + } + + /** + * Formats a BigDecimal number. + * + * @stable ICU 2.0 + */ + public StringBuffer format(BigDecimal number, StringBuffer result, + FieldPosition fieldPosition) { + return super.format(number, result, fieldPosition); + } + + /** + * Parses the given string, returning a Number object to represent the + * parsed value. Double objects are returned to represent non-integral + * values which cannot be stored in a BigDecimal. These are + * NaN, infinity, -infinity, and -0.0. If {@link #isParseBigDecimal()} is + * false (the default), all other values are returned as Long, + * BigInteger, or BigDecimal values, in that order of + * preference. If {@link #isParseBigDecimal()} is true, all other values are returned + * as BigDecimal valuse. If the parse fails, null is returned. + * + * @param text the string to be parsed + * @param parsePosition defines the position where parsing is to begin, and upon + * return, the position where parsing left off. If the position has not changed upon + * return, then parsing failed. + * @return a Number object with the parsed value or + * null if the parse failed + * @stable ICU 2.0 + */ + public Number parse(String text, ParsePosition parsePosition) { + return super.parse(text, parsePosition); + } + + /** + * Parses text from the given string as a CurrencyAmount. Unlike the parse() method, + * this method will attempt to parse a generic currency name, searching for a match of + * this object's locale's currency display names, or for a 3-letter ISO currency + * code. This method will fail if this format is not a currency format, that is, if it + * does not contain the currency pattern symbol (U+00A4) in its prefix or suffix. + * + * @param text the string to parse + * @param pos input-output position; on input, the position within text to match; must + * have 0 <= pos.getIndex() < text.length(); on output, the position after the last + * matched character. If the parse fails, the position in unchanged upon output. + * @return a CurrencyAmount, or null upon failure + */ + CurrencyAmount parseCurrency(String text, ParsePosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns a copy of the decimal format symbols used by this format. + * + * @return desired DecimalFormatSymbols + * @see DecimalFormatSymbols + * @stable ICU 2.0 + */ + public DecimalFormatSymbols getDecimalFormatSymbols() { + return new DecimalFormatSymbols(((java.text.DecimalFormat)numberFormat).getDecimalFormatSymbols()); + } + + /** + * Sets the decimal format symbols used by this format. The format uses a copy of the + * provided symbols. + * + * @param newSymbols desired DecimalFormatSymbols + * @see DecimalFormatSymbols + * @stable ICU 2.0 + */ + public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { + ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(newSymbols.dfs); + } + + /** + * Returns the positive prefix. + * + *

      Examples: +123, $123, sFr123 + * @return the prefix + * @stable ICU 2.0 + */ + public String getPositivePrefix() { + return ((java.text.DecimalFormat)numberFormat).getPositivePrefix(); + } + + /** + * Sets the positive prefix. + * + *

      Examples: +123, $123, sFr123 + * @param newValue the prefix + * @stable ICU 2.0 + */ + public void setPositivePrefix(String newValue) { + ((java.text.DecimalFormat)numberFormat).setPositivePrefix(newValue); + } + + /** + * Returns the negative prefix. + * + *

      Examples: -123, ($123) (with negative suffix), sFr-123 + * + * @return the prefix + * @stable ICU 2.0 + */ + public String getNegativePrefix() { + return ((java.text.DecimalFormat)numberFormat).getNegativePrefix(); + } + + /** + * Sets the negative prefix. + * + *

      Examples: -123, ($123) (with negative suffix), sFr-123 + * @param newValue the prefix + * @stable ICU 2.0 + */ + public void setNegativePrefix(String newValue) { + ((java.text.DecimalFormat)numberFormat).setNegativePrefix(newValue); + } + + /** + * Returns the positive suffix. + * + *

      Example: 123% + * + * @return the suffix + * @stable ICU 2.0 + */ + public String getPositiveSuffix() { + return ((java.text.DecimalFormat)numberFormat).getPositiveSuffix(); + } + + /** + * Sets the positive suffix. + * + *

      Example: 123% + * @param newValue the suffix + * @stable ICU 2.0 + */ + public void setPositiveSuffix(String newValue) { + ((java.text.DecimalFormat)numberFormat).setPositiveSuffix(newValue); + } + + /** + * Returns the negative suffix. + * + *

      Examples: -123%, ($123) (with positive suffixes) + * + * @return the suffix + * @stable ICU 2.0 + */ + public String getNegativeSuffix() { + return ((java.text.DecimalFormat)numberFormat).getNegativeSuffix(); + } + + /** + * Sets the positive suffix. + * + *

      Examples: 123% + * @param newValue the suffix + * @stable ICU 2.0 + */ + public void setNegativeSuffix(String newValue) { + ((java.text.DecimalFormat)numberFormat).setNegativeSuffix(newValue); + } + + /** + * Returns the multiplier for use in percent, permill, etc. For a percentage, set the + * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent + * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be + * 1000. + * + *

      Examples: with 100, 1.23 -> "123", and "123" -> 1.23 + * + * @return the multiplier + * @stable ICU 2.0 + */ + public int getMultiplier() { + return ((java.text.DecimalFormat)numberFormat).getMultiplier(); + } + + /** + * Sets the multiplier for use in percent, permill, etc. For a percentage, set the + * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent + * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be + * 1000. + * + *

      Examples: with 100, 1.23 -> "123", and "123" -> 1.23 + * + * @param newValue the multiplier + * @stable ICU 2.0 + */ + public void setMultiplier(int newValue) { + ((java.text.DecimalFormat)numberFormat).setMultiplier(newValue); + } + + /** + * {@icu} Returns the rounding increment. + * + * @return A positive rounding increment, or null if rounding is not in + * effect. + * @see #setRoundingIncrement + * @see #getRoundingMode + * @see #setRoundingMode + * @stable ICU 2.0 + */ + public BigDecimal getRoundingIncrement() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the rounding increment. This method also controls whether rounding is + * enabled. + * + * @param newValue A positive rounding increment, or null or + * BigDecimal(0.0) to disable rounding. + * @throws IllegalArgumentException if newValue is < 0.0 + * @see #getRoundingIncrement + * @see #getRoundingMode + * @see #setRoundingMode + * @stable ICU 2.0 + */ + public void setRoundingIncrement(java.math.BigDecimal newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the rounding increment. This method also controls whether rounding is + * enabled. + * + * @param newValue A positive rounding increment, or null or + * BigDecimal(0.0) to disable rounding. + * @throws IllegalArgumentException if newValue is < 0.0 + * @see #getRoundingIncrement + * @see #getRoundingMode + * @see #setRoundingMode + * @stable ICU 3.6 + */ + public void setRoundingIncrement(BigDecimal newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the rounding increment. This method also controls whether rounding is + * enabled. + * + * @param newValue A positive rounding increment, or 0.0 to disable rounding. + * @throws IllegalArgumentException if newValue is < 0.0 + * @see #getRoundingIncrement + * @see #getRoundingMode + * @see #setRoundingMode + * @stable ICU 2.0 + */ + public void setRoundingIncrement(double newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the rounding mode. + * + * @return A rounding mode, between BigDecimal.ROUND_UP and + * BigDecimal.ROUND_UNNECESSARY. + * @see #setRoundingIncrement + * @see #getRoundingIncrement + * @see #setRoundingMode + * @see java.math.BigDecimal + * @stable ICU 2.0 + */ + public int getRoundingMode() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the rounding mode. This has no effect unless the rounding increment is greater + * than zero. + * + * @param roundingMode A rounding mode, between BigDecimal.ROUND_UP and + * BigDecimal.ROUND_UNNECESSARY. + * @exception IllegalArgumentException if roundingMode is unrecognized. + * @see #setRoundingIncrement + * @see #getRoundingIncrement + * @see #getRoundingMode + * @see java.math.BigDecimal + * @stable ICU 2.0 + */ + public void setRoundingMode(int roundingMode) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the width to which the output of format() is padded. The width is + * counted in 16-bit code units. + * + * @return the format width, or zero if no padding is in effect + * @see #setFormatWidth + * @see #getPadCharacter + * @see #setPadCharacter + * @see #getPadPosition + * @see #setPadPosition + * @stable ICU 2.0 + */ + public int getFormatWidth() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the width to which the output of format() is + * padded. The width is counted in 16-bit code units. This method + * also controls whether padding is enabled. + * + * @param width the width to which to pad the result of + * format(), or zero to disable padding + * @exception IllegalArgumentException if width is < 0 + * @see #getFormatWidth + * @see #getPadCharacter + * @see #setPadCharacter + * @see #getPadPosition + * @see #setPadPosition + * @stable ICU 2.0 + */ + public void setFormatWidth(int width) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the character used to pad to the format width. The default is ' '. + * + * @return the pad character + * @see #setFormatWidth + * @see #getFormatWidth + * @see #setPadCharacter + * @see #getPadPosition + * @see #setPadPosition + * @stable ICU 2.0 + */ + public char getPadCharacter() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the character used to pad to the format width. If padding is not + * enabled, then this will take effect if padding is later enabled. + * + * @param padChar the pad character + * @see #setFormatWidth + * @see #getFormatWidth + * @see #getPadCharacter + * @see #getPadPosition + * @see #setPadPosition + * @stable ICU 2.0 + */ + public void setPadCharacter(char padChar) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the position at which padding will take place. This is the location at + * which padding will be inserted if the result of format() is shorter + * than the format width. + * + * @return the pad position, one of PAD_BEFORE_PREFIX, + * PAD_AFTER_PREFIX, PAD_BEFORE_SUFFIX, or + * PAD_AFTER_SUFFIX. + * @see #setFormatWidth + * @see #getFormatWidth + * @see #setPadCharacter + * @see #getPadCharacter + * @see #setPadPosition + * @see #PAD_BEFORE_PREFIX + * @see #PAD_AFTER_PREFIX + * @see #PAD_BEFORE_SUFFIX + * @see #PAD_AFTER_SUFFIX + * @stable ICU 2.0 + */ + public int getPadPosition() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the position at which padding will take place. This is the location at + * which padding will be inserted if the result of format() is shorter + * than the format width. This has no effect unless padding is enabled. + * + * @param padPos the pad position, one of PAD_BEFORE_PREFIX, + * PAD_AFTER_PREFIX, PAD_BEFORE_SUFFIX, or + * PAD_AFTER_SUFFIX. + * @exception IllegalArgumentException if the pad position in unrecognized + * @see #setFormatWidth + * @see #getFormatWidth + * @see #setPadCharacter + * @see #getPadCharacter + * @see #getPadPosition + * @see #PAD_BEFORE_PREFIX + * @see #PAD_AFTER_PREFIX + * @see #PAD_BEFORE_SUFFIX + * @see #PAD_AFTER_SUFFIX + * @stable ICU 2.0 + */ + public void setPadPosition(int padPos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns whether or not scientific notation is used. + * + * @return true if this object formats and parses scientific notation + * @see #setScientificNotation + * @see #getMinimumExponentDigits + * @see #setMinimumExponentDigits + * @see #isExponentSignAlwaysShown + * @see #setExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public boolean isScientificNotation() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets whether or not scientific notation is used. When scientific notation is + * used, the effective maximum number of integer digits is <= 8. If the maximum number + * of integer digits is set to more than 8, the effective maximum will be 1. This + * allows this call to generate a 'default' scientific number format without + * additional changes. + * + * @param useScientific true if this object formats and parses scientific notation + * @see #isScientificNotation + * @see #getMinimumExponentDigits + * @see #setMinimumExponentDigits + * @see #isExponentSignAlwaysShown + * @see #setExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public void setScientificNotation(boolean useScientific) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the minimum exponent digits that will be shown. + * + * @return the minimum exponent digits that will be shown + * @see #setScientificNotation + * @see #isScientificNotation + * @see #setMinimumExponentDigits + * @see #isExponentSignAlwaysShown + * @see #setExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public byte getMinimumExponentDigits() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the minimum exponent digits that will be shown. This has no effect + * unless scientific notation is in use. + * + * @param minExpDig a value >= 1 indicating the fewest exponent + * digits that will be shown + * @exception IllegalArgumentException if minExpDig < 1 + * @see #setScientificNotation + * @see #isScientificNotation + * @see #getMinimumExponentDigits + * @see #isExponentSignAlwaysShown + * @see #setExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public void setMinimumExponentDigits(byte minExpDig) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns whether the exponent sign is always shown. + * + * @return true if the exponent is always prefixed with either the localized minus + * sign or the localized plus sign, false if only negative exponents are prefixed with + * the localized minus sign. + * @see #setScientificNotation + * @see #isScientificNotation + * @see #setMinimumExponentDigits + * @see #getMinimumExponentDigits + * @see #setExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public boolean isExponentSignAlwaysShown() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets whether the exponent sign is always shown. This has no effect unless + * scientific notation is in use. + * + * @param expSignAlways true if the exponent is always prefixed with either the + * localized minus sign or the localized plus sign, false if only negative exponents + * are prefixed with the localized minus sign. + * @see #setScientificNotation + * @see #isScientificNotation + * @see #setMinimumExponentDigits + * @see #getMinimumExponentDigits + * @see #isExponentSignAlwaysShown + * @stable ICU 2.0 + */ + public void setExponentSignAlwaysShown(boolean expSignAlways) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the grouping size. Grouping size is the number of digits between grouping + * separators in the integer portion of a number. For example, in the number + * "123,456.78", the grouping size is 3. + * + * @see #setGroupingSize + * @see NumberFormat#isGroupingUsed + * @see DecimalFormatSymbols#getGroupingSeparator + * @stable ICU 2.0 + */ + public int getGroupingSize() { + return ((java.text.DecimalFormat)numberFormat).getGroupingSize(); + } + + /** + * Sets the grouping size. Grouping size is the number of digits between grouping + * separators in the integer portion of a number. For example, in the number + * "123,456.78", the grouping size is 3. + * + * @see #getGroupingSize + * @see NumberFormat#setGroupingUsed + * @see DecimalFormatSymbols#setGroupingSeparator + * @stable ICU 2.0 + */ + public void setGroupingSize(int newValue) { + ((java.text.DecimalFormat)numberFormat).setGroupingSize(newValue); + } + + /** + * {@icu} Returns the secondary grouping size. In some locales one grouping interval + * is used for the least significant integer digits (the primary grouping size), and + * another is used for all others (the secondary grouping size). A formatter + * supporting a secondary grouping size will return a positive integer unequal to the + * primary grouping size returned by getGroupingSize(). For example, if + * the primary grouping size is 4, and the secondary grouping size is 2, then the + * number 123456789 formats as "1,23,45,6789", and the pattern appears as "#,##,###0". + * + * @return the secondary grouping size, or a value less than one if there is none + * @see #setSecondaryGroupingSize + * @see NumberFormat#isGroupingUsed + * @see DecimalFormatSymbols#getGroupingSeparator + * @stable ICU 2.0 + */ + public int getSecondaryGroupingSize() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the secondary grouping size. If set to a value less than 1, then + * secondary grouping is turned off, and the primary grouping size is used for all + * intervals, not just the least significant. + * + * @see #getSecondaryGroupingSize + * @see NumberFormat#setGroupingUsed + * @see DecimalFormatSymbols#setGroupingSeparator + * @stable ICU 2.0 + */ + public void setSecondaryGroupingSize(int newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the MathContext used by this format. + * + * @return desired MathContext + * @see #getMathContext + * @stable ICU 4.2 + */ + public MathContext getMathContextICU() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the MathContext used by this format. + * + * @return desired MathContext + * @see #getMathContext + * @stable ICU 4.2 + */ + public java.math.MathContext getMathContext() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the MathContext used by this format. + * + * @param newValue desired MathContext + * @see #getMathContext + * @stable ICU 4.2 + */ + public void setMathContextICU(MathContext newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the MathContext used by this format. + * + * @param newValue desired MathContext + * @see #getMathContext + * @stable ICU 4.2 + */ + public void setMathContext(java.math.MathContext newValue) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the behavior of the decimal separator with integers. (The decimal + * separator will always appear with decimals.)

      Example: Decimal ON: 12345 -> + * 12345.; OFF: 12345 -> 12345 + * + * @stable ICU 2.0 + */ + public boolean isDecimalSeparatorAlwaysShown() { + return ((java.text.DecimalFormat)numberFormat).isDecimalSeparatorAlwaysShown(); + } + + /** + * Sets the behavior of the decimal separator with integers. (The decimal separator + * will always appear with decimals.) + * + *

      This only affects formatting, and only where there might be no digits after the + * decimal point, e.g., if true, 3456.00 -> "3,456." if false, 3456.00 -> "3456" This + * is independent of parsing. If you want parsing to stop at the decimal point, use + * setParseIntegerOnly. + * + *

      + * Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 + * + * @stable ICU 2.0 + */ + public void setDecimalSeparatorAlwaysShown(boolean newValue) { + ((java.text.DecimalFormat)numberFormat).setDecimalSeparatorAlwaysShown(newValue); + } + + /** + * {@icu} Returns a copy of the CurrencyPluralInfo used by this format. It might + * return null if the decimal format is not a plural type currency decimal + * format. Plural type currency decimal format means either the pattern in the decimal + * format contains 3 currency signs, or the decimal format is initialized with + * PLURALCURRENCYSTYLE. + * + * @return desired CurrencyPluralInfo + * @see CurrencyPluralInfo + * @stable ICU 4.2 + */ + public CurrencyPluralInfo getCurrencyPluralInfo() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the CurrencyPluralInfo used by this format. The format uses a copy of + * the provided information. + * + * @param newInfo desired CurrencyPluralInfo + * @see CurrencyPluralInfo + * @stable ICU 4.2 + */ + public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Overrides clone. + * @stable ICU 2.0 + */ + public Object clone() { + return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)numberFormat.clone()); + } + + /** + * Overrides equals. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) { + return super.equals(obj); + } + + /** + * Overrides hashCode. + * @stable ICU 2.0 + */ + public int hashCode() { + return super.hashCode(); + } + + /** + * Synthesizes a pattern string that represents the current state of this Format + * object. + * + * @see #applyPattern + * @stable ICU 2.0 + */ + public String toPattern() { + return ((java.text.DecimalFormat)numberFormat).toPattern(); + } + + /** + * Synthesizes a localized pattern string that represents the current state of this + * Format object. + * + * @see #applyPattern + * @stable ICU 2.0 + */ + public String toLocalizedPattern() { + return ((java.text.DecimalFormat)numberFormat).toLocalizedPattern(); + } + + /** + * Formats the object to an attributed string, and return the corresponding iterator. + * + * @stable ICU 3.6 + */ + public AttributedCharacterIterator formatToCharacterIterator(Object obj) { + AttributedCharacterIterator it = numberFormat.formatToCharacterIterator(obj); + + // Extract formatted String first + StringBuilder sb = new StringBuilder(); + for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { + sb.append(c); + } + + // Create AttributedString + AttributedString attrstr = new AttributedString(sb.toString()); + + // Map JDK Field to ICU Field + int idx = 0; + it.first(); + while (idx < it.getEndIndex()) { + int end = it.getRunLimit(); + Map attributes = it.getAttributes(); + if (attributes != null) { + for (Entry entry : attributes.entrySet()) { + Attribute attr = entry.getKey(); + Object val = entry.getValue(); + if (attr.equals(java.text.NumberFormat.Field.CURRENCY)) { + val = attr = Field.CURRENCY; + } else if (attr.equals(java.text.NumberFormat.Field.DECIMAL_SEPARATOR)) { + val = attr = Field.DECIMAL_SEPARATOR; + } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT)) { + val = attr = Field.EXPONENT; + } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SIGN)) { + val = attr = Field.EXPONENT_SIGN; + } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SYMBOL)) { + val = attr = Field.EXPONENT_SYMBOL; + } else if (attr.equals(java.text.NumberFormat.Field.FRACTION)) { + val = attr = Field.FRACTION; + } else if (attr.equals(java.text.NumberFormat.Field.GROUPING_SEPARATOR)) { + val = attr = Field.GROUPING_SEPARATOR; + } else if (attr.equals(java.text.NumberFormat.Field.INTEGER)) { + val = attr = Field.INTEGER; + } else if (attr.equals(java.text.NumberFormat.Field.PERCENT)) { + val = attr = Field.PERCENT; + } else if (attr.equals(java.text.NumberFormat.Field.PERMILLE)) { + val = attr = Field.PERMILLE; + } else if (attr.equals(java.text.NumberFormat.Field.SIGN)) { + val = attr = Field.SIGN; + } + attrstr.addAttribute(attr, val, idx, end); + } + } + idx = end; + while (it.getIndex() < idx) { + it.next(); + } + } + + return attrstr.getIterator(); + } + + /** + * Applies the given pattern to this Format object. A pattern is a short-hand + * specification for the various formatting properties. These properties can also be + * changed individually through the various setter methods. + * + *

      There is no limit to integer digits are set by this routine, since that is the + * typical end-user desire; use setMaximumInteger if you want to set a real value. For + * negative numbers, use a second pattern, separated by a semicolon + * + *

      Example "#,#00.0#" -> 1,234.56 + * + *

      This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 + * fraction digits. + * + *

      Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses. + * + *

      In negative patterns, the minimum and maximum counts are ignored; these are + * presumed to be set in the positive pattern. + * + * @stable ICU 2.0 + */ + public void applyPattern(String pattern) { + ((java.text.DecimalFormat)numberFormat).applyPattern(pattern); + } + + /** + * Applies the given pattern to this Format object. The pattern is assumed to be in a + * localized notation. A pattern is a short-hand specification for the various + * formatting properties. These properties can also be changed individually through + * the various setter methods. + * + *

      There is no limit to integer digits are set by this routine, since that is the + * typical end-user desire; use setMaximumInteger if you want to set a real value. For + * negative numbers, use a second pattern, separated by a semicolon + * + *

      Example "#,#00.0#" -> 1,234.56 + * + *

      This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 + * fraction digits. + * + *

      Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses. + * + *

      In negative patterns, the minimum and maximum counts are ignored; these are + * presumed to be set in the positive pattern. + * + * @stable ICU 2.0 + */ + public void applyLocalizedPattern(String pattern) { + ((java.text.DecimalFormat)numberFormat).applyLocalizedPattern(pattern); + } + + /** + * Sets the maximum number of digits allowed in the integer portion of a number. This + * override limits the integer digit count to 309. + * + * @see NumberFormat#setMaximumIntegerDigits + * @stable ICU 2.0 + */ + public void setMaximumIntegerDigits(int newValue) { + super.setMaximumIntegerDigits(newValue); + } + + /** + * Sets the minimum number of digits allowed in the integer portion of a number. This + * override limits the integer digit count to 309. + * + * @see NumberFormat#setMinimumIntegerDigits + * @stable ICU 2.0 + */ + public void setMinimumIntegerDigits(int newValue) { + super.setMinimumIntegerDigits(newValue); + } + + /** + * {@icu} Returns the minimum number of significant digits that will be + * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()} + * returns true. + * + * @return the fewest significant digits that will be shown + * @stable ICU 3.0 + */ + public int getMinimumSignificantDigits() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the maximum number of significant digits that will be + * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()} + * returns true. + * + * @return the most significant digits that will be shown + * @stable ICU 3.0 + */ + public int getMaximumSignificantDigits() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the minimum number of significant digits that will be displayed. If + * min is less than one then it is set to one. If the maximum significant + * digits count is less than min, then it is set to + * min. This value has no effect unless {@link #areSignificantDigitsUsed()} + * returns true. + * + * @param min the fewest significant digits to be shown + * @stable ICU 3.0 + */ + public void setMinimumSignificantDigits(int min) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets the maximum number of significant digits that will be displayed. If + * max is less than one then it is set to one. If the minimum significant + * digits count is greater than max, then it is set to + * max. This value has no effect unless {@link #areSignificantDigitsUsed()} + * returns true. + * + * @param max the most significant digits to be shown + * @stable ICU 3.0 + */ + public void setMaximumSignificantDigits(int max) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns true if significant digits are in use or false if integer and + * fraction digit counts are in use. + * + * @return true if significant digits are in use + * @stable ICU 3.0 + */ + public boolean areSignificantDigitsUsed() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Sets whether significant digits are in use, or integer and fraction digit + * counts are in use. + * + * @param useSignificantDigits true to use significant digits, or false to use integer + * and fraction digit counts + * @stable ICU 3.0 + */ + public void setSignificantDigitsUsed(boolean useSignificantDigits) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the Currency object used to display currency amounts. This takes + * effect immediately, if this format is a currency format. If this format is not a + * currency format, then the currency object is used if and when this object becomes a + * currency format through the application of a new pattern. + * + * @param theCurrency new currency object to use. Must not be null. + * @stable ICU 2.2 + */ + public void setCurrency(Currency theCurrency) { + super.setCurrency(theCurrency); + } + + /** + * Sets the maximum number of digits allowed in the fraction portion of a number. This + * override limits the fraction digit count to 340. + * + * @see NumberFormat#setMaximumFractionDigits + * @stable ICU 2.0 + */ + public void setMaximumFractionDigits(int newValue) { + super.setMaximumFractionDigits(newValue); + } + + /** + * Sets the minimum number of digits allowed in the fraction portion of a number. This + * override limits the fraction digit count to 340. + * + * @see NumberFormat#setMinimumFractionDigits + * @stable ICU 2.0 + */ + public void setMinimumFractionDigits(int newValue) { + super.setMinimumFractionDigits(newValue); + } + + /** + * Sets whether {@link #parse(String, ParsePosition)} returns BigDecimal. The + * default value is false. + * + * @param value true if {@link #parse(String, ParsePosition)} + * returns BigDecimal. + * @stable ICU 3.6 + */ + public void setParseBigDecimal(boolean value) { + ((java.text.DecimalFormat)numberFormat).setParseBigDecimal(value); + } + + /** + * Returns whether {@link #parse(String, ParsePosition)} returns BigDecimal. + * + * @return true if {@link #parse(String, ParsePosition)} returns BigDecimal. + * @stable ICU 3.6 + */ + public boolean isParseBigDecimal() { + return ((java.text.DecimalFormat)numberFormat).isParseBigDecimal(); + } + + // ---------------------------------------------------------------------- + // CONSTANTS + // ---------------------------------------------------------------------- + + /** + * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to + * specify pad characters inserted before the prefix. + * + * @see #setPadPosition + * @see #getPadPosition + * @see #PAD_AFTER_PREFIX + * @see #PAD_BEFORE_SUFFIX + * @see #PAD_AFTER_SUFFIX + * @stable ICU 2.0 + */ + public static final int PAD_BEFORE_PREFIX = 0; + + /** + * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to + * specify pad characters inserted after the prefix. + * + * @see #setPadPosition + * @see #getPadPosition + * @see #PAD_BEFORE_PREFIX + * @see #PAD_BEFORE_SUFFIX + * @see #PAD_AFTER_SUFFIX + * @stable ICU 2.0 + */ + public static final int PAD_AFTER_PREFIX = 1; + + /** + * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to + * specify pad characters inserted before the suffix. + * + * @see #setPadPosition + * @see #getPadPosition + * @see #PAD_BEFORE_PREFIX + * @see #PAD_AFTER_PREFIX + * @see #PAD_AFTER_SUFFIX + * @stable ICU 2.0 + */ + public static final int PAD_BEFORE_SUFFIX = 2; + + /** + * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to + * specify pad characters inserted after the suffix. + * + * @see #setPadPosition + * @see #getPadPosition + * @see #PAD_BEFORE_PREFIX + * @see #PAD_AFTER_PREFIX + * @see #PAD_BEFORE_SUFFIX + * @stable ICU 2.0 + */ + public static final int PAD_AFTER_SUFFIX = 3; +} + +// eof diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java index 9436fa6a3da..51fc72ac54d 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java @@ -1,350 +1,350 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.text; - - -import java.io.Serializable; -import java.util.Locale; - -import com.ibm.icu.util.ULocale; - -/** - * This class represents the set of symbols (such as the decimal separator, the - * grouping separator, and so on) needed by DecimalFormat to format - * numbers. DecimalFormat creates for itself an instance of - * DecimalFormatSymbols from its locale data. If you need to - * change any of these symbols, you can get the - * DecimalFormatSymbols object from your DecimalFormat - * and modify it. - * - *

      This is an enhanced version of DecimalFormatSymbols that - * is based on the standard version in the JDK. New or changed functionality - * is labeled - * NEW. - * - * @see java.util.Locale - * @see DecimalFormat - * @author Mark Davis - * @author Alan Liu - * @stable ICU 2.0 - */ -final public class DecimalFormatSymbols implements Cloneable, Serializable { - - private static final long serialVersionUID =1L; - - /** - * @internal - */ - public final java.text.DecimalFormatSymbols dfs; - - /** - * @internal - */ - public DecimalFormatSymbols(java.text.DecimalFormatSymbols delegate) { - this.dfs = delegate; - } - - /** - * Create a DecimalFormatSymbols object for the default locale. - * @stable ICU 2.0 - */ - public DecimalFormatSymbols() { - this(new java.text.DecimalFormatSymbols()); - } - - /** - * Create a DecimalFormatSymbols object for the given locale. - * @param locale the locale - * @stable ICU 2.0 - */ - public DecimalFormatSymbols(Locale locale) { - this(new java.text.DecimalFormatSymbols(locale)); - } - - /** - * Create a DecimalFormatSymbols object for the given locale. - * @param locale the locale - * @stable ICU 3.2 - */ - public DecimalFormatSymbols(ULocale locale) { - this(new java.text.DecimalFormatSymbols(locale.toLocale())); - } - - /** - * Return the character used for zero. Different for Arabic, etc. - * @return the character - * @stable ICU 2.0 - */ - public char getZeroDigit() { - return dfs.getZeroDigit(); - } - - /** - * Set the character used for zero. - * @param zeroDigit the zero character. - * @stable ICU 2.0 - */ - public void setZeroDigit(char zeroDigit) { - dfs.setZeroDigit(zeroDigit); - } - - /** - * Return the character used for thousands separator. Different for French, etc. - * @return the thousands character - * @stable ICU 2.0 - */ - public char getGroupingSeparator() { - return dfs.getGroupingSeparator(); - } - - /** - * Set the character used for thousands separator. Different for French, etc. - * @param groupingSeparator the thousands character - * @stable ICU 2.0 - */ - public void setGroupingSeparator(char groupingSeparator) { - dfs.setGroupingSeparator(groupingSeparator); - } - - /** - * Return the character used for decimal sign. Different for French, etc. - * @return the decimal character - * @stable ICU 2.0 - */ - public char getDecimalSeparator() { - return dfs.getDecimalSeparator(); - } - - /** - * Set the character used for decimal sign. Different for French, etc. - * @param decimalSeparator the decimal character - * @stable ICU 2.0 - */ - public void setDecimalSeparator(char decimalSeparator) { - dfs.setDecimalSeparator(decimalSeparator); - } - - /** - * Return the character used for mille percent sign. Different for Arabic, etc. - * @return the mille percent character - * @stable ICU 2.0 - */ - public char getPerMill() { - return dfs.getPerMill(); - } - - /** - * Set the character used for mille percent sign. Different for Arabic, etc. - * @param perMill the mille percent character - * @stable ICU 2.0 - */ - public void setPerMill(char perMill) { - dfs.setPerMill(perMill); - } - - /** - * Return the character used for percent sign. Different for Arabic, etc. - * @return the percent character - * @stable ICU 2.0 - */ - public char getPercent() { - return dfs.getPercent(); - } - - /** - * Set the character used for percent sign. Different for Arabic, etc. - * @param percent the percent character - * @stable ICU 2.0 - */ - public void setPercent(char percent) { - dfs.setPercent(percent); - } - - /** - * Return the character used for a digit in a pattern. - * @return the digit pattern character - * @stable ICU 2.0 - */ - public char getDigit() { - return dfs.getDigit(); - } - - /** - * Set the character used for a digit in a pattern. - * @param digit the digit pattern character - * @stable ICU 2.0 - */ - public void setDigit(char digit) { - dfs.setDigit(digit); - } - - /** - * Return the character used to separate positive and negative subpatterns - * in a pattern. - * @return the pattern separator character - * @stable ICU 2.0 - */ - public char getPatternSeparator() { - return dfs.getPatternSeparator(); - } - - /** - * Set the character used to separate positive and negative subpatterns - * in a pattern. - * @param patternSeparator the pattern separator character - * @stable ICU 2.0 - */ - public void setPatternSeparator(char patternSeparator) { - dfs.setPatternSeparator(patternSeparator); - } - - /** - * Return the String used to represent infinity. Almost always left - * unchanged. - * @return the Infinity string - * @stable ICU 2.0 - */ - public String getInfinity() { - return dfs.getInfinity(); - } - - /** - * Set the String used to represent infinity. Almost always left - * unchanged. - * @param infinity the Infinity String - * @stable ICU 2.0 - */ - public void setInfinity(String infinity) { - dfs.setInfinity(infinity); - } - - /** - * Return the String used to represent NaN. Almost always left - * unchanged. - * @return the NaN String - * @stable ICU 2.0 - */ - public String getNaN() { - return dfs.getNaN(); - } - - /** - * Set the String used to represent NaN. Almost always left - * unchanged. - * @param NaN the NaN String - * @stable ICU 2.0 - */ - public void setNaN(String NaN) { - dfs.setNaN(NaN); - } - - /** - * Return the character used to represent minus sign. If no explicit - * negative format is specified, one is formed by prefixing - * minusSign to the positive format. - * @return the minus sign character - * @stable ICU 2.0 - */ - public char getMinusSign() { - return dfs.getMinusSign(); - } - - /** - * Set the character used to represent minus sign. If no explicit - * negative format is specified, one is formed by prefixing - * minusSign to the positive format. - * @param minusSign the minus sign character - * @stable ICU 2.0 - */ - public void setMinusSign(char minusSign) { - dfs.setMinusSign(minusSign); - } - - /** - * Return the string denoting the local currency. - * @return the local currency String. - * @stable ICU 2.0 - */ - public String getCurrencySymbol() { - return dfs.getCurrencySymbol(); - } - - /** - * Set the string denoting the local currency. - * @param currency the local currency String. - * @stable ICU 2.0 - */ - public void setCurrencySymbol(String currency) { - dfs.setCurrencySymbol(currency); - } - - /** - * Return the international string denoting the local currency. - * @return the international string denoting the local currency - * @stable ICU 2.0 - */ - public String getInternationalCurrencySymbol() { - return dfs.getInternationalCurrencySymbol(); - } - - /** - * Set the international string denoting the local currency. - * @param currency the international string denoting the local currency. - * @stable ICU 2.0 - */ - public void setInternationalCurrencySymbol(String currency) { - dfs.setInternationalCurrencySymbol(currency); - } - - /** - * Return the monetary decimal separator. - * @return the monetary decimal separator character - * @stable ICU 2.0 - */ - public char getMonetaryDecimalSeparator() { - return dfs.getMonetaryDecimalSeparator(); - } - - /** - * Set the monetary decimal separator. - * @param sep the monetary decimal separator character - * @stable ICU 2.0 - */ - public void setMonetaryDecimalSeparator(char sep) { - dfs.setMonetaryDecimalSeparator(sep); - } - - /** - * Standard override. - * @stable ICU 2.0 - */ - public Object clone() { - return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)dfs.clone()); - } - - /** - * Override equals. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) { - try { - return dfs.equals(((DecimalFormatSymbols)obj).dfs); - } - catch (Exception e) { - return false; - } - } - - /** - * Override hashCode - * @stable ICU 2.0 - */ - public int hashCode() { - return dfs.hashCode(); - } -} +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.text; + + +import java.io.Serializable; +import java.util.Locale; + +import com.ibm.icu.util.ULocale; + +/** + * This class represents the set of symbols (such as the decimal separator, the + * grouping separator, and so on) needed by DecimalFormat to format + * numbers. DecimalFormat creates for itself an instance of + * DecimalFormatSymbols from its locale data. If you need to + * change any of these symbols, you can get the + * DecimalFormatSymbols object from your DecimalFormat + * and modify it. + * + *

      This is an enhanced version of DecimalFormatSymbols that + * is based on the standard version in the JDK. New or changed functionality + * is labeled + * NEW. + * + * @see java.util.Locale + * @see DecimalFormat + * @author Mark Davis + * @author Alan Liu + * @stable ICU 2.0 + */ +final public class DecimalFormatSymbols implements Cloneable, Serializable { + + private static final long serialVersionUID =1L; + + /** + * @internal + */ + public final java.text.DecimalFormatSymbols dfs; + + /** + * @internal + */ + public DecimalFormatSymbols(java.text.DecimalFormatSymbols delegate) { + this.dfs = delegate; + } + + /** + * Create a DecimalFormatSymbols object for the default locale. + * @stable ICU 2.0 + */ + public DecimalFormatSymbols() { + this(new java.text.DecimalFormatSymbols()); + } + + /** + * Create a DecimalFormatSymbols object for the given locale. + * @param locale the locale + * @stable ICU 2.0 + */ + public DecimalFormatSymbols(Locale locale) { + this(new java.text.DecimalFormatSymbols(locale)); + } + + /** + * Create a DecimalFormatSymbols object for the given locale. + * @param locale the locale + * @stable ICU 3.2 + */ + public DecimalFormatSymbols(ULocale locale) { + this(new java.text.DecimalFormatSymbols(locale.toLocale())); + } + + /** + * Return the character used for zero. Different for Arabic, etc. + * @return the character + * @stable ICU 2.0 + */ + public char getZeroDigit() { + return dfs.getZeroDigit(); + } + + /** + * Set the character used for zero. + * @param zeroDigit the zero character. + * @stable ICU 2.0 + */ + public void setZeroDigit(char zeroDigit) { + dfs.setZeroDigit(zeroDigit); + } + + /** + * Return the character used for thousands separator. Different for French, etc. + * @return the thousands character + * @stable ICU 2.0 + */ + public char getGroupingSeparator() { + return dfs.getGroupingSeparator(); + } + + /** + * Set the character used for thousands separator. Different for French, etc. + * @param groupingSeparator the thousands character + * @stable ICU 2.0 + */ + public void setGroupingSeparator(char groupingSeparator) { + dfs.setGroupingSeparator(groupingSeparator); + } + + /** + * Return the character used for decimal sign. Different for French, etc. + * @return the decimal character + * @stable ICU 2.0 + */ + public char getDecimalSeparator() { + return dfs.getDecimalSeparator(); + } + + /** + * Set the character used for decimal sign. Different for French, etc. + * @param decimalSeparator the decimal character + * @stable ICU 2.0 + */ + public void setDecimalSeparator(char decimalSeparator) { + dfs.setDecimalSeparator(decimalSeparator); + } + + /** + * Return the character used for mille percent sign. Different for Arabic, etc. + * @return the mille percent character + * @stable ICU 2.0 + */ + public char getPerMill() { + return dfs.getPerMill(); + } + + /** + * Set the character used for mille percent sign. Different for Arabic, etc. + * @param perMill the mille percent character + * @stable ICU 2.0 + */ + public void setPerMill(char perMill) { + dfs.setPerMill(perMill); + } + + /** + * Return the character used for percent sign. Different for Arabic, etc. + * @return the percent character + * @stable ICU 2.0 + */ + public char getPercent() { + return dfs.getPercent(); + } + + /** + * Set the character used for percent sign. Different for Arabic, etc. + * @param percent the percent character + * @stable ICU 2.0 + */ + public void setPercent(char percent) { + dfs.setPercent(percent); + } + + /** + * Return the character used for a digit in a pattern. + * @return the digit pattern character + * @stable ICU 2.0 + */ + public char getDigit() { + return dfs.getDigit(); + } + + /** + * Set the character used for a digit in a pattern. + * @param digit the digit pattern character + * @stable ICU 2.0 + */ + public void setDigit(char digit) { + dfs.setDigit(digit); + } + + /** + * Return the character used to separate positive and negative subpatterns + * in a pattern. + * @return the pattern separator character + * @stable ICU 2.0 + */ + public char getPatternSeparator() { + return dfs.getPatternSeparator(); + } + + /** + * Set the character used to separate positive and negative subpatterns + * in a pattern. + * @param patternSeparator the pattern separator character + * @stable ICU 2.0 + */ + public void setPatternSeparator(char patternSeparator) { + dfs.setPatternSeparator(patternSeparator); + } + + /** + * Return the String used to represent infinity. Almost always left + * unchanged. + * @return the Infinity string + * @stable ICU 2.0 + */ + public String getInfinity() { + return dfs.getInfinity(); + } + + /** + * Set the String used to represent infinity. Almost always left + * unchanged. + * @param infinity the Infinity String + * @stable ICU 2.0 + */ + public void setInfinity(String infinity) { + dfs.setInfinity(infinity); + } + + /** + * Return the String used to represent NaN. Almost always left + * unchanged. + * @return the NaN String + * @stable ICU 2.0 + */ + public String getNaN() { + return dfs.getNaN(); + } + + /** + * Set the String used to represent NaN. Almost always left + * unchanged. + * @param NaN the NaN String + * @stable ICU 2.0 + */ + public void setNaN(String NaN) { + dfs.setNaN(NaN); + } + + /** + * Return the character used to represent minus sign. If no explicit + * negative format is specified, one is formed by prefixing + * minusSign to the positive format. + * @return the minus sign character + * @stable ICU 2.0 + */ + public char getMinusSign() { + return dfs.getMinusSign(); + } + + /** + * Set the character used to represent minus sign. If no explicit + * negative format is specified, one is formed by prefixing + * minusSign to the positive format. + * @param minusSign the minus sign character + * @stable ICU 2.0 + */ + public void setMinusSign(char minusSign) { + dfs.setMinusSign(minusSign); + } + + /** + * Return the string denoting the local currency. + * @return the local currency String. + * @stable ICU 2.0 + */ + public String getCurrencySymbol() { + return dfs.getCurrencySymbol(); + } + + /** + * Set the string denoting the local currency. + * @param currency the local currency String. + * @stable ICU 2.0 + */ + public void setCurrencySymbol(String currency) { + dfs.setCurrencySymbol(currency); + } + + /** + * Return the international string denoting the local currency. + * @return the international string denoting the local currency + * @stable ICU 2.0 + */ + public String getInternationalCurrencySymbol() { + return dfs.getInternationalCurrencySymbol(); + } + + /** + * Set the international string denoting the local currency. + * @param currency the international string denoting the local currency. + * @stable ICU 2.0 + */ + public void setInternationalCurrencySymbol(String currency) { + dfs.setInternationalCurrencySymbol(currency); + } + + /** + * Return the monetary decimal separator. + * @return the monetary decimal separator character + * @stable ICU 2.0 + */ + public char getMonetaryDecimalSeparator() { + return dfs.getMonetaryDecimalSeparator(); + } + + /** + * Set the monetary decimal separator. + * @param sep the monetary decimal separator character + * @stable ICU 2.0 + */ + public void setMonetaryDecimalSeparator(char sep) { + dfs.setMonetaryDecimalSeparator(sep); + } + + /** + * Standard override. + * @stable ICU 2.0 + */ + public Object clone() { + return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)dfs.clone()); + } + + /** + * Override equals. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) { + try { + return dfs.equals(((DecimalFormatSymbols)obj).dfs); + } + catch (Exception e) { + return false; + } + } + + /** + * Override hashCode + * @stable ICU 2.0 + */ + public int hashCode() { + return dfs.hashCode(); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java index 91bec490eb7..31c27132836 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java @@ -1,1415 +1,1415 @@ -/* -********************************************************************** -* Copyright (c) 2004-2011, International Business Machines -* Corporation and others. All Rights Reserved. -********************************************************************** -* Author: Alan Liu -* Created: April 6, 2004 -* Since: ICU 3.0 -********************************************************************** -*/ -package com.ibm.icu.text; - -import java.io.InvalidObjectException; -import java.text.AttributedCharacterIterator; -import java.text.AttributedCharacterIterator.Attribute; -import java.text.AttributedString; -import java.text.CharacterIterator; -import java.text.ChoiceFormat; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.ibm.icu.util.ULocale; - -/** - * {@icuenhanced java.text.MessageFormat}.{@icu _usage_} - * - *

      MessageFormat produces concatenated messages in a language-neutral - * way. Use this whenever concatenating strings that are displayed to - * end users. - * - *

      A MessageFormat contains an array of subformats arranged - * within a template string. Together, the subformats and - * template string determine how the MessageFormat will operate during - * formatting and parsing. - * - *

      Typically, both the subformats and the template string are - * specified at once in a pattern. By using different - * patterns for different locales, messages may be localized. - * - *

      When formatting, MessageFormat takes a collection of arguments - * and produces a user-readable string. The arguments may be passed - * as an array or as a Map. Each argument is matched up with its - * corresponding subformat, which then formats it into a string. The - * resulting strings are then assembled within the string template of - * the MessageFormat to produce the final output string. - * - *

      Note: - * MessageFormat differs from the other Format - * classes in that you create a MessageFormat object with one - * of its constructors (not with a getInstance style factory - * method). The factory methods aren't necessary because MessageFormat - * itself doesn't implement locale-specific behavior. Any locale-specific - * behavior is defined by the pattern that you provide and the - * subformats used for inserted arguments. - * - *

      Note: - * In ICU 3.8 MessageFormat supports named arguments. If a named argument - * is used, all arguments must be named. Names start with a character in - * :ID_START: and continue with characters in :ID_CONTINUE:, - * in particular they do not start with a digit. If named arguments - * are used, {@link #usesNamedArguments()} will return true. - * - *

      The other new methods supporting named arguments are - * {@link #setFormatsByArgumentName(Map)}, - * {@link #setFormatByArgumentName(String, Format)}, - * {@link #format(Map, StringBuffer, FieldPosition)}, - * {@link #format(String, Map)}, {@link #parseToMap(String, ParsePosition)}, - * and {@link #parseToMap(String)}. These methods are all compatible - * with patterns that do not used named arguments-- in these cases - * the keys in the input or output Maps use - * Strings that name the argument indices, e.g. "0", - * "1", "2"... etc. - * - *

      When named arguments are used, certain methods on MessageFormat that take or - * return arrays will throw an exception, since it is not possible to - * identify positions in an array using a name. These methods are - * {@link #setFormatsByArgumentIndex(Format[])}, - * {@link #setFormatByArgumentIndex(int, Format)}, - * {@link #getFormatsByArgumentIndex()}, - * {@link #getFormats()}, - * {@link #format(Object[], StringBuffer, FieldPosition)}, - * {@link #format(String, Object[])}, - * {@link #parse(String, ParsePosition)}, and - * {@link #parse(String)}. - * These APIs all have corresponding new versions as listed above. - * - *

      The API {@link #format(Object, StringBuffer, FieldPosition)} has - * been modified so that the Object argument can be - * either an Object array or a Map. If this - * format uses named arguments, this argument must not be an - * Object array otherwise an exception will be thrown. - * If the argument is a Map it can be used with Strings that - * represent indices as described above. - * - *

      Patterns and Their Interpretation

      - * - * MessageFormat uses patterns of the following form: - *
      - * MessageFormatPattern:
      - *         String
      - *         MessageFormatPattern FormatElement String
      - *
      - * FormatElement:
      - *         { ArgumentIndexOrName }
      - *         { ArgumentIndexOrName , FormatType }
      - *         { ArgumentIndexOrName , FormatType , FormatStyle }
      - *
      - * ArgumentIndexOrName: one of 
      - *         ['0'-'9']+
      - *         [:ID_START:][:ID_CONTINUE:]*
      - *
      - * FormatType: one of 
      - *         number date time choice spellout ordinal duration plural
      - *
      - * FormatStyle:
      - *         short
      - *         medium
      - *         long
      - *         full
      - *         integer
      - *         currency
      - *         percent
      - *         SubformatPattern
      - *         RulesetName
      - *
      - * String:
      - *         StringPartopt
      - *         String StringPart
      - *
      - * StringPart:
      - *         ''
      - *         ' QuotedString '
      - *         UnquotedString
      - *
      - * SubformatPattern:
      - *         SubformatPatternPartopt
      - *         SubformatPattern SubformatPatternPart
      - *
      - * SubFormatPatternPart:
      - *         ' QuotedPattern '
      - *         UnquotedPattern
      - * 
      - * - * RulesetName: - * UnquotedString - * - *

      Within a String, "''" represents a single - * quote. A QuotedString can contain arbitrary characters - * except single quotes; the surrounding single quotes are removed. - * An UnquotedString can contain arbitrary characters - * except single quotes and left curly brackets. Thus, a string that - * should result in the formatted message "'{0}'" can be written as - * "'''{'0}''" or "'''{0}'''". - * - *

      Within a SubformatPattern, different rules apply. - * A QuotedPattern can contain arbitrary characters - * except single quotes; but the surrounding single quotes are - * not removed, so they may be interpreted by the - * subformat. For example, "{1,number,$'#',##}" will - * produce a number format with the pound-sign quoted, with a result - * such as: "$#31,45". - * An UnquotedPattern can contain arbitrary characters - * except single quotes, but curly braces within it must be balanced. - * For example, "ab {0} de" and "ab '}' de" - * are valid subformat patterns, but "ab {0'}' de" and - * "ab } de" are not. - * - *

      Warning:
      The rules for using quotes within message - * format patterns unfortunately have shown to be somewhat confusing. - * In particular, it isn't always obvious to localizers whether single - * quotes need to be doubled or not. Make sure to inform localizers about - * the rules, and tell them (for example, by using comments in resource - * bundle source files) which strings will be processed by MessageFormat. - * Note that localizers may need to use single quotes in translated - * strings where the original version doesn't have them. - * - *
      Note also that the simplest way to avoid the problem is to - * use the real apostrophe (single quote) character \u2019 (') for - * human-readable text, and to use the ASCII apostrophe (\u0027 ' ) - * only in program syntax, like quoting in MessageFormat. - * See the annotations for U+0027 Apostrophe in The Unicode Standard.

      - *
      - * - *

      The ArgumentIndex value is a non-negative integer written - * using the digits '0' through '9', and represents an index into the - * arguments array passed to the format methods - * or the result array returned by the parse methods. - * - *

      The FormatType and FormatStyle values are used to create - * a Format instance for the format element. The following - * table shows how the values map to Format instances. Combinations not - * shown in the table are illegal. A SubformatPattern must - * be a valid pattern string for the Format subclass used. - * - *

      - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      Format Type - * Format Style - * Subformat Created - *
      (none) - * null - *
      number - * (none) - * NumberFormat.getInstance(getLocale()) - *
      integer - * NumberFormat.getIntegerInstance(getLocale()) - *
      currency - * NumberFormat.getCurrencyInstance(getLocale()) - *
      percent - * NumberFormat.getPercentInstance(getLocale()) - *
      SubformatPattern - * new DecimalFormat(subformatPattern, new DecimalFormatSymbols(getLocale())) - *
      date - * (none) - * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) - *
      short - * DateFormat.getDateInstance(DateFormat.SHORT, getLocale()) - *
      medium - * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) - *
      long - * DateFormat.getDateInstance(DateFormat.LONG, getLocale()) - *
      full - * DateFormat.getDateInstance(DateFormat.FULL, getLocale()) - *
      SubformatPattern - * new SimpleDateFormat(subformatPattern, getLocale()) - *
      time - * (none) - * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) - *
      short - * DateFormat.getTimeInstance(DateFormat.SHORT, getLocale()) - *
      medium - * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) - *
      long - * DateFormat.getTimeInstance(DateFormat.LONG, getLocale()) - *
      full - * DateFormat.getTimeInstance(DateFormat.FULL, getLocale()) - *
      SubformatPattern - * new SimpleDateFormat(subformatPattern, getLocale()) - *
      choice - * SubformatPattern - * new ChoiceFormat(subformatPattern) - *
      spellout - * RulesetName (optional) - * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.SPELLOUT) - *
          .setDefaultRuleset(ruleset);
      - *
      ordinal - * RulesetName (optional) - * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.ORDINAL) - *
          .setDefaultRuleset(ruleset);
      - *
      duration - * RulesetName (optional) - * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.DURATION) - *
          .setDefaultRuleset(ruleset);
      - *
      plural - * SubformatPattern - * new PluralFormat(subformatPattern) - *
      select - * SubformatPattern - * new SelectFormat(subformatPattern) - *
      - *

      - * - *

      Usage Information

      - * - *

      Here are some examples of usage: - *

      - *
      - * Object[] arguments = {
      - *     new Integer(7),
      - *     new Date(System.currentTimeMillis()),
      - *     "a disturbance in the Force"
      - * };
      - *
      - * String result = MessageFormat.format(
      - *     "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
      - *     arguments);
      - *
      - * output: At 12:30 PM on Jul 3, 2053, there was a disturbance
      - *           in the Force on planet 7.
      - *
      - * 
      - *
      - * Typically, the message format will come from resources, and the - * arguments will be dynamically set at runtime. - * - *

      Example 2: - *

      - *
      - * Object[] testArgs = {new Long(3), "MyDisk"};
      - *
      - * MessageFormat form = new MessageFormat(
      - *     "The disk \"{1}\" contains {0} file(s).");
      - *
      - * System.out.println(form.format(testArgs));
      - *
      - * // output, with different testArgs
      - * output: The disk "MyDisk" contains 0 file(s).
      - * output: The disk "MyDisk" contains 1 file(s).
      - * output: The disk "MyDisk" contains 1,273 file(s).
      - * 
      - *
      - * - *

      For more sophisticated patterns, you can use a ChoiceFormat to get - * output such as: - *

      - *
      - * MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
      - * double[] filelimits = {0,1,2};
      - * String[] filepart = {"no files","one file","{0,number} files"};
      - * ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
      - * form.setFormatByArgumentIndex(0, fileform);
      - *
      - * Object[] testArgs = {new Long(12373), "MyDisk"};
      - *
      - * System.out.println(form.format(testArgs));
      - *
      - * // output, with different testArgs
      - * output: The disk "MyDisk" contains no files.
      - * output: The disk "MyDisk" contains one file.
      - * output: The disk "MyDisk" contains 1,273 files.
      - * 
      - *
      - * You can either do this programmatically, as in the above example, - * or by using a pattern (see - * {@link ChoiceFormat} - * for more information) as in: - *
      - *
      - * form.applyPattern(
      - *    "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
      - * 
      - *
      - * - *

      Note: As we see above, the string produced - * by a ChoiceFormat in MessageFormat is treated specially; - * occurances of '{' are used to indicated subformats, and cause recursion. - * If you create both a MessageFormat and ChoiceFormat - * programmatically (instead of using the string patterns), then be careful not to - * produce a format that recurses on itself, which will cause an infinite loop. - * - *

      When a single argument is parsed more than once in the string, the last match - * will be the final result of the parsing. For example, - *

      - * MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
      - * Object[] objs = {new Double(3.1415)};
      - * String result = mf.format( objs );
      - * // result now equals "3.14, 3.1"
      - * objs = null;
      - * objs = mf.parse(result, new ParsePosition(0));
      - * // objs now equals {new Double(3.1)}
      - * 
      - * - *

      Likewise, parsing with a MessageFormat object using patterns containing - * multiple occurances of the same argument would return the last match. For - * example, - *

      - * MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
      - * String forParsing = "x, y, z";
      - * Object[] objs = mf.parse(forParsing, new ParsePosition(0));
      - * // result now equals {new String("z")}
      - * 
      - * - *

      Synchronization

      - * - *

      Message formats are not synchronized. - * It is recommended to create separate format instances for each thread. - * If multiple threads access a format concurrently, it must be synchronized - * externally. - * - * @see java.util.Locale - * @see Format - * @see NumberFormat - * @see DecimalFormat - * @see ChoiceFormat - * @see PluralFormat - * @see SelectFormat - * @author Mark Davis - * @stable ICU 3.0 - */ -public class MessageFormat extends UFormat { - static final long serialVersionUID = 1L; - - /** - * @internal - */ - public final java.text.MessageFormat messageFormat; - - /** - * @internal - * @param delegate the DateFormat to which to delegate - */ - public MessageFormat(java.text.MessageFormat delegate) { - wrapNestedFormatters(delegate); - this.messageFormat = delegate; - } - - /** - * Constructs a MessageFormat for the default locale and the - * specified pattern. - * The constructor first sets the locale, then parses the pattern and - * creates a list of subformats for the format elements contained in it. - * Patterns and their interpretation are specified in the - * class description. - * - * @param pattern the pattern for this message format - * @exception IllegalArgumentException if the pattern is invalid - * @stable ICU 3.0 - */ - public MessageFormat(String pattern) { - this(new java.text.MessageFormat(pattern)); - } - - /** - * Constructs a MessageFormat for the specified locale and - * pattern. - * The constructor first sets the locale, then parses the pattern and - * creates a list of subformats for the format elements contained in it. - * Patterns and their interpretation are specified in the - * class description. - * - * @param pattern the pattern for this message format - * @param locale the locale for this message format - * @exception IllegalArgumentException if the pattern is invalid - * @stable ICU 3.0 - */ - public MessageFormat(String pattern, Locale locale) { - this(new java.text.MessageFormat(pattern, locale)); - } - - /** - * Constructs a MessageFormat for the specified locale and - * pattern. - * The constructor first sets the locale, then parses the pattern and - * creates a list of subformats for the format elements contained in it. - * Patterns and their interpretation are specified in the - * class description. - * - * @param pattern the pattern for this message format - * @param locale the locale for this message format - * @exception IllegalArgumentException if the pattern is invalid - * @stable ICU 3.2 - */ - public MessageFormat(String pattern, ULocale locale) { - this(new java.text.MessageFormat(pattern, locale.toLocale())); - } - - /** - * Sets the locale to be used when creating or comparing subformats. - * This affects subsequent calls to the {@link #applyPattern applyPattern} - * and {@link #toPattern toPattern} methods as well as to the - * format and - * {@link #formatToCharacterIterator formatToCharacterIterator} methods. - * - * @param locale the locale to be used when creating or comparing subformats - * @stable ICU 3.0 - */ - public void setLocale(Locale locale) { - messageFormat.setLocale(locale); - } - - /** - * Sets the locale to be used when creating or comparing subformats. - * This affects subsequent calls to the {@link #applyPattern applyPattern} - * and {@link #toPattern toPattern} methods as well as to the - * format and - * {@link #formatToCharacterIterator formatToCharacterIterator} methods. - * - * @param locale the locale to be used when creating or comparing subformats - * @stable ICU 3.2 - */ - public void setLocale(ULocale locale) { - messageFormat.setLocale(locale.toLocale()); - } - - /** - * Returns the locale that's used when creating or comparing subformats. - * - * @return the locale used when creating or comparing subformats - * @stable ICU 3.0 - */ - public Locale getLocale() { - return messageFormat.getLocale(); - } - - /** - * {@icu} Returns the locale that's used when creating or comparing subformats. - * - * @return the locale used when creating or comparing subformats - * @stable ICU 3.2 - */ - public ULocale getULocale() { - return ULocale.forLocale(messageFormat.getLocale()); - } - - /** - * Sets the pattern used by this message format. - * The method parses the pattern and creates a list of subformats - * for the format elements contained in it. - * Patterns and their interpretation are specified in the - * class description. - *

      - * The pattern must contain only named or only numeric arguments, - * mixing them is not allowed. - * - * @param pttrn the pattern for this message format - * @throws IllegalArgumentException if the pattern is invalid - * @stable ICU 3.0 - */ - public void applyPattern(String pttrn) { - messageFormat.applyPattern(pttrn); - wrapNestedFormatters(messageFormat); - } - - /** - * Returns a pattern representing the current state of the message format. - * The string is constructed from internal information and therefore - * does not necessarily equal the previously applied pattern. - * - * @return a pattern representing the current state of the message format - * @stable ICU 3.0 - */ - public String toPattern() { - String pattern = savedPattern == null ? messageFormat.toPattern() : savedPattern; - return pattern; - } - - /** - * Sets the formats to use for the values passed into - * format methods or returned from parse - * methods. The indices of elements in newFormats - * correspond to the argument indices used in the previously set - * pattern string. - * The order of formats in newFormats thus corresponds to - * the order of elements in the arguments array passed - * to the format methods or the result array returned - * by the parse methods. - *

      - * If an argument index is used for more than one format element - * in the pattern string, then the corresponding new format is used - * for all such format elements. If an argument index is not used - * for any format element in the pattern string, then the - * corresponding new format is ignored. If fewer formats are provided - * than needed, then only the formats for argument indices less - * than newFormats.length are replaced. - * - * This method is only supported if the format does not use - * named arguments, otherwise an IllegalArgumentException is thrown. - * - * @param newFormats the new formats to use - * @throws NullPointerException if newFormats is null - * @throws IllegalArgumentException if this formatter uses named arguments - * @stable ICU 3.0 - */ - public void setFormatsByArgumentIndex(Format[] newFormats) { - messageFormat.setFormatsByArgumentIndex(newFormats); - savedPattern = null; - } - - /** - * {@icu} Sets the formats to use for the values passed into - * format methods or returned from parse - * methods. The keys in newFormats are the argument - * names in the previously set pattern string, and the values - * are the formats. - *

      - * Only argument names from the pattern string are considered. - * Extra keys in newFormats that do not correspond - * to an argument name are ignored. Similarly, if there is no - * format in newFormats for an argument name, the formatter - * for that argument remains unchanged. - *

      - * This may be called on formats that do not use named arguments. - * In this case the map will be queried for key Strings that - * represent argument indices, e.g. "0", "1", "2" etc. - * - * @param newFormats a map from String to Format providing new - * formats for named arguments. - * @stable ICU 3.8 - */ - public void setFormatsByArgumentName(Map newFormats) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the formats to use for the format elements in the - * previously set pattern string. - * The order of formats in newFormats corresponds to - * the order of format elements in the pattern string. - *

      - * If more formats are provided than needed by the pattern string, - * the remaining ones are ignored. If fewer formats are provided - * than needed, then only the first newFormats.length - * formats are replaced. - *

      - * Since the order of format elements in a pattern string often - * changes during localization, it is generally better to use the - * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex} - * method, which assumes an order of formats corresponding to the - * order of elements in the arguments array passed to - * the format methods or the result array returned by - * the parse methods. - * - * @param newFormats the new formats to use - * @exception NullPointerException if newFormats is null - * @stable ICU 3.0 - */ - public void setFormats(Format[] newFormats) { - messageFormat.setFormats(newFormats); - savedPattern = null; - } - - /** - * Sets the format to use for the format elements within the - * previously set pattern string that use the given argument - * index. - * The argument index is part of the format element definition and - * represents an index into the arguments array passed - * to the format methods or the result array returned - * by the parse methods. - *

      - * If the argument index is used for more than one format element - * in the pattern string, then the new format is used for all such - * format elements. If the argument index is not used for any format - * element in the pattern string, then the new format is ignored. - * - * This method is only supported when exclusively numbers are used for - * argument names. Otherwise an IllegalArgumentException is thrown. - * - * @param argumentIndex the argument index for which to use the new format - * @param newFormat the new format to use - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public void setFormatByArgumentIndex(int argumentIndex, Format newFormat) { - messageFormat.setFormatByArgumentIndex(argumentIndex, newFormat); - savedPattern = null; - } - - /** - * {@icu} Sets the format to use for the format elements within the - * previously set pattern string that use the given argument - * name. - *

      - * If the argument name is used for more than one format element - * in the pattern string, then the new format is used for all such - * format elements. If the argument name is not used for any format - * element in the pattern string, then the new format is ignored. - *

      - * This API may be used on formats that do not use named arguments. - * In this case argumentName should be a String that names - * an argument index, e.g. "0", "1", "2"... etc. If it does not name - * a valid index, the format will be ignored. No error is thrown. - * - * @param argumentName the name of the argument to change - * @param newFormat the new format to use - * @stable ICU 3.8 - */ - public void setFormatByArgumentName(String argumentName, Format newFormat) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the format to use for the format element with the given - * format element index within the previously set pattern string. - * The format element index is the zero-based number of the format - * element counting from the start of the pattern string. - *

      - * Since the order of format elements in a pattern string often - * changes during localization, it is generally better to use the - * {@link #setFormatByArgumentIndex setFormatByArgumentIndex} - * method, which accesses format elements based on the argument - * index they specify. - * - * @param formatElementIndex the index of a format element within the pattern - * @param newFormat the format to use for the specified format element - * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or - * larger than the number of format elements in the pattern string - * @stable ICU 3.0 - */ - public void setFormat(int formatElementIndex, Format newFormat) { - messageFormat.setFormat(formatElementIndex, newFormat); - savedPattern = null; - } - - /** - * Returns the formats used for the values passed into - * format methods or returned from parse - * methods. The indices of elements in the returned array - * correspond to the argument indices used in the previously set - * pattern string. - * The order of formats in the returned array thus corresponds to - * the order of elements in the arguments array passed - * to the format methods or the result array returned - * by the parse methods. - *

      - * If an argument index is used for more than one format element - * in the pattern string, then the format used for the last such - * format element is returned in the array. If an argument index - * is not used for any format element in the pattern string, then - * null is returned in the array. - * - * This method is only supported when exclusively numbers are used for - * argument names. Otherwise an IllegalArgumentException is thrown. - * - * @return the formats used for the arguments within the pattern - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public Format[] getFormatsByArgumentIndex() { - return messageFormat.getFormatsByArgumentIndex(); - } - - /** - * Returns the formats used for the format elements in the - * previously set pattern string. - * The order of formats in the returned array corresponds to - * the order of format elements in the pattern string. - *

      - * Since the order of format elements in a pattern string often - * changes during localization, it's generally better to use the - * {@link #getFormatsByArgumentIndex()} - * method, which assumes an order of formats corresponding to the - * order of elements in the arguments array passed to - * the format methods or the result array returned by - * the parse methods. - * - * This method is only supported when exclusively numbers are used for - * argument names. Otherwise an IllegalArgumentException is thrown. - * - * @return the formats used for the format elements in the pattern - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public Format[] getFormats() { - return messageFormat.getFormats(); - } - - /** - * {@icu} Returns the format argument names. For more details, see - * {@link #setFormatByArgumentName(String, Format)}. - * @return List of names - * @internal - * @deprecated This API is ICU internal only. - */ - public Set getFormatArgumentNames() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the formats according to their argument names. For more details, see - * {@link #setFormatByArgumentName(String, Format)}. - * @return format associated with the name, or null if there isn't one. - * @internal - * @deprecated This API is ICU internal only. - */ - public Format getFormatByArgumentName(String argumentName) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Formats an array of objects and appends the MessageFormat's - * pattern, with format elements replaced by the formatted objects, to the - * provided StringBuffer. - *

      - * The text substituted for the individual format elements is derived from - * the current subformat of the format element and the - * arguments element at the format element's argument index - * as indicated by the first matching line of the following table. An - * argument is unavailable if arguments is - * null or has fewer than argumentIndex+1 elements. When - * an argument is unavailable no substitution is performed. - *

      - * - * - * - * - * - * - * - * - * - * - *
      Subformat - * Argument - * Formatted Text - *
      any - * unavailable - * "{" + argumentIndex + "}" - *
      any - * null - * "null" - *
      instanceof ChoiceFormat - * any - * subformat.format(argument).indexOf('{') >= 0 ?
      - * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : - * subformat.format(argument)
      - *
      != null - * any - * subformat.format(argument) - *
      null - * instanceof Number - * NumberFormat.getInstance(getLocale()).format(argument) - *
      null - * instanceof Date - * DateFormat.getDateTimeInstance(DateFormat.SHORT, - * DateFormat.SHORT, getLocale()).format(argument) - *
      null - * instanceof String - * argument - *
      null - * any - * argument.toString() - *
      - *

      - * If pos is non-null, and refers to - * Field.ARGUMENT, the location of the first formatted - * string will be returned. - * - * This method is only supported when the format does not use named - * arguments, otherwise an IllegalArgumentException is thrown. - * - * @param arguments an array of objects to be formatted and substituted. - * @param result where text is appended. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @throws IllegalArgumentException if an argument in the - * arguments array is not of the type - * expected by the format element(s) that use it. - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public final StringBuffer format(Object[] arguments, StringBuffer result, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = messageFormat.format(arguments, result, jdkPos); - if (jdkPos != null) { - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - } - return buf; - } - - /** - * Formats a map of objects and appends the MessageFormat's - * pattern, with format elements replaced by the formatted objects, to the - * provided StringBuffer. - *

      - * The text substituted for the individual format elements is derived from - * the current subformat of the format element and the - * arguments value corresopnding to the format element's - * argument name. - *

      - * This API may be called on formats that do not use named arguments. - * In this case the the keys in arguments must be numeric - * strings (e.g. "0", "1", "2"...). - *

      - * An argument is unavailable if arguments is - * null or does not have a value corresponding to an argument - * name in the pattern. When an argument is unavailable no substitution - * is performed. - * - * @param arguments a map of objects to be formatted and substituted. - * @param result where text is appended. - * @param pos On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @throws IllegalArgumentException if an argument in the - * arguments array is not of the type - * expected by the format element(s) that use it. - * @return the passed-in StringBuffer - * @stable ICU 3.8 - */ - public final StringBuffer format(Map arguments, StringBuffer result, - FieldPosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Creates a MessageFormat with the given pattern and uses it - * to format the given arguments. This is equivalent to - *

      - * (new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link - * #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) - * format}(arguments, new StringBuffer(), null).toString() - *
      - * - * @throws IllegalArgumentException if the pattern is invalid, - * or if an argument in the arguments array - * is not of the type expected by the format element(s) - * that use it. - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public static String format(String pattern, Object... arguments) { - return java.text.MessageFormat.format(pattern, arguments); - } - - /** - * Creates a MessageFormat with the given pattern and uses it to - * format the given arguments. The pattern must identifyarguments - * by name instead of by number. - *

      - * @throws IllegalArgumentException if the pattern is invalid, - * or if an argument in the arguments map - * is not of the type expected by the format element(s) - * that use it. - * @see #format(Map, StringBuffer, FieldPosition) - * @see #format(String, Object[]) - * @stable ICU 3.8 - */ - public static String format(String pattern, Map arguments) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns true if this MessageFormat uses named arguments, - * and false otherwise. See class description. - * - * @return true if named arguments are used. - * @stable ICU 3.8 - */ - public boolean usesNamedArguments() { - // always false with com.ibm.icu.base - return false; - } - - // Overrides - /** - * Formats a map or array of objects and appends the MessageFormat's - * pattern, with format elements replaced by the formatted objects, to the - * provided StringBuffer. - * This is equivalent to either of - *

      - * {@link #format(java.lang.Object[], java.lang.StringBuffer, - * java.text.FieldPosition) format}((Object[]) arguments, result, pos) - * {@link #format(java.util.Map, java.lang.StringBuffer, - * java.text.FieldPosition) format}((Map) arguments, result, pos) - *
      - * A map must be provided if this format uses named arguments, otherwise - * an IllegalArgumentException will be thrown. - * @param arguments a map or array of objects to be formatted - * @param result where text is appended - * @param pos On input: an alignment field, if desired - * On output: the offsets of the alignment field - * @throws IllegalArgumentException if an argument in - * arguments is not of the type - * expected by the format element(s) that use it - * @throws IllegalArgumentException if arguments is - * an array of Object and this format uses named arguments - * @stable ICU 3.0 - */ - public final StringBuffer format(Object arguments, StringBuffer result, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = messageFormat.format(arguments, result, jdkPos); - if (jdkPos != null) { - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - } - return buf; - } - - /** - * Formats an array of objects and inserts them into the - * MessageFormat's pattern, producing an - * AttributedCharacterIterator. - * You can use the returned AttributedCharacterIterator - * to build the resulting String, as well as to determine information - * about the resulting String. - *

      - * The text of the returned AttributedCharacterIterator is - * the same that would be returned by - *

      - * {@link #format(java.lang.Object[], java.lang.StringBuffer, - * java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString() - *
      - *

      - * In addition, the AttributedCharacterIterator contains at - * least attributes indicating where text was generated from an - * argument in the arguments array. The keys of these attributes are of - * type MessageFormat.Field, their values are - * Integer objects indicating the index in the arguments - * array of the argument from which the text was generated. - *

      - * The attributes/value from the underlying Format - * instances that MessageFormat uses will also be - * placed in the resulting AttributedCharacterIterator. - * This allows you to not only find where an argument is placed in the - * resulting String, but also which fields it contains in turn. - * - * @param arguments an array of objects to be formatted and substituted. - * @return AttributedCharacterIterator describing the formatted value. - * @exception NullPointerException if arguments is null. - * @exception IllegalArgumentException if an argument in the - * arguments array is not of the type - * expected by the format element(s) that use it. - * @stable ICU 3.8 - */ - public AttributedCharacterIterator formatToCharacterIterator(Object arguments) { - AttributedCharacterIterator it = messageFormat.formatToCharacterIterator(arguments); - - // Extract formatted String first - StringBuilder sb = new StringBuilder(); - for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { - sb.append(c); - } - - // Create AttributedString - AttributedString attrstr = new AttributedString(sb.toString()); - - // Map JDK Field to ICU Field - int idx = 0; - it.first(); - while (idx < it.getEndIndex()) { - int end = it.getRunLimit(); - Map attributes = it.getAttributes(); - if (attributes != null) { - for (Entry entry : attributes.entrySet()) { - Attribute attr = entry.getKey(); - Object val = entry.getValue(); - if (attr.equals(java.text.MessageFormat.Field.ARGUMENT)) { - val = attr = Field.ARGUMENT; - } - attrstr.addAttribute(attr, val, idx, end); - } - } - idx = end; - while (it.getIndex() < idx) { - it.next(); - } - } - - return attrstr.getIterator(); - } - - /** - * Parses the string. - * - *

      Caveats: The parse may fail in a number of circumstances. - * For example: - *

        - *
      • If one of the arguments does not occur in the pattern. - *
      • If the format of an argument loses information, such as - * with a choice format where a large number formats to "many". - *
      • Does not yet handle recursion (where - * the substituted strings contain {n} references.) - *
      • Will not always find a match (or the correct match) - * if some part of the parse is ambiguous. - * For example, if the pattern "{1},{2}" is used with the - * string arguments {"a,b", "c"}, it will format as "a,b,c". - * When the result is parsed, it will return {"a", "b,c"}. - *
      • If a single argument is parsed more than once in the string, - * then the later parse wins. - *
      - * When the parse fails, use ParsePosition.getErrorIndex() to find out - * where in the string did the parsing failed. The returned error - * index is the starting offset of the sub-patterns that the string - * is comparing with. For example, if the parsing string "AAA {0} BBB" - * is comparing against the pattern "AAD {0} BBB", the error index is - * 0. When an error occurs, the call to this method will return null. - * If the source is null, return an empty array. - *

      - * This method is only supported with numbered arguments. If - * the format pattern used named argument an - * IllegalArgumentException is thrown. - * - * @throws IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public Object[] parse(String source, ParsePosition pos) { - return messageFormat.parse(source, pos); - } - - /** - * {@icu} Parses the string, returning the results in a Map. - * This is similar to the version that returns an array - * of Object. This supports both named and numbered - * arguments-- if numbered, the keys in the map are the - * corresponding Strings (e.g. "0", "1", "2"...). - * - * @param source the text to parse - * @param pos the position at which to start parsing. on return, - * contains the result of the parse. - * @return a Map containing key/value pairs for each parsed argument. - * @stable ICU 3.8 - */ - public Map parseToMap(String source, ParsePosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Parses text from the beginning of the given string to produce an object - * array. - * The method may not use the entire text of the given string. - *

      - * See the {@link #parse(String, ParsePosition)} method for more information - * on message parsing. - * - * @param source A String whose beginning should be parsed. - * @return An Object array parsed from the string. - * @exception ParseException if the beginning of the specified string cannot be parsed. - * @exception IllegalArgumentException if this format uses named arguments - * @stable ICU 3.0 - */ - public Object[] parse(String source) throws ParseException { - return messageFormat.parse(source); - } - - /** - * {@icu} Parses text from the beginning of the given string to produce a map from - * argument to values. The method may not use the entire text of the given string. - * - *

      See the {@link #parse(String, ParsePosition)} method for more information on - * message parsing. - * - * @param source A String whose beginning should be parsed. - * @return A Map parsed from the string. - * @throws ParseException if the beginning of the specified string cannot - * be parsed. - * @see #parseToMap(String, ParsePosition) - * @stable ICU 3.8 - */ - public Map parseToMap(String source) throws ParseException { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Parses text from a string to produce an object array or Map. - *

      - * The method attempts to parse text starting at the index given by - * pos. - * If parsing succeeds, then the index of pos is updated - * to the index after the last character used (parsing does not necessarily - * use all characters up to the end of the string), and the parsed - * object array is returned. The updated pos can be used to - * indicate the starting point for the next call to this method. - * If an error occurs, then the index of pos is not - * changed, the error index of pos is set to the index of - * the character where the error occurred, and null is returned. - *

      - * See the {@link #parse(String, ParsePosition)} method for more information - * on message parsing. - * - * @param source A String, part of which should be parsed. - * @param pos A ParsePosition object with index and error - * index information as described above. - * @return An Object parsed from the string, either an - * array of Object, or a Map, depending on whether named - * arguments are used. This can be queried using usesNamedArguments. - * In case of error, returns null. - * @throws NullPointerException if pos is null. - * @stable ICU 3.0 - */ - public Object parseObject(String source, ParsePosition pos) { - return messageFormat.parse(source, pos); - } - - /** - * Overrides clone. - * - * @return a clone of this instance. - * @stable ICU 3.0 - */ - public Object clone() { - MessageFormat fmt = new MessageFormat((java.text.MessageFormat)messageFormat.clone()); - fmt.savedPattern = savedPattern; - return fmt; - } - - /** - * Overrides equals. - * @stable ICU 3.0 - */ - public boolean equals(Object obj) { - try { - return messageFormat.equals(((MessageFormat)obj).messageFormat); - } - catch (Exception e) { - return false; - } - } - - /** - * Overrides hashCode. - * @stable ICU 3.0 - */ - public int hashCode() { - return messageFormat.hashCode(); - } - - /** - * Defines constants that are used as attribute keys in the - * AttributedCharacterIterator returned - * from MessageFormat.formatToCharacterIterator. - * - * @stable ICU 3.8 - */ - public static class Field extends Format.Field { - - private static final long serialVersionUID = 7510380454602616157L; - - /** - * Create a Field with the specified name. - * - * @param name The name of the attribute - * - * @stable ICU 3.8 - */ - protected Field(String name) { - super(name); - } - - /** - * Resolves instances being deserialized to the predefined constants. - * - * @return resolved MessageFormat.Field constant - * @throws InvalidObjectException if the constant could not be resolved. - * - * @stable ICU 3.8 - */ - protected Object readResolve() throws InvalidObjectException { - if (this.getClass() != MessageFormat.Field.class) { - throw new InvalidObjectException( - "A subclass of MessageFormat.Field must implement readResolve."); - } - if (this.getName().equals(ARGUMENT.getName())) { - return ARGUMENT; - } else { - throw new InvalidObjectException("Unknown attribute name."); - } - } - - /** - * Constant identifying a portion of a message that was generated - * from an argument passed into formatToCharacterIterator. - * The value associated with the key will be an Integer - * indicating the index in the arguments array of the - * argument from which the text was generated. - * - * @stable ICU 3.8 - */ - public static final Field ARGUMENT = new Field("message argument field"); - - } - - private static final char SINGLE_QUOTE = '\''; - private static final char CURLY_BRACE_LEFT = '{'; - private static final char CURLY_BRACE_RIGHT = '}'; - - private static final int STATE_INITIAL = 0; - private static final int STATE_SINGLE_QUOTE = 1; - private static final int STATE_IN_QUOTE = 2; - private static final int STATE_MSG_ELEMENT = 3; - - /** - * {@icu} Converts an 'apostrophe-friendly' pattern into a standard - * pattern. Standard patterns treat all apostrophes as - * quotes, which is problematic in some languages, e.g. - * French, where apostrophe is commonly used. This utility - * assumes that only an unpaired apostrophe immediately before - * a brace is a true quote. Other unpaired apostrophes are paired, - * and the resulting standard pattern string is returned. - * - *

      Note it is not guaranteed that the returned pattern - * is indeed a valid pattern. The only effect is to convert - * between patterns having different quoting semantics. - * - * @param pattern the 'apostrophe-friendly' patttern to convert - * @return the standard equivalent of the original pattern - * @stable ICU 3.4 - */ - public static String autoQuoteApostrophe(String pattern) { - StringBuilder buf = new StringBuilder(pattern.length() * 2); - int state = STATE_INITIAL; - int braceCount = 0; - for (int i = 0, j = pattern.length(); i < j; ++i) { - char c = pattern.charAt(i); - switch (state) { - case STATE_INITIAL: - switch (c) { - case SINGLE_QUOTE: - state = STATE_SINGLE_QUOTE; - break; - case CURLY_BRACE_LEFT: - state = STATE_MSG_ELEMENT; - ++braceCount; - break; - } - break; - case STATE_SINGLE_QUOTE: - switch (c) { - case SINGLE_QUOTE: - state = STATE_INITIAL; - break; - case CURLY_BRACE_LEFT: - case CURLY_BRACE_RIGHT: - state = STATE_IN_QUOTE; - break; - default: - buf.append(SINGLE_QUOTE); - state = STATE_INITIAL; - break; - } - break; - case STATE_IN_QUOTE: - switch (c) { - case SINGLE_QUOTE: - state = STATE_INITIAL; - break; - } - break; - case STATE_MSG_ELEMENT: - switch (c) { - case CURLY_BRACE_LEFT: - ++braceCount; - break; - case CURLY_BRACE_RIGHT: - if (--braceCount == 0) { - state = STATE_INITIAL; - } - break; - } - break; - ///CLOVER:OFF - default: // Never happens. - break; - ///CLOVER:ON - } - buf.append(c); - } - // End of scan - if (state == STATE_SINGLE_QUOTE || state == STATE_IN_QUOTE) { - buf.append(SINGLE_QUOTE); - } - return new String(buf); - } - - private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { - if (icuPos == null) { - return null; - } - - int fieldID = icuPos.getField(); - Format.Field fieldAttribute = icuPos.getFieldAttribute(); - - FieldPosition jdkPos = null; - if (fieldAttribute != null) { - // map field - if (fieldAttribute.equals(Field.ARGUMENT)) { - fieldAttribute = java.text.MessageFormat.Field.ARGUMENT; - } - jdkPos = new FieldPosition(fieldAttribute, fieldID); - } else { - jdkPos = new FieldPosition(fieldID); - } - - jdkPos.setBeginIndex(icuPos.getBeginIndex()); - jdkPos.setEndIndex(icuPos.getEndIndex()); - - return jdkPos; - - } - - private void wrapNestedFormatters(java.text.MessageFormat mfmt) { - // Update nested formatters created by Java MessageFormat - // with ICU versions, so FieldPosition / AttributedText will - // use ICU formatter's definition, such as com.ibm.icu.text.NumberFormat.INTEGER_FIELD - - // Replacing nested formatter may change the pattern string - // originally used. For example, "{0,integer} files" is replaced - // with "{0} files". We preserve the original pattern. - savedPattern = mfmt.toPattern(); - - Format[] subfmts = mfmt.getFormats(); - for (int i = 0; i < subfmts.length; i++) { - if (subfmts[i] instanceof java.text.DateFormat) { - subfmts[i] = new DateFormat((java.text.DateFormat)subfmts[i]); - } else if (subfmts[i] instanceof java.text.NumberFormat) { - subfmts[i] = new NumberFormat((java.text.NumberFormat)subfmts[i]); - } - } - mfmt.setFormats(subfmts); - } - - private String savedPattern; -} +/* +********************************************************************** +* Copyright (c) 2004-2011, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* Author: Alan Liu +* Created: April 6, 2004 +* Since: ICU 3.0 +********************************************************************** +*/ +package com.ibm.icu.text; + +import java.io.InvalidObjectException; +import java.text.AttributedCharacterIterator; +import java.text.AttributedCharacterIterator.Attribute; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.text.ChoiceFormat; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.ibm.icu.util.ULocale; + +/** + * {@icuenhanced java.text.MessageFormat}.{@icu _usage_} + * + *

      MessageFormat produces concatenated messages in a language-neutral + * way. Use this whenever concatenating strings that are displayed to + * end users. + * + *

      A MessageFormat contains an array of subformats arranged + * within a template string. Together, the subformats and + * template string determine how the MessageFormat will operate during + * formatting and parsing. + * + *

      Typically, both the subformats and the template string are + * specified at once in a pattern. By using different + * patterns for different locales, messages may be localized. + * + *

      When formatting, MessageFormat takes a collection of arguments + * and produces a user-readable string. The arguments may be passed + * as an array or as a Map. Each argument is matched up with its + * corresponding subformat, which then formats it into a string. The + * resulting strings are then assembled within the string template of + * the MessageFormat to produce the final output string. + * + *

      Note: + * MessageFormat differs from the other Format + * classes in that you create a MessageFormat object with one + * of its constructors (not with a getInstance style factory + * method). The factory methods aren't necessary because MessageFormat + * itself doesn't implement locale-specific behavior. Any locale-specific + * behavior is defined by the pattern that you provide and the + * subformats used for inserted arguments. + * + *

      Note: + * In ICU 3.8 MessageFormat supports named arguments. If a named argument + * is used, all arguments must be named. Names start with a character in + * :ID_START: and continue with characters in :ID_CONTINUE:, + * in particular they do not start with a digit. If named arguments + * are used, {@link #usesNamedArguments()} will return true. + * + *

      The other new methods supporting named arguments are + * {@link #setFormatsByArgumentName(Map)}, + * {@link #setFormatByArgumentName(String, Format)}, + * {@link #format(Map, StringBuffer, FieldPosition)}, + * {@link #format(String, Map)}, {@link #parseToMap(String, ParsePosition)}, + * and {@link #parseToMap(String)}. These methods are all compatible + * with patterns that do not used named arguments-- in these cases + * the keys in the input or output Maps use + * Strings that name the argument indices, e.g. "0", + * "1", "2"... etc. + * + *

      When named arguments are used, certain methods on MessageFormat that take or + * return arrays will throw an exception, since it is not possible to + * identify positions in an array using a name. These methods are + * {@link #setFormatsByArgumentIndex(Format[])}, + * {@link #setFormatByArgumentIndex(int, Format)}, + * {@link #getFormatsByArgumentIndex()}, + * {@link #getFormats()}, + * {@link #format(Object[], StringBuffer, FieldPosition)}, + * {@link #format(String, Object[])}, + * {@link #parse(String, ParsePosition)}, and + * {@link #parse(String)}. + * These APIs all have corresponding new versions as listed above. + * + *

      The API {@link #format(Object, StringBuffer, FieldPosition)} has + * been modified so that the Object argument can be + * either an Object array or a Map. If this + * format uses named arguments, this argument must not be an + * Object array otherwise an exception will be thrown. + * If the argument is a Map it can be used with Strings that + * represent indices as described above. + * + *

      Patterns and Their Interpretation

      + * + * MessageFormat uses patterns of the following form: + *
      + * MessageFormatPattern:
      + *         String
      + *         MessageFormatPattern FormatElement String
      + *
      + * FormatElement:
      + *         { ArgumentIndexOrName }
      + *         { ArgumentIndexOrName , FormatType }
      + *         { ArgumentIndexOrName , FormatType , FormatStyle }
      + *
      + * ArgumentIndexOrName: one of 
      + *         ['0'-'9']+
      + *         [:ID_START:][:ID_CONTINUE:]*
      + *
      + * FormatType: one of 
      + *         number date time choice spellout ordinal duration plural
      + *
      + * FormatStyle:
      + *         short
      + *         medium
      + *         long
      + *         full
      + *         integer
      + *         currency
      + *         percent
      + *         SubformatPattern
      + *         RulesetName
      + *
      + * String:
      + *         StringPartopt
      + *         String StringPart
      + *
      + * StringPart:
      + *         ''
      + *         ' QuotedString '
      + *         UnquotedString
      + *
      + * SubformatPattern:
      + *         SubformatPatternPartopt
      + *         SubformatPattern SubformatPatternPart
      + *
      + * SubFormatPatternPart:
      + *         ' QuotedPattern '
      + *         UnquotedPattern
      + * 
      + * + * RulesetName: + * UnquotedString + * + *

      Within a String, "''" represents a single + * quote. A QuotedString can contain arbitrary characters + * except single quotes; the surrounding single quotes are removed. + * An UnquotedString can contain arbitrary characters + * except single quotes and left curly brackets. Thus, a string that + * should result in the formatted message "'{0}'" can be written as + * "'''{'0}''" or "'''{0}'''". + * + *

      Within a SubformatPattern, different rules apply. + * A QuotedPattern can contain arbitrary characters + * except single quotes; but the surrounding single quotes are + * not removed, so they may be interpreted by the + * subformat. For example, "{1,number,$'#',##}" will + * produce a number format with the pound-sign quoted, with a result + * such as: "$#31,45". + * An UnquotedPattern can contain arbitrary characters + * except single quotes, but curly braces within it must be balanced. + * For example, "ab {0} de" and "ab '}' de" + * are valid subformat patterns, but "ab {0'}' de" and + * "ab } de" are not. + * + *

      Warning:
      The rules for using quotes within message + * format patterns unfortunately have shown to be somewhat confusing. + * In particular, it isn't always obvious to localizers whether single + * quotes need to be doubled or not. Make sure to inform localizers about + * the rules, and tell them (for example, by using comments in resource + * bundle source files) which strings will be processed by MessageFormat. + * Note that localizers may need to use single quotes in translated + * strings where the original version doesn't have them. + * + *
      Note also that the simplest way to avoid the problem is to + * use the real apostrophe (single quote) character \u2019 (') for + * human-readable text, and to use the ASCII apostrophe (\u0027 ' ) + * only in program syntax, like quoting in MessageFormat. + * See the annotations for U+0027 Apostrophe in The Unicode Standard.

      + *
      + * + *

      The ArgumentIndex value is a non-negative integer written + * using the digits '0' through '9', and represents an index into the + * arguments array passed to the format methods + * or the result array returned by the parse methods. + * + *

      The FormatType and FormatStyle values are used to create + * a Format instance for the format element. The following + * table shows how the values map to Format instances. Combinations not + * shown in the table are illegal. A SubformatPattern must + * be a valid pattern string for the Format subclass used. + * + *

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Format Type + * Format Style + * Subformat Created + *
      (none) + * null + *
      number + * (none) + * NumberFormat.getInstance(getLocale()) + *
      integer + * NumberFormat.getIntegerInstance(getLocale()) + *
      currency + * NumberFormat.getCurrencyInstance(getLocale()) + *
      percent + * NumberFormat.getPercentInstance(getLocale()) + *
      SubformatPattern + * new DecimalFormat(subformatPattern, new DecimalFormatSymbols(getLocale())) + *
      date + * (none) + * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) + *
      short + * DateFormat.getDateInstance(DateFormat.SHORT, getLocale()) + *
      medium + * DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale()) + *
      long + * DateFormat.getDateInstance(DateFormat.LONG, getLocale()) + *
      full + * DateFormat.getDateInstance(DateFormat.FULL, getLocale()) + *
      SubformatPattern + * new SimpleDateFormat(subformatPattern, getLocale()) + *
      time + * (none) + * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) + *
      short + * DateFormat.getTimeInstance(DateFormat.SHORT, getLocale()) + *
      medium + * DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale()) + *
      long + * DateFormat.getTimeInstance(DateFormat.LONG, getLocale()) + *
      full + * DateFormat.getTimeInstance(DateFormat.FULL, getLocale()) + *
      SubformatPattern + * new SimpleDateFormat(subformatPattern, getLocale()) + *
      choice + * SubformatPattern + * new ChoiceFormat(subformatPattern) + *
      spellout + * RulesetName (optional) + * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.SPELLOUT) + *
          .setDefaultRuleset(ruleset);
      + *
      ordinal + * RulesetName (optional) + * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.ORDINAL) + *
          .setDefaultRuleset(ruleset);
      + *
      duration + * RulesetName (optional) + * new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.DURATION) + *
          .setDefaultRuleset(ruleset);
      + *
      plural + * SubformatPattern + * new PluralFormat(subformatPattern) + *
      select + * SubformatPattern + * new SelectFormat(subformatPattern) + *
      + *

      + * + *

      Usage Information

      + * + *

      Here are some examples of usage: + *

      + *
      + * Object[] arguments = {
      + *     new Integer(7),
      + *     new Date(System.currentTimeMillis()),
      + *     "a disturbance in the Force"
      + * };
      + *
      + * String result = MessageFormat.format(
      + *     "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
      + *     arguments);
      + *
      + * output: At 12:30 PM on Jul 3, 2053, there was a disturbance
      + *           in the Force on planet 7.
      + *
      + * 
      + *
      + * Typically, the message format will come from resources, and the + * arguments will be dynamically set at runtime. + * + *

      Example 2: + *

      + *
      + * Object[] testArgs = {new Long(3), "MyDisk"};
      + *
      + * MessageFormat form = new MessageFormat(
      + *     "The disk \"{1}\" contains {0} file(s).");
      + *
      + * System.out.println(form.format(testArgs));
      + *
      + * // output, with different testArgs
      + * output: The disk "MyDisk" contains 0 file(s).
      + * output: The disk "MyDisk" contains 1 file(s).
      + * output: The disk "MyDisk" contains 1,273 file(s).
      + * 
      + *
      + * + *

      For more sophisticated patterns, you can use a ChoiceFormat to get + * output such as: + *

      + *
      + * MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
      + * double[] filelimits = {0,1,2};
      + * String[] filepart = {"no files","one file","{0,number} files"};
      + * ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
      + * form.setFormatByArgumentIndex(0, fileform);
      + *
      + * Object[] testArgs = {new Long(12373), "MyDisk"};
      + *
      + * System.out.println(form.format(testArgs));
      + *
      + * // output, with different testArgs
      + * output: The disk "MyDisk" contains no files.
      + * output: The disk "MyDisk" contains one file.
      + * output: The disk "MyDisk" contains 1,273 files.
      + * 
      + *
      + * You can either do this programmatically, as in the above example, + * or by using a pattern (see + * {@link ChoiceFormat} + * for more information) as in: + *
      + *
      + * form.applyPattern(
      + *    "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
      + * 
      + *
      + * + *

      Note: As we see above, the string produced + * by a ChoiceFormat in MessageFormat is treated specially; + * occurances of '{' are used to indicated subformats, and cause recursion. + * If you create both a MessageFormat and ChoiceFormat + * programmatically (instead of using the string patterns), then be careful not to + * produce a format that recurses on itself, which will cause an infinite loop. + * + *

      When a single argument is parsed more than once in the string, the last match + * will be the final result of the parsing. For example, + *

      + * MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
      + * Object[] objs = {new Double(3.1415)};
      + * String result = mf.format( objs );
      + * // result now equals "3.14, 3.1"
      + * objs = null;
      + * objs = mf.parse(result, new ParsePosition(0));
      + * // objs now equals {new Double(3.1)}
      + * 
      + * + *

      Likewise, parsing with a MessageFormat object using patterns containing + * multiple occurances of the same argument would return the last match. For + * example, + *

      + * MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
      + * String forParsing = "x, y, z";
      + * Object[] objs = mf.parse(forParsing, new ParsePosition(0));
      + * // result now equals {new String("z")}
      + * 
      + * + *

      Synchronization

      + * + *

      Message formats are not synchronized. + * It is recommended to create separate format instances for each thread. + * If multiple threads access a format concurrently, it must be synchronized + * externally. + * + * @see java.util.Locale + * @see Format + * @see NumberFormat + * @see DecimalFormat + * @see ChoiceFormat + * @see PluralFormat + * @see SelectFormat + * @author Mark Davis + * @stable ICU 3.0 + */ +public class MessageFormat extends UFormat { + static final long serialVersionUID = 1L; + + /** + * @internal + */ + public final java.text.MessageFormat messageFormat; + + /** + * @internal + * @param delegate the DateFormat to which to delegate + */ + public MessageFormat(java.text.MessageFormat delegate) { + wrapNestedFormatters(delegate); + this.messageFormat = delegate; + } + + /** + * Constructs a MessageFormat for the default locale and the + * specified pattern. + * The constructor first sets the locale, then parses the pattern and + * creates a list of subformats for the format elements contained in it. + * Patterns and their interpretation are specified in the + * class description. + * + * @param pattern the pattern for this message format + * @exception IllegalArgumentException if the pattern is invalid + * @stable ICU 3.0 + */ + public MessageFormat(String pattern) { + this(new java.text.MessageFormat(pattern)); + } + + /** + * Constructs a MessageFormat for the specified locale and + * pattern. + * The constructor first sets the locale, then parses the pattern and + * creates a list of subformats for the format elements contained in it. + * Patterns and their interpretation are specified in the + * class description. + * + * @param pattern the pattern for this message format + * @param locale the locale for this message format + * @exception IllegalArgumentException if the pattern is invalid + * @stable ICU 3.0 + */ + public MessageFormat(String pattern, Locale locale) { + this(new java.text.MessageFormat(pattern, locale)); + } + + /** + * Constructs a MessageFormat for the specified locale and + * pattern. + * The constructor first sets the locale, then parses the pattern and + * creates a list of subformats for the format elements contained in it. + * Patterns and their interpretation are specified in the + * class description. + * + * @param pattern the pattern for this message format + * @param locale the locale for this message format + * @exception IllegalArgumentException if the pattern is invalid + * @stable ICU 3.2 + */ + public MessageFormat(String pattern, ULocale locale) { + this(new java.text.MessageFormat(pattern, locale.toLocale())); + } + + /** + * Sets the locale to be used when creating or comparing subformats. + * This affects subsequent calls to the {@link #applyPattern applyPattern} + * and {@link #toPattern toPattern} methods as well as to the + * format and + * {@link #formatToCharacterIterator formatToCharacterIterator} methods. + * + * @param locale the locale to be used when creating or comparing subformats + * @stable ICU 3.0 + */ + public void setLocale(Locale locale) { + messageFormat.setLocale(locale); + } + + /** + * Sets the locale to be used when creating or comparing subformats. + * This affects subsequent calls to the {@link #applyPattern applyPattern} + * and {@link #toPattern toPattern} methods as well as to the + * format and + * {@link #formatToCharacterIterator formatToCharacterIterator} methods. + * + * @param locale the locale to be used when creating or comparing subformats + * @stable ICU 3.2 + */ + public void setLocale(ULocale locale) { + messageFormat.setLocale(locale.toLocale()); + } + + /** + * Returns the locale that's used when creating or comparing subformats. + * + * @return the locale used when creating or comparing subformats + * @stable ICU 3.0 + */ + public Locale getLocale() { + return messageFormat.getLocale(); + } + + /** + * {@icu} Returns the locale that's used when creating or comparing subformats. + * + * @return the locale used when creating or comparing subformats + * @stable ICU 3.2 + */ + public ULocale getULocale() { + return ULocale.forLocale(messageFormat.getLocale()); + } + + /** + * Sets the pattern used by this message format. + * The method parses the pattern and creates a list of subformats + * for the format elements contained in it. + * Patterns and their interpretation are specified in the + * class description. + *

      + * The pattern must contain only named or only numeric arguments, + * mixing them is not allowed. + * + * @param pttrn the pattern for this message format + * @throws IllegalArgumentException if the pattern is invalid + * @stable ICU 3.0 + */ + public void applyPattern(String pttrn) { + messageFormat.applyPattern(pttrn); + wrapNestedFormatters(messageFormat); + } + + /** + * Returns a pattern representing the current state of the message format. + * The string is constructed from internal information and therefore + * does not necessarily equal the previously applied pattern. + * + * @return a pattern representing the current state of the message format + * @stable ICU 3.0 + */ + public String toPattern() { + String pattern = savedPattern == null ? messageFormat.toPattern() : savedPattern; + return pattern; + } + + /** + * Sets the formats to use for the values passed into + * format methods or returned from parse + * methods. The indices of elements in newFormats + * correspond to the argument indices used in the previously set + * pattern string. + * The order of formats in newFormats thus corresponds to + * the order of elements in the arguments array passed + * to the format methods or the result array returned + * by the parse methods. + *

      + * If an argument index is used for more than one format element + * in the pattern string, then the corresponding new format is used + * for all such format elements. If an argument index is not used + * for any format element in the pattern string, then the + * corresponding new format is ignored. If fewer formats are provided + * than needed, then only the formats for argument indices less + * than newFormats.length are replaced. + * + * This method is only supported if the format does not use + * named arguments, otherwise an IllegalArgumentException is thrown. + * + * @param newFormats the new formats to use + * @throws NullPointerException if newFormats is null + * @throws IllegalArgumentException if this formatter uses named arguments + * @stable ICU 3.0 + */ + public void setFormatsByArgumentIndex(Format[] newFormats) { + messageFormat.setFormatsByArgumentIndex(newFormats); + savedPattern = null; + } + + /** + * {@icu} Sets the formats to use for the values passed into + * format methods or returned from parse + * methods. The keys in newFormats are the argument + * names in the previously set pattern string, and the values + * are the formats. + *

      + * Only argument names from the pattern string are considered. + * Extra keys in newFormats that do not correspond + * to an argument name are ignored. Similarly, if there is no + * format in newFormats for an argument name, the formatter + * for that argument remains unchanged. + *

      + * This may be called on formats that do not use named arguments. + * In this case the map will be queried for key Strings that + * represent argument indices, e.g. "0", "1", "2" etc. + * + * @param newFormats a map from String to Format providing new + * formats for named arguments. + * @stable ICU 3.8 + */ + public void setFormatsByArgumentName(Map newFormats) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the formats to use for the format elements in the + * previously set pattern string. + * The order of formats in newFormats corresponds to + * the order of format elements in the pattern string. + *

      + * If more formats are provided than needed by the pattern string, + * the remaining ones are ignored. If fewer formats are provided + * than needed, then only the first newFormats.length + * formats are replaced. + *

      + * Since the order of format elements in a pattern string often + * changes during localization, it is generally better to use the + * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex} + * method, which assumes an order of formats corresponding to the + * order of elements in the arguments array passed to + * the format methods or the result array returned by + * the parse methods. + * + * @param newFormats the new formats to use + * @exception NullPointerException if newFormats is null + * @stable ICU 3.0 + */ + public void setFormats(Format[] newFormats) { + messageFormat.setFormats(newFormats); + savedPattern = null; + } + + /** + * Sets the format to use for the format elements within the + * previously set pattern string that use the given argument + * index. + * The argument index is part of the format element definition and + * represents an index into the arguments array passed + * to the format methods or the result array returned + * by the parse methods. + *

      + * If the argument index is used for more than one format element + * in the pattern string, then the new format is used for all such + * format elements. If the argument index is not used for any format + * element in the pattern string, then the new format is ignored. + * + * This method is only supported when exclusively numbers are used for + * argument names. Otherwise an IllegalArgumentException is thrown. + * + * @param argumentIndex the argument index for which to use the new format + * @param newFormat the new format to use + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public void setFormatByArgumentIndex(int argumentIndex, Format newFormat) { + messageFormat.setFormatByArgumentIndex(argumentIndex, newFormat); + savedPattern = null; + } + + /** + * {@icu} Sets the format to use for the format elements within the + * previously set pattern string that use the given argument + * name. + *

      + * If the argument name is used for more than one format element + * in the pattern string, then the new format is used for all such + * format elements. If the argument name is not used for any format + * element in the pattern string, then the new format is ignored. + *

      + * This API may be used on formats that do not use named arguments. + * In this case argumentName should be a String that names + * an argument index, e.g. "0", "1", "2"... etc. If it does not name + * a valid index, the format will be ignored. No error is thrown. + * + * @param argumentName the name of the argument to change + * @param newFormat the new format to use + * @stable ICU 3.8 + */ + public void setFormatByArgumentName(String argumentName, Format newFormat) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the format to use for the format element with the given + * format element index within the previously set pattern string. + * The format element index is the zero-based number of the format + * element counting from the start of the pattern string. + *

      + * Since the order of format elements in a pattern string often + * changes during localization, it is generally better to use the + * {@link #setFormatByArgumentIndex setFormatByArgumentIndex} + * method, which accesses format elements based on the argument + * index they specify. + * + * @param formatElementIndex the index of a format element within the pattern + * @param newFormat the format to use for the specified format element + * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or + * larger than the number of format elements in the pattern string + * @stable ICU 3.0 + */ + public void setFormat(int formatElementIndex, Format newFormat) { + messageFormat.setFormat(formatElementIndex, newFormat); + savedPattern = null; + } + + /** + * Returns the formats used for the values passed into + * format methods or returned from parse + * methods. The indices of elements in the returned array + * correspond to the argument indices used in the previously set + * pattern string. + * The order of formats in the returned array thus corresponds to + * the order of elements in the arguments array passed + * to the format methods or the result array returned + * by the parse methods. + *

      + * If an argument index is used for more than one format element + * in the pattern string, then the format used for the last such + * format element is returned in the array. If an argument index + * is not used for any format element in the pattern string, then + * null is returned in the array. + * + * This method is only supported when exclusively numbers are used for + * argument names. Otherwise an IllegalArgumentException is thrown. + * + * @return the formats used for the arguments within the pattern + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public Format[] getFormatsByArgumentIndex() { + return messageFormat.getFormatsByArgumentIndex(); + } + + /** + * Returns the formats used for the format elements in the + * previously set pattern string. + * The order of formats in the returned array corresponds to + * the order of format elements in the pattern string. + *

      + * Since the order of format elements in a pattern string often + * changes during localization, it's generally better to use the + * {@link #getFormatsByArgumentIndex()} + * method, which assumes an order of formats corresponding to the + * order of elements in the arguments array passed to + * the format methods or the result array returned by + * the parse methods. + * + * This method is only supported when exclusively numbers are used for + * argument names. Otherwise an IllegalArgumentException is thrown. + * + * @return the formats used for the format elements in the pattern + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public Format[] getFormats() { + return messageFormat.getFormats(); + } + + /** + * {@icu} Returns the format argument names. For more details, see + * {@link #setFormatByArgumentName(String, Format)}. + * @return List of names + * @internal + * @deprecated This API is ICU internal only. + */ + public Set getFormatArgumentNames() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the formats according to their argument names. For more details, see + * {@link #setFormatByArgumentName(String, Format)}. + * @return format associated with the name, or null if there isn't one. + * @internal + * @deprecated This API is ICU internal only. + */ + public Format getFormatByArgumentName(String argumentName) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Formats an array of objects and appends the MessageFormat's + * pattern, with format elements replaced by the formatted objects, to the + * provided StringBuffer. + *

      + * The text substituted for the individual format elements is derived from + * the current subformat of the format element and the + * arguments element at the format element's argument index + * as indicated by the first matching line of the following table. An + * argument is unavailable if arguments is + * null or has fewer than argumentIndex+1 elements. When + * an argument is unavailable no substitution is performed. + *

      + * + * + * + * + * + * + * + * + * + * + *
      Subformat + * Argument + * Formatted Text + *
      any + * unavailable + * "{" + argumentIndex + "}" + *
      any + * null + * "null" + *
      instanceof ChoiceFormat + * any + * subformat.format(argument).indexOf('{') >= 0 ?
      + * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : + * subformat.format(argument)
      + *
      != null + * any + * subformat.format(argument) + *
      null + * instanceof Number + * NumberFormat.getInstance(getLocale()).format(argument) + *
      null + * instanceof Date + * DateFormat.getDateTimeInstance(DateFormat.SHORT, + * DateFormat.SHORT, getLocale()).format(argument) + *
      null + * instanceof String + * argument + *
      null + * any + * argument.toString() + *
      + *

      + * If pos is non-null, and refers to + * Field.ARGUMENT, the location of the first formatted + * string will be returned. + * + * This method is only supported when the format does not use named + * arguments, otherwise an IllegalArgumentException is thrown. + * + * @param arguments an array of objects to be formatted and substituted. + * @param result where text is appended. + * @param pos On input: an alignment field, if desired. + * On output: the offsets of the alignment field. + * @throws IllegalArgumentException if an argument in the + * arguments array is not of the type + * expected by the format element(s) that use it. + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public final StringBuffer format(Object[] arguments, StringBuffer result, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = messageFormat.format(arguments, result, jdkPos); + if (jdkPos != null) { + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + } + return buf; + } + + /** + * Formats a map of objects and appends the MessageFormat's + * pattern, with format elements replaced by the formatted objects, to the + * provided StringBuffer. + *

      + * The text substituted for the individual format elements is derived from + * the current subformat of the format element and the + * arguments value corresopnding to the format element's + * argument name. + *

      + * This API may be called on formats that do not use named arguments. + * In this case the the keys in arguments must be numeric + * strings (e.g. "0", "1", "2"...). + *

      + * An argument is unavailable if arguments is + * null or does not have a value corresponding to an argument + * name in the pattern. When an argument is unavailable no substitution + * is performed. + * + * @param arguments a map of objects to be formatted and substituted. + * @param result where text is appended. + * @param pos On input: an alignment field, if desired. + * On output: the offsets of the alignment field. + * @throws IllegalArgumentException if an argument in the + * arguments array is not of the type + * expected by the format element(s) that use it. + * @return the passed-in StringBuffer + * @stable ICU 3.8 + */ + public final StringBuffer format(Map arguments, StringBuffer result, + FieldPosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Creates a MessageFormat with the given pattern and uses it + * to format the given arguments. This is equivalent to + *

      + * (new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link + * #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) + * format}(arguments, new StringBuffer(), null).toString() + *
      + * + * @throws IllegalArgumentException if the pattern is invalid, + * or if an argument in the arguments array + * is not of the type expected by the format element(s) + * that use it. + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public static String format(String pattern, Object... arguments) { + return java.text.MessageFormat.format(pattern, arguments); + } + + /** + * Creates a MessageFormat with the given pattern and uses it to + * format the given arguments. The pattern must identifyarguments + * by name instead of by number. + *

      + * @throws IllegalArgumentException if the pattern is invalid, + * or if an argument in the arguments map + * is not of the type expected by the format element(s) + * that use it. + * @see #format(Map, StringBuffer, FieldPosition) + * @see #format(String, Object[]) + * @stable ICU 3.8 + */ + public static String format(String pattern, Map arguments) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns true if this MessageFormat uses named arguments, + * and false otherwise. See class description. + * + * @return true if named arguments are used. + * @stable ICU 3.8 + */ + public boolean usesNamedArguments() { + // always false with com.ibm.icu.base + return false; + } + + // Overrides + /** + * Formats a map or array of objects and appends the MessageFormat's + * pattern, with format elements replaced by the formatted objects, to the + * provided StringBuffer. + * This is equivalent to either of + *

      + * {@link #format(java.lang.Object[], java.lang.StringBuffer, + * java.text.FieldPosition) format}((Object[]) arguments, result, pos) + * {@link #format(java.util.Map, java.lang.StringBuffer, + * java.text.FieldPosition) format}((Map) arguments, result, pos) + *
      + * A map must be provided if this format uses named arguments, otherwise + * an IllegalArgumentException will be thrown. + * @param arguments a map or array of objects to be formatted + * @param result where text is appended + * @param pos On input: an alignment field, if desired + * On output: the offsets of the alignment field + * @throws IllegalArgumentException if an argument in + * arguments is not of the type + * expected by the format element(s) that use it + * @throws IllegalArgumentException if arguments is + * an array of Object and this format uses named arguments + * @stable ICU 3.0 + */ + public final StringBuffer format(Object arguments, StringBuffer result, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = messageFormat.format(arguments, result, jdkPos); + if (jdkPos != null) { + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + } + return buf; + } + + /** + * Formats an array of objects and inserts them into the + * MessageFormat's pattern, producing an + * AttributedCharacterIterator. + * You can use the returned AttributedCharacterIterator + * to build the resulting String, as well as to determine information + * about the resulting String. + *

      + * The text of the returned AttributedCharacterIterator is + * the same that would be returned by + *

      + * {@link #format(java.lang.Object[], java.lang.StringBuffer, + * java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString() + *
      + *

      + * In addition, the AttributedCharacterIterator contains at + * least attributes indicating where text was generated from an + * argument in the arguments array. The keys of these attributes are of + * type MessageFormat.Field, their values are + * Integer objects indicating the index in the arguments + * array of the argument from which the text was generated. + *

      + * The attributes/value from the underlying Format + * instances that MessageFormat uses will also be + * placed in the resulting AttributedCharacterIterator. + * This allows you to not only find where an argument is placed in the + * resulting String, but also which fields it contains in turn. + * + * @param arguments an array of objects to be formatted and substituted. + * @return AttributedCharacterIterator describing the formatted value. + * @exception NullPointerException if arguments is null. + * @exception IllegalArgumentException if an argument in the + * arguments array is not of the type + * expected by the format element(s) that use it. + * @stable ICU 3.8 + */ + public AttributedCharacterIterator formatToCharacterIterator(Object arguments) { + AttributedCharacterIterator it = messageFormat.formatToCharacterIterator(arguments); + + // Extract formatted String first + StringBuilder sb = new StringBuilder(); + for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { + sb.append(c); + } + + // Create AttributedString + AttributedString attrstr = new AttributedString(sb.toString()); + + // Map JDK Field to ICU Field + int idx = 0; + it.first(); + while (idx < it.getEndIndex()) { + int end = it.getRunLimit(); + Map attributes = it.getAttributes(); + if (attributes != null) { + for (Entry entry : attributes.entrySet()) { + Attribute attr = entry.getKey(); + Object val = entry.getValue(); + if (attr.equals(java.text.MessageFormat.Field.ARGUMENT)) { + val = attr = Field.ARGUMENT; + } + attrstr.addAttribute(attr, val, idx, end); + } + } + idx = end; + while (it.getIndex() < idx) { + it.next(); + } + } + + return attrstr.getIterator(); + } + + /** + * Parses the string. + * + *

      Caveats: The parse may fail in a number of circumstances. + * For example: + *

        + *
      • If one of the arguments does not occur in the pattern. + *
      • If the format of an argument loses information, such as + * with a choice format where a large number formats to "many". + *
      • Does not yet handle recursion (where + * the substituted strings contain {n} references.) + *
      • Will not always find a match (or the correct match) + * if some part of the parse is ambiguous. + * For example, if the pattern "{1},{2}" is used with the + * string arguments {"a,b", "c"}, it will format as "a,b,c". + * When the result is parsed, it will return {"a", "b,c"}. + *
      • If a single argument is parsed more than once in the string, + * then the later parse wins. + *
      + * When the parse fails, use ParsePosition.getErrorIndex() to find out + * where in the string did the parsing failed. The returned error + * index is the starting offset of the sub-patterns that the string + * is comparing with. For example, if the parsing string "AAA {0} BBB" + * is comparing against the pattern "AAD {0} BBB", the error index is + * 0. When an error occurs, the call to this method will return null. + * If the source is null, return an empty array. + *

      + * This method is only supported with numbered arguments. If + * the format pattern used named argument an + * IllegalArgumentException is thrown. + * + * @throws IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public Object[] parse(String source, ParsePosition pos) { + return messageFormat.parse(source, pos); + } + + /** + * {@icu} Parses the string, returning the results in a Map. + * This is similar to the version that returns an array + * of Object. This supports both named and numbered + * arguments-- if numbered, the keys in the map are the + * corresponding Strings (e.g. "0", "1", "2"...). + * + * @param source the text to parse + * @param pos the position at which to start parsing. on return, + * contains the result of the parse. + * @return a Map containing key/value pairs for each parsed argument. + * @stable ICU 3.8 + */ + public Map parseToMap(String source, ParsePosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Parses text from the beginning of the given string to produce an object + * array. + * The method may not use the entire text of the given string. + *

      + * See the {@link #parse(String, ParsePosition)} method for more information + * on message parsing. + * + * @param source A String whose beginning should be parsed. + * @return An Object array parsed from the string. + * @exception ParseException if the beginning of the specified string cannot be parsed. + * @exception IllegalArgumentException if this format uses named arguments + * @stable ICU 3.0 + */ + public Object[] parse(String source) throws ParseException { + return messageFormat.parse(source); + } + + /** + * {@icu} Parses text from the beginning of the given string to produce a map from + * argument to values. The method may not use the entire text of the given string. + * + *

      See the {@link #parse(String, ParsePosition)} method for more information on + * message parsing. + * + * @param source A String whose beginning should be parsed. + * @return A Map parsed from the string. + * @throws ParseException if the beginning of the specified string cannot + * be parsed. + * @see #parseToMap(String, ParsePosition) + * @stable ICU 3.8 + */ + public Map parseToMap(String source) throws ParseException { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Parses text from a string to produce an object array or Map. + *

      + * The method attempts to parse text starting at the index given by + * pos. + * If parsing succeeds, then the index of pos is updated + * to the index after the last character used (parsing does not necessarily + * use all characters up to the end of the string), and the parsed + * object array is returned. The updated pos can be used to + * indicate the starting point for the next call to this method. + * If an error occurs, then the index of pos is not + * changed, the error index of pos is set to the index of + * the character where the error occurred, and null is returned. + *

      + * See the {@link #parse(String, ParsePosition)} method for more information + * on message parsing. + * + * @param source A String, part of which should be parsed. + * @param pos A ParsePosition object with index and error + * index information as described above. + * @return An Object parsed from the string, either an + * array of Object, or a Map, depending on whether named + * arguments are used. This can be queried using usesNamedArguments. + * In case of error, returns null. + * @throws NullPointerException if pos is null. + * @stable ICU 3.0 + */ + public Object parseObject(String source, ParsePosition pos) { + return messageFormat.parse(source, pos); + } + + /** + * Overrides clone. + * + * @return a clone of this instance. + * @stable ICU 3.0 + */ + public Object clone() { + MessageFormat fmt = new MessageFormat((java.text.MessageFormat)messageFormat.clone()); + fmt.savedPattern = savedPattern; + return fmt; + } + + /** + * Overrides equals. + * @stable ICU 3.0 + */ + public boolean equals(Object obj) { + try { + return messageFormat.equals(((MessageFormat)obj).messageFormat); + } + catch (Exception e) { + return false; + } + } + + /** + * Overrides hashCode. + * @stable ICU 3.0 + */ + public int hashCode() { + return messageFormat.hashCode(); + } + + /** + * Defines constants that are used as attribute keys in the + * AttributedCharacterIterator returned + * from MessageFormat.formatToCharacterIterator. + * + * @stable ICU 3.8 + */ + public static class Field extends Format.Field { + + private static final long serialVersionUID = 7510380454602616157L; + + /** + * Create a Field with the specified name. + * + * @param name The name of the attribute + * + * @stable ICU 3.8 + */ + protected Field(String name) { + super(name); + } + + /** + * Resolves instances being deserialized to the predefined constants. + * + * @return resolved MessageFormat.Field constant + * @throws InvalidObjectException if the constant could not be resolved. + * + * @stable ICU 3.8 + */ + protected Object readResolve() throws InvalidObjectException { + if (this.getClass() != MessageFormat.Field.class) { + throw new InvalidObjectException( + "A subclass of MessageFormat.Field must implement readResolve."); + } + if (this.getName().equals(ARGUMENT.getName())) { + return ARGUMENT; + } else { + throw new InvalidObjectException("Unknown attribute name."); + } + } + + /** + * Constant identifying a portion of a message that was generated + * from an argument passed into formatToCharacterIterator. + * The value associated with the key will be an Integer + * indicating the index in the arguments array of the + * argument from which the text was generated. + * + * @stable ICU 3.8 + */ + public static final Field ARGUMENT = new Field("message argument field"); + + } + + private static final char SINGLE_QUOTE = '\''; + private static final char CURLY_BRACE_LEFT = '{'; + private static final char CURLY_BRACE_RIGHT = '}'; + + private static final int STATE_INITIAL = 0; + private static final int STATE_SINGLE_QUOTE = 1; + private static final int STATE_IN_QUOTE = 2; + private static final int STATE_MSG_ELEMENT = 3; + + /** + * {@icu} Converts an 'apostrophe-friendly' pattern into a standard + * pattern. Standard patterns treat all apostrophes as + * quotes, which is problematic in some languages, e.g. + * French, where apostrophe is commonly used. This utility + * assumes that only an unpaired apostrophe immediately before + * a brace is a true quote. Other unpaired apostrophes are paired, + * and the resulting standard pattern string is returned. + * + *

      Note it is not guaranteed that the returned pattern + * is indeed a valid pattern. The only effect is to convert + * between patterns having different quoting semantics. + * + * @param pattern the 'apostrophe-friendly' patttern to convert + * @return the standard equivalent of the original pattern + * @stable ICU 3.4 + */ + public static String autoQuoteApostrophe(String pattern) { + StringBuilder buf = new StringBuilder(pattern.length() * 2); + int state = STATE_INITIAL; + int braceCount = 0; + for (int i = 0, j = pattern.length(); i < j; ++i) { + char c = pattern.charAt(i); + switch (state) { + case STATE_INITIAL: + switch (c) { + case SINGLE_QUOTE: + state = STATE_SINGLE_QUOTE; + break; + case CURLY_BRACE_LEFT: + state = STATE_MSG_ELEMENT; + ++braceCount; + break; + } + break; + case STATE_SINGLE_QUOTE: + switch (c) { + case SINGLE_QUOTE: + state = STATE_INITIAL; + break; + case CURLY_BRACE_LEFT: + case CURLY_BRACE_RIGHT: + state = STATE_IN_QUOTE; + break; + default: + buf.append(SINGLE_QUOTE); + state = STATE_INITIAL; + break; + } + break; + case STATE_IN_QUOTE: + switch (c) { + case SINGLE_QUOTE: + state = STATE_INITIAL; + break; + } + break; + case STATE_MSG_ELEMENT: + switch (c) { + case CURLY_BRACE_LEFT: + ++braceCount; + break; + case CURLY_BRACE_RIGHT: + if (--braceCount == 0) { + state = STATE_INITIAL; + } + break; + } + break; + ///CLOVER:OFF + default: // Never happens. + break; + ///CLOVER:ON + } + buf.append(c); + } + // End of scan + if (state == STATE_SINGLE_QUOTE || state == STATE_IN_QUOTE) { + buf.append(SINGLE_QUOTE); + } + return new String(buf); + } + + private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { + if (icuPos == null) { + return null; + } + + int fieldID = icuPos.getField(); + Format.Field fieldAttribute = icuPos.getFieldAttribute(); + + FieldPosition jdkPos = null; + if (fieldAttribute != null) { + // map field + if (fieldAttribute.equals(Field.ARGUMENT)) { + fieldAttribute = java.text.MessageFormat.Field.ARGUMENT; + } + jdkPos = new FieldPosition(fieldAttribute, fieldID); + } else { + jdkPos = new FieldPosition(fieldID); + } + + jdkPos.setBeginIndex(icuPos.getBeginIndex()); + jdkPos.setEndIndex(icuPos.getEndIndex()); + + return jdkPos; + + } + + private void wrapNestedFormatters(java.text.MessageFormat mfmt) { + // Update nested formatters created by Java MessageFormat + // with ICU versions, so FieldPosition / AttributedText will + // use ICU formatter's definition, such as com.ibm.icu.text.NumberFormat.INTEGER_FIELD + + // Replacing nested formatter may change the pattern string + // originally used. For example, "{0,integer} files" is replaced + // with "{0} files". We preserve the original pattern. + savedPattern = mfmt.toPattern(); + + Format[] subfmts = mfmt.getFormats(); + for (int i = 0; i < subfmts.length; i++) { + if (subfmts[i] instanceof java.text.DateFormat) { + subfmts[i] = new DateFormat((java.text.DateFormat)subfmts[i]); + } else if (subfmts[i] instanceof java.text.NumberFormat) { + subfmts[i] = new NumberFormat((java.text.NumberFormat)subfmts[i]); + } + } + mfmt.setFormats(subfmts); + } + + private String savedPattern; +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java index 62f3202f043..9f808836fb3 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java @@ -1,1312 +1,1312 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.text; - -import java.io.InvalidObjectException; -import java.math.BigInteger; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Locale; -import java.util.Set; - -import com.ibm.icu.util.Currency; -import com.ibm.icu.util.CurrencyAmount; -import com.ibm.icu.util.ULocale; - -/** - * {@icuenhanced java.text.NumberFormat}.{@icu _usage_} - * - * NumberFormat is the abstract base class for all number - * formats. This class provides the interface for formatting and parsing - * numbers. NumberFormat also provides methods for determining - * which locales have number formats, and what their names are. - * - * NumberFormat helps you to format and parse numbers for any locale. - * Your code can be completely independent of the locale conventions for - * decimal points, thousands-separators, or even the particular decimal - * digits used, or whether the number format is even decimal. - * - *

      - * To format a number for the current Locale, use one of the factory - * class methods: - *

      - *
      - *  myString = NumberFormat.getInstance().format(myNumber);
      - * 
      - *
      - * If you are formatting multiple numbers, it is - * more efficient to get the format and use it multiple times so that - * the system doesn't have to fetch the information about the local - * language and country conventions multiple times. - *
      - *
      - * NumberFormat nf = NumberFormat.getInstance();
      - * for (int i = 0; i < a.length; ++i) {
      - *     output.println(nf.format(myNumber[i]) + "; ");
      - * }
      - * 
      - *
      - * To format a number for a different Locale, specify it in the - * call to getInstance. - *
      - *
      - * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
      - * 
      - *
      - * You can also use a NumberFormat to parse numbers: - *
      - *
      - * myNumber = nf.parse(myString);
      - * 
      - *
      - * Use getInstance or getNumberInstance to get the - * normal number format. Use getIntegerInstance to get an - * integer number format. Use getCurrencyInstance to get the - * currency number format. And use getPercentInstance to get a - * format for displaying percentages. With this format, a fraction like - * 0.53 is displayed as 53%. - * - *

      - * Starting from ICU 4.2, you can use getInstance() by passing in a 'style' - * as parameter to get the correct instance. - * For example, - * use getInstance(...NUMBERSTYLE) to get the normal number format, - * getInstance(...PERCENTSTYLE) to get a format for displaying percentage, - * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number, - * getInstance(...INTEGERSTYLE) to get an integer number format, - * getInstance(...CURRENCYSTYLE) to get the currency number format, - * in which the currency is represented by its symbol, for example, "$3.00". - * getInstance(...ISOCURRENCYSTYLE) to get the currency number format, - * in which the currency is represented by its ISO code, for example "USD3.00". - * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format, - * in which the currency is represented by its full name in plural format, - * for example, "3.00 US dollars" or "1.00 US dollar". - * - * - *

      - * You can also control the display of numbers with such methods as - * setMinimumFractionDigits. - * If you want even more control over the format or parsing, - * or want to give your users more control, - * you can try casting the NumberFormat you get from the factory methods - * to a DecimalFormat. This will work for the vast majority - * of locales; just remember to put it in a try block in case you - * encounter an unusual one. - * - *

      - * NumberFormat is designed such that some controls - * work for formatting and others work for parsing. The following is - * the detailed description for each these control methods, - *

      - * setParseIntegerOnly : only affects parsing, e.g. - * if true, "3456.78" -> 3456 (and leaves the parse position just after '6') - * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8') - * This is independent of formatting. If you want to not show a decimal point - * where there might be no digits after the decimal point, use - * setDecimalSeparatorAlwaysShown on DecimalFormat. - *

      - * You can also use forms of the parse and format - * methods with ParsePosition and FieldPosition to - * allow you to: - *

        - *
      • progressively parse through pieces of a string - *
      • align the decimal point and other areas - *
      - * For example, you can align numbers in two ways: - *
        - *
      1. If you are using a monospaced font with spacing for alignment, - * you can pass the FieldPosition in your format call, with - * field = INTEGER_FIELD. On output, - * getEndIndex will be set to the offset between the - * last character of the integer and the decimal. Add - * (desiredSpaceCount - getEndIndex) spaces at the front of the string. - * - *
      2. If you are using proportional fonts, - * instead of padding with spaces, measure the width - * of the string in pixels from the start to getEndIndex. - * Then move the pen by - * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text. - * It also works where there is no decimal, but possibly additional - * characters at the end, e.g., with parentheses in negative - * numbers: "(12)" for -12. - *
      - * - *

      Synchronization

      - *

      - * Number formats are generally not synchronized. It is recommended to create - * separate format instances for each thread. If multiple threads access a format - * concurrently, it must be synchronized externally. - *

      - * - *

      DecimalFormat

      - *

      DecimalFormat is the concrete implementation of NumberFormat, and the - * NumberFormat API is essentially an abstraction from DecimalFormat's API. - * Refer to DecimalFormat for more information about this API.

      - * - * see DecimalFormat - * see java.text.ChoiceFormat - * @author Mark Davis - * @author Helena Shih - * @author Alan Liu - * @stable ICU 2.0 - */ -public class NumberFormat extends Format { - private static final long serialVersionUID = 1; - - /** - * @internal - */ - public final java.text.NumberFormat numberFormat; - - /** - * @internal - * @param delegate the NumberFormat to which to delegate - */ - public NumberFormat(java.text.NumberFormat delegate) { - this.numberFormat = delegate; - } - - /** - * {@icu} Constant to specify normal number style of format. - * @stable ICU 4.2 - */ - public static final int NUMBERSTYLE = 0; - /** - * {@icu} Constant to specify currency style of format which uses currency symbol - * to represent currency, for example: "$3.00". - * @stable ICU 4.2 - */ - public static final int CURRENCYSTYLE = 1; - /** - * {@icu} Constant to specify a style of format to display percent. - * @stable ICU 4.2 - */ - public static final int PERCENTSTYLE = 2; - /** - * {@icu} Constant to specify a style of format to display scientific number. - * @stable ICU 4.2 - */ - public static final int SCIENTIFICSTYLE = 3; - /** - * {@icu} Constant to specify a integer number style format. - * @stable ICU 4.2 - */ - public static final int INTEGERSTYLE = 4; - /** - * {@icu} Constant to specify currency style of format which uses currency - * ISO code to represent currency, for example: "USD3.00". - * @stable ICU 4.2 - */ - public static final int ISOCURRENCYSTYLE = 5; - /** - * {@icu} Constant to specify currency style of format which uses currency - * long name with plural format to represent currency, for example, - * "3.00 US Dollars". - * @stable ICU 4.2 - */ - public static final int PLURALCURRENCYSTYLE = 6; - - /** - * Field constant used to construct a FieldPosition object. Signifies that - * the position of the integer part of a formatted number should be returned. - * @see java.text.FieldPosition - * @stable ICU 2.0 - */ - public static final int INTEGER_FIELD = 0; - - /** - * Field constant used to construct a FieldPosition object. Signifies that - * the position of the fraction part of a formatted number should be returned. - * @see java.text.FieldPosition - * @stable ICU 2.0 - */ - public static final int FRACTION_FIELD = 1; - - /** - * Formats a number and appends the resulting text to the given string buffer. - * {@icunote} recognizes BigInteger - * and BigDecimal objects. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(Object number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); - if (jdkPos != null) { - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - } - return buf; - } - - /** - * Parses text from a string to produce a number. - * @param source the String to parse - * @param parsePosition the position at which to start the parse - * @return the parsed number, or null - * @see java.text.NumberFormat#parseObject(String, ParsePosition) - * @stable ICU 2.0 - */ - public final Object parseObject(String source, - ParsePosition parsePosition) { - return numberFormat.parse(source, parsePosition); - } - - /** - * Specialization of format. - * @see java.text.Format#format(Object) - * @stable ICU 2.0 - */ - public final String format(double number) { - return numberFormat.format(number); - } - - /** - * Specialization of format. - * @see java.text.Format#format(Object) - * @stable ICU 2.0 - */ - public final String format(long number) { - return numberFormat.format(number); - } - - /** - * {@icu} Convenience method to format a BigInteger. - * @stable ICU 2.0 - */ - public final String format(BigInteger number) { - return numberFormat.format(number); - } - - /** - * Convenience method to format a BigDecimal. - * @stable ICU 2.0 - */ - public final String format(java.math.BigDecimal number) { - return numberFormat.format(number); - } - - /** - * {@icu} Convenience method to format an ICU BigDecimal. - * @stable ICU 2.0 - */ - public final String format(com.ibm.icu.math.BigDecimal number) { - return numberFormat.format(number.toBigDecimal()); - } - - /** - * {@icu} Convenience method to format a CurrencyAmount. - * @stable ICU 3.0 - */ - public final String format(CurrencyAmount currAmt) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(double number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - return buf; - } - - /** - * Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(long number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - return buf; - } - /** - * {@icu} Formats a BigInteger. Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(BigInteger number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - return buf; - } - /** - * {@icu} Formats a BigDecimal. Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(java.math.BigDecimal number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - return buf; - } - /** - * {@icu} Formats an ICU BigDecimal. Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 2.0 - */ - public StringBuffer format(com.ibm.icu.math.BigDecimal number, - StringBuffer toAppendTo, - FieldPosition pos) { - FieldPosition jdkPos = toJDKFieldPosition(pos); - StringBuffer buf = numberFormat.format(number.toBigDecimal(), toAppendTo, jdkPos); - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - return buf; - } - - /** - * {@icu} Formats a CurrencyAmount. Specialization of format. - * @see java.text.Format#format(Object, StringBuffer, FieldPosition) - * @stable ICU 3.0 - */ - public StringBuffer format(CurrencyAmount currAmt, - StringBuffer toAppendTo, - FieldPosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, - * Long.MAX_VALUE] and with no decimals), otherwise a Double. - * If IntegerOnly is set, will stop at a decimal - * point (or equivalent; e.g., for rational numbers "1 2/3", will stop - * after the 1). - * Does not throw an exception; if no object can be parsed, index is - * unchanged! - * @see #isParseIntegerOnly - * @see java.text.Format#parseObject(String, ParsePosition) - * @stable ICU 2.0 - */ - public Number parse(String text, ParsePosition parsePosition) { - return numberFormat.parse(text, parsePosition); - } - - /** - * Parses text from the beginning of the given string to produce a number. - * The method might not use the entire text of the given string. - * - * @param text A String whose beginning should be parsed. - * @return A Number parsed from the string. - * @throws ParseException if the beginning of the specified string - * cannot be parsed. - * @see #format - * @stable ICU 2.0 - */ - public Number parse(String text) throws ParseException { - return numberFormat.parse(text); - } - - /** - * Parses text from the given string as a CurrencyAmount. Unlike - * the parse() method, this method will attempt to parse a generic - * currency name, searching for a match of this object's locale's - * currency display names, or for a 3-letter ISO currency code. - * This method will fail if this format is not a currency format, - * that is, if it does not contain the currency pattern symbol - * (U+00A4) in its prefix or suffix. - * - * @param text the string to parse - * @param pos input-output position; on input, the position within - * text to match; must have 0 <= pos.getIndex() < text.length(); - * on output, the position after the last matched character. If - * the parse fails, the position in unchanged upon output. - * @return a CurrencyAmount, or null upon failure - */ - CurrencyAmount parseCurrency(String text, ParsePosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns true if this format will parse numbers as integers only. - * For example in the English locale, with ParseIntegerOnly true, the - * string "1234." would be parsed as the integer value 1234 and parsing - * would stop at the "." character. The decimal separator accepted - * by the parse operation is locale-dependent and determined by the - * subclass. - * @return true if this will parse integers only - * @stable ICU 2.0 - */ - public boolean isParseIntegerOnly() { - return numberFormat.isParseIntegerOnly(); - } - - /** - * Sets whether or not numbers should be parsed as integers only. - * @param value true if this should parse integers only - * @see #isParseIntegerOnly - * @stable ICU 2.0 - */ - public void setParseIntegerOnly(boolean value) { - numberFormat.setParseIntegerOnly(value); - } - - /** - * {@icu} Sets whether strict parsing is in effect. When this is true, the - * following conditions cause a parse failure (examples use the pattern "#,##0.#"):
        - *
      • Leading zeros
        - * '00', '0123' fail the parse, but '0' and '0.001' pass
      • - *
      • Leading or doubled grouping separators
        - * ',123' and '1,,234" fail
      • - *
      • Groups of incorrect length when grouping is used
        - * '1,23' and '1234,567' fail, but '1234' passes
      • - *
      • Grouping separators used in numbers followed by exponents
        - * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when - * not followed by a number)
      • - *
      - * When strict parsing is off, leading zeros and all grouping separators are ignored. - * This is the default behavior. - * @param value True to enable strict parsing. Default is false. - * @see #isParseStrict - * @stable ICU 3.6 - */ - public void setParseStrict(boolean value) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns whether strict parsing is in effect. - * @return true if strict parsing is in effect - * @see #setParseStrict - * @stable ICU 3.6 - */ - public boolean isParseStrict() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - //============== Locale Stuff ===================== - - /** - * Returns the default number format for the current default locale. - * The default format is one of the styles provided by the other - * factory methods: getNumberInstance, getIntegerInstance, - * getCurrencyInstance or getPercentInstance. - * Exactly which one is locale-dependent. - * @stable ICU 2.0 - */ - //Bug 4408066 [Richard/GCL] - public final static NumberFormat getInstance() { - return getInstance(ULocale.getDefault(), NUMBERSTYLE); - } - - /** - * Returns the default number format for the specified locale. - * The default format is one of the styles provided by the other - * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance. - * Exactly which one is locale-dependent. - * @stable ICU 2.0 - */ - public static NumberFormat getInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE); - } - - /** - * {@icu} Returns the default number format for the specified locale. - * The default format is one of the styles provided by the other - * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance. - * Exactly which one is locale-dependent. - * @stable ICU 3.2 - */ - public static NumberFormat getInstance(ULocale inLocale) { - return getInstance(inLocale, NUMBERSTYLE); - } - - /** - * {@icu} Returns a specific style number format for default locale. - * @param style number format style - * @stable ICU 4.2 - */ - public final static NumberFormat getInstance(int style) { - return getInstance(ULocale.getDefault(), style); - } - - /** - * {@icu} Returns a specific style number format for a specific locale. - * @param inLocale the specific locale. - * @param style number format style - * @stable ICU 4.2 - */ - public static NumberFormat getInstance(Locale inLocale, int style) { - return getInstance(ULocale.forLocale(inLocale), style); - } - - - /** - * Returns a general-purpose number format for the current default locale. - * @stable ICU 2.0 - */ - public final static NumberFormat getNumberInstance() { - return getInstance(ULocale.getDefault(), NUMBERSTYLE); - } - - /** - * Returns a general-purpose number format for the specified locale. - * @stable ICU 2.0 - */ - public static NumberFormat getNumberInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE); - } - - /** - * {@icu} Returns a general-purpose number format for the specified locale. - * @stable ICU 3.2 - */ - public static NumberFormat getNumberInstance(ULocale inLocale) { - return getInstance(inLocale, NUMBERSTYLE); - } - - /** - * Returns an integer number format for the current default locale. The - * returned number format is configured to round floating point numbers - * to the nearest integer using IEEE half-even rounding (see {@link - * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, - * and to parse only the integer part of an input string (see {@link - * #isParseIntegerOnly isParseIntegerOnly}). - * - * @return a number format for integer values - * @stable ICU 2.0 - */ - //Bug 4408066 [Richard/GCL] - public final static NumberFormat getIntegerInstance() { - return getInstance(ULocale.getDefault(), INTEGERSTYLE); - } - - /** - * Returns an integer number format for the specified locale. The - * returned number format is configured to round floating point numbers - * to the nearest integer using IEEE half-even rounding (see {@link - * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, - * and to parse only the integer part of an input string (see {@link - * #isParseIntegerOnly isParseIntegerOnly}). - * - * @param inLocale the locale for which a number format is needed - * @return a number format for integer values - * @stable ICU 2.0 - */ - //Bug 4408066 [Richard/GCL] - public static NumberFormat getIntegerInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE); - } - - /** - * {@icu} Returns an integer number format for the specified locale. The - * returned number format is configured to round floating point numbers - * to the nearest integer using IEEE half-even rounding (see {@link - * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, - * and to parse only the integer part of an input string (see {@link - * #isParseIntegerOnly isParseIntegerOnly}). - * - * @param inLocale the locale for which a number format is needed - * @return a number format for integer values - * @stable ICU 3.2 - */ - public static NumberFormat getIntegerInstance(ULocale inLocale) { - return getInstance(inLocale, INTEGERSTYLE); - } - - /** - * Returns a currency format for the current default locale. - * @return a number format for currency - * @stable ICU 2.0 - */ - public final static NumberFormat getCurrencyInstance() { - return getInstance(ULocale.getDefault(), CURRENCYSTYLE); - } - - /** - * Returns a currency format for the specified locale. - * @return a number format for currency - * @stable ICU 2.0 - */ - public static NumberFormat getCurrencyInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE); - } - - /** - * {@icu} Returns a currency format for the specified locale. - * @return a number format for currency - * @stable ICU 3.2 - */ - public static NumberFormat getCurrencyInstance(ULocale inLocale) { - return getInstance(inLocale, CURRENCYSTYLE); - } - - /** - * Returns a percentage format for the current default locale. - * @return a number format for percents - * @stable ICU 2.0 - */ - public final static NumberFormat getPercentInstance() { - return getInstance(ULocale.getDefault(), PERCENTSTYLE); - } - - /** - * Returns a percentage format for the specified locale. - * @return a number format for percents - * @stable ICU 2.0 - */ - public static NumberFormat getPercentInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE); - } - - /** - * {@icu} Returns a percentage format for the specified locale. - * @return a number format for percents - * @stable ICU 3.2 - */ - public static NumberFormat getPercentInstance(ULocale inLocale) { - return getInstance(inLocale, PERCENTSTYLE); - } - - /** - * {@icu} Returns a scientific format for the current default locale. - * @return a scientific number format - * @stable ICU 2.0 - */ - public final static NumberFormat getScientificInstance() { - return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE); - } - - /** - * {@icu} Returns a scientific format for the specified locale. - * @return a scientific number format - * @stable ICU 2.0 - */ - public static NumberFormat getScientificInstance(Locale inLocale) { - return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE); - } - - /** - * {@icu} Returns a scientific format for the specified locale. - * @return a scientific number format - * @stable ICU 3.2 - */ - public static NumberFormat getScientificInstance(ULocale inLocale) { - return getInstance(inLocale, SCIENTIFICSTYLE); - } - - /** - * A NumberFormatFactory is used to register new number formats. The factory - * should be able to create any of the predefined formats for each locale it - * supports. When registered, the locales it supports extend or override the - * locales already supported by ICU. - * - *

      Note: as of ICU4J 3.2, the default API for NumberFormatFactory uses - * ULocale instead of Locale. Instead of overriding createFormat(Locale, int), - * new implementations should override createFactory(ULocale, int). Note that - * one of these two methods MUST be overridden or else an infinite - * loop will occur. - * - * @stable ICU 2.6 - */ - public static abstract class NumberFormatFactory { - /** - * Value passed to format requesting a default number format. - * @stable ICU 2.6 - */ - public static final int FORMAT_NUMBER = NUMBERSTYLE; - - /** - * Value passed to format requesting a currency format. - * @stable ICU 2.6 - */ - public static final int FORMAT_CURRENCY = CURRENCYSTYLE; - - /** - * Value passed to format requesting a percent format. - * @stable ICU 2.6 - */ - public static final int FORMAT_PERCENT = PERCENTSTYLE; - - /** - * Value passed to format requesting a scientific format. - * @stable ICU 2.6 - */ - public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE; - - /** - * Value passed to format requesting an integer format. - * @stable ICU 2.6 - */ - public static final int FORMAT_INTEGER = INTEGERSTYLE; - - /** - * Returns true if this factory is visible. Default is true. - * If not visible, the locales supported by this factory will not - * be listed by getAvailableLocales. This value must not change. - * @return true if the factory is visible. - * @stable ICU 2.6 - */ - public boolean visible() { - return true; - } - - /** - * Returns an immutable collection of the locale names directly - * supported by this factory. - * @return the supported locale names. - * @stable ICU 2.6 - */ - public abstract Set getSupportedLocaleNames(); - - /** - * Returns a number format of the appropriate type. If the locale - * is not supported, return null. If the locale is supported, but - * the type is not provided by this service, return null. Otherwise - * return an appropriate instance of NumberFormat. - * Note: as of ICU4J 3.2, implementations should override - * this method instead of createFormat(Locale, int). - * @param loc the locale for which to create the format - * @param formatType the type of format - * @return the NumberFormat, or null. - * @stable ICU 3.2 - */ - public NumberFormat createFormat(ULocale loc, int formatType) { - return createFormat(loc.toLocale(), formatType); - } - - /** - * Returns a number format of the appropriate type. If the locale - * is not supported, return null. If the locale is supported, but - * the type is not provided by this service, return null. Otherwise - * return an appropriate instance of NumberFormat. - * Note: as of ICU4J 3.2, createFormat(ULocale, int) should be - * overridden instead of this method. This method is no longer - * abstract and delegates to that method. - * @param loc the locale for which to create the format - * @param formatType the type of format - * @return the NumberFormat, or null. - * @stable ICU 2.6 - */ - public NumberFormat createFormat(Locale loc, int formatType) { - return createFormat(ULocale.forLocale(loc), formatType); - } - - /** - * @stable ICU 2.6 - */ - protected NumberFormatFactory() { - } - } - - /** - * Returns the list of Locales for which NumberFormats are available. - * @return the available locales - * @stable ICU 2.0 - */ - public static Locale[] getAvailableLocales() { - return java.text.NumberFormat.getAvailableLocales(); - } - - /** - * {@icu} Returns the list of Locales for which NumberFormats are available. - * @return the available locales - * @draft ICU 3.2 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static ULocale[] getAvailableULocales() { - if (availableULocales == null) { - synchronized (NumberFormat.class) { - if (availableULocales == null) { - Locale[] locales = java.text.NumberFormat.getAvailableLocales(); - ULocale[] ulocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; ++i) { - ulocales[i] = ULocale.forLocale(locales[i]); - } - availableULocales = ulocales; - } - } - } - return (ULocale[])availableULocales.clone(); - } - private static volatile ULocale[] availableULocales; - - /** - * {@icu} Registers a new NumberFormatFactory. The factory is adopted by - * the service and must not be modified. The returned object is a - * key that can be used to unregister this factory. - * @param factory the factory to register - * @return a key with which to unregister the factory - * @stable ICU 2.6 - */ - public static Object registerFactory(NumberFormatFactory factory) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Unregisters the factory or instance associated with this key (obtained from - * registerInstance or registerFactory). - * @param registryKey a key obtained from registerFactory - * @return true if the object was successfully unregistered - * @stable ICU 2.6 - */ - public static boolean unregister(Object registryKey) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Overrides hashCode. - * @stable ICU 2.0 - */ - public int hashCode() { - return numberFormat.hashCode(); - } - - /** - * Overrides equals. - * Two NumberFormats are equal if they are of the same class - * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc. - * are equal. - * @param obj the object to compare against - * @return true if the object is equal to this. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) { - try { - return numberFormat.equals(((NumberFormat)obj).numberFormat); - } - catch (Exception e) { - return false; - } - } - - /** - * Overrides clone. - * @stable ICU 2.0 - */ - public Object clone() { - return new NumberFormat((java.text.NumberFormat)numberFormat.clone()); - } - - /** - * Returns true if grouping is used in this format. For example, in the - * en_US locale, with grouping on, the number 1234567 will be formatted - * as "1,234,567". The grouping separator as well as the size of each group - * is locale-dependent and is determined by subclasses of NumberFormat. - * Grouping affects both parsing and formatting. - * @return true if grouping is used - * @see #setGroupingUsed - * @stable ICU 2.0 - */ - public boolean isGroupingUsed() { - return numberFormat.isGroupingUsed(); - } - - /** - * Sets whether or not grouping will be used in this format. Grouping - * affects both parsing and formatting. - * @see #isGroupingUsed - * @param newValue true to use grouping. - * @stable ICU 2.0 - */ - public void setGroupingUsed(boolean newValue) { - numberFormat.setGroupingUsed(newValue); - } - - /** - * Returns the maximum number of digits allowed in the integer portion of a - * number. The default value is 40, which subclasses can override. - * When formatting, the exact behavior when this value is exceeded is - * subclass-specific. When parsing, this has no effect. - * @return the maximum number of integer digits - * @see #setMaximumIntegerDigits - * @stable ICU 2.0 - */ - public int getMaximumIntegerDigits() { - return numberFormat.getMaximumIntegerDigits(); - } - - /** - * Sets the maximum number of digits allowed in the integer portion of a - * number. This must be >= minimumIntegerDigits. If the - * new value for maximumIntegerDigits is less than the current value - * of minimumIntegerDigits, then minimumIntegerDigits will also be set to - * the new value. - * @param newValue the maximum number of integer digits to be shown; if - * less than zero, then zero is used. Subclasses might enforce an - * upper limit to this value appropriate to the numeric type being formatted. - * @see #getMaximumIntegerDigits - * @stable ICU 2.0 - */ - public void setMaximumIntegerDigits(int newValue) { - numberFormat.setMaximumIntegerDigits(newValue); - } - - /** - * Returns the minimum number of digits allowed in the integer portion of a - * number. The default value is 1, which subclasses can override. - * When formatting, if this value is not reached, numbers are padded on the - * left with the locale-specific '0' character to ensure at least this - * number of integer digits. When parsing, this has no effect. - * @return the minimum number of integer digits - * @see #setMinimumIntegerDigits - * @stable ICU 2.0 - */ - public int getMinimumIntegerDigits() { - return numberFormat.getMinimumIntegerDigits(); - } - - /** - * Sets the minimum number of digits allowed in the integer portion of a - * number. This must be <= maximumIntegerDigits. If the - * new value for minimumIntegerDigits is more than the current value - * of maximumIntegerDigits, then maximumIntegerDigits will also be set to - * the new value. - * @param newValue the minimum number of integer digits to be shown; if - * less than zero, then zero is used. Subclasses might enforce an - * upper limit to this value appropriate to the numeric type being formatted. - * @see #getMinimumIntegerDigits - * @stable ICU 2.0 - */ - public void setMinimumIntegerDigits(int newValue) { - numberFormat.setMinimumIntegerDigits(newValue); - } - - /** - * Returns the maximum number of digits allowed in the fraction - * portion of a number. The default value is 3, which subclasses - * can override. When formatting, the exact behavior when this - * value is exceeded is subclass-specific. When parsing, this has - * no effect. - * @return the maximum number of fraction digits - * @see #setMaximumFractionDigits - * @stable ICU 2.0 - */ - public int getMaximumFractionDigits() { - return numberFormat.getMaximumFractionDigits(); - } - - /** - * Sets the maximum number of digits allowed in the fraction portion of a - * number. This must be >= minimumFractionDigits. If the - * new value for maximumFractionDigits is less than the current value - * of minimumFractionDigits, then minimumFractionDigits will also be set to - * the new value. - * @param newValue the maximum number of fraction digits to be shown; if - * less than zero, then zero is used. The concrete subclass may enforce an - * upper limit to this value appropriate to the numeric type being formatted. - * @see #getMaximumFractionDigits - * @stable ICU 2.0 - */ - public void setMaximumFractionDigits(int newValue) { - numberFormat.setMaximumFractionDigits(newValue); - } - - /** - * Returns the minimum number of digits allowed in the fraction portion of a - * number. The default value is 0, which subclasses can override. - * When formatting, if this value is not reached, numbers are padded on - * the right with the locale-specific '0' character to ensure at least - * this number of fraction digits. When parsing, this has no effect. - * @return the minimum number of fraction digits - * @see #setMinimumFractionDigits - * @stable ICU 2.0 - */ - public int getMinimumFractionDigits() { - return numberFormat.getMinimumFractionDigits(); - } - - /** - * Sets the minimum number of digits allowed in the fraction portion of a - * number. This must be <= maximumFractionDigits. If the - * new value for minimumFractionDigits exceeds the current value - * of maximumFractionDigits, then maximumFractionDigits will also be set to - * the new value. - * @param newValue the minimum number of fraction digits to be shown; if - * less than zero, then zero is used. Subclasses might enforce an - * upper limit to this value appropriate to the numeric type being formatted. - * @see #getMinimumFractionDigits - * @stable ICU 2.0 - */ - public void setMinimumFractionDigits(int newValue) { - numberFormat.setMinimumFractionDigits(newValue); - } - - /** - * Sets the Currency object used to display currency - * amounts. This takes effect immediately, if this format is a - * currency format. If this format is not a currency format, then - * the currency object is used if and when this object becomes a - * currency format. - * @param theCurrency new currency object to use. May be null for - * some subclasses. - * @stable ICU 2.6 - */ - public void setCurrency(Currency theCurrency) { - numberFormat.setCurrency(theCurrency.currency); - } - - /** - * Returns the Currency object used to display currency - * amounts. This may be null. - * @stable ICU 2.6 - */ - public Currency getCurrency() { - return new Currency(numberFormat.getCurrency()); - } - - /** - * Returns the rounding mode used in this NumberFormat. The default implementation of - * tis method in NumberFormat always throws UnsupportedOperationException. - * @return A rounding mode, between BigDecimal.ROUND_UP - * and BigDecimal.ROUND_UNNECESSARY. - * @see #setRoundingMode(int) - * @stable ICU 4.0 - */ - public int getRoundingMode() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Set the rounding mode used in this NumberFormat. The default implementation of - * tis method in NumberFormat always throws UnsupportedOperationException. - * @param roundingMode A rounding mode, between - * BigDecimal.ROUND_UP and - * BigDecimal.ROUND_UNNECESSARY. - * @see #getRoundingMode() - * @stable ICU 4.0 - */ - public void setRoundingMode(int roundingMode) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - - /** - * Returns a specific style number format for a specific locale. - * @param desiredLocale the specific locale. - * @param choice number format style - * @throws IllegalArgumentException if choice is not one of - * NUMBERSTYLE, CURRENCYSTYLE, - * PERCENTSTYLE, SCIENTIFICSTYLE, - * INTEGERSTYLE, - * ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE, - * @stable ICU 4.2 - */ - public static NumberFormat getInstance(ULocale desiredLocale, int choice) { - Locale locale = desiredLocale.toLocale(); - java.text.NumberFormat nf = null; - switch (choice) { - case NUMBERSTYLE: - nf = java.text.NumberFormat.getInstance(locale); - break; - case INTEGERSTYLE: - nf = java.text.NumberFormat.getIntegerInstance(locale); - break; - case CURRENCYSTYLE: - nf = java.text.NumberFormat.getCurrencyInstance(locale); - break; - case PERCENTSTYLE: - nf = java.text.NumberFormat.getPercentInstance(locale); - break; - case SCIENTIFICSTYLE: - nf = new java.text.DecimalFormat("#E0", - new java.text.DecimalFormatSymbols(locale)); - nf.setMaximumFractionDigits(10); - break; - } - return new NumberFormat(nf); - } - - /** - * Empty constructor. Public for compatibily with JDK which lets the - * compiler generate a default public constructor even though this is - * an abstract class. - * @stable ICU 2.6 - */ - public NumberFormat() { - this(java.text.NumberFormat.getInstance()); - } - - /** - * The instances of this inner class are used as attribute keys and values - * in AttributedCharacterIterator that - * NumberFormat.formatToCharacterIterator() method returns. - *

      - * There is no public constructor to this class, the only instances are the - * constants defined here. - *

      - * @stable ICU 3.6 - */ - public static class Field extends Format.Field { - // generated by serialver from JDK 1.4.1_01 - static final long serialVersionUID = -4516273749929385842L; - - /** - * @stable ICU 3.6 - */ - public static final Field SIGN = new Field("sign"); - - /** - * @stable ICU 3.6 - */ - public static final Field INTEGER = new Field("integer"); - - /** - * @stable ICU 3.6 - */ - public static final Field FRACTION = new Field("fraction"); - - /** - * @stable ICU 3.6 - */ - public static final Field EXPONENT = new Field("exponent"); - - /** - * @stable ICU 3.6 - */ - public static final Field EXPONENT_SIGN = new Field("exponent sign"); - - /** - * @stable ICU 3.6 - */ - public static final Field EXPONENT_SYMBOL = new Field("exponent symbol"); - - /** - * @stable ICU 3.6 - */ - public static final Field DECIMAL_SEPARATOR = new Field("decimal separator"); - /** - * @stable ICU 3.6 - */ - public static final Field GROUPING_SEPARATOR = new Field("grouping separator"); - - /** - * @stable ICU 3.6 - */ - public static final Field PERCENT = new Field("percent"); - - /** - * @stable ICU 3.6 - */ - public static final Field PERMILLE = new Field("per mille"); - - /** - * @stable ICU 3.6 - */ - public static final Field CURRENCY = new Field("currency"); - - /** - * Constructs a new instance of NumberFormat.Field with the given field - * name. - * @stable ICU 3.6 - */ - protected Field(String fieldName) { - super(fieldName); - } - - /** - * serizalization method resolve instances to the constant - * NumberFormat.Field values - * @stable ICU 3.6 - */ - protected Object readResolve() throws InvalidObjectException { - if (this.getName().equals(INTEGER.getName())) - return INTEGER; - if (this.getName().equals(FRACTION.getName())) - return FRACTION; - if (this.getName().equals(EXPONENT.getName())) - return EXPONENT; - if (this.getName().equals(EXPONENT_SIGN.getName())) - return EXPONENT_SIGN; - if (this.getName().equals(EXPONENT_SYMBOL.getName())) - return EXPONENT_SYMBOL; - if (this.getName().equals(CURRENCY.getName())) - return CURRENCY; - if (this.getName().equals(DECIMAL_SEPARATOR.getName())) - return DECIMAL_SEPARATOR; - if (this.getName().equals(GROUPING_SEPARATOR.getName())) - return GROUPING_SEPARATOR; - if (this.getName().equals(PERCENT.getName())) - return PERCENT; - if (this.getName().equals(PERMILLE.getName())) - return PERMILLE; - if (this.getName().equals(SIGN.getName())) - return SIGN; - - throw new InvalidObjectException("An invalid object."); - } - } - - private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { - if (icuPos == null) { - return null; - } - - int fieldID = icuPos.getField(); - Format.Field fieldAttribute = icuPos.getFieldAttribute(); - - FieldPosition jdkPos = null; - - if (fieldID >= 0) { - if (fieldID == FRACTION_FIELD) { - fieldID = java.text.NumberFormat.FRACTION_FIELD; - } else if (fieldID == INTEGER_FIELD) { - fieldID = java.text.NumberFormat.INTEGER_FIELD; - } - } - - if (fieldAttribute != null) { - // map field - if (fieldAttribute.equals(Field.CURRENCY)) { - fieldAttribute = java.text.NumberFormat.Field.CURRENCY; - } else if (fieldAttribute.equals(Field.DECIMAL_SEPARATOR)) { - fieldAttribute = java.text.NumberFormat.Field.DECIMAL_SEPARATOR; - } else if (fieldAttribute.equals(Field.EXPONENT)) { - fieldAttribute = java.text.NumberFormat.Field.EXPONENT; - } else if (fieldAttribute.equals(Field.EXPONENT_SIGN)) { - fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SIGN; - } else if (fieldAttribute.equals(Field.EXPONENT_SYMBOL)) { - fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SYMBOL; - } else if (fieldAttribute.equals(Field.FRACTION)) { - fieldAttribute = java.text.NumberFormat.Field.FRACTION; - } else if (fieldAttribute.equals(Field.GROUPING_SEPARATOR)) { - fieldAttribute = java.text.NumberFormat.Field.GROUPING_SEPARATOR; - } else if (fieldAttribute.equals(Field.INTEGER)) { - fieldAttribute = java.text.NumberFormat.Field.INTEGER; - } else if (fieldAttribute.equals(Field.PERCENT)) { - fieldAttribute = java.text.NumberFormat.Field.PERCENT; - } else if (fieldAttribute.equals(Field.PERMILLE)) { - fieldAttribute = java.text.NumberFormat.Field.PERMILLE; - } else if (fieldAttribute.equals(Field.SIGN)) { - fieldAttribute = java.text.NumberFormat.Field.SIGN; - } - - jdkPos = new FieldPosition(fieldAttribute, fieldID); - } else { - jdkPos = new FieldPosition(fieldID); - } - - jdkPos.setBeginIndex(icuPos.getBeginIndex()); - jdkPos.setEndIndex(icuPos.getEndIndex()); - - return jdkPos; - } -} +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.text; + +import java.io.InvalidObjectException; +import java.math.BigInteger; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Locale; +import java.util.Set; + +import com.ibm.icu.util.Currency; +import com.ibm.icu.util.CurrencyAmount; +import com.ibm.icu.util.ULocale; + +/** + * {@icuenhanced java.text.NumberFormat}.{@icu _usage_} + * + * NumberFormat is the abstract base class for all number + * formats. This class provides the interface for formatting and parsing + * numbers. NumberFormat also provides methods for determining + * which locales have number formats, and what their names are. + * + * NumberFormat helps you to format and parse numbers for any locale. + * Your code can be completely independent of the locale conventions for + * decimal points, thousands-separators, or even the particular decimal + * digits used, or whether the number format is even decimal. + * + *

      + * To format a number for the current Locale, use one of the factory + * class methods: + *

      + *
      + *  myString = NumberFormat.getInstance().format(myNumber);
      + * 
      + *
      + * If you are formatting multiple numbers, it is + * more efficient to get the format and use it multiple times so that + * the system doesn't have to fetch the information about the local + * language and country conventions multiple times. + *
      + *
      + * NumberFormat nf = NumberFormat.getInstance();
      + * for (int i = 0; i < a.length; ++i) {
      + *     output.println(nf.format(myNumber[i]) + "; ");
      + * }
      + * 
      + *
      + * To format a number for a different Locale, specify it in the + * call to getInstance. + *
      + *
      + * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
      + * 
      + *
      + * You can also use a NumberFormat to parse numbers: + *
      + *
      + * myNumber = nf.parse(myString);
      + * 
      + *
      + * Use getInstance or getNumberInstance to get the + * normal number format. Use getIntegerInstance to get an + * integer number format. Use getCurrencyInstance to get the + * currency number format. And use getPercentInstance to get a + * format for displaying percentages. With this format, a fraction like + * 0.53 is displayed as 53%. + * + *

      + * Starting from ICU 4.2, you can use getInstance() by passing in a 'style' + * as parameter to get the correct instance. + * For example, + * use getInstance(...NUMBERSTYLE) to get the normal number format, + * getInstance(...PERCENTSTYLE) to get a format for displaying percentage, + * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number, + * getInstance(...INTEGERSTYLE) to get an integer number format, + * getInstance(...CURRENCYSTYLE) to get the currency number format, + * in which the currency is represented by its symbol, for example, "$3.00". + * getInstance(...ISOCURRENCYSTYLE) to get the currency number format, + * in which the currency is represented by its ISO code, for example "USD3.00". + * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format, + * in which the currency is represented by its full name in plural format, + * for example, "3.00 US dollars" or "1.00 US dollar". + * + * + *

      + * You can also control the display of numbers with such methods as + * setMinimumFractionDigits. + * If you want even more control over the format or parsing, + * or want to give your users more control, + * you can try casting the NumberFormat you get from the factory methods + * to a DecimalFormat. This will work for the vast majority + * of locales; just remember to put it in a try block in case you + * encounter an unusual one. + * + *

      + * NumberFormat is designed such that some controls + * work for formatting and others work for parsing. The following is + * the detailed description for each these control methods, + *

      + * setParseIntegerOnly : only affects parsing, e.g. + * if true, "3456.78" -> 3456 (and leaves the parse position just after '6') + * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8') + * This is independent of formatting. If you want to not show a decimal point + * where there might be no digits after the decimal point, use + * setDecimalSeparatorAlwaysShown on DecimalFormat. + *

      + * You can also use forms of the parse and format + * methods with ParsePosition and FieldPosition to + * allow you to: + *

        + *
      • progressively parse through pieces of a string + *
      • align the decimal point and other areas + *
      + * For example, you can align numbers in two ways: + *
        + *
      1. If you are using a monospaced font with spacing for alignment, + * you can pass the FieldPosition in your format call, with + * field = INTEGER_FIELD. On output, + * getEndIndex will be set to the offset between the + * last character of the integer and the decimal. Add + * (desiredSpaceCount - getEndIndex) spaces at the front of the string. + * + *
      2. If you are using proportional fonts, + * instead of padding with spaces, measure the width + * of the string in pixels from the start to getEndIndex. + * Then move the pen by + * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text. + * It also works where there is no decimal, but possibly additional + * characters at the end, e.g., with parentheses in negative + * numbers: "(12)" for -12. + *
      + * + *

      Synchronization

      + *

      + * Number formats are generally not synchronized. It is recommended to create + * separate format instances for each thread. If multiple threads access a format + * concurrently, it must be synchronized externally. + *

      + * + *

      DecimalFormat

      + *

      DecimalFormat is the concrete implementation of NumberFormat, and the + * NumberFormat API is essentially an abstraction from DecimalFormat's API. + * Refer to DecimalFormat for more information about this API.

      + * + * see DecimalFormat + * see java.text.ChoiceFormat + * @author Mark Davis + * @author Helena Shih + * @author Alan Liu + * @stable ICU 2.0 + */ +public class NumberFormat extends Format { + private static final long serialVersionUID = 1; + + /** + * @internal + */ + public final java.text.NumberFormat numberFormat; + + /** + * @internal + * @param delegate the NumberFormat to which to delegate + */ + public NumberFormat(java.text.NumberFormat delegate) { + this.numberFormat = delegate; + } + + /** + * {@icu} Constant to specify normal number style of format. + * @stable ICU 4.2 + */ + public static final int NUMBERSTYLE = 0; + /** + * {@icu} Constant to specify currency style of format which uses currency symbol + * to represent currency, for example: "$3.00". + * @stable ICU 4.2 + */ + public static final int CURRENCYSTYLE = 1; + /** + * {@icu} Constant to specify a style of format to display percent. + * @stable ICU 4.2 + */ + public static final int PERCENTSTYLE = 2; + /** + * {@icu} Constant to specify a style of format to display scientific number. + * @stable ICU 4.2 + */ + public static final int SCIENTIFICSTYLE = 3; + /** + * {@icu} Constant to specify a integer number style format. + * @stable ICU 4.2 + */ + public static final int INTEGERSTYLE = 4; + /** + * {@icu} Constant to specify currency style of format which uses currency + * ISO code to represent currency, for example: "USD3.00". + * @stable ICU 4.2 + */ + public static final int ISOCURRENCYSTYLE = 5; + /** + * {@icu} Constant to specify currency style of format which uses currency + * long name with plural format to represent currency, for example, + * "3.00 US Dollars". + * @stable ICU 4.2 + */ + public static final int PLURALCURRENCYSTYLE = 6; + + /** + * Field constant used to construct a FieldPosition object. Signifies that + * the position of the integer part of a formatted number should be returned. + * @see java.text.FieldPosition + * @stable ICU 2.0 + */ + public static final int INTEGER_FIELD = 0; + + /** + * Field constant used to construct a FieldPosition object. Signifies that + * the position of the fraction part of a formatted number should be returned. + * @see java.text.FieldPosition + * @stable ICU 2.0 + */ + public static final int FRACTION_FIELD = 1; + + /** + * Formats a number and appends the resulting text to the given string buffer. + * {@icunote} recognizes BigInteger + * and BigDecimal objects. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(Object number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); + if (jdkPos != null) { + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + } + return buf; + } + + /** + * Parses text from a string to produce a number. + * @param source the String to parse + * @param parsePosition the position at which to start the parse + * @return the parsed number, or null + * @see java.text.NumberFormat#parseObject(String, ParsePosition) + * @stable ICU 2.0 + */ + public final Object parseObject(String source, + ParsePosition parsePosition) { + return numberFormat.parse(source, parsePosition); + } + + /** + * Specialization of format. + * @see java.text.Format#format(Object) + * @stable ICU 2.0 + */ + public final String format(double number) { + return numberFormat.format(number); + } + + /** + * Specialization of format. + * @see java.text.Format#format(Object) + * @stable ICU 2.0 + */ + public final String format(long number) { + return numberFormat.format(number); + } + + /** + * {@icu} Convenience method to format a BigInteger. + * @stable ICU 2.0 + */ + public final String format(BigInteger number) { + return numberFormat.format(number); + } + + /** + * Convenience method to format a BigDecimal. + * @stable ICU 2.0 + */ + public final String format(java.math.BigDecimal number) { + return numberFormat.format(number); + } + + /** + * {@icu} Convenience method to format an ICU BigDecimal. + * @stable ICU 2.0 + */ + public final String format(com.ibm.icu.math.BigDecimal number) { + return numberFormat.format(number.toBigDecimal()); + } + + /** + * {@icu} Convenience method to format a CurrencyAmount. + * @stable ICU 3.0 + */ + public final String format(CurrencyAmount currAmt) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(double number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + return buf; + } + + /** + * Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(long number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + return buf; + } + /** + * {@icu} Formats a BigInteger. Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(BigInteger number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + return buf; + } + /** + * {@icu} Formats a BigDecimal. Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(java.math.BigDecimal number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos); + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + return buf; + } + /** + * {@icu} Formats an ICU BigDecimal. Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 2.0 + */ + public StringBuffer format(com.ibm.icu.math.BigDecimal number, + StringBuffer toAppendTo, + FieldPosition pos) { + FieldPosition jdkPos = toJDKFieldPosition(pos); + StringBuffer buf = numberFormat.format(number.toBigDecimal(), toAppendTo, jdkPos); + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + return buf; + } + + /** + * {@icu} Formats a CurrencyAmount. Specialization of format. + * @see java.text.Format#format(Object, StringBuffer, FieldPosition) + * @stable ICU 3.0 + */ + public StringBuffer format(CurrencyAmount currAmt, + StringBuffer toAppendTo, + FieldPosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, + * Long.MAX_VALUE] and with no decimals), otherwise a Double. + * If IntegerOnly is set, will stop at a decimal + * point (or equivalent; e.g., for rational numbers "1 2/3", will stop + * after the 1). + * Does not throw an exception; if no object can be parsed, index is + * unchanged! + * @see #isParseIntegerOnly + * @see java.text.Format#parseObject(String, ParsePosition) + * @stable ICU 2.0 + */ + public Number parse(String text, ParsePosition parsePosition) { + return numberFormat.parse(text, parsePosition); + } + + /** + * Parses text from the beginning of the given string to produce a number. + * The method might not use the entire text of the given string. + * + * @param text A String whose beginning should be parsed. + * @return A Number parsed from the string. + * @throws ParseException if the beginning of the specified string + * cannot be parsed. + * @see #format + * @stable ICU 2.0 + */ + public Number parse(String text) throws ParseException { + return numberFormat.parse(text); + } + + /** + * Parses text from the given string as a CurrencyAmount. Unlike + * the parse() method, this method will attempt to parse a generic + * currency name, searching for a match of this object's locale's + * currency display names, or for a 3-letter ISO currency code. + * This method will fail if this format is not a currency format, + * that is, if it does not contain the currency pattern symbol + * (U+00A4) in its prefix or suffix. + * + * @param text the string to parse + * @param pos input-output position; on input, the position within + * text to match; must have 0 <= pos.getIndex() < text.length(); + * on output, the position after the last matched character. If + * the parse fails, the position in unchanged upon output. + * @return a CurrencyAmount, or null upon failure + */ + CurrencyAmount parseCurrency(String text, ParsePosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns true if this format will parse numbers as integers only. + * For example in the English locale, with ParseIntegerOnly true, the + * string "1234." would be parsed as the integer value 1234 and parsing + * would stop at the "." character. The decimal separator accepted + * by the parse operation is locale-dependent and determined by the + * subclass. + * @return true if this will parse integers only + * @stable ICU 2.0 + */ + public boolean isParseIntegerOnly() { + return numberFormat.isParseIntegerOnly(); + } + + /** + * Sets whether or not numbers should be parsed as integers only. + * @param value true if this should parse integers only + * @see #isParseIntegerOnly + * @stable ICU 2.0 + */ + public void setParseIntegerOnly(boolean value) { + numberFormat.setParseIntegerOnly(value); + } + + /** + * {@icu} Sets whether strict parsing is in effect. When this is true, the + * following conditions cause a parse failure (examples use the pattern "#,##0.#"):
        + *
      • Leading zeros
        + * '00', '0123' fail the parse, but '0' and '0.001' pass
      • + *
      • Leading or doubled grouping separators
        + * ',123' and '1,,234" fail
      • + *
      • Groups of incorrect length when grouping is used
        + * '1,23' and '1234,567' fail, but '1234' passes
      • + *
      • Grouping separators used in numbers followed by exponents
        + * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when + * not followed by a number)
      • + *
      + * When strict parsing is off, leading zeros and all grouping separators are ignored. + * This is the default behavior. + * @param value True to enable strict parsing. Default is false. + * @see #isParseStrict + * @stable ICU 3.6 + */ + public void setParseStrict(boolean value) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns whether strict parsing is in effect. + * @return true if strict parsing is in effect + * @see #setParseStrict + * @stable ICU 3.6 + */ + public boolean isParseStrict() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + //============== Locale Stuff ===================== + + /** + * Returns the default number format for the current default locale. + * The default format is one of the styles provided by the other + * factory methods: getNumberInstance, getIntegerInstance, + * getCurrencyInstance or getPercentInstance. + * Exactly which one is locale-dependent. + * @stable ICU 2.0 + */ + //Bug 4408066 [Richard/GCL] + public final static NumberFormat getInstance() { + return getInstance(ULocale.getDefault(), NUMBERSTYLE); + } + + /** + * Returns the default number format for the specified locale. + * The default format is one of the styles provided by the other + * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance. + * Exactly which one is locale-dependent. + * @stable ICU 2.0 + */ + public static NumberFormat getInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE); + } + + /** + * {@icu} Returns the default number format for the specified locale. + * The default format is one of the styles provided by the other + * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance. + * Exactly which one is locale-dependent. + * @stable ICU 3.2 + */ + public static NumberFormat getInstance(ULocale inLocale) { + return getInstance(inLocale, NUMBERSTYLE); + } + + /** + * {@icu} Returns a specific style number format for default locale. + * @param style number format style + * @stable ICU 4.2 + */ + public final static NumberFormat getInstance(int style) { + return getInstance(ULocale.getDefault(), style); + } + + /** + * {@icu} Returns a specific style number format for a specific locale. + * @param inLocale the specific locale. + * @param style number format style + * @stable ICU 4.2 + */ + public static NumberFormat getInstance(Locale inLocale, int style) { + return getInstance(ULocale.forLocale(inLocale), style); + } + + + /** + * Returns a general-purpose number format for the current default locale. + * @stable ICU 2.0 + */ + public final static NumberFormat getNumberInstance() { + return getInstance(ULocale.getDefault(), NUMBERSTYLE); + } + + /** + * Returns a general-purpose number format for the specified locale. + * @stable ICU 2.0 + */ + public static NumberFormat getNumberInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE); + } + + /** + * {@icu} Returns a general-purpose number format for the specified locale. + * @stable ICU 3.2 + */ + public static NumberFormat getNumberInstance(ULocale inLocale) { + return getInstance(inLocale, NUMBERSTYLE); + } + + /** + * Returns an integer number format for the current default locale. The + * returned number format is configured to round floating point numbers + * to the nearest integer using IEEE half-even rounding (see {@link + * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, + * and to parse only the integer part of an input string (see {@link + * #isParseIntegerOnly isParseIntegerOnly}). + * + * @return a number format for integer values + * @stable ICU 2.0 + */ + //Bug 4408066 [Richard/GCL] + public final static NumberFormat getIntegerInstance() { + return getInstance(ULocale.getDefault(), INTEGERSTYLE); + } + + /** + * Returns an integer number format for the specified locale. The + * returned number format is configured to round floating point numbers + * to the nearest integer using IEEE half-even rounding (see {@link + * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, + * and to parse only the integer part of an input string (see {@link + * #isParseIntegerOnly isParseIntegerOnly}). + * + * @param inLocale the locale for which a number format is needed + * @return a number format for integer values + * @stable ICU 2.0 + */ + //Bug 4408066 [Richard/GCL] + public static NumberFormat getIntegerInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE); + } + + /** + * {@icu} Returns an integer number format for the specified locale. The + * returned number format is configured to round floating point numbers + * to the nearest integer using IEEE half-even rounding (see {@link + * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting, + * and to parse only the integer part of an input string (see {@link + * #isParseIntegerOnly isParseIntegerOnly}). + * + * @param inLocale the locale for which a number format is needed + * @return a number format for integer values + * @stable ICU 3.2 + */ + public static NumberFormat getIntegerInstance(ULocale inLocale) { + return getInstance(inLocale, INTEGERSTYLE); + } + + /** + * Returns a currency format for the current default locale. + * @return a number format for currency + * @stable ICU 2.0 + */ + public final static NumberFormat getCurrencyInstance() { + return getInstance(ULocale.getDefault(), CURRENCYSTYLE); + } + + /** + * Returns a currency format for the specified locale. + * @return a number format for currency + * @stable ICU 2.0 + */ + public static NumberFormat getCurrencyInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE); + } + + /** + * {@icu} Returns a currency format for the specified locale. + * @return a number format for currency + * @stable ICU 3.2 + */ + public static NumberFormat getCurrencyInstance(ULocale inLocale) { + return getInstance(inLocale, CURRENCYSTYLE); + } + + /** + * Returns a percentage format for the current default locale. + * @return a number format for percents + * @stable ICU 2.0 + */ + public final static NumberFormat getPercentInstance() { + return getInstance(ULocale.getDefault(), PERCENTSTYLE); + } + + /** + * Returns a percentage format for the specified locale. + * @return a number format for percents + * @stable ICU 2.0 + */ + public static NumberFormat getPercentInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE); + } + + /** + * {@icu} Returns a percentage format for the specified locale. + * @return a number format for percents + * @stable ICU 3.2 + */ + public static NumberFormat getPercentInstance(ULocale inLocale) { + return getInstance(inLocale, PERCENTSTYLE); + } + + /** + * {@icu} Returns a scientific format for the current default locale. + * @return a scientific number format + * @stable ICU 2.0 + */ + public final static NumberFormat getScientificInstance() { + return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE); + } + + /** + * {@icu} Returns a scientific format for the specified locale. + * @return a scientific number format + * @stable ICU 2.0 + */ + public static NumberFormat getScientificInstance(Locale inLocale) { + return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE); + } + + /** + * {@icu} Returns a scientific format for the specified locale. + * @return a scientific number format + * @stable ICU 3.2 + */ + public static NumberFormat getScientificInstance(ULocale inLocale) { + return getInstance(inLocale, SCIENTIFICSTYLE); + } + + /** + * A NumberFormatFactory is used to register new number formats. The factory + * should be able to create any of the predefined formats for each locale it + * supports. When registered, the locales it supports extend or override the + * locales already supported by ICU. + * + *

      Note: as of ICU4J 3.2, the default API for NumberFormatFactory uses + * ULocale instead of Locale. Instead of overriding createFormat(Locale, int), + * new implementations should override createFactory(ULocale, int). Note that + * one of these two methods MUST be overridden or else an infinite + * loop will occur. + * + * @stable ICU 2.6 + */ + public static abstract class NumberFormatFactory { + /** + * Value passed to format requesting a default number format. + * @stable ICU 2.6 + */ + public static final int FORMAT_NUMBER = NUMBERSTYLE; + + /** + * Value passed to format requesting a currency format. + * @stable ICU 2.6 + */ + public static final int FORMAT_CURRENCY = CURRENCYSTYLE; + + /** + * Value passed to format requesting a percent format. + * @stable ICU 2.6 + */ + public static final int FORMAT_PERCENT = PERCENTSTYLE; + + /** + * Value passed to format requesting a scientific format. + * @stable ICU 2.6 + */ + public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE; + + /** + * Value passed to format requesting an integer format. + * @stable ICU 2.6 + */ + public static final int FORMAT_INTEGER = INTEGERSTYLE; + + /** + * Returns true if this factory is visible. Default is true. + * If not visible, the locales supported by this factory will not + * be listed by getAvailableLocales. This value must not change. + * @return true if the factory is visible. + * @stable ICU 2.6 + */ + public boolean visible() { + return true; + } + + /** + * Returns an immutable collection of the locale names directly + * supported by this factory. + * @return the supported locale names. + * @stable ICU 2.6 + */ + public abstract Set getSupportedLocaleNames(); + + /** + * Returns a number format of the appropriate type. If the locale + * is not supported, return null. If the locale is supported, but + * the type is not provided by this service, return null. Otherwise + * return an appropriate instance of NumberFormat. + * Note: as of ICU4J 3.2, implementations should override + * this method instead of createFormat(Locale, int). + * @param loc the locale for which to create the format + * @param formatType the type of format + * @return the NumberFormat, or null. + * @stable ICU 3.2 + */ + public NumberFormat createFormat(ULocale loc, int formatType) { + return createFormat(loc.toLocale(), formatType); + } + + /** + * Returns a number format of the appropriate type. If the locale + * is not supported, return null. If the locale is supported, but + * the type is not provided by this service, return null. Otherwise + * return an appropriate instance of NumberFormat. + * Note: as of ICU4J 3.2, createFormat(ULocale, int) should be + * overridden instead of this method. This method is no longer + * abstract and delegates to that method. + * @param loc the locale for which to create the format + * @param formatType the type of format + * @return the NumberFormat, or null. + * @stable ICU 2.6 + */ + public NumberFormat createFormat(Locale loc, int formatType) { + return createFormat(ULocale.forLocale(loc), formatType); + } + + /** + * @stable ICU 2.6 + */ + protected NumberFormatFactory() { + } + } + + /** + * Returns the list of Locales for which NumberFormats are available. + * @return the available locales + * @stable ICU 2.0 + */ + public static Locale[] getAvailableLocales() { + return java.text.NumberFormat.getAvailableLocales(); + } + + /** + * {@icu} Returns the list of Locales for which NumberFormats are available. + * @return the available locales + * @draft ICU 3.2 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static ULocale[] getAvailableULocales() { + if (availableULocales == null) { + synchronized (NumberFormat.class) { + if (availableULocales == null) { + Locale[] locales = java.text.NumberFormat.getAvailableLocales(); + ULocale[] ulocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + ulocales[i] = ULocale.forLocale(locales[i]); + } + availableULocales = ulocales; + } + } + } + return (ULocale[])availableULocales.clone(); + } + private static volatile ULocale[] availableULocales; + + /** + * {@icu} Registers a new NumberFormatFactory. The factory is adopted by + * the service and must not be modified. The returned object is a + * key that can be used to unregister this factory. + * @param factory the factory to register + * @return a key with which to unregister the factory + * @stable ICU 2.6 + */ + public static Object registerFactory(NumberFormatFactory factory) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Unregisters the factory or instance associated with this key (obtained from + * registerInstance or registerFactory). + * @param registryKey a key obtained from registerFactory + * @return true if the object was successfully unregistered + * @stable ICU 2.6 + */ + public static boolean unregister(Object registryKey) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Overrides hashCode. + * @stable ICU 2.0 + */ + public int hashCode() { + return numberFormat.hashCode(); + } + + /** + * Overrides equals. + * Two NumberFormats are equal if they are of the same class + * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc. + * are equal. + * @param obj the object to compare against + * @return true if the object is equal to this. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) { + try { + return numberFormat.equals(((NumberFormat)obj).numberFormat); + } + catch (Exception e) { + return false; + } + } + + /** + * Overrides clone. + * @stable ICU 2.0 + */ + public Object clone() { + return new NumberFormat((java.text.NumberFormat)numberFormat.clone()); + } + + /** + * Returns true if grouping is used in this format. For example, in the + * en_US locale, with grouping on, the number 1234567 will be formatted + * as "1,234,567". The grouping separator as well as the size of each group + * is locale-dependent and is determined by subclasses of NumberFormat. + * Grouping affects both parsing and formatting. + * @return true if grouping is used + * @see #setGroupingUsed + * @stable ICU 2.0 + */ + public boolean isGroupingUsed() { + return numberFormat.isGroupingUsed(); + } + + /** + * Sets whether or not grouping will be used in this format. Grouping + * affects both parsing and formatting. + * @see #isGroupingUsed + * @param newValue true to use grouping. + * @stable ICU 2.0 + */ + public void setGroupingUsed(boolean newValue) { + numberFormat.setGroupingUsed(newValue); + } + + /** + * Returns the maximum number of digits allowed in the integer portion of a + * number. The default value is 40, which subclasses can override. + * When formatting, the exact behavior when this value is exceeded is + * subclass-specific. When parsing, this has no effect. + * @return the maximum number of integer digits + * @see #setMaximumIntegerDigits + * @stable ICU 2.0 + */ + public int getMaximumIntegerDigits() { + return numberFormat.getMaximumIntegerDigits(); + } + + /** + * Sets the maximum number of digits allowed in the integer portion of a + * number. This must be >= minimumIntegerDigits. If the + * new value for maximumIntegerDigits is less than the current value + * of minimumIntegerDigits, then minimumIntegerDigits will also be set to + * the new value. + * @param newValue the maximum number of integer digits to be shown; if + * less than zero, then zero is used. Subclasses might enforce an + * upper limit to this value appropriate to the numeric type being formatted. + * @see #getMaximumIntegerDigits + * @stable ICU 2.0 + */ + public void setMaximumIntegerDigits(int newValue) { + numberFormat.setMaximumIntegerDigits(newValue); + } + + /** + * Returns the minimum number of digits allowed in the integer portion of a + * number. The default value is 1, which subclasses can override. + * When formatting, if this value is not reached, numbers are padded on the + * left with the locale-specific '0' character to ensure at least this + * number of integer digits. When parsing, this has no effect. + * @return the minimum number of integer digits + * @see #setMinimumIntegerDigits + * @stable ICU 2.0 + */ + public int getMinimumIntegerDigits() { + return numberFormat.getMinimumIntegerDigits(); + } + + /** + * Sets the minimum number of digits allowed in the integer portion of a + * number. This must be <= maximumIntegerDigits. If the + * new value for minimumIntegerDigits is more than the current value + * of maximumIntegerDigits, then maximumIntegerDigits will also be set to + * the new value. + * @param newValue the minimum number of integer digits to be shown; if + * less than zero, then zero is used. Subclasses might enforce an + * upper limit to this value appropriate to the numeric type being formatted. + * @see #getMinimumIntegerDigits + * @stable ICU 2.0 + */ + public void setMinimumIntegerDigits(int newValue) { + numberFormat.setMinimumIntegerDigits(newValue); + } + + /** + * Returns the maximum number of digits allowed in the fraction + * portion of a number. The default value is 3, which subclasses + * can override. When formatting, the exact behavior when this + * value is exceeded is subclass-specific. When parsing, this has + * no effect. + * @return the maximum number of fraction digits + * @see #setMaximumFractionDigits + * @stable ICU 2.0 + */ + public int getMaximumFractionDigits() { + return numberFormat.getMaximumFractionDigits(); + } + + /** + * Sets the maximum number of digits allowed in the fraction portion of a + * number. This must be >= minimumFractionDigits. If the + * new value for maximumFractionDigits is less than the current value + * of minimumFractionDigits, then minimumFractionDigits will also be set to + * the new value. + * @param newValue the maximum number of fraction digits to be shown; if + * less than zero, then zero is used. The concrete subclass may enforce an + * upper limit to this value appropriate to the numeric type being formatted. + * @see #getMaximumFractionDigits + * @stable ICU 2.0 + */ + public void setMaximumFractionDigits(int newValue) { + numberFormat.setMaximumFractionDigits(newValue); + } + + /** + * Returns the minimum number of digits allowed in the fraction portion of a + * number. The default value is 0, which subclasses can override. + * When formatting, if this value is not reached, numbers are padded on + * the right with the locale-specific '0' character to ensure at least + * this number of fraction digits. When parsing, this has no effect. + * @return the minimum number of fraction digits + * @see #setMinimumFractionDigits + * @stable ICU 2.0 + */ + public int getMinimumFractionDigits() { + return numberFormat.getMinimumFractionDigits(); + } + + /** + * Sets the minimum number of digits allowed in the fraction portion of a + * number. This must be <= maximumFractionDigits. If the + * new value for minimumFractionDigits exceeds the current value + * of maximumFractionDigits, then maximumFractionDigits will also be set to + * the new value. + * @param newValue the minimum number of fraction digits to be shown; if + * less than zero, then zero is used. Subclasses might enforce an + * upper limit to this value appropriate to the numeric type being formatted. + * @see #getMinimumFractionDigits + * @stable ICU 2.0 + */ + public void setMinimumFractionDigits(int newValue) { + numberFormat.setMinimumFractionDigits(newValue); + } + + /** + * Sets the Currency object used to display currency + * amounts. This takes effect immediately, if this format is a + * currency format. If this format is not a currency format, then + * the currency object is used if and when this object becomes a + * currency format. + * @param theCurrency new currency object to use. May be null for + * some subclasses. + * @stable ICU 2.6 + */ + public void setCurrency(Currency theCurrency) { + numberFormat.setCurrency(theCurrency.currency); + } + + /** + * Returns the Currency object used to display currency + * amounts. This may be null. + * @stable ICU 2.6 + */ + public Currency getCurrency() { + return new Currency(numberFormat.getCurrency()); + } + + /** + * Returns the rounding mode used in this NumberFormat. The default implementation of + * tis method in NumberFormat always throws UnsupportedOperationException. + * @return A rounding mode, between BigDecimal.ROUND_UP + * and BigDecimal.ROUND_UNNECESSARY. + * @see #setRoundingMode(int) + * @stable ICU 4.0 + */ + public int getRoundingMode() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Set the rounding mode used in this NumberFormat. The default implementation of + * tis method in NumberFormat always throws UnsupportedOperationException. + * @param roundingMode A rounding mode, between + * BigDecimal.ROUND_UP and + * BigDecimal.ROUND_UNNECESSARY. + * @see #getRoundingMode() + * @stable ICU 4.0 + */ + public void setRoundingMode(int roundingMode) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + + /** + * Returns a specific style number format for a specific locale. + * @param desiredLocale the specific locale. + * @param choice number format style + * @throws IllegalArgumentException if choice is not one of + * NUMBERSTYLE, CURRENCYSTYLE, + * PERCENTSTYLE, SCIENTIFICSTYLE, + * INTEGERSTYLE, + * ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE, + * @stable ICU 4.2 + */ + public static NumberFormat getInstance(ULocale desiredLocale, int choice) { + Locale locale = desiredLocale.toLocale(); + java.text.NumberFormat nf = null; + switch (choice) { + case NUMBERSTYLE: + nf = java.text.NumberFormat.getInstance(locale); + break; + case INTEGERSTYLE: + nf = java.text.NumberFormat.getIntegerInstance(locale); + break; + case CURRENCYSTYLE: + nf = java.text.NumberFormat.getCurrencyInstance(locale); + break; + case PERCENTSTYLE: + nf = java.text.NumberFormat.getPercentInstance(locale); + break; + case SCIENTIFICSTYLE: + nf = new java.text.DecimalFormat("#E0", + new java.text.DecimalFormatSymbols(locale)); + nf.setMaximumFractionDigits(10); + break; + } + return new NumberFormat(nf); + } + + /** + * Empty constructor. Public for compatibily with JDK which lets the + * compiler generate a default public constructor even though this is + * an abstract class. + * @stable ICU 2.6 + */ + public NumberFormat() { + this(java.text.NumberFormat.getInstance()); + } + + /** + * The instances of this inner class are used as attribute keys and values + * in AttributedCharacterIterator that + * NumberFormat.formatToCharacterIterator() method returns. + *

      + * There is no public constructor to this class, the only instances are the + * constants defined here. + *

      + * @stable ICU 3.6 + */ + public static class Field extends Format.Field { + // generated by serialver from JDK 1.4.1_01 + static final long serialVersionUID = -4516273749929385842L; + + /** + * @stable ICU 3.6 + */ + public static final Field SIGN = new Field("sign"); + + /** + * @stable ICU 3.6 + */ + public static final Field INTEGER = new Field("integer"); + + /** + * @stable ICU 3.6 + */ + public static final Field FRACTION = new Field("fraction"); + + /** + * @stable ICU 3.6 + */ + public static final Field EXPONENT = new Field("exponent"); + + /** + * @stable ICU 3.6 + */ + public static final Field EXPONENT_SIGN = new Field("exponent sign"); + + /** + * @stable ICU 3.6 + */ + public static final Field EXPONENT_SYMBOL = new Field("exponent symbol"); + + /** + * @stable ICU 3.6 + */ + public static final Field DECIMAL_SEPARATOR = new Field("decimal separator"); + /** + * @stable ICU 3.6 + */ + public static final Field GROUPING_SEPARATOR = new Field("grouping separator"); + + /** + * @stable ICU 3.6 + */ + public static final Field PERCENT = new Field("percent"); + + /** + * @stable ICU 3.6 + */ + public static final Field PERMILLE = new Field("per mille"); + + /** + * @stable ICU 3.6 + */ + public static final Field CURRENCY = new Field("currency"); + + /** + * Constructs a new instance of NumberFormat.Field with the given field + * name. + * @stable ICU 3.6 + */ + protected Field(String fieldName) { + super(fieldName); + } + + /** + * serizalization method resolve instances to the constant + * NumberFormat.Field values + * @stable ICU 3.6 + */ + protected Object readResolve() throws InvalidObjectException { + if (this.getName().equals(INTEGER.getName())) + return INTEGER; + if (this.getName().equals(FRACTION.getName())) + return FRACTION; + if (this.getName().equals(EXPONENT.getName())) + return EXPONENT; + if (this.getName().equals(EXPONENT_SIGN.getName())) + return EXPONENT_SIGN; + if (this.getName().equals(EXPONENT_SYMBOL.getName())) + return EXPONENT_SYMBOL; + if (this.getName().equals(CURRENCY.getName())) + return CURRENCY; + if (this.getName().equals(DECIMAL_SEPARATOR.getName())) + return DECIMAL_SEPARATOR; + if (this.getName().equals(GROUPING_SEPARATOR.getName())) + return GROUPING_SEPARATOR; + if (this.getName().equals(PERCENT.getName())) + return PERCENT; + if (this.getName().equals(PERMILLE.getName())) + return PERMILLE; + if (this.getName().equals(SIGN.getName())) + return SIGN; + + throw new InvalidObjectException("An invalid object."); + } + } + + private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) { + if (icuPos == null) { + return null; + } + + int fieldID = icuPos.getField(); + Format.Field fieldAttribute = icuPos.getFieldAttribute(); + + FieldPosition jdkPos = null; + + if (fieldID >= 0) { + if (fieldID == FRACTION_FIELD) { + fieldID = java.text.NumberFormat.FRACTION_FIELD; + } else if (fieldID == INTEGER_FIELD) { + fieldID = java.text.NumberFormat.INTEGER_FIELD; + } + } + + if (fieldAttribute != null) { + // map field + if (fieldAttribute.equals(Field.CURRENCY)) { + fieldAttribute = java.text.NumberFormat.Field.CURRENCY; + } else if (fieldAttribute.equals(Field.DECIMAL_SEPARATOR)) { + fieldAttribute = java.text.NumberFormat.Field.DECIMAL_SEPARATOR; + } else if (fieldAttribute.equals(Field.EXPONENT)) { + fieldAttribute = java.text.NumberFormat.Field.EXPONENT; + } else if (fieldAttribute.equals(Field.EXPONENT_SIGN)) { + fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SIGN; + } else if (fieldAttribute.equals(Field.EXPONENT_SYMBOL)) { + fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SYMBOL; + } else if (fieldAttribute.equals(Field.FRACTION)) { + fieldAttribute = java.text.NumberFormat.Field.FRACTION; + } else if (fieldAttribute.equals(Field.GROUPING_SEPARATOR)) { + fieldAttribute = java.text.NumberFormat.Field.GROUPING_SEPARATOR; + } else if (fieldAttribute.equals(Field.INTEGER)) { + fieldAttribute = java.text.NumberFormat.Field.INTEGER; + } else if (fieldAttribute.equals(Field.PERCENT)) { + fieldAttribute = java.text.NumberFormat.Field.PERCENT; + } else if (fieldAttribute.equals(Field.PERMILLE)) { + fieldAttribute = java.text.NumberFormat.Field.PERMILLE; + } else if (fieldAttribute.equals(Field.SIGN)) { + fieldAttribute = java.text.NumberFormat.Field.SIGN; + } + + jdkPos = new FieldPosition(fieldAttribute, fieldID); + } else { + jdkPos = new FieldPosition(fieldID); + } + + jdkPos.setBeginIndex(icuPos.getBeginIndex()); + jdkPos.setEndIndex(icuPos.getEndIndex()); + + return jdkPos; + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/RawCollationKey.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/RawCollationKey.java index 71fcb59dda1..45316dc2179 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/RawCollationKey.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/RawCollationKey.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -/* - * Empty stub - */ -public class RawCollationKey { - private RawCollationKey() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +/* + * Empty stub + */ +public class RawCollationKey { + private RawCollationKey() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java index befcaa6c762..e8e5785fc90 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java @@ -1,514 +1,514 @@ -/* - ******************************************************************************* - * Copyright (C) 1996-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ - -package com.ibm.icu.text; - -import java.text.AttributedCharacterIterator; -import java.text.AttributedCharacterIterator.Attribute; -import java.text.AttributedString; -import java.text.CharacterIterator; -import java.text.FieldPosition; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; - -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.ULocale; - - -/** - * {@icuenhanced java.text.SimpleDateFormat}.{@icu _usage_} - * - *

      SimpleDateFormat is a concrete class for formatting and - * parsing dates in a locale-sensitive manner. It allows for formatting - * (date -> text), parsing (text -> date), and normalization. - * - *

      - * SimpleDateFormat allows you to start by choosing - * any user-defined patterns for date-time formatting. However, you - * are encouraged to create a date-time formatter with either - * getTimeInstance, getDateInstance, or - * getDateTimeInstance in DateFormat. Each - * of these class methods can return a date/time formatter initialized - * with a default format pattern. You may modify the format pattern - * using the applyPattern methods as desired. - * For more information on using these methods, see - * {@link DateFormat}. - * - *

      - * Time Format Syntax: - *

      - * To specify the time format use a time pattern string. - * In this pattern, all ASCII letters are reserved as pattern letters, - * which are defined as the following: - *

      - *
      - * Symbol   Meaning                 Presentation        Example
      - * ------   -------                 ------------        -------
      - * G        era designator          (Text)              AD
      - * y†       year                    (Number)            1996
      - * Y*       year (week of year)     (Number)            1997
      - * u*       extended year           (Number)            4601
      - * M        month in year           (Text & Number)     July & 07
      - * d        day in month            (Number)            10
      - * h        hour in am/pm (1~12)    (Number)            12
      - * H        hour in day (0~23)      (Number)            0
      - * m        minute in hour          (Number)            30
      - * s        second in minute        (Number)            55
      - * S        fractional second       (Number)            978
      - * E        day of week             (Text)              Tuesday
      - * e*       day of week (local 1~7) (Text & Number)     Tuesday & 2
      - * D        day in year             (Number)            189
      - * F        day of week in month    (Number)            2 (2nd Wed in July)
      - * w        week in year            (Number)            27
      - * W        week in month           (Number)            2
      - * a        am/pm marker            (Text)              PM
      - * k        hour in day (1~24)      (Number)            24
      - * K        hour in am/pm (0~11)    (Number)            0
      - * z        time zone               (Text)              Pacific Standard Time
      - * Z        time zone (RFC 822)     (Number)            -0800
      - * v        time zone (generic)     (Text)              Pacific Time
      - * V        time zone (location)    (Text)              United States (Los Angeles)
      - * g*       Julian day              (Number)            2451334
      - * A*       milliseconds in day     (Number)            69540000
      - * Q*       quarter in year         (Text & Number)     Q1 & 01
      - * c*       stand alone day of week (Text & Number)     Tuesday & 2
      - * L*       stand alone month       (Text & Number)     July & 07
      - * q*       stand alone quarter     (Text & Number)     Q1 & 01
      - * '        escape for text         (Delimiter)         'Date='
      - * ''       single quote            (Literal)           'o''clock'
      - * 
      - *
      - * * These items are not supported by Java's SimpleDateFormat.
      - * ICU interprets a single 'y' differently than Java.

      - *

      - * The count of pattern letters determine the format. - *

      - * (Text): 4 or more pattern letters--use full form, - * < 4--use short or abbreviated form if one exists. - *

      - * (Number): the minimum number of digits. Shorter - * numbers are zero-padded to this amount. Year is handled specially; - * that is, if the count of 'y' is 2, the Year will be truncated to 2 digits. - * (e.g., if "yyyy" produces "1997", "yy" produces "97".) - * Unlike other fields, fractional seconds are padded on the right with zero. - *

      - * (Text & Number): 3 or over, use text, otherwise use number. - *

      - * Any characters in the pattern that are not in the ranges of ['a'..'z'] - * and ['A'..'Z'] will be treated as quoted text. For instance, characters - * like ':', '.', ' ', '#' and '@' will appear in the resulting time text - * even they are not embraced within single quotes. - *

      - * A pattern containing any invalid pattern letter will result in a thrown - * exception during formatting or parsing. - * - *

      - * Examples Using the US Locale: - *

      - *
      - * Format Pattern                         Result
      - * --------------                         -------
      - * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->>  1996.07.10 AD at 15:08:56 Pacific Time
      - * "EEE, MMM d, ''yy"                ->>  Wed, July 10, '96
      - * "h:mm a"                          ->>  12:08 PM
      - * "hh 'o''clock' a, zzzz"           ->>  12 o'clock PM, Pacific Daylight Time
      - * "K:mm a, vvv"                     ->>  0:00 PM, PT
      - * "yyyyy.MMMMM.dd GGG hh:mm aaa"    ->>  01996.July.10 AD 12:08 PM
      - * 
      - *
      - * Code Sample: - *
      - *
      - * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST");
      - * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*60*60*1000);
      - * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000);
      - * 
      - * // Format the current time. - * SimpleDateFormat formatter - * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz"); - * Date currentTime_1 = new Date(); - * String dateString = formatter.format(currentTime_1); - *
      - * // Parse the previous string back into a Date. - * ParsePosition pos = new ParsePosition(0); - * Date currentTime_2 = formatter.parse(dateString, pos); - *
      - *
      - * In the example, the time value currentTime_2 obtained from - * parsing will be equal to currentTime_1. However, they may not be - * equal if the am/pm marker 'a' is left out from the format pattern while - * the "hour in am/pm" pattern symbol is used. This information loss can - * happen when formatting the time in PM. - * - *

      When parsing a date string using the abbreviated year pattern ("yy"), - * SimpleDateFormat must interpret the abbreviated year - * relative to some century. It does this by adjusting dates to be - * within 80 years before and 20 years after the time the SimpleDateFormat - * instance is created. For example, using a pattern of "MM/dd/yy" and a - * SimpleDateFormat instance created on Jan 1, 1997, the string - * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" - * would be interpreted as May 4, 1964. - * During parsing, only strings consisting of exactly two digits, as defined by - * {@link com.ibm.icu.lang.UCharacter#isDigit(int)}, will be parsed into the default - * century. - * Any other numeric string, such as a one digit string, a three or more digit - * string, or a two digit string that isn't all digits (for example, "-1"), is - * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the - * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC. - * - *

      If the year pattern does not have exactly two 'y' characters, the year is - * interpreted literally, regardless of the number of digits. So using the - * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. - * - *

      When numeric fields abut one another directly, with no intervening delimiter - * characters, they constitute a run of abutting numeric fields. Such runs are - * parsed specially. For example, the format "HHmmss" parses the input text - * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to - * parse "1234". In other words, the leftmost field of the run is flexible, - * while the others keep a fixed width. If the parse fails anywhere in the run, - * then the leftmost field is shortened by one character, and the entire run is - * parsed again. This is repeated until either the parse succeeds or the - * leftmost field is one character in length. If the parse still fails at that - * point, the parse of the run fails. - * - *

      For time zones that have no names, use strings GMT+hours:minutes or - * GMT-hours:minutes. - * - *

      The calendar defines what is the first day of the week, the first week - * of the year, whether hours are zero based or not (0 vs 12 or 24), and the - * time zone. There is one common decimal format to handle all the numbers; - * the digit count is handled programmatically according to the pattern. - * - *

      Synchronization

      - * - * Date formats are not synchronized. It is recommended to create separate - * format instances for each thread. If multiple threads access a format - * concurrently, it must be synchronized externally. - * - * @see com.ibm.icu.util.Calendar - * @see com.ibm.icu.util.GregorianCalendar - * @see com.ibm.icu.util.TimeZone - * @see DateFormat - * @see DateFormatSymbols - * @see DecimalFormat - * @author Mark Davis, Chen-Lieh Huang, Alan Liu - * @stable ICU 2.0 - */ -public class SimpleDateFormat extends DateFormat { - private static final long serialVersionUID = 1L; - - /** - * Constructs a SimpleDateFormat using the default pattern for the default - * locale. Note: Not all locales support SimpleDateFormat; for full - * generality, use the factory methods in the DateFormat class. - * - * @see DateFormat - * @stable ICU 2.0 - */ - public SimpleDateFormat() { - super(new java.text.SimpleDateFormat()); - } - - /** - * Constructs a SimpleDateFormat using the given pattern in the default - * locale. Note: Not all locales support SimpleDateFormat; for full - * generality, use the factory methods in the DateFormat class. - * @stable ICU 2.0 - */ - public SimpleDateFormat(String pattern) - { - super(new java.text.SimpleDateFormat(pattern)); - } - - /** - * Constructs a SimpleDateFormat using the given pattern and locale. - * Note: Not all locales support SimpleDateFormat; for full - * generality, use the factory methods in the DateFormat class. - * @stable ICU 2.0 - */ - public SimpleDateFormat(String pattern, Locale loc) - { - super(new java.text.SimpleDateFormat(pattern, loc)); - } - - /** - * Constructs a SimpleDateFormat using the given pattern and locale. - * Note: Not all locales support SimpleDateFormat; for full - * generality, use the factory methods in the DateFormat class. - * @stable ICU 3.2 - */ - public SimpleDateFormat(String pattern, ULocale loc) - { - this(pattern, loc.toLocale()); - } - - /** - * Constructs a SimpleDateFormat using the given pattern , override and locale. - * @param pattern The pattern to be used - * @param override The override string. A numbering system override string can take one of the following forms: - * 1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern. - * 2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern - * followed by an = sign, followed by the numbering system name. For example, to specify that just the year - * be formatted using Hebrew digits, use the override "y=hebr". Multiple overrides can be specified in a single - * string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using - * Thai digits for the month and Devanagari digits for the year. - * @param loc The locale to be used - * @stable ICU 4.2 - */ - public SimpleDateFormat(String pattern, String override, ULocale loc) - { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Constructs a SimpleDateFormat using the given pattern and - * locale-specific symbol data. - * Warning: uses default locale for digits! - * @stable ICU 2.0 - */ - public SimpleDateFormat(String pattern, DateFormatSymbols formatData) - { - super(new java.text.SimpleDateFormat(pattern, formatData.dfs)); - } - - /** - * Sets the 100-year period 2-digit years will be interpreted as being in - * to begin on the date the user specifies. - * @param startDate During parsing, two digit years will be placed in the range - * startDate to startDate + 100 years. - * @stable ICU 2.0 - */ - public void set2DigitYearStart(Date startDate) { - ((java.text.SimpleDateFormat)dateFormat).set2DigitYearStart(startDate); - } - - /** - * Returns the beginning date of the 100-year period 2-digit years are interpreted - * as being within. - * @return the start of the 100-year period into which two digit years are - * parsed - * @stable ICU 2.0 - */ - public Date get2DigitYearStart() { - return ((java.text.SimpleDateFormat)dateFormat).get2DigitYearStart(); - } - - /** - * Formats a date or time, which is the standard millis - * since January 1, 1970, 00:00:00 GMT. - *

      Example: using the US locale: - * "yyyy.MM.dd G 'at' HH:mm:ss zzz" ->> 1996.07.10 AD at 15:08:56 PDT - * @param cal the calendar whose date-time value is to be formatted into a date-time string - * @param toAppendTo where the new date-time text is to be appended - * @param pos the formatting position. On input: an alignment field, - * if desired. On output: the offsets of the alignment field. - * @return the formatted date-time string. - * @see DateFormat - * @stable ICU 2.0 - */ - public StringBuffer format(Calendar cal, StringBuffer toAppendTo, - FieldPosition pos) { - StringBuffer result; - FieldPosition jdkPos = toJDKFieldPosition(pos); - synchronized(dateFormat) { - java.util.Calendar oldCal = dateFormat.getCalendar(); - dateFormat.setCalendar(cal.calendar); - result = dateFormat.format(cal.getTime(), toAppendTo, jdkPos); - dateFormat.setCalendar(oldCal); - } - if (jdkPos != null) { - pos.setBeginIndex(jdkPos.getBeginIndex()); - pos.setEndIndex(jdkPos.getEndIndex()); - } - return result; - } - - /** - * Overrides superclass method - * @stable ICU 2.0 - */ - public void setNumberFormat(NumberFormat newNumberFormat) { - super.setNumberFormat(newNumberFormat); - } - - /** - * Overrides DateFormat - * @see DateFormat - * @stable ICU 2.0 - */ - public void parse(String text, Calendar cal, ParsePosition parsePos) - { - // Note: parsed time zone won't be set in the result calendar - cal.setTime(dateFormat.parse(text, parsePos)); - } - - /** - * Return a pattern string describing this date format. - * @stable ICU 2.0 - */ - public String toPattern() { - return ((java.text.SimpleDateFormat)dateFormat).toPattern(); - } - - /** - * Return a localized pattern string describing this date format. - * @stable ICU 2.0 - */ - public String toLocalizedPattern() { - return ((java.text.SimpleDateFormat)dateFormat).toLocalizedPattern(); - } - - /** - * Apply the given unlocalized pattern string to this date format. - * @stable ICU 2.0 - */ - public void applyPattern(String pat) { - ((java.text.SimpleDateFormat)dateFormat).applyPattern(pat); - } - - /** - * Apply the given localized pattern string to this date format. - * @stable ICU 2.0 - */ - public void applyLocalizedPattern(String pat) { - ((java.text.SimpleDateFormat)dateFormat).applyLocalizedPattern(pat); - } - - /** - * Gets the date/time formatting data. - * @return a copy of the date-time formatting data associated - * with this date-time formatter. - * @stable ICU 2.0 - */ - public DateFormatSymbols getDateFormatSymbols() { - return new DateFormatSymbols(((java.text.SimpleDateFormat)dateFormat).getDateFormatSymbols()); - } - - /** - * Allows you to set the date/time formatting data. - * @param newFormatSymbols the new symbols - * @stable ICU 2.0 - */ - public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) { - ((java.text.SimpleDateFormat)dateFormat).setDateFormatSymbols(newFormatSymbols.dfs); - } - - // For clone to use - private SimpleDateFormat(java.text.SimpleDateFormat sdf) { - super(sdf); - } - - /** - * Overrides Cloneable - * @stable ICU 2.0 - */ - public Object clone() { - return new SimpleDateFormat((java.text.SimpleDateFormat)dateFormat.clone()); - } - - /** - * Override hashCode. - * Generates the hash code for the SimpleDateFormat object - * @stable ICU 2.0 - */ - public int hashCode() - { - return super.hashCode(); - } - - /** - * Override equals. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) - { - return super.equals(obj); - } - - /** - * Format the object to an attributed string, and return the corresponding iterator - * Overrides superclass method. - * - * @param obj The object to format - * @return AttributedCharacterIterator describing the formatted value. - * - * @stable ICU 3.8 - */ - public AttributedCharacterIterator formatToCharacterIterator(Object obj) { - AttributedCharacterIterator it = dateFormat.formatToCharacterIterator(obj); - - // Extract formatted String first - StringBuilder sb = new StringBuilder(); - for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { - sb.append(c); - } - - // Create AttributedString - AttributedString attrstr = new AttributedString(sb.toString()); - - // Map JDK Field to ICU Field - int idx = 0; - it.first(); - while (idx < it.getEndIndex()) { - int end = it.getRunLimit(); - Map attributes = it.getAttributes(); - if (attributes != null) { - for (Entry entry : attributes.entrySet()) { - Attribute attr = entry.getKey(); - Object val = entry.getValue(); - if (attr.equals(java.text.DateFormat.Field.AM_PM)) { - val = attr = Field.AM_PM; - } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_MONTH)) { - val = attr = Field.DAY_OF_MONTH; - } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK)) { - val = attr = Field.DAY_OF_WEEK ; - } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH)) { - val = attr = Field.DAY_OF_WEEK_IN_MONTH ; - } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_YEAR)) { - val = attr = Field.DAY_OF_YEAR; - } else if (attr.equals(java.text.DateFormat.Field.ERA)) { - val = attr = Field.ERA; - } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY0)) { - val = attr = Field.HOUR_OF_DAY0; - } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY1)) { - val = attr = Field.HOUR_OF_DAY1; - } else if (attr.equals(java.text.DateFormat.Field.HOUR0)) { - val = attr = Field.HOUR0; - } else if (attr.equals(java.text.DateFormat.Field.HOUR1)) { - val = attr = Field.HOUR1; - } else if (attr.equals(java.text.DateFormat.Field.MILLISECOND)) { - val = attr = Field.MILLISECOND; - } else if (attr.equals(java.text.DateFormat.Field.MINUTE)) { - val = attr = Field.MINUTE; - } else if (attr.equals(java.text.DateFormat.Field.MONTH)) { - val = attr = Field.MONTH; - } else if (attr.equals(java.text.DateFormat.Field.SECOND)) { - val = attr = Field.SECOND; - } else if (attr.equals(java.text.DateFormat.Field.TIME_ZONE)) { - val = attr = Field.TIME_ZONE; - } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_MONTH)) { - val = attr = Field.WEEK_OF_MONTH; - } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_YEAR)) { - val = attr = Field.WEEK_OF_YEAR; - } else if (attr.equals(java.text.DateFormat.Field.YEAR)) { - val = attr = Field.YEAR; - } - attrstr.addAttribute(attr, val, idx, end); - } - } - idx = end; - while (it.getIndex() < idx) { - it.next(); - } - } - - return attrstr.getIterator(); - } -} +/* + ******************************************************************************* + * Copyright (C) 1996-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +package com.ibm.icu.text; + +import java.text.AttributedCharacterIterator; +import java.text.AttributedCharacterIterator.Attribute; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; + +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.ULocale; + + +/** + * {@icuenhanced java.text.SimpleDateFormat}.{@icu _usage_} + * + *

      SimpleDateFormat is a concrete class for formatting and + * parsing dates in a locale-sensitive manner. It allows for formatting + * (date -> text), parsing (text -> date), and normalization. + * + *

      + * SimpleDateFormat allows you to start by choosing + * any user-defined patterns for date-time formatting. However, you + * are encouraged to create a date-time formatter with either + * getTimeInstance, getDateInstance, or + * getDateTimeInstance in DateFormat. Each + * of these class methods can return a date/time formatter initialized + * with a default format pattern. You may modify the format pattern + * using the applyPattern methods as desired. + * For more information on using these methods, see + * {@link DateFormat}. + * + *

      + * Time Format Syntax: + *

      + * To specify the time format use a time pattern string. + * In this pattern, all ASCII letters are reserved as pattern letters, + * which are defined as the following: + *

      + *
      + * Symbol   Meaning                 Presentation        Example
      + * ------   -------                 ------------        -------
      + * G        era designator          (Text)              AD
      + * y†       year                    (Number)            1996
      + * Y*       year (week of year)     (Number)            1997
      + * u*       extended year           (Number)            4601
      + * M        month in year           (Text & Number)     July & 07
      + * d        day in month            (Number)            10
      + * h        hour in am/pm (1~12)    (Number)            12
      + * H        hour in day (0~23)      (Number)            0
      + * m        minute in hour          (Number)            30
      + * s        second in minute        (Number)            55
      + * S        fractional second       (Number)            978
      + * E        day of week             (Text)              Tuesday
      + * e*       day of week (local 1~7) (Text & Number)     Tuesday & 2
      + * D        day in year             (Number)            189
      + * F        day of week in month    (Number)            2 (2nd Wed in July)
      + * w        week in year            (Number)            27
      + * W        week in month           (Number)            2
      + * a        am/pm marker            (Text)              PM
      + * k        hour in day (1~24)      (Number)            24
      + * K        hour in am/pm (0~11)    (Number)            0
      + * z        time zone               (Text)              Pacific Standard Time
      + * Z        time zone (RFC 822)     (Number)            -0800
      + * v        time zone (generic)     (Text)              Pacific Time
      + * V        time zone (location)    (Text)              United States (Los Angeles)
      + * g*       Julian day              (Number)            2451334
      + * A*       milliseconds in day     (Number)            69540000
      + * Q*       quarter in year         (Text & Number)     Q1 & 01
      + * c*       stand alone day of week (Text & Number)     Tuesday & 2
      + * L*       stand alone month       (Text & Number)     July & 07
      + * q*       stand alone quarter     (Text & Number)     Q1 & 01
      + * '        escape for text         (Delimiter)         'Date='
      + * ''       single quote            (Literal)           'o''clock'
      + * 
      + *
      + * * These items are not supported by Java's SimpleDateFormat.
      + * ICU interprets a single 'y' differently than Java.

      + *

      + * The count of pattern letters determine the format. + *

      + * (Text): 4 or more pattern letters--use full form, + * < 4--use short or abbreviated form if one exists. + *

      + * (Number): the minimum number of digits. Shorter + * numbers are zero-padded to this amount. Year is handled specially; + * that is, if the count of 'y' is 2, the Year will be truncated to 2 digits. + * (e.g., if "yyyy" produces "1997", "yy" produces "97".) + * Unlike other fields, fractional seconds are padded on the right with zero. + *

      + * (Text & Number): 3 or over, use text, otherwise use number. + *

      + * Any characters in the pattern that are not in the ranges of ['a'..'z'] + * and ['A'..'Z'] will be treated as quoted text. For instance, characters + * like ':', '.', ' ', '#' and '@' will appear in the resulting time text + * even they are not embraced within single quotes. + *

      + * A pattern containing any invalid pattern letter will result in a thrown + * exception during formatting or parsing. + * + *

      + * Examples Using the US Locale: + *

      + *
      + * Format Pattern                         Result
      + * --------------                         -------
      + * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->>  1996.07.10 AD at 15:08:56 Pacific Time
      + * "EEE, MMM d, ''yy"                ->>  Wed, July 10, '96
      + * "h:mm a"                          ->>  12:08 PM
      + * "hh 'o''clock' a, zzzz"           ->>  12 o'clock PM, Pacific Daylight Time
      + * "K:mm a, vvv"                     ->>  0:00 PM, PT
      + * "yyyyy.MMMMM.dd GGG hh:mm aaa"    ->>  01996.July.10 AD 12:08 PM
      + * 
      + *
      + * Code Sample: + *
      + *
      + * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST");
      + * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*60*60*1000);
      + * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000);
      + * 
      + * // Format the current time. + * SimpleDateFormat formatter + * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz"); + * Date currentTime_1 = new Date(); + * String dateString = formatter.format(currentTime_1); + *
      + * // Parse the previous string back into a Date. + * ParsePosition pos = new ParsePosition(0); + * Date currentTime_2 = formatter.parse(dateString, pos); + *
      + *
      + * In the example, the time value currentTime_2 obtained from + * parsing will be equal to currentTime_1. However, they may not be + * equal if the am/pm marker 'a' is left out from the format pattern while + * the "hour in am/pm" pattern symbol is used. This information loss can + * happen when formatting the time in PM. + * + *

      When parsing a date string using the abbreviated year pattern ("yy"), + * SimpleDateFormat must interpret the abbreviated year + * relative to some century. It does this by adjusting dates to be + * within 80 years before and 20 years after the time the SimpleDateFormat + * instance is created. For example, using a pattern of "MM/dd/yy" and a + * SimpleDateFormat instance created on Jan 1, 1997, the string + * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" + * would be interpreted as May 4, 1964. + * During parsing, only strings consisting of exactly two digits, as defined by + * {@link com.ibm.icu.lang.UCharacter#isDigit(int)}, will be parsed into the default + * century. + * Any other numeric string, such as a one digit string, a three or more digit + * string, or a two digit string that isn't all digits (for example, "-1"), is + * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the + * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC. + * + *

      If the year pattern does not have exactly two 'y' characters, the year is + * interpreted literally, regardless of the number of digits. So using the + * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. + * + *

      When numeric fields abut one another directly, with no intervening delimiter + * characters, they constitute a run of abutting numeric fields. Such runs are + * parsed specially. For example, the format "HHmmss" parses the input text + * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to + * parse "1234". In other words, the leftmost field of the run is flexible, + * while the others keep a fixed width. If the parse fails anywhere in the run, + * then the leftmost field is shortened by one character, and the entire run is + * parsed again. This is repeated until either the parse succeeds or the + * leftmost field is one character in length. If the parse still fails at that + * point, the parse of the run fails. + * + *

      For time zones that have no names, use strings GMT+hours:minutes or + * GMT-hours:minutes. + * + *

      The calendar defines what is the first day of the week, the first week + * of the year, whether hours are zero based or not (0 vs 12 or 24), and the + * time zone. There is one common decimal format to handle all the numbers; + * the digit count is handled programmatically according to the pattern. + * + *

      Synchronization

      + * + * Date formats are not synchronized. It is recommended to create separate + * format instances for each thread. If multiple threads access a format + * concurrently, it must be synchronized externally. + * + * @see com.ibm.icu.util.Calendar + * @see com.ibm.icu.util.GregorianCalendar + * @see com.ibm.icu.util.TimeZone + * @see DateFormat + * @see DateFormatSymbols + * @see DecimalFormat + * @author Mark Davis, Chen-Lieh Huang, Alan Liu + * @stable ICU 2.0 + */ +public class SimpleDateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + + /** + * Constructs a SimpleDateFormat using the default pattern for the default + * locale. Note: Not all locales support SimpleDateFormat; for full + * generality, use the factory methods in the DateFormat class. + * + * @see DateFormat + * @stable ICU 2.0 + */ + public SimpleDateFormat() { + super(new java.text.SimpleDateFormat()); + } + + /** + * Constructs a SimpleDateFormat using the given pattern in the default + * locale. Note: Not all locales support SimpleDateFormat; for full + * generality, use the factory methods in the DateFormat class. + * @stable ICU 2.0 + */ + public SimpleDateFormat(String pattern) + { + super(new java.text.SimpleDateFormat(pattern)); + } + + /** + * Constructs a SimpleDateFormat using the given pattern and locale. + * Note: Not all locales support SimpleDateFormat; for full + * generality, use the factory methods in the DateFormat class. + * @stable ICU 2.0 + */ + public SimpleDateFormat(String pattern, Locale loc) + { + super(new java.text.SimpleDateFormat(pattern, loc)); + } + + /** + * Constructs a SimpleDateFormat using the given pattern and locale. + * Note: Not all locales support SimpleDateFormat; for full + * generality, use the factory methods in the DateFormat class. + * @stable ICU 3.2 + */ + public SimpleDateFormat(String pattern, ULocale loc) + { + this(pattern, loc.toLocale()); + } + + /** + * Constructs a SimpleDateFormat using the given pattern , override and locale. + * @param pattern The pattern to be used + * @param override The override string. A numbering system override string can take one of the following forms: + * 1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern. + * 2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern + * followed by an = sign, followed by the numbering system name. For example, to specify that just the year + * be formatted using Hebrew digits, use the override "y=hebr". Multiple overrides can be specified in a single + * string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using + * Thai digits for the month and Devanagari digits for the year. + * @param loc The locale to be used + * @stable ICU 4.2 + */ + public SimpleDateFormat(String pattern, String override, ULocale loc) + { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Constructs a SimpleDateFormat using the given pattern and + * locale-specific symbol data. + * Warning: uses default locale for digits! + * @stable ICU 2.0 + */ + public SimpleDateFormat(String pattern, DateFormatSymbols formatData) + { + super(new java.text.SimpleDateFormat(pattern, formatData.dfs)); + } + + /** + * Sets the 100-year period 2-digit years will be interpreted as being in + * to begin on the date the user specifies. + * @param startDate During parsing, two digit years will be placed in the range + * startDate to startDate + 100 years. + * @stable ICU 2.0 + */ + public void set2DigitYearStart(Date startDate) { + ((java.text.SimpleDateFormat)dateFormat).set2DigitYearStart(startDate); + } + + /** + * Returns the beginning date of the 100-year period 2-digit years are interpreted + * as being within. + * @return the start of the 100-year period into which two digit years are + * parsed + * @stable ICU 2.0 + */ + public Date get2DigitYearStart() { + return ((java.text.SimpleDateFormat)dateFormat).get2DigitYearStart(); + } + + /** + * Formats a date or time, which is the standard millis + * since January 1, 1970, 00:00:00 GMT. + *

      Example: using the US locale: + * "yyyy.MM.dd G 'at' HH:mm:ss zzz" ->> 1996.07.10 AD at 15:08:56 PDT + * @param cal the calendar whose date-time value is to be formatted into a date-time string + * @param toAppendTo where the new date-time text is to be appended + * @param pos the formatting position. On input: an alignment field, + * if desired. On output: the offsets of the alignment field. + * @return the formatted date-time string. + * @see DateFormat + * @stable ICU 2.0 + */ + public StringBuffer format(Calendar cal, StringBuffer toAppendTo, + FieldPosition pos) { + StringBuffer result; + FieldPosition jdkPos = toJDKFieldPosition(pos); + synchronized(dateFormat) { + java.util.Calendar oldCal = dateFormat.getCalendar(); + dateFormat.setCalendar(cal.calendar); + result = dateFormat.format(cal.getTime(), toAppendTo, jdkPos); + dateFormat.setCalendar(oldCal); + } + if (jdkPos != null) { + pos.setBeginIndex(jdkPos.getBeginIndex()); + pos.setEndIndex(jdkPos.getEndIndex()); + } + return result; + } + + /** + * Overrides superclass method + * @stable ICU 2.0 + */ + public void setNumberFormat(NumberFormat newNumberFormat) { + super.setNumberFormat(newNumberFormat); + } + + /** + * Overrides DateFormat + * @see DateFormat + * @stable ICU 2.0 + */ + public void parse(String text, Calendar cal, ParsePosition parsePos) + { + // Note: parsed time zone won't be set in the result calendar + cal.setTime(dateFormat.parse(text, parsePos)); + } + + /** + * Return a pattern string describing this date format. + * @stable ICU 2.0 + */ + public String toPattern() { + return ((java.text.SimpleDateFormat)dateFormat).toPattern(); + } + + /** + * Return a localized pattern string describing this date format. + * @stable ICU 2.0 + */ + public String toLocalizedPattern() { + return ((java.text.SimpleDateFormat)dateFormat).toLocalizedPattern(); + } + + /** + * Apply the given unlocalized pattern string to this date format. + * @stable ICU 2.0 + */ + public void applyPattern(String pat) { + ((java.text.SimpleDateFormat)dateFormat).applyPattern(pat); + } + + /** + * Apply the given localized pattern string to this date format. + * @stable ICU 2.0 + */ + public void applyLocalizedPattern(String pat) { + ((java.text.SimpleDateFormat)dateFormat).applyLocalizedPattern(pat); + } + + /** + * Gets the date/time formatting data. + * @return a copy of the date-time formatting data associated + * with this date-time formatter. + * @stable ICU 2.0 + */ + public DateFormatSymbols getDateFormatSymbols() { + return new DateFormatSymbols(((java.text.SimpleDateFormat)dateFormat).getDateFormatSymbols()); + } + + /** + * Allows you to set the date/time formatting data. + * @param newFormatSymbols the new symbols + * @stable ICU 2.0 + */ + public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) { + ((java.text.SimpleDateFormat)dateFormat).setDateFormatSymbols(newFormatSymbols.dfs); + } + + // For clone to use + private SimpleDateFormat(java.text.SimpleDateFormat sdf) { + super(sdf); + } + + /** + * Overrides Cloneable + * @stable ICU 2.0 + */ + public Object clone() { + return new SimpleDateFormat((java.text.SimpleDateFormat)dateFormat.clone()); + } + + /** + * Override hashCode. + * Generates the hash code for the SimpleDateFormat object + * @stable ICU 2.0 + */ + public int hashCode() + { + return super.hashCode(); + } + + /** + * Override equals. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) + { + return super.equals(obj); + } + + /** + * Format the object to an attributed string, and return the corresponding iterator + * Overrides superclass method. + * + * @param obj The object to format + * @return AttributedCharacterIterator describing the formatted value. + * + * @stable ICU 3.8 + */ + public AttributedCharacterIterator formatToCharacterIterator(Object obj) { + AttributedCharacterIterator it = dateFormat.formatToCharacterIterator(obj); + + // Extract formatted String first + StringBuilder sb = new StringBuilder(); + for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { + sb.append(c); + } + + // Create AttributedString + AttributedString attrstr = new AttributedString(sb.toString()); + + // Map JDK Field to ICU Field + int idx = 0; + it.first(); + while (idx < it.getEndIndex()) { + int end = it.getRunLimit(); + Map attributes = it.getAttributes(); + if (attributes != null) { + for (Entry entry : attributes.entrySet()) { + Attribute attr = entry.getKey(); + Object val = entry.getValue(); + if (attr.equals(java.text.DateFormat.Field.AM_PM)) { + val = attr = Field.AM_PM; + } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_MONTH)) { + val = attr = Field.DAY_OF_MONTH; + } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK)) { + val = attr = Field.DAY_OF_WEEK ; + } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH)) { + val = attr = Field.DAY_OF_WEEK_IN_MONTH ; + } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_YEAR)) { + val = attr = Field.DAY_OF_YEAR; + } else if (attr.equals(java.text.DateFormat.Field.ERA)) { + val = attr = Field.ERA; + } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY0)) { + val = attr = Field.HOUR_OF_DAY0; + } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY1)) { + val = attr = Field.HOUR_OF_DAY1; + } else if (attr.equals(java.text.DateFormat.Field.HOUR0)) { + val = attr = Field.HOUR0; + } else if (attr.equals(java.text.DateFormat.Field.HOUR1)) { + val = attr = Field.HOUR1; + } else if (attr.equals(java.text.DateFormat.Field.MILLISECOND)) { + val = attr = Field.MILLISECOND; + } else if (attr.equals(java.text.DateFormat.Field.MINUTE)) { + val = attr = Field.MINUTE; + } else if (attr.equals(java.text.DateFormat.Field.MONTH)) { + val = attr = Field.MONTH; + } else if (attr.equals(java.text.DateFormat.Field.SECOND)) { + val = attr = Field.SECOND; + } else if (attr.equals(java.text.DateFormat.Field.TIME_ZONE)) { + val = attr = Field.TIME_ZONE; + } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_MONTH)) { + val = attr = Field.WEEK_OF_MONTH; + } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_YEAR)) { + val = attr = Field.WEEK_OF_YEAR; + } else if (attr.equals(java.text.DateFormat.Field.YEAR)) { + val = attr = Field.YEAR; + } + attrstr.addAttribute(attr, val, idx, end); + } + } + idx = end; + while (it.getIndex() < idx) { + it.next(); + } + } + + return attrstr.getIterator(); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java index 9fc73a6f5dc..52194dbb5c0 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java @@ -1,80 +1,80 @@ -/* - ******************************************************************************* - * Copyright (C) 2003-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -import java.text.Format; - -import com.ibm.icu.util.ULocale; - -/** - * An abstract class that extends {@link java.text.Format} to provide - * additional ICU protocol, specifically, the getLocale() - * API. All ICU format classes are subclasses of this class. - * - * @see com.ibm.icu.util.ULocale - * @author weiv - * @author Alan Liu - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ -public abstract class UFormat extends Format { - private static final long serialVersionUID = 1L; - - /** - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public UFormat() {} - - /** - * Return the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 - * contains a partial preview implementation. The actual - * locale is returned correctly, but the valid locale is - * not, in most cases. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Set information about the locales that were used to create this - * object. If the object was not constructed from locale data, - * both arguments should be set to null. Otherwise, neither - * should be null. The actual locale must be at the same level or - * less specific than the valid locale. This method is intended - * for use by factories or other entities that create objects of - * this class. - * @param valid the most specific locale containing any resource - * data, or null - * @param actual the locale containing data used to construct this - * object, or null - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - */ - final void setLocale(ULocale valid, ULocale actual) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } -} +/* + ******************************************************************************* + * Copyright (C) 2003-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +import java.text.Format; + +import com.ibm.icu.util.ULocale; + +/** + * An abstract class that extends {@link java.text.Format} to provide + * additional ICU protocol, specifically, the getLocale() + * API. All ICU format classes are subclasses of this class. + * + * @see com.ibm.icu.util.ULocale + * @author weiv + * @author Alan Liu + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ +public abstract class UFormat extends Format { + private static final long serialVersionUID = 1L; + + /** + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public UFormat() {} + + /** + * Return the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 + * contains a partial preview implementation. The actual + * locale is returned correctly, but the valid locale is + * not, in most cases. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Set information about the locales that were used to create this + * object. If the object was not constructed from locale data, + * both arguments should be set to null. Otherwise, neither + * should be null. The actual locale must be at the same level or + * less specific than the valid locale. This method is intended + * for use by factories or other entities that create objects of + * this class. + * @param valid the most specific locale containing any resource + * data, or null + * @param actual the locale containing data used to construct this + * object, or null + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + */ + final void setLocale(ULocale valid, ULocale actual) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UnicodeSet.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UnicodeSet.java index 1092ba99685..e99df5f828d 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UnicodeSet.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UnicodeSet.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.text; - -/* - * Empty stub - */ -public class UnicodeSet { - private UnicodeSet() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.text; + +/* + * Empty stub + */ +public class UnicodeSet { + private UnicodeSet() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java index 739a040d8b6..b09abaef91b 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java @@ -1,2345 +1,2345 @@ -/* -* Copyright (C) 1996-2011, International Business Machines -* Corporation and others. All Rights Reserved. -*/ - -package com.ibm.icu.util; - -import java.io.Serializable; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; - -import com.ibm.icu.text.DateFormat; - -/** - * {@icuenhanced java.util.Calendar}.{@icu _usage_} - * - *

      Calendar is an abstract base class for converting between - * a Date object and a set of integer fields such as - * YEAR, MONTH, DAY, HOUR, - * and so on. (A Date object represents a specific instant in - * time with millisecond precision. See - * {@link Date} - * for information about the Date class.) - * - *

      Subclasses of Calendar interpret a Date - * according to the rules of a specific calendar system. ICU4J contains - * several subclasses implementing different international calendar systems. - * - *

      - * Like other locale-sensitive classes, Calendar provides a - * class method, getInstance, for getting a generally useful - * object of this type. Calendar's getInstance method - * returns a calendar of a type appropriate to the locale, whose - * time fields have been initialized with the current date and time: - *

      - *
      Calendar rightNow = Calendar.getInstance()
      - *
      - * - *

      When a ULocale is used by getInstance, its - * 'calendar' tag and value are retrieved if present. If a recognized - * value is supplied, a calendar is provided and configured as appropriate. - * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic", - * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc". For - * example:

      - *
      Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));
      - *
      will return an instance of JapaneseCalendar (using en_US conventions for - * minimum days in first week, start day of week, et cetera). - * - *

      A Calendar object can produce all the time field values - * needed to implement the date-time formatting for a particular language and - * calendar style (for example, Japanese-Gregorian, Japanese-Traditional). - * Calendar defines the range of values returned by certain fields, - * as well as their meaning. For example, the first month of the year has value - * MONTH == JANUARY for all calendars. Other values - * are defined by the concrete subclass, such as ERA and - * YEAR. See individual field documentation and subclass - * documentation for details. - * - *

      When a Calendar is lenient, it accepts a wider range - * of field values than it produces. For example, a lenient - * GregorianCalendar interprets MONTH == - * JANUARY, DAY_OF_MONTH == 32 as February 1. A - * non-lenient GregorianCalendar throws an exception when given - * out-of-range field settings. When calendars recompute field values for - * return by get(), they normalize them. For example, a - * GregorianCalendar always produces DAY_OF_MONTH - * values between 1 and the length of the month. - * - *

      Calendar defines a locale-specific seven day week using two - * parameters: the first day of the week and the minimal days in first week - * (from 1 to 7). These numbers are taken from the locale resource data when a - * Calendar is constructed. They may also be specified explicitly - * through the API. - * - *

      When setting or getting the WEEK_OF_MONTH or - * WEEK_OF_YEAR fields, Calendar must determine the - * first week of the month or year as a reference point. The first week of a - * month or year is defined as the earliest seven day period beginning on - * getFirstDayOfWeek() and containing at least - * getMinimalDaysInFirstWeek() days of that month or year. Weeks - * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow - * it. Note that the normalized numbering returned by get() may be - * different. For example, a specific Calendar subclass may - * designate the week before week 1 of a year as week n of the previous - * year. - * - *

      When computing a Date from time fields, two special - * circumstances may arise: there may be insufficient information to compute the - * Date (such as only year and month but no day in the month), or - * there may be inconsistent information (such as "Tuesday, July 15, 1996" -- - * July 15, 1996 is actually a Monday). - * - *

      Insufficient information. The calendar will use default - * information to specify the missing fields. This may vary by calendar; for - * the Gregorian calendar, the default for a field is the same as that of the - * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc. - * - *

      Inconsistent information. If fields conflict, the calendar - * will give preference to fields set more recently. For example, when - * determining the day, the calendar will look for one of the following - * combinations of fields. The most recent combination, as determined by the - * most recently set single field, will be used. - * - *

      - *
      - * MONTH + DAY_OF_MONTH
      - * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
      - * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
      - * DAY_OF_YEAR
      - * DAY_OF_WEEK + WEEK_OF_YEAR
      - *
      - * - * For the time of day: - * - *
      - *
      - * HOUR_OF_DAY
      - * AM_PM + HOUR
      - *
      - * - *

      Note: for some non-Gregorian calendars, different - * fields may be necessary for complete disambiguation. For example, a full - * specification of the historial Arabic astronomical calendar requires year, - * month, day-of-month and day-of-week in some cases. - * - *

      Note: There are certain possible ambiguities in - * interpretation of certain singular times, which are resolved in the - * following ways: - *

        - *
      1. 24:00:00 "belongs" to the following day. That is, - * 23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 - * - *
      2. Although historically not precise, midnight also belongs to "am", - * and noon belongs to "pm", so on the same day, - * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm - *
      - * - *

      The date or time format strings are not part of the definition of a - * calendar, as those must be modifiable or overridable by the user at - * runtime. Use {@link DateFormat} - * to format dates. - * - *

      Field manipulation methods

      - * - *

      Calendar fields can be changed using three methods: - * set(), add(), and roll().

      - * - *

      set(f, value) changes field - * f to value. In addition, it sets an - * internal member variable to indicate that field f has - * been changed. Although field f is changed immediately, - * the calendar's milliseconds is not recomputed until the next call to - * get(), getTime(), or - * getTimeInMillis() is made. Thus, multiple calls to - * set() do not trigger multiple, unnecessary - * computations. As a result of changing a field using - * set(), other fields may also change, depending on the - * field, the field value, and the calendar system. In addition, - * get(f) will not necessarily return value - * after the fields have been recomputed. The specifics are determined by - * the concrete calendar class.

      - * - *

      Example: Consider a GregorianCalendar - * originally set to August 31, 1999. Calling set(Calendar.MONTH, - * Calendar.SEPTEMBER) sets the calendar to September 31, - * 1999. This is a temporary internal representation that resolves to - * October 1, 1999 if getTime()is then called. However, a - * call to set(Calendar.DAY_OF_MONTH, 30) before the call to - * getTime() sets the calendar to September 30, 1999, since - * no recomputation occurs after set() itself.

      - * - *

      add(f, delta) adds delta - * to field f. This is equivalent to calling set(f, - * get(f) + delta) with two adjustments:

      - * - *
      - *

      Add rule 1. The value of field f - * after the call minus the value of field f before the - * call is delta, modulo any overflow that has occurred in - * field f. Overflow occurs when a field value exceeds its - * range and, as a result, the next larger field is incremented or - * decremented and the field value is adjusted back into its range.

      - * - *

      Add rule 2. If a smaller field is expected to be - * invariant, but   it is impossible for it to be equal to its - * prior value because of changes in its minimum or maximum after field - * f is changed, then its value is adjusted to be as close - * as possible to its expected value. A smaller field represents a - * smaller unit of time. HOUR is a smaller field than - * DAY_OF_MONTH. No adjustment is made to smaller fields - * that are not expected to be invariant. The calendar system - * determines what fields are expected to be invariant.

      - *
      - * - *

      In addition, unlike set(), add() forces - * an immediate recomputation of the calendar's milliseconds and all - * fields.

      - * - *

      Example: Consider a GregorianCalendar - * originally set to August 31, 1999. Calling add(Calendar.MONTH, - * 13) sets the calendar to September 30, 2000. Add rule - * 1 sets the MONTH field to September, since - * adding 13 months to August gives September of the next year. Since - * DAY_OF_MONTH cannot be 31 in September in a - * GregorianCalendar, add rule 2 sets the - * DAY_OF_MONTH to 30, the closest possible value. Although - * it is a smaller field, DAY_OF_WEEK is not adjusted by - * rule 2, since it is expected to change when the month changes in a - * GregorianCalendar.

      - * - *

      roll(f, delta) adds - * delta to field f without changing larger - * fields. This is equivalent to calling add(f, delta) with - * the following adjustment:

      - * - *
      - *

      Roll rule. Larger fields are unchanged after the - * call. A larger field represents a larger unit of - * time. DAY_OF_MONTH is a larger field than - * HOUR.

      - *
      - * - *

      Example: Consider a GregorianCalendar - * originally set to August 31, 1999. Calling roll(Calendar.MONTH, - * 8) sets the calendar to April 30, 1999. Add - * rule 1 sets the MONTH field to April. Using a - * GregorianCalendar, the DAY_OF_MONTH cannot - * be 31 in the month April. Add rule 2 sets it to the closest possible - * value, 30. Finally, the roll rule maintains the - * YEAR field value of 1999.

      - * - *

      Example: Consider a GregorianCalendar - * originally set to Sunday June 6, 1999. Calling - * roll(Calendar.WEEK_OF_MONTH, -1) sets the calendar to - * Tuesday June 1, 1999, whereas calling - * add(Calendar.WEEK_OF_MONTH, -1) sets the calendar to - * Sunday May 30, 1999. This is because the roll rule imposes an - * additional constraint: The MONTH must not change when the - * WEEK_OF_MONTH is rolled. Taken together with add rule 1, - * the resultant date must be between Tuesday June 1 and Saturday June - * 5. According to add rule 2, the DAY_OF_WEEK, an invariant - * when changing the WEEK_OF_MONTH, is set to Tuesday, the - * closest possible value to Sunday (where Sunday is the first day of the - * week).

      - * - *

      Usage model. To motivate the behavior of - * add() and roll(), consider a user interface - * component with increment and decrement buttons for the month, day, and - * year, and an underlying GregorianCalendar. If the - * interface reads January 31, 1999 and the user presses the month - * increment button, what should it read? If the underlying - * implementation uses set(), it might read March 3, 1999. A - * better result would be February 28, 1999. Furthermore, if the user - * presses the month increment button again, it should read March 31, - * 1999, not March 28, 1999. By saving the original date and using either - * add() or roll(), depending on whether larger - * fields should be affected, the user interface can behave as most users - * will intuitively expect.

      - * - *

      Note: You should always use {@link #roll roll} and {@link #add add} rather - * than attempting to perform arithmetic operations directly on the fields - * of a Calendar. It is quite possible for Calendar subclasses - * to have fields with non-linear behavior, for example missing months - * or days during non-leap years. The subclasses' add and roll - * methods will take this into account, while simple arithmetic manipulations - * may give invalid results. - * - *

      Calendar Architecture in ICU4J

      - * - *

      Recently the implementation of Calendar has changed - * significantly in order to better support subclassing. The original - * Calendar class was designed to support subclassing, but - * it had only one implemented subclass, GregorianCalendar. - * With the implementation of several new calendar subclasses, including - * the BuddhistCalendar, ChineseCalendar, - * HebrewCalendar, IslamicCalendar, and - * JapaneseCalendar, the subclassing API has been reworked - * thoroughly. This section details the new subclassing API and other - * ways in which com.ibm.icu.util.Calendar differs from - * java.util.Calendar. - *

      - * - *

      Changes

      - * - *

      Overview of changes between the classic Calendar - * architecture and the new architecture. - * - *

        - * - *
      • The fields[] array is private now - * instead of protected. Subclasses must access it - * using the methods {@link #internalSet} and - * {@link #internalGet}. Motivation: Subclasses should - * not directly access data members.
      • - * - *
      • The time long word is private now - * instead of protected. Subclasses may access it using - * the method {@link #internalGetTimeInMillis}, which does not - * provoke an update. Motivation: Subclasses should not - * directly access data members.
      • - * - *
      • The scope of responsibility of subclasses has been drastically - * reduced. As much functionality as possible is implemented in the - * Calendar base class. As a result, it is much easier - * to subclass Calendar. Motivation: Subclasses - * should not have to reimplement common code. Certain behaviors are - * common across calendar systems: The definition and behavior of - * week-related fields and time fields, the arithmetic - * ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many - * fields, and the field validation system.
      • - * - *
      • The subclassing API has been completely redesigned.
      • - * - *
      • The Calendar base class contains some Gregorian - * calendar algorithmic support that subclasses can use (specifically - * in {@link #handleComputeFields}). Subclasses can use the - * methods getGregorianXxx() to obtain precomputed - * values. Motivation: This is required by all - * Calendar subclasses in order to implement consistent - * time zone behavior, and Gregorian-derived systems can use the - * already computed data.
      • - * - *
      • The FIELD_COUNT constant has been removed. Use - * {@link #getFieldCount}. In addition, framework API has been - * added to allow subclasses to define additional fields. - * Motivation: The number of fields is not constant across - * calendar systems.
      • - * - *
      • The range of handled dates has been narrowed from +/- - * ~300,000,000 years to +/- ~5,000,000 years. In practical terms - * this should not affect clients. However, it does mean that client - * code cannot be guaranteed well-behaved results with dates such as - * Date(Long.MIN_VALUE) or - * Date(Long.MAX_VALUE). Instead, the - * Calendar protected constants should be used. - * Motivation: With - * the addition of the {@link #JULIAN_DAY} field, Julian day - * numbers must be restricted to a 32-bit int. This - * restricts the overall supported range. Furthermore, restricting - * the supported range simplifies the computations by removing - * special case code that was used to accomodate arithmetic overflow - * at millis near Long.MIN_VALUE and - * Long.MAX_VALUE.
      • - * - *
      • New fields are implemented: {@link #JULIAN_DAY} defines - * single-field specification of the - * date. {@link #MILLISECONDS_IN_DAY} defines a single-field - * specification of the wall time. {@link #DOW_LOCAL} and - * {@link #YEAR_WOY} implement localized day-of-week and - * week-of-year behavior.
      • - * - *
      • Subclasses can access protected millisecond constants - * defined in Calendar.
      • - * - *
      • New API has been added to support calendar-specific subclasses - * of DateFormat.
      • - * - *
      • Several subclasses have been implemented, representing - * various international calendar systems.
      • - * - *
      - * - *

      Subclass API

      - * - *

      The original Calendar API was based on the experience - * of implementing a only a single subclass, - * GregorianCalendar. As a result, all of the subclassing - * kinks had not been worked out. The new subclassing API has been - * refined based on several implemented subclasses. This includes methods - * that must be overridden and methods for subclasses to call. Subclasses - * no longer have direct access to fields and - * stamp. Instead, they have new API to access - * these. Subclasses are able to allocate the fields array - * through a protected framework method; this allows subclasses to - * specify additional fields.

      - * - *

      More functionality has been moved into the base class. The base - * class now contains much of the computational machinery to support the - * Gregorian calendar. This is based on two things: (1) Many calendars - * are based on the Gregorian calendar (such as the Buddhist and Japanese - * imperial calendars). (2) All calendars require basic - * Gregorian support in order to handle timezone computations.

      - * - *

      Common computations have been moved into - * Calendar. Subclasses no longer compute the week related - * fields and the time related fields. These are commonly handled for all - * calendars by the base class.

      - * - *

      Subclass computation of time => fields - * - *

      The {@link #ERA}, {@link #YEAR}, - * {@link #EXTENDED_YEAR}, {@link #MONTH}, - * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are - * computed by the subclass, based on the Julian day. All other fields - * are computed by Calendar. - * - *

        - * - *
      • Subclasses should implement {@link #handleComputeFields} - * to compute the {@link #ERA}, {@link #YEAR}, - * {@link #EXTENDED_YEAR}, {@link #MONTH}, - * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields, - * based on the value of the {@link #JULIAN_DAY} field. If there - * are calendar-specific fields not defined by Calendar, - * they must also be computed. These are the only fields that the - * subclass should compute. All other fields are computed by the base - * class, so time and week fields behave in a consistent way across - * all calendars. The default version of this method in - * Calendar implements a proleptic Gregorian - * calendar. Within this method, subclasses may call - * getGregorianXxx() to obtain the Gregorian calendar - * month, day of month, and extended year for the given date.
      • - * - *
      - * - *

      Subclass computation of fields => time - * - *

      The interpretation of most field values is handled entirely by - * Calendar. Calendar determines which fields - * are set, which are not, which are set more recently, and so on. In - * addition, Calendar handles the computation of the time - * from the time fields and handles the week-related fields. The only - * thing the subclass must do is determine the extended year, based on - * the year fields, and then, given an extended year and a month, it must - * return a Julian day number. - * - *

        - * - *
      • Subclasses should implement {@link #handleGetExtendedYear} - * to return the extended year for this calendar system, based on the - * {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that - * the calendar system uses that are larger than a year, such as - * {@link #ERA}.
      • - * - *
      • Subclasses should implement {@link #handleComputeMonthStart} - * to return the Julian day number - * associated with a month and extended year. This is the Julian day - * number of the day before the first day of the month. The month - * number is zero-based. This computation should not depend on any - * field values.
      • - * - *
      - * - *

      Other methods - * - *

        - * - *
      • Subclasses should implement {@link #handleGetMonthLength} - * to return the number of days in a - * given month of a given extended year. The month number, as always, - * is zero-based.
      • - * - *
      • Subclasses should implement {@link #handleGetYearLength} - * to return the number of days in the given - * extended year. This method is used by - * computeWeekFields to compute the - * {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.
      • - * - *
      • Subclasses should implement {@link #handleGetLimit} - * to return the protected values of a field, depending on the value of - * limitType. This method only needs to handle the - * fields {@link #ERA}, {@link #YEAR}, {@link #MONTH}, - * {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH}, - * {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR}, - * {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and - * {@link #EXTENDED_YEAR}. Other fields are invariant (with - * respect to calendar system) and are handled by the base - * class.
      • - * - *
      • Optionally, subclasses may override {@link #validateField} - * to check any subclass-specific fields. If the - * field's value is out of range, the method should throw an - * IllegalArgumentException. The method may call - * super.validateField(field) to handle fields in a - * generic way, that is, to compare them to the range - * getMinimum(field)..getMaximum(field).
      • - * - *
      • Optionally, subclasses may override - * {@link #handleCreateFields} to create an int[] - * array large enough to hold the calendar's fields. This is only - * necessary if the calendar defines additional fields beyond those - * defined by Calendar. The length of the result must be - * be between the base and maximum field counts.
      • - * - *
      • Optionally, subclasses may override - * {@link #handleGetDateFormat} to create a - * DateFormat appropriate to this calendar. This is only - * required if a calendar subclass redefines the use of a field (for - * example, changes the {@link #ERA} field from a symbolic field - * to a numeric one) or defines an additional field.
      • - * - *
      • Optionally, subclasses may override {@link #roll roll} and - * {@link #add add} to handle fields that are discontinuous. For - * example, in the Hebrew calendar the month "Adar I" only - * occurs in leap years; in other years the calendar jumps from - * Shevat (month #4) to Adar (month #6). The {@link - * HebrewCalendar#add HebrewCalendar.add} and {@link - * HebrewCalendar#roll HebrewCalendar.roll} methods take this into - * account, so that adding 1 month to Shevat gives the proper result - * (Adar) in a non-leap year. The protected utility method {@link - * #pinField pinField} is often useful when implementing these two - * methods.
      • - * - *
      - * - *

      Normalized behavior - * - *

      The behavior of certain fields has been made consistent across all - * calendar systems and implemented in Calendar. - * - *

        - * - *
      • Time is normalized. Even though some calendar systems transition - * between days at sunset or at other times, all ICU4J calendars - * transition between days at local zone midnight. This - * allows ICU4J to centralize the time computations in - * Calendar and to maintain basic correpsondences - * between calendar systems. Affected fields: {@link #AM_PM}, - * {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE}, - * {@link #SECOND}, {@link #MILLISECOND}, - * {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.
      • - * - *
      • DST behavior is normalized. Daylight savings time behavior is - * computed the same for all calendar systems, and depends on the - * value of several GregorianCalendar fields: the - * {@link #YEAR}, {@link #MONTH}, and - * {@link #DAY_OF_MONTH}. As a result, Calendar - * always computes these fields, even for non-Gregorian calendar - * systems. These fields are available to subclasses.
      • - * - *
      • Weeks are normalized. Although locales define the week - * differently, in terms of the day on which it starts, and the - * designation of week number one of a month or year, they all use a - * common mechanism. Furthermore, the day of the week has a simple - * and consistent definition throughout history. For example, - * although the Gregorian calendar introduced a discontinuity when - * first instituted, the day of week was not disrupted. For this - * reason, the fields {@link #DAY_OF_WEEK}, WEEK_OF_YEAR, - * WEEK_OF_MONTH, {@link #DAY_OF_WEEK_IN_MONTH}, - * {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in - * a consistent way in the base class, based on the - * {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR}, - * {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are - * computed by the subclass.
      • - * - *
      - * - *

      Supported range - * - *

      The allowable range of Calendar has been - * narrowed. GregorianCalendar used to attempt to support - * the range of dates with millisecond values from - * Long.MIN_VALUE to Long.MAX_VALUE. This - * introduced awkward constructions (hacks) which slowed down - * performance. It also introduced non-uniform behavior at the - * boundaries. The new Calendar protocol specifies the - * maximum range of supportable dates as those having Julian day numbers - * of -0x7F000000 to +0x7F000000. This - * corresponds to years from ~5,000,000 BCE to ~5,000,000 CE. Programmers - * should use the protected constants in Calendar to - * specify an extremely early or extremely late date.

      - * - *

      General notes - * - *

        - * - *
      • Calendars implementations are proleptic. For example, - * even though the Gregorian calendar was not instituted until the - * 16th century, the GregorianCalendar class supports - * dates before the historical onset of the calendar by extending the - * calendar system backward in time. Similarly, the - * HebrewCalendar extends backward before the start of - * its epoch into zero and negative years. Subclasses do not throw - * exceptions because a date precedes the historical start of a - * calendar system. Instead, they implement - * {@link #handleGetLimit} to return appropriate limits on - * {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the - * calendar is set to not be lenient, out-of-range field values will - * trigger an exception.
      • - * - *
      • Calendar system subclasses compute a extended - * year. This differs from the {@link #YEAR} field in that - * it ranges over all integer values, including zero and negative - * values, and it encapsulates the information of the - * {@link #YEAR} field and all larger fields. Thus, for the - * Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as - * ERA==AD ? YEAR : 1-YEAR. Another example is the Mayan - * long count, which has years (KUN) and nested cycles - * of years (KATUN and BAKTUN). The Mayan - * {@link #EXTENDED_YEAR} is computed as TUN + 20 * (KATUN - * + 20 * BAKTUN). The Calendar base class uses - * the {@link #EXTENDED_YEAR} field to compute the week-related - * fields.
      • - * - *
      - * - * @see Date - * @see GregorianCalendar - * @see TimeZone - * @see DateFormat - * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner - * @stable ICU 2.0 - */ -public class Calendar implements Serializable, Cloneable, Comparable { - private static final long serialVersionUID = 1L; - - /** - * @internal - */ - public final java.util.Calendar calendar; - - /** - * @internal - * @param delegate the Calendar to which to delegate - */ - public Calendar(java.util.Calendar delegate) { - this.calendar = delegate; - } - - // Data flow in Calendar - // --------------------- - - // The current time is represented in two ways by Calendar: as UTC - // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local - // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the - // millis from the fields, and vice versa. The data needed to do this - // conversion is encapsulated by a TimeZone object owned by the Calendar. - // The data provided by the TimeZone object may also be overridden if the - // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class - // keeps track of what information was most recently set by the caller, and - // uses that to compute any other information as needed. - - // If the user sets the fields using set(), the data flow is as follows. - // This is implemented by the Calendar subclass's computeTime() method. - // During this process, certain fields may be ignored. The disambiguation - // algorithm for resolving which fields to pay attention to is described - // above. - - // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) - // | - // | Using Calendar-specific algorithm - // V - // local standard millis - // | - // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET - // V - // UTC millis (in time data member) - - // If the user sets the UTC millis using setTime(), the data flow is as - // follows. This is implemented by the Calendar subclass's computeFields() - // method. - - // UTC millis (in time data member) - // | - // | Using TimeZone getOffset() - // V - // local standard millis - // | - // | Using Calendar-specific algorithm - // V - // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) - - // In general, a round trip from fields, through local and UTC millis, and - // back out to fields is made when necessary. This is implemented by the - // complete() method. Resolving a partial set of fields into a UTC millis - // value allows all remaining fields to be generated from that value. If - // the Calendar is lenient, the fields are also renormalized to standard - // ranges when they are regenerated. - - /** - * Field number for get and set indicating the - * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific - * value; see subclass documentation. - * @see GregorianCalendar#AD - * @see GregorianCalendar#BC - * @stable ICU 2.0 - */ - public final static int ERA = 0; - - /** - * Field number for get and set indicating the - * year. This is a calendar-specific value; see subclass documentation. - * @stable ICU 2.0 - */ - public final static int YEAR = 1; - - /** - * Field number for get and set indicating the - * month. This is a calendar-specific value. The first month of the year is - * JANUARY; the last depends on the number of months in a year. - * @see #JANUARY - * @see #FEBRUARY - * @see #MARCH - * @see #APRIL - * @see #MAY - * @see #JUNE - * @see #JULY - * @see #AUGUST - * @see #SEPTEMBER - * @see #OCTOBER - * @see #NOVEMBER - * @see #DECEMBER - * @see #UNDECIMBER - * @stable ICU 2.0 - */ - public final static int MONTH = 2; - - /** - * Field number for get and set indicating the - * week number within the current year. The first week of the year, as - * defined by {@link #getFirstDayOfWeek()} and - * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define - * the value of {@link #WEEK_OF_YEAR} for days before the first week of - * the year. - * @see #getFirstDayOfWeek - * @see #getMinimalDaysInFirstWeek - * @stable ICU 2.0 - */ - public final static int WEEK_OF_YEAR = 3; - - /** - * Field number for get and set indicating the - * week number within the current month. The first week of the month, as - * defined by {@link #getFirstDayOfWeek()} and - * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define - * the value of {@link #WEEK_OF_MONTH} for days before the first week of - * the month. - * @see #getFirstDayOfWeek - * @see #getMinimalDaysInFirstWeek - * @stable ICU 2.0 - */ - public final static int WEEK_OF_MONTH = 4; - - /** - * Field number for get and set indicating the - * day of the month. This is a synonym for {@link #DAY_OF_MONTH}. - * The first day of the month has value 1. - * @see #DAY_OF_MONTH - * @stable ICU 2.0 - */ - public final static int DATE = 5; - - /** - * Field number for get and set indicating the - * day of the month. This is a synonym for {@link #DATE}. - * The first day of the month has value 1. - * @see #DATE - * @stable ICU 2.0 - */ - public final static int DAY_OF_MONTH = 5; - - /** - * Field number for get and set indicating the day - * number within the current year. The first day of the year has value 1. - * @stable ICU 2.0 - */ - public final static int DAY_OF_YEAR = 6; - - /** - * Field number for get and set indicating the day - * of the week. This field takes values {@link #SUNDAY}, - * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY}, - * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}. - * @see #SUNDAY - * @see #MONDAY - * @see #TUESDAY - * @see #WEDNESDAY - * @see #THURSDAY - * @see #FRIDAY - * @see #SATURDAY - * @stable ICU 2.0 - */ - public final static int DAY_OF_WEEK = 7; - - /** - * Field number for get and set indicating the - * ordinal number of the day of the week within the current month. Together - * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day - * within a month. Unlike {@link #WEEK_OF_MONTH} and - * {@link #WEEK_OF_YEAR}, this field's value does not depend on - * {@link #getFirstDayOfWeek()} or - * {@link #getMinimalDaysInFirstWeek()}. DAY_OF_MONTH 1 - * through 7 always correspond to DAY_OF_WEEK_IN_MONTH - * 1; 8 through 15 correspond to - * DAY_OF_WEEK_IN_MONTH 2, and so on. - * DAY_OF_WEEK_IN_MONTH 0 indicates the week before - * DAY_OF_WEEK_IN_MONTH 1. Negative values count back from the - * end of the month, so the last Sunday of a month is specified as - * DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1. Because - * negative values count backward they will usually be aligned differently - * within the month than positive values. For example, if a month has 31 - * days, DAY_OF_WEEK_IN_MONTH -1 will overlap - * DAY_OF_WEEK_IN_MONTH 5 and the end of 4. - * @see #DAY_OF_WEEK - * @see #WEEK_OF_MONTH - * @stable ICU 2.0 - */ - public final static int DAY_OF_WEEK_IN_MONTH = 8; - - /** - * Field number for get and set indicating - * whether the HOUR is before or after noon. - * E.g., at 10:04:15.250 PM the AM_PM is PM. - * @see #AM - * @see #PM - * @see #HOUR - * @stable ICU 2.0 - */ - public final static int AM_PM = 9; - - /** - * Field number for get and set indicating the - * hour of the morning or afternoon. HOUR is used for the 12-hour - * clock. - * E.g., at 10:04:15.250 PM the HOUR is 10. - * @see #AM_PM - * @see #HOUR_OF_DAY - * @stable ICU 2.0 - */ - public final static int HOUR = 10; - - /** - * Field number for get and set indicating the - * hour of the day. HOUR_OF_DAY is used for the 24-hour clock. - * E.g., at 10:04:15.250 PM the HOUR_OF_DAY is 22. - * @see #HOUR - * @stable ICU 2.0 - */ - public final static int HOUR_OF_DAY = 11; - - /** - * Field number for get and set indicating the - * minute within the hour. - * E.g., at 10:04:15.250 PM the MINUTE is 4. - * @stable ICU 2.0 - */ - public final static int MINUTE = 12; - - /** - * Field number for get and set indicating the - * second within the minute. - * E.g., at 10:04:15.250 PM the SECOND is 15. - * @stable ICU 2.0 - */ - public final static int SECOND = 13; - - /** - * Field number for get and set indicating the - * millisecond within the second. - * E.g., at 10:04:15.250 PM the MILLISECOND is 250. - * @stable ICU 2.0 - */ - public final static int MILLISECOND = 14; - - /** - * Field number for get and set indicating the - * raw offset from GMT in milliseconds. - * @stable ICU 2.0 - */ - public final static int ZONE_OFFSET = 15; - - /** - * Field number for get and set indicating the - * daylight savings offset in milliseconds. - * @stable ICU 2.0 - */ - public final static int DST_OFFSET = 16; - - /** - * {@icu} Field number for get() and set() - * indicating the extended year corresponding to the - * {@link #WEEK_OF_YEAR} field. This may be one greater or less - * than the value of {@link #EXTENDED_YEAR}. - * @stable ICU 2.0 - */ - public static final int YEAR_WOY = 17; - - /** - * {@icu} Field number for get() and set() - * indicating the localized day of week. This will be a value from 1 - * to 7 inclusive, with 1 being the localized first day of the week. - * @stable ICU 2.0 - */ - public static final int DOW_LOCAL = 18; - - /** - * {@icu} Field number for get() and set() - * indicating the extended year. This is a single number designating - * the year of this calendar system, encompassing all supra-year - * fields. For example, for the Julian calendar system, year numbers - * are positive, with an era of BCE or CE. An extended year value for - * the Julian calendar system assigns positive values to CE years and - * negative values to BCE years, with 1 BCE being year 0. - * @stable ICU 2.0 - */ - public static final int EXTENDED_YEAR = 19; - - /** - * {@icu} Field number for get() and set() - * indicating the modified Julian day number. This is different from - * the conventional Julian day number in two regards. First, it - * demarcates days at local zone midnight, rather than noon GMT. - * Second, it is a local number; that is, it depends on the local time - * zone. It can be thought of as a single number that encompasses all - * the date-related fields. - * @stable ICU 2.0 - */ - public static final int JULIAN_DAY = 20; - - /** - * {@icu} Field number for get() and set() - * indicating the milliseconds in the day. This ranges from 0 to - * 23:59:59.999 (regardless of DST). This field behaves - * exactly like a composite of all time-related fields, not - * including the zone fields. As such, it also reflects - * discontinuities of those fields on DST transition days. On a day of - * DST onset, it will jump forward. On a day of DST cessation, it will - * jump backward. This reflects the fact that is must be combined with - * the DST_OFFSET field to obtain a unique local time value. - * @stable ICU 2.0 - */ - public static final int MILLISECONDS_IN_DAY = 21; - - /** - * {@icu} Field indicating whether or not the current month is a leap month. - * Should have a value of 0 for non-leap months, and 1 for leap months. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int IS_LEAP_MONTH = 22; - - /** - * Value of the DAY_OF_WEEK field indicating - * Sunday. - * @stable ICU 2.0 - */ - public final static int SUNDAY = 1; - - /** - * Value of the DAY_OF_WEEK field indicating - * Monday. - * @stable ICU 2.0 - */ - public final static int MONDAY = 2; - - /** - * Value of the DAY_OF_WEEK field indicating - * Tuesday. - * @stable ICU 2.0 - */ - public final static int TUESDAY = 3; - - /** - * Value of the DAY_OF_WEEK field indicating - * Wednesday. - * @stable ICU 2.0 - */ - public final static int WEDNESDAY = 4; - - /** - * Value of the DAY_OF_WEEK field indicating - * Thursday. - * @stable ICU 2.0 - */ - public final static int THURSDAY = 5; - - /** - * Value of the DAY_OF_WEEK field indicating - * Friday. - * @stable ICU 2.0 - */ - public final static int FRIDAY = 6; - - /** - * Value of the DAY_OF_WEEK field indicating - * Saturday. - * @stable ICU 2.0 - */ - public final static int SATURDAY = 7; - - /** - * Value of the MONTH field indicating the - * first month of the year. - * @stable ICU 2.0 - */ - public final static int JANUARY = 0; - - /** - * Value of the MONTH field indicating the - * second month of the year. - * @stable ICU 2.0 - */ - public final static int FEBRUARY = 1; - - /** - * Value of the MONTH field indicating the - * third month of the year. - * @stable ICU 2.0 - */ - public final static int MARCH = 2; - - /** - * Value of the MONTH field indicating the - * fourth month of the year. - * @stable ICU 2.0 - */ - public final static int APRIL = 3; - - /** - * Value of the MONTH field indicating the - * fifth month of the year. - * @stable ICU 2.0 - */ - public final static int MAY = 4; - - /** - * Value of the MONTH field indicating the - * sixth month of the year. - * @stable ICU 2.0 - */ - public final static int JUNE = 5; - - /** - * Value of the MONTH field indicating the - * seventh month of the year. - * @stable ICU 2.0 - */ - public final static int JULY = 6; - - /** - * Value of the MONTH field indicating the - * eighth month of the year. - * @stable ICU 2.0 - */ - public final static int AUGUST = 7; - - /** - * Value of the MONTH field indicating the - * ninth month of the year. - * @stable ICU 2.0 - */ - public final static int SEPTEMBER = 8; - - /** - * Value of the MONTH field indicating the - * tenth month of the year. - * @stable ICU 2.0 - */ - public final static int OCTOBER = 9; - - /** - * Value of the MONTH field indicating the - * eleventh month of the year. - * @stable ICU 2.0 - */ - public final static int NOVEMBER = 10; - - /** - * Value of the MONTH field indicating the - * twelfth month of the year. - * @stable ICU 2.0 - */ - public final static int DECEMBER = 11; - - /** - * Value of the MONTH field indicating the - * thirteenth month of the year. Although {@link GregorianCalendar} - * does not use this value, lunar calendars do. - * @stable ICU 2.0 - */ - public final static int UNDECIMBER = 12; - - /** - * Value of the AM_PM field indicating the - * period of the day from midnight to just before noon. - * @stable ICU 2.0 - */ - public final static int AM = 0; - - /** - * Value of the AM_PM field indicating the - * period of the day from noon to just before midnight. - * @stable ICU 2.0 - */ - public final static int PM = 1; - - /** - * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a - * weekday. - * @see #WEEKEND - * @see #WEEKEND_ONSET - * @see #WEEKEND_CEASE - * @see #getDayOfWeekType - * @stable ICU 2.0 - */ - public static final int WEEKDAY = 0; - - /** - * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a - * weekend day. - * @see #WEEKDAY - * @see #WEEKEND_ONSET - * @see #WEEKEND_CEASE - * @see #getDayOfWeekType - * @stable ICU 2.0 - */ - public static final int WEEKEND = 1; - - /** - * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a - * day that starts as a weekday and transitions to the weekend. - * Call getWeekendTransition() to get the point of transition. - * @see #WEEKDAY - * @see #WEEKEND - * @see #WEEKEND_CEASE - * @see #getDayOfWeekType - * @stable ICU 2.0 - */ - public static final int WEEKEND_ONSET = 2; - - /** - * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a - * day that starts as the weekend and transitions to a weekday. - * Call getWeekendTransition() to get the point of transition. - * @see #WEEKDAY - * @see #WEEKEND - * @see #WEEKEND_ONSET - * @see #getDayOfWeekType - * @stable ICU 2.0 - */ - public static final int WEEKEND_CEASE = 3; - - /** - * Constructs a Calendar with the default time zone - * and locale. - * @see TimeZone#getDefault - * @stable ICU 2.0 - */ - protected Calendar() - { - this(TimeZone.getDefault(), ULocale.getDefault()); - } - - /** - * Constructs a calendar with the specified time zone and locale. - * @param zone the time zone to use - * @param aLocale the locale for the week data - * @stable ICU 2.0 - */ - protected Calendar(TimeZone zone, Locale aLocale) - { - this(zone, ULocale.forLocale(aLocale)); - } - - /** - * Constructs a calendar with the specified time zone and locale. - * @param zone the time zone to use - * @param locale the ulocale for the week data - * @stable ICU 3.2 - */ - protected Calendar(TimeZone zone, ULocale locale) - { - calendar = java.util.Calendar.getInstance(zone.timeZone, locale.toLocale()); - } - - /** - * Returns a calendar using the default time zone and locale. - * @return a Calendar. - * @stable ICU 2.0 - */ - public static synchronized Calendar getInstance() - { - return new Calendar(java.util.Calendar.getInstance()); - } - - /** - * Returns a calendar using the specified time zone and default locale. - * @param zone the time zone to use - * @return a Calendar. - * @stable ICU 2.0 - */ - public static synchronized Calendar getInstance(TimeZone zone) - { - return new Calendar(java.util.Calendar.getInstance(zone.timeZone)); - } - - /** - * Returns a calendar using the default time zone and specified locale. - * @param aLocale the locale for the week data - * @return a Calendar. - * @stable ICU 2.0 - */ - public static synchronized Calendar getInstance(Locale aLocale) - { - return new Calendar(java.util.Calendar.getInstance(aLocale)); - } - - /** - * Returns a calendar using the default time zone and specified locale. - * @param locale the ulocale for the week data - * @return a Calendar. - * @stable ICU 3.2 - */ - public static synchronized Calendar getInstance(ULocale locale) - { - return new Calendar(java.util.Calendar.getInstance(locale.toLocale())); - } - - /** - * Returns a calendar with the specified time zone and locale. - * @param zone the time zone to use - * @param aLocale the locale for the week data - * @return a Calendar. - * @stable ICU 2.0 - */ - public static synchronized Calendar getInstance(TimeZone zone, - Locale aLocale) { - return new Calendar(java.util.Calendar.getInstance(zone.timeZone, aLocale)); - } - - /** - * Returns a calendar with the specified time zone and locale. - * @param zone the time zone to use - * @param locale the ulocale for the week data - * @return a Calendar. - * @stable ICU 3.2 - */ - public static synchronized Calendar getInstance(TimeZone zone, - ULocale locale) { - return new Calendar(java.util.Calendar.getInstance(zone.timeZone, locale.toLocale())); - } - - /** - * Returns the list of locales for which Calendars are installed. - * @return the list of locales for which Calendars are installed. - * @stable ICU 2.0 - */ - public static Locale[] getAvailableLocales() - { - return java.util.Calendar.getAvailableLocales(); - } - - /** - * {@icu} Returns the list of locales for which Calendars are installed. - * @return the list of locales for which Calendars are installed. - * @draft ICU 3.2 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static ULocale[] getAvailableULocales() - { - if (availableLocales == null) { - synchronized (Calendar.class) { - if (availableLocales == null) { - Locale[] locales = Locale.getAvailableLocales(); - availableLocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; i++) { - availableLocales[i] = ULocale.forLocale(locales[i]); - } - } - } - } - return availableLocales.clone(); - } - private static volatile ULocale[] availableLocales; - - /** - * {@icu} Given a key and a locale, returns an array of string values in a preferred - * order that would make a difference. These are all and only those values where - * the open (creation) of the service with the locale formed from the input locale - * plus input keyword and that value has different behavior than creation with the - * input locale alone. - * @param key one of the keys supported by this service. For now, only - * "calendar" is supported. - * @param locale the locale - * @param commonlyUsed if set to true it will return only commonly used values - * with the given locale in preferred order. Otherwise, - * it will return all the available values for the locale. - * @return an array of string values for the given key and the locale. - * @stable ICU 4.2 - */ - public static final String[] getKeywordValuesForLocale(String key, ULocale locale, - boolean commonlyUsed) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns this Calendar's current time. - * @return the current time. - * @stable ICU 2.0 - */ - public final Date getTime() { - return calendar.getTime(); - } - - /** - * Sets this Calendar's current time with the given Date. - * - *

      Note: Calling setTime with - * Date(Long.MAX_VALUE) or Date(Long.MIN_VALUE) - * may yield incorrect field values from {@link #get(int)}. - * @param date the given Date. - * @stable ICU 2.0 - */ - public final void setTime(Date date) { - calendar.setTime(date); - } - - /** - * Returns this Calendar's current time as a long. - * @return the current time as UTC milliseconds from the epoch. - * @stable ICU 2.0 - */ - public long getTimeInMillis() { - return calendar.getTimeInMillis(); - } - - /** - * Sets this Calendar's current time from the given long value. - * @param millis the new time in UTC milliseconds from the epoch. - * @stable ICU 2.0 - */ - public void setTimeInMillis( long millis ) { - calendar.setTimeInMillis(millis); - } - - /** - * Returns the value for a given time field. - * @param field the given time field. - * @return the value for the given time field. - * @stable ICU 2.0 - */ - public final int get(int field) - { - return calendar.get(getJDKField(field)); - } - - /** - * Sets the time field with the given value. - * @param field the given time field. - * @param value the value to be set for the given time field. - * @stable ICU 2.0 - */ - public final void set(int field, int value) - { - calendar.set(getJDKField(field), value); - } - - /** - * Sets the values for the fields year, month, and date. - * Previous values of other fields are retained. If this is not desired, - * call {@link #clear()} first. - * @param year the value used to set the YEAR time field. - * @param month the value used to set the MONTH time field. - * Month value is 0-based. e.g., 0 for January. - * @param date the value used to set the DATE time field. - * @stable ICU 2.0 - */ - public final void set(int year, int month, int date) - { - calendar.set(getJDKField(YEAR), year); - calendar.set(getJDKField(MONTH), month); - calendar.set(getJDKField(DATE), date); - } - - /** - * Sets the values for the fields year, month, date, hour, and minute. - * Previous values of other fields are retained. If this is not desired, - * call {@link #clear()} first. - * @param year the value used to set the YEAR time field. - * @param month the value used to set the MONTH time field. - * Month value is 0-based. e.g., 0 for January. - * @param date the value used to set the DATE time field. - * @param hour the value used to set the HOUR_OF_DAY time field. - * @param minute the value used to set the MINUTE time field. - * @stable ICU 2.0 - */ - public final void set(int year, int month, int date, int hour, int minute) - { - calendar.set(getJDKField(YEAR), year); - calendar.set(getJDKField(MONTH), month); - calendar.set(getJDKField(DATE), date); - calendar.set(getJDKField(HOUR_OF_DAY), hour); - calendar.set(getJDKField(MINUTE), minute); - } - - /** - * Sets the values for the fields year, month, date, hour, minute, and second. - * Previous values of other fields are retained. If this is not desired, - * call {@link #clear} first. - * @param year the value used to set the YEAR time field. - * @param month the value used to set the MONTH time field. - * Month value is 0-based. e.g., 0 for January. - * @param date the value used to set the DATE time field. - * @param hour the value used to set the HOUR_OF_DAY time field. - * @param minute the value used to set the MINUTE time field. - * @param second the value used to set the SECOND time field. - * @stable ICU 2.0 - */ - public final void set(int year, int month, int date, int hour, int minute, - int second) - { - calendar.set(getJDKField(YEAR), year); - calendar.set(getJDKField(MONTH), month); - calendar.set(getJDKField(DATE), date); - calendar.set(getJDKField(HOUR_OF_DAY), hour); - calendar.set(getJDKField(MINUTE), minute); - calendar.set(getJDKField(SECOND), second); - } - - /** - * Clears the values of all the time fields. - * @stable ICU 2.0 - */ - public final void clear() - { - calendar.clear(); - } - - /** - * Clears the value in the given time field. - * @param field the time field to be cleared. - * @stable ICU 2.0 - */ - public final void clear(int field) - { - calendar.clear(getJDKField(field)); - } - - /** - * Determines if the given time field has a value set. - * @return true if the given time field has a value set; false otherwise. - * @stable ICU 2.0 - */ - public final boolean isSet(int field) - { - return calendar.isSet(getJDKField(field)); - } - - /** - * Compares this calendar to the specified object. - * The result is true if and only if the argument is - * not null and is a Calendar object that - * represents the same calendar as this object. - * @param obj the object to compare with. - * @return true if the objects are the same; - * false otherwise. - * @stable ICU 2.0 - */ - public boolean equals(Object obj) { - try { - return calendar.equals(((Calendar)obj).calendar); - } catch (Exception e) { - return false; - } - } - - /** - * {@icu} Returns true if the given Calendar object is equivalent to this - * one. An equivalent Calendar will behave exactly as this one - * does, but it may be set to a different time. By contrast, for - * the equals() method to return true, the other Calendar must - * be set to the same time. - * - * @param other the Calendar to be compared with this Calendar - * @stable ICU 2.4 - */ - public boolean isEquivalentTo(Calendar other) { - return calendar.getClass() == other.calendar.getClass() && - calendar.isLenient() == other.calendar.isLenient() && - calendar.getFirstDayOfWeek() == other.calendar.getFirstDayOfWeek() && - calendar.getMinimalDaysInFirstWeek() == other.calendar.getMinimalDaysInFirstWeek() && - calendar.getTimeZone().equals(other.calendar.getTimeZone()); - } - - /** - * Returns a hash code for this calendar. - * @return a hash code value for this object. - * @stable ICU 2.0 - */ - public int hashCode() { - return calendar.hashCode(); - } - - /** - * Returns the difference in milliseconds between the moment this - * calendar is set to and the moment the given calendar or Date object - * is set to. - */ - private long compare(Object that) { - long thatMs; - if (that instanceof Calendar) { - thatMs = ((Calendar)that).getTimeInMillis(); - } else if (that instanceof Date) { - thatMs = ((Date)that).getTime(); - } else { - throw new IllegalArgumentException(that + "is not a Calendar or Date"); - } - return getTimeInMillis() - thatMs; - } - - /** - * Compares the time field records. - * Equivalent to comparing result of conversion to UTC. - * @param when the Calendar to be compared with this Calendar. - * @return true if the current time of this Calendar is before - * the time of Calendar when; false otherwise. - * @stable ICU 2.0 - */ - public boolean before(Object when) { - return compare(when) < 0; - } - - /** - * Compares the time field records. - * Equivalent to comparing result of conversion to UTC. - * @param when the Calendar to be compared with this Calendar. - * @return true if the current time of this Calendar is after - * the time of Calendar when; false otherwise. - * @stable ICU 2.0 - */ - public boolean after(Object when) { - return compare(when) > 0; - } - - /** - * Returns the maximum value that this field could have, given the - * current date. For example, with the Gregorian date February 3, 1997 - * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum - * is 28; for February 3, 1996 it is 29. - * - *

      The actual maximum computation ignores smaller fields and the - * current value of like-sized fields. For example, the actual maximum - * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year - * fields. The actual maximum of the DAY_OF_MONTH depends, in - * addition, on the MONTH field and any other fields at that - * granularity (such as IS_LEAP_MONTH). The - * DAY_OF_WEEK_IN_MONTH field does not depend on the current - * DAY_OF_WEEK; it returns the maximum for any day of week in the - * current month. Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR - * fields. - * - * @param field the field whose maximum is desired - * @return the maximum of the given field for the current date of this calendar - * @see #getMaximum - * @see #getLeastMaximum - * @stable ICU 2.0 - */ - public int getActualMaximum(int field) { - return calendar.getActualMaximum(getJDKField(field)); - } - - /** - * Returns the minimum value that this field could have, given the current date. - * For most fields, this is the same as {@link #getMinimum getMinimum} - * and {@link #getGreatestMinimum getGreatestMinimum}. However, some fields, - * especially those related to week number, are more complicated. - *

      - * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} - * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY. - * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday - * there will be four or more days in the first week, so it will be week number 1, - * and getActualMinimum(WEEK_OF_MONTH) will return 1. However, - * if the first of the month is a Thursday, Friday, or Saturday, there are - * not four days in that week, so it is week number 0, and - * getActualMinimum(WEEK_OF_MONTH) will return 0. - *

      - * @param field the field whose actual minimum value is desired. - * @return the minimum of the given field for the current date of this calendar - * - * @see #getMinimum - * @see #getGreatestMinimum - * @stable ICU 2.0 - */ - public int getActualMinimum(int field) { - return calendar.getActualMinimum(getJDKField(field)); - } - - /** - * Rolls (up/down) a single unit of time on the given field. If the - * field is rolled past its maximum allowable value, it will "wrap" back - * to its minimum and continue rolling. For - * example, to roll the current date up by one day, you can call: - *

      - * roll({@link #DATE}, true) - *

      - * When rolling on the {@link #YEAR} field, it will roll the year - * value in the range between 1 and the value returned by calling - * {@link #getMaximum getMaximum}({@link #YEAR}). - *

      - * When rolling on certain fields, the values of other fields may conflict and - * need to be changed. For example, when rolling the MONTH field - * for the Gregorian date 1/31/96 upward, the DAY_OF_MONTH field - * must be adjusted so that the result is 2/29/96 rather than the invalid - * 2/31/96. - *

      - * Note: Calling roll(field, true) N times is not - * necessarily equivalent to calling roll(field, N). For example, - * imagine that you start with the date Gregorian date January 31, 1995. If you call - * roll(Calendar.MONTH, 2), the result will be March 31, 1995. - * But if you call roll(Calendar.MONTH, true), the result will be - * February 28, 1995. Calling it one more time will give March 28, 1995, which - * is usually not the desired result. - *

      - * Note: You should always use roll and add rather - * than attempting to perform arithmetic operations directly on the fields - * of a Calendar. It is quite possible for Calendar subclasses - * to have fields with non-linear behavior, for example missing months - * or days during non-leap years. The subclasses' add and roll - * methods will take this into account, while simple arithmetic manipulations - * may give invalid results. - *

      - * @param field the calendar field to roll. - * - * @param up indicates if the value of the specified time field is to be - * rolled up or rolled down. Use true if rolling up, - * false otherwise. - * - * @exception IllegalArgumentException if the field is invalid or refers - * to a field that cannot be handled by this method. - * @see #roll(int, int) - * @see #add - * @stable ICU 2.0 - */ - public final void roll(int field, boolean up) - { - calendar.roll(getJDKField(field), up); - } - - /** - * Rolls (up/down) a specified amount time on the given field. For - * example, to roll the current date up by three days, you can call - * roll(Calendar.DATE, 3). If the - * field is rolled past its maximum allowable value, it will "wrap" back - * to its minimum and continue rolling. - * For example, calling roll(Calendar.DATE, 10) - * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96. - *

      - * When rolling on certain fields, the values of other fields may conflict and - * need to be changed. For example, when rolling the {@link #MONTH MONTH} field - * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field - * must be adjusted so that the result is 2/29/96 rather than the invalid - * 2/31/96. - *

      - * {@icunote} the ICU implementation of this method is able to roll - * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, - * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for - * additional fields in their overrides of roll. - *

      - * Note: You should always use roll and add rather - * than attempting to perform arithmetic operations directly on the fields - * of a Calendar. It is quite possible for Calendar subclasses - * to have fields with non-linear behavior, for example missing months - * or days during non-leap years. The subclasses' add and roll - * methods will take this into account, while simple arithmetic manipulations - * may give invalid results. - *

      - * Subclassing:
      - * This implementation of roll assumes that the behavior of the - * field is continuous between its minimum and maximum, which are found by - * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}. - * For most such fields, simple addition, subtraction, and modulus operations - * are sufficient to perform the roll. For week-related fields, - * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and - * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary. - * Subclasses can override these two methods if their values differ from the defaults. - *

      - * Subclasses that have fields for which the assumption of continuity breaks - * down must overide roll to handle those fields specially. - * For example, in the Hebrew calendar the month "Adar I" - * only occurs in leap years; in other years the calendar jumps from - * Shevat (month #4) to Adar (month #6). The - * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account, - * so that rolling the month of Shevat by one gives the proper result (Adar) in a - * non-leap year. - *

      - * @param field the calendar field to roll. - * @param amount the amount by which the field should be rolled. - * - * @exception IllegalArgumentException if the field is invalid or refers - * to a field that cannot be handled by this method. - * @see #roll(int, boolean) - * @see #add - * @stable ICU 2.0 - */ - public void roll(int field, int amount) { - calendar.roll(getJDKField(field), amount); - } - - /** - * Add a signed amount to a specified field, using this calendar's rules. - * For example, to add three days to the current date, you can call - * add(Calendar.DATE, 3). - *

      - * When adding to certain fields, the values of other fields may conflict and - * need to be changed. For example, when adding one to the {@link #MONTH MONTH} field - * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field - * must be adjusted so that the result is 2/29/96 rather than the invalid - * 2/31/96. - *

      - * {@icunote} The ICU implementation of this method is able to add to - * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, - * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for - * additional fields in their overrides of add. - *

      - * Note: You should always use roll and add rather - * than attempting to perform arithmetic operations directly on the fields - * of a Calendar. It is quite possible for Calendar subclasses - * to have fields with non-linear behavior, for example missing months - * or days during non-leap years. The subclasses' add and roll - * methods will take this into account, while simple arithmetic manipulations - * may give invalid results. - *

      - * Subclassing:
      - * This implementation of add assumes that the behavior of the - * field is continuous between its minimum and maximum, which are found by - * calling {@link #getActualMinimum getActualMinimum} and - * {@link #getActualMaximum getActualMaximum}. - * For such fields, simple arithmetic operations are sufficient to - * perform the add. - *

      - * Subclasses that have fields for which this assumption of continuity breaks - * down must overide add to handle those fields specially. - * For example, in the Hebrew calendar the month "Adar I" - * only occurs in leap years; in other years the calendar jumps from - * Shevat (month #4) to Adar (month #6). The - * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account, - * so that adding one month - * to a date in Shevat gives the proper result (Adar) in a non-leap year. - *

      - * @param field the time field. - * @param amount the amount to add to the field. - * - * @exception IllegalArgumentException if the field is invalid or refers - * to a field that cannot be handled by this method. - * @see #roll(int, int) - * @stable ICU 2.0 - */ - public void add(int field, int amount) { - calendar.add(getJDKField(field), amount); - } - - private static String _getDisplayName(Calendar cal) { - String type = cal.getType(); - if (type.equals("japanese")) { - return "Japanese Calendar"; - } else if (type.equals("buddhist")) { - return "Buddhist Calendar"; - } - return "Gregorian Calendar"; - } - - /** - * Returns the name of this calendar in the language of the given locale. - * @stable ICU 2.0 - */ - public String getDisplayName(Locale loc) { - return _getDisplayName(this); - } - - /** - * Returns the name of this calendar in the language of the given locale. - * @stable ICU 3.2 - */ - public String getDisplayName(ULocale loc) { - return _getDisplayName(this); - } - - /** - * Compares the times (in millis) represented by two - * Calendar objects. - * - * @param that the Calendar to compare to this. - * @return 0 if the time represented by - * this Calendar is equal to the time represented - * by that Calendar, a value less than - * 0 if the time represented by this is before - * the time represented by that, and a value greater than - * 0 if the time represented by this - * is after the time represented by that. - * @throws NullPointerException if that - * Calendar is null. - * @throws IllegalArgumentException if the time of that - * Calendar can't be obtained because of invalid - * calendar values. - * @stable ICU 3.4 - */ - public int compareTo(Calendar that) { - return calendar.compareTo(that.calendar); - } - - //------------------------------------------------------------------------- - // Interface for creating custon DateFormats for different types of Calendars - //------------------------------------------------------------------------- - - /** - * {@icu} Returns a DateFormat appropriate to this calendar. - * Subclasses wishing to specialize this behavior should override - * {@link #handleGetDateFormat}. - * @stable ICU 2.0 - */ - public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) { - if (dateStyle != DateFormat.NONE) { - if (timeStyle == DateFormat.NONE) { - return DateFormat.getDateInstance((Calendar)this.clone(), dateStyle, loc); - } else { - return DateFormat.getDateTimeInstance((Calendar)this.clone(), dateStyle, timeStyle, loc); - } - } else if (timeStyle != DateFormat.NONE) { - return DateFormat.getTimeInstance((Calendar)this.clone(), timeStyle, loc); - } else { - return null; - } - } - - /** - * {@icu} Returns a DateFormat appropriate to this calendar. - * Subclasses wishing to specialize this behavior should override - * {@link #handleGetDateFormat}. - * @stable ICU 3.2 - */ - public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) { - return getDateTimeFormat(dateStyle, timeStyle, loc.toLocale()); - } - - //------------------------------------------------------------------------- - // Constants - //------------------------------------------------------------------------- - - /** - * {@icu} Returns the difference between the given time and the time this - * calendar object is set to. If this calendar is set - * before the given time, the returned value will be - * positive. If this calendar is set after the given - * time, the returned value will be negative. The - * field parameter specifies the units of the return - * value. For example, if fieldDifference(when, - * Calendar.MONTH) returns 3, then this calendar is set to - * 3 months before when, and possibly some additional - * time less than one month. - * - *

      As a side effect of this call, this calendar is advanced - * toward when by the given amount. That is, calling - * this method has the side effect of calling add(field, - * n), where n is the return value. - * - *

      Usage: To use this method, call it first with the largest - * field of interest, then with progressively smaller fields. For - * example: - * - *

      -     * int y = cal.fieldDifference(when, Calendar.YEAR);
      -     * int m = cal.fieldDifference(when, Calendar.MONTH);
      -     * int d = cal.fieldDifference(when, Calendar.DATE);
      - * - * computes the difference between cal and - * when in years, months, and days. - * - *

      Note: fieldDifference() is - * asymmetrical. That is, in the following code: - * - *

      -     * cal.setTime(date1);
      -     * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
      -     * int d1 = cal.fieldDifference(date2, Calendar.DATE);
      -     * cal.setTime(date2);
      -     * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
      -     * int d2 = cal.fieldDifference(date1, Calendar.DATE);
      - * - * one might expect that m1 == -m2 && d1 == -d2. - * However, this is not generally the case, because of - * irregularities in the underlying calendar system (e.g., the - * Gregorian calendar has a varying number of days per month). - * - * @param when the date to compare this calendar's time to - * @param field the field in which to compute the result - * @return the difference, either positive or negative, between - * this calendar's time and when, in terms of - * field. - * @stable ICU 2.0 - */ - public int fieldDifference(Date when, int field) { - int min = 0; - long startMs = getTimeInMillis(); - long targetMs = when.getTime(); - // Always add from the start millis. This accomodates - // operations like adding years from February 29, 2000 up to - // February 29, 2004. If 1, 1, 1, 1 is added to the year - // field, the DOM gets pinned to 28 and stays there, giving an - // incorrect DOM difference of 1. We have to add 1, reset, 2, - // reset, 3, reset, 4. - if (startMs < targetMs) { - int max = 1; - // Find a value that is too large - for (;;) { - setTimeInMillis(startMs); - add(field, max); - long ms = getTimeInMillis(); - if (ms == targetMs) { - return max; - } else if (ms > targetMs) { - break; - } else { - max <<= 1; - if (max < 0) { - // Field difference too large to fit into int - throw new RuntimeException(); - } - } - } - // Do a binary search - while ((max - min) > 1) { - int t = (min + max) / 2; - setTimeInMillis(startMs); - add(field, t); - long ms = getTimeInMillis(); - if (ms == targetMs) { - return t; - } else if (ms > targetMs) { - max = t; - } else { - min = t; - } - } - } else if (startMs > targetMs) { - //Eclipse stated the following is "dead code" - /*if (false) { - // This works, and makes the code smaller, but costs - // an extra object creation and an extra couple cycles - // of calendar computation. - setTimeInMillis(targetMs); - min = -fieldDifference(new Date(startMs), field); - }*/ - int max = -1; - // Find a value that is too small - for (;;) { - setTimeInMillis(startMs); - add(field, max); - long ms = getTimeInMillis(); - if (ms == targetMs) { - return max; - } else if (ms < targetMs) { - break; - } else { - max <<= 1; - if (max == 0) { - // Field difference too large to fit into int - throw new RuntimeException(); - } - } - } - // Do a binary search - while ((min - max) > 1) { - int t = (min + max) / 2; - setTimeInMillis(startMs); - add(field, t); - long ms = getTimeInMillis(); - if (ms == targetMs) { - return t; - } else if (ms < targetMs) { - max = t; - } else { - min = t; - } - } - } - // Set calendar to end point - setTimeInMillis(startMs); - add(field, min); - return min; - } - - /** - * Sets the time zone with the given time zone value. - * @param value the given time zone. - * @stable ICU 2.0 - */ - public void setTimeZone(TimeZone value) - { - calendar.setTimeZone(value.timeZone); - } - - /** - * Returns the time zone. - * @return the time zone object associated with this calendar. - * @stable ICU 2.0 - */ - public TimeZone getTimeZone() - { - return new TimeZone(calendar.getTimeZone()); - } - - /** - * Specify whether or not date/time interpretation is to be lenient. With - * lenient interpretation, a date such as "February 942, 1996" will be - * treated as being equivalent to the 941st day after February 1, 1996. - * With strict interpretation, such dates will cause an exception to be - * thrown. - * - * @see DateFormat#setLenient - * @stable ICU 2.0 - */ - public void setLenient(boolean lenient) - { - calendar.setLenient(lenient); - } - - /** - * Tell whether date/time interpretation is to be lenient. - * @stable ICU 2.0 - */ - public boolean isLenient() - { - return calendar.isLenient(); - } - - /** - * Sets what the first day of the week is; e.g., Sunday in US, - * Monday in France. - * @param value the given first day of the week. - * @stable ICU 2.0 - */ - public void setFirstDayOfWeek(int value) - { - calendar.setFirstDayOfWeek(value); - } - - /** - * Returns what the first day of the week is; e.g., Sunday in US, - * Monday in France. - * @return the first day of the week. - * @stable ICU 2.0 - */ - public int getFirstDayOfWeek() - { - return calendar.getFirstDayOfWeek(); - } - - /** - * Sets what the minimal days required in the first week of the year are. - * For example, if the first week is defined as one that contains the first - * day of the first month of a year, call the method with value 1. If it - * must be a full week, use value 7. - * @param value the given minimal days required in the first week - * of the year. - * @stable ICU 2.0 - */ - public void setMinimalDaysInFirstWeek(int value) - { - calendar.setMinimalDaysInFirstWeek(value); - } - - /** - * Returns what the minimal days required in the first week of the year are; - * e.g., if the first week is defined as one that contains the first day - * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If - * the minimal days required must be a full week, getMinimalDaysInFirstWeek - * returns 7. - * @return the minimal days required in the first week of the year. - * @stable ICU 2.0 - */ - public int getMinimalDaysInFirstWeek() - { - return calendar.getMinimalDaysInFirstWeek(); - } - - /** - * Returns the minimum value for the given time field. - * e.g., for Gregorian DAY_OF_MONTH, 1. - * @param field the given time field. - * @return the minimum value for the given time field. - * @stable ICU 2.0 - */ - public final int getMinimum(int field) { - return calendar.getMinimum(getJDKField(field)); - } - - /** - * Returns the maximum value for the given time field. - * e.g. for Gregorian DAY_OF_MONTH, 31. - * @param field the given time field. - * @return the maximum value for the given time field. - * @stable ICU 2.0 - */ - public final int getMaximum(int field) { - return calendar.getMaximum(getJDKField(field)); - } - - /** - * Returns the highest minimum value for the given field if varies. - * Otherwise same as getMinimum(). For Gregorian, no difference. - * @param field the given time field. - * @return the highest minimum value for the given time field. - * @stable ICU 2.0 - */ - public final int getGreatestMinimum(int field) { - return calendar.getGreatestMinimum(getJDKField(field)); - } - - /** - * Returns the lowest maximum value for the given field if varies. - * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28. - * @param field the given time field. - * @return the lowest maximum value for the given time field. - * @stable ICU 2.0 - */ - public final int getLeastMaximum(int field) { - return calendar.getLeastMaximum(getJDKField(field)); - } - - //------------------------------------------------------------------------- - // Weekend support -- determining which days of the week are the weekend - // in a given locale - //------------------------------------------------------------------------- - - /** - * {@icu} Returns whether the given day of the week is a weekday, a - * weekend day, or a day that transitions from one to the other, - * in this calendar system. If a transition occurs at midnight, - * then the days before and after the transition will have the - * type WEEKDAY or WEEKEND. If a transition occurs at a time - * other than midnight, then the day of the transition will have - * the type WEEKEND_ONSET or WEEKEND_CEASE. In this case, the - * method getWeekendTransition() will return the point of - * transition. - * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, - * THURSDAY, FRIDAY, or SATURDAY - * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or - * WEEKEND_CEASE - * @exception IllegalArgumentException if dayOfWeek is not - * between SUNDAY and SATURDAY, inclusive - * @see #WEEKDAY - * @see #WEEKEND - * @see #WEEKEND_ONSET - * @see #WEEKEND_CEASE - * @see #getWeekendTransition - * @see #isWeekend(Date) - * @see #isWeekend() - * @stable ICU 2.0 - */ - public int getDayOfWeekType(int dayOfWeek) { - // weekend always full saturday and sunday with com.ibm.icu.base - if (dayOfWeek < SUNDAY || dayOfWeek > 7) { - throw new IllegalArgumentException("illegal day of week: " + dayOfWeek); - } else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY) { - return WEEKEND; - } - return WEEKDAY;} - - /** - * {@icu} Returns the time during the day at which the weekend begins or end in this - * calendar system. If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time - * at which the weekend begins. If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE - * return the time at which the weekend ends. If getDayOfWeekType(dayOfWeek) has some - * other value, then throw an exception. - * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, - * THURSDAY, FRIDAY, or SATURDAY - * @return the milliseconds after midnight at which the - * weekend begins or ends - * @exception IllegalArgumentException if dayOfWeek is not - * WEEKEND_ONSET or WEEKEND_CEASE - * @see #getDayOfWeekType - * @see #isWeekend(Date) - * @see #isWeekend() - * @stable ICU 2.0 - */ - public int getWeekendTransition(int dayOfWeek) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns true if the given date and time is in the weekend in this calendar - * system. Equivalent to calling setTime() followed by isWeekend(). Note: This - * method changes the time this calendar is set to. - * @param date the date and time - * @return true if the given date and time is part of the - * weekend - * @see #getDayOfWeekType - * @see #getWeekendTransition - * @see #isWeekend() - * @stable ICU 2.0 - */ - public boolean isWeekend(Date date) { - calendar.setTime(date); - return isWeekend(); - } - - /** - * {@icu} Returns true if this Calendar's current date and time is in the weekend in - * this calendar system. - * @return true if the given date and time is part of the - * weekend - * @see #getDayOfWeekType - * @see #getWeekendTransition - * @see #isWeekend(Date) - * @stable ICU 2.0 - */ - public boolean isWeekend() { - // weekend always full saturday and sunday with com.ibm.icu.base - int dow = calendar.get(Calendar.DAY_OF_WEEK); - if (dow == SATURDAY || dow == SUNDAY) { - return true; - } - return false; - } - - //------------------------------------------------------------------------- - // End of weekend support - //------------------------------------------------------------------------- - - /** - * Overrides Cloneable - * @stable ICU 2.0 - */ - public Object clone() - { - return new Calendar((java.util.Calendar)calendar.clone()); - } - - /** - * Returns a string representation of this calendar. This method - * is intended to be used only for debugging purposes, and the - * format of the returned string may vary between implementations. - * The returned string may be empty but may not be null. - * - * @return a string representation of this calendar. - * @stable ICU 2.0 - */ - public String toString() { - return calendar.toString(); - } - - /** - * {@icu} Returns the number of fields defined by this calendar. Valid field - * arguments to set() and get() are - * 0..getFieldCount()-1. - * @stable ICU 2.0 - */ - public final int getFieldCount() { - return FIELD_COUNT; - } - private static final int FIELD_COUNT = IS_LEAP_MONTH + 1; - - /** - * {@icu} Returns the current Calendar type. Note, in 3.0 this function will return - * 'gregorian' in Calendar to emulate legacy behavior - * @return type of calendar (gregorian, etc) - * @stable ICU 3.8 - */ - public String getType() { - // JDK supports Gregorian, Japanese and Buddhist - String name = calendar.getClass().getSimpleName().toLowerCase(Locale.US); - if (name.contains("japanese")) { - return "japanese"; - } else if (name.contains("buddhist")) { - return "buddhist"; - } - return "gregorian"; - } - - // -------- BEGIN ULocale boilerplate -------- - - /** - * {@icu} Returns the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 - * contains a partial preview implementation. The * actual - * locale is returned correctly, but the valid locale is - * not, in most cases. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - // -------- END ULocale boilerplate -------- - - - private static int getJDKField(int icuField) { - switch (icuField) { - case ERA: - return java.util.Calendar.ERA; - case YEAR: - return java.util.Calendar.YEAR; - case MONTH: - return java.util.Calendar.MONTH; - case WEEK_OF_YEAR: - return java.util.Calendar.WEEK_OF_YEAR; - case WEEK_OF_MONTH: - return java.util.Calendar.WEEK_OF_MONTH; - case DATE: - return java.util.Calendar.DATE; -// case DAY_OF_MONTH: -// return java.util.Calendar.DAY_OF_MONTH; - case DAY_OF_YEAR: - return java.util.Calendar.DAY_OF_YEAR; - case DAY_OF_WEEK: - return java.util.Calendar.DAY_OF_WEEK; - case DAY_OF_WEEK_IN_MONTH: - return java.util.Calendar.DAY_OF_WEEK_IN_MONTH; - case AM_PM: - return java.util.Calendar.AM_PM; - case HOUR: - return java.util.Calendar.HOUR; - case HOUR_OF_DAY: - return java.util.Calendar.HOUR_OF_DAY; - case MINUTE: - return java.util.Calendar.MINUTE; - case SECOND: - return java.util.Calendar.SECOND; - case MILLISECOND: - return java.util.Calendar.MILLISECOND; - case ZONE_OFFSET: - return java.util.Calendar.ZONE_OFFSET; - case DST_OFFSET: - return java.util.Calendar.DST_OFFSET; - - case YEAR_WOY: - case DOW_LOCAL: - case EXTENDED_YEAR: - case JULIAN_DAY: - case MILLISECONDS_IN_DAY: - // Unmappable - throw new UnsupportedOperationException("Calendar field type not supported by com.ibm.icu.base"); - default: - // Illegal - throw new ArrayIndexOutOfBoundsException("Specified calendar field is out of range"); - } - } -} +/* +* Copyright (C) 1996-2011, International Business Machines +* Corporation and others. All Rights Reserved. +*/ + +package com.ibm.icu.util; + +import java.io.Serializable; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; + +import com.ibm.icu.text.DateFormat; + +/** + * {@icuenhanced java.util.Calendar}.{@icu _usage_} + * + *

      Calendar is an abstract base class for converting between + * a Date object and a set of integer fields such as + * YEAR, MONTH, DAY, HOUR, + * and so on. (A Date object represents a specific instant in + * time with millisecond precision. See + * {@link Date} + * for information about the Date class.) + * + *

      Subclasses of Calendar interpret a Date + * according to the rules of a specific calendar system. ICU4J contains + * several subclasses implementing different international calendar systems. + * + *

      + * Like other locale-sensitive classes, Calendar provides a + * class method, getInstance, for getting a generally useful + * object of this type. Calendar's getInstance method + * returns a calendar of a type appropriate to the locale, whose + * time fields have been initialized with the current date and time: + *

      + *
      Calendar rightNow = Calendar.getInstance()
      + *
      + * + *

      When a ULocale is used by getInstance, its + * 'calendar' tag and value are retrieved if present. If a recognized + * value is supplied, a calendar is provided and configured as appropriate. + * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic", + * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc". For + * example:

      + *
      Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));
      + *
      will return an instance of JapaneseCalendar (using en_US conventions for + * minimum days in first week, start day of week, et cetera). + * + *

      A Calendar object can produce all the time field values + * needed to implement the date-time formatting for a particular language and + * calendar style (for example, Japanese-Gregorian, Japanese-Traditional). + * Calendar defines the range of values returned by certain fields, + * as well as their meaning. For example, the first month of the year has value + * MONTH == JANUARY for all calendars. Other values + * are defined by the concrete subclass, such as ERA and + * YEAR. See individual field documentation and subclass + * documentation for details. + * + *

      When a Calendar is lenient, it accepts a wider range + * of field values than it produces. For example, a lenient + * GregorianCalendar interprets MONTH == + * JANUARY, DAY_OF_MONTH == 32 as February 1. A + * non-lenient GregorianCalendar throws an exception when given + * out-of-range field settings. When calendars recompute field values for + * return by get(), they normalize them. For example, a + * GregorianCalendar always produces DAY_OF_MONTH + * values between 1 and the length of the month. + * + *

      Calendar defines a locale-specific seven day week using two + * parameters: the first day of the week and the minimal days in first week + * (from 1 to 7). These numbers are taken from the locale resource data when a + * Calendar is constructed. They may also be specified explicitly + * through the API. + * + *

      When setting or getting the WEEK_OF_MONTH or + * WEEK_OF_YEAR fields, Calendar must determine the + * first week of the month or year as a reference point. The first week of a + * month or year is defined as the earliest seven day period beginning on + * getFirstDayOfWeek() and containing at least + * getMinimalDaysInFirstWeek() days of that month or year. Weeks + * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow + * it. Note that the normalized numbering returned by get() may be + * different. For example, a specific Calendar subclass may + * designate the week before week 1 of a year as week n of the previous + * year. + * + *

      When computing a Date from time fields, two special + * circumstances may arise: there may be insufficient information to compute the + * Date (such as only year and month but no day in the month), or + * there may be inconsistent information (such as "Tuesday, July 15, 1996" -- + * July 15, 1996 is actually a Monday). + * + *

      Insufficient information. The calendar will use default + * information to specify the missing fields. This may vary by calendar; for + * the Gregorian calendar, the default for a field is the same as that of the + * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc. + * + *

      Inconsistent information. If fields conflict, the calendar + * will give preference to fields set more recently. For example, when + * determining the day, the calendar will look for one of the following + * combinations of fields. The most recent combination, as determined by the + * most recently set single field, will be used. + * + *

      + *
      + * MONTH + DAY_OF_MONTH
      + * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
      + * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
      + * DAY_OF_YEAR
      + * DAY_OF_WEEK + WEEK_OF_YEAR
      + *
      + * + * For the time of day: + * + *
      + *
      + * HOUR_OF_DAY
      + * AM_PM + HOUR
      + *
      + * + *

      Note: for some non-Gregorian calendars, different + * fields may be necessary for complete disambiguation. For example, a full + * specification of the historial Arabic astronomical calendar requires year, + * month, day-of-month and day-of-week in some cases. + * + *

      Note: There are certain possible ambiguities in + * interpretation of certain singular times, which are resolved in the + * following ways: + *

        + *
      1. 24:00:00 "belongs" to the following day. That is, + * 23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 + * + *
      2. Although historically not precise, midnight also belongs to "am", + * and noon belongs to "pm", so on the same day, + * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm + *
      + * + *

      The date or time format strings are not part of the definition of a + * calendar, as those must be modifiable or overridable by the user at + * runtime. Use {@link DateFormat} + * to format dates. + * + *

      Field manipulation methods

      + * + *

      Calendar fields can be changed using three methods: + * set(), add(), and roll().

      + * + *

      set(f, value) changes field + * f to value. In addition, it sets an + * internal member variable to indicate that field f has + * been changed. Although field f is changed immediately, + * the calendar's milliseconds is not recomputed until the next call to + * get(), getTime(), or + * getTimeInMillis() is made. Thus, multiple calls to + * set() do not trigger multiple, unnecessary + * computations. As a result of changing a field using + * set(), other fields may also change, depending on the + * field, the field value, and the calendar system. In addition, + * get(f) will not necessarily return value + * after the fields have been recomputed. The specifics are determined by + * the concrete calendar class.

      + * + *

      Example: Consider a GregorianCalendar + * originally set to August 31, 1999. Calling set(Calendar.MONTH, + * Calendar.SEPTEMBER) sets the calendar to September 31, + * 1999. This is a temporary internal representation that resolves to + * October 1, 1999 if getTime()is then called. However, a + * call to set(Calendar.DAY_OF_MONTH, 30) before the call to + * getTime() sets the calendar to September 30, 1999, since + * no recomputation occurs after set() itself.

      + * + *

      add(f, delta) adds delta + * to field f. This is equivalent to calling set(f, + * get(f) + delta) with two adjustments:

      + * + *
      + *

      Add rule 1. The value of field f + * after the call minus the value of field f before the + * call is delta, modulo any overflow that has occurred in + * field f. Overflow occurs when a field value exceeds its + * range and, as a result, the next larger field is incremented or + * decremented and the field value is adjusted back into its range.

      + * + *

      Add rule 2. If a smaller field is expected to be + * invariant, but   it is impossible for it to be equal to its + * prior value because of changes in its minimum or maximum after field + * f is changed, then its value is adjusted to be as close + * as possible to its expected value. A smaller field represents a + * smaller unit of time. HOUR is a smaller field than + * DAY_OF_MONTH. No adjustment is made to smaller fields + * that are not expected to be invariant. The calendar system + * determines what fields are expected to be invariant.

      + *
      + * + *

      In addition, unlike set(), add() forces + * an immediate recomputation of the calendar's milliseconds and all + * fields.

      + * + *

      Example: Consider a GregorianCalendar + * originally set to August 31, 1999. Calling add(Calendar.MONTH, + * 13) sets the calendar to September 30, 2000. Add rule + * 1 sets the MONTH field to September, since + * adding 13 months to August gives September of the next year. Since + * DAY_OF_MONTH cannot be 31 in September in a + * GregorianCalendar, add rule 2 sets the + * DAY_OF_MONTH to 30, the closest possible value. Although + * it is a smaller field, DAY_OF_WEEK is not adjusted by + * rule 2, since it is expected to change when the month changes in a + * GregorianCalendar.

      + * + *

      roll(f, delta) adds + * delta to field f without changing larger + * fields. This is equivalent to calling add(f, delta) with + * the following adjustment:

      + * + *
      + *

      Roll rule. Larger fields are unchanged after the + * call. A larger field represents a larger unit of + * time. DAY_OF_MONTH is a larger field than + * HOUR.

      + *
      + * + *

      Example: Consider a GregorianCalendar + * originally set to August 31, 1999. Calling roll(Calendar.MONTH, + * 8) sets the calendar to April 30, 1999. Add + * rule 1 sets the MONTH field to April. Using a + * GregorianCalendar, the DAY_OF_MONTH cannot + * be 31 in the month April. Add rule 2 sets it to the closest possible + * value, 30. Finally, the roll rule maintains the + * YEAR field value of 1999.

      + * + *

      Example: Consider a GregorianCalendar + * originally set to Sunday June 6, 1999. Calling + * roll(Calendar.WEEK_OF_MONTH, -1) sets the calendar to + * Tuesday June 1, 1999, whereas calling + * add(Calendar.WEEK_OF_MONTH, -1) sets the calendar to + * Sunday May 30, 1999. This is because the roll rule imposes an + * additional constraint: The MONTH must not change when the + * WEEK_OF_MONTH is rolled. Taken together with add rule 1, + * the resultant date must be between Tuesday June 1 and Saturday June + * 5. According to add rule 2, the DAY_OF_WEEK, an invariant + * when changing the WEEK_OF_MONTH, is set to Tuesday, the + * closest possible value to Sunday (where Sunday is the first day of the + * week).

      + * + *

      Usage model. To motivate the behavior of + * add() and roll(), consider a user interface + * component with increment and decrement buttons for the month, day, and + * year, and an underlying GregorianCalendar. If the + * interface reads January 31, 1999 and the user presses the month + * increment button, what should it read? If the underlying + * implementation uses set(), it might read March 3, 1999. A + * better result would be February 28, 1999. Furthermore, if the user + * presses the month increment button again, it should read March 31, + * 1999, not March 28, 1999. By saving the original date and using either + * add() or roll(), depending on whether larger + * fields should be affected, the user interface can behave as most users + * will intuitively expect.

      + * + *

      Note: You should always use {@link #roll roll} and {@link #add add} rather + * than attempting to perform arithmetic operations directly on the fields + * of a Calendar. It is quite possible for Calendar subclasses + * to have fields with non-linear behavior, for example missing months + * or days during non-leap years. The subclasses' add and roll + * methods will take this into account, while simple arithmetic manipulations + * may give invalid results. + * + *

      Calendar Architecture in ICU4J

      + * + *

      Recently the implementation of Calendar has changed + * significantly in order to better support subclassing. The original + * Calendar class was designed to support subclassing, but + * it had only one implemented subclass, GregorianCalendar. + * With the implementation of several new calendar subclasses, including + * the BuddhistCalendar, ChineseCalendar, + * HebrewCalendar, IslamicCalendar, and + * JapaneseCalendar, the subclassing API has been reworked + * thoroughly. This section details the new subclassing API and other + * ways in which com.ibm.icu.util.Calendar differs from + * java.util.Calendar. + *

      + * + *

      Changes

      + * + *

      Overview of changes between the classic Calendar + * architecture and the new architecture. + * + *

        + * + *
      • The fields[] array is private now + * instead of protected. Subclasses must access it + * using the methods {@link #internalSet} and + * {@link #internalGet}. Motivation: Subclasses should + * not directly access data members.
      • + * + *
      • The time long word is private now + * instead of protected. Subclasses may access it using + * the method {@link #internalGetTimeInMillis}, which does not + * provoke an update. Motivation: Subclasses should not + * directly access data members.
      • + * + *
      • The scope of responsibility of subclasses has been drastically + * reduced. As much functionality as possible is implemented in the + * Calendar base class. As a result, it is much easier + * to subclass Calendar. Motivation: Subclasses + * should not have to reimplement common code. Certain behaviors are + * common across calendar systems: The definition and behavior of + * week-related fields and time fields, the arithmetic + * ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many + * fields, and the field validation system.
      • + * + *
      • The subclassing API has been completely redesigned.
      • + * + *
      • The Calendar base class contains some Gregorian + * calendar algorithmic support that subclasses can use (specifically + * in {@link #handleComputeFields}). Subclasses can use the + * methods getGregorianXxx() to obtain precomputed + * values. Motivation: This is required by all + * Calendar subclasses in order to implement consistent + * time zone behavior, and Gregorian-derived systems can use the + * already computed data.
      • + * + *
      • The FIELD_COUNT constant has been removed. Use + * {@link #getFieldCount}. In addition, framework API has been + * added to allow subclasses to define additional fields. + * Motivation: The number of fields is not constant across + * calendar systems.
      • + * + *
      • The range of handled dates has been narrowed from +/- + * ~300,000,000 years to +/- ~5,000,000 years. In practical terms + * this should not affect clients. However, it does mean that client + * code cannot be guaranteed well-behaved results with dates such as + * Date(Long.MIN_VALUE) or + * Date(Long.MAX_VALUE). Instead, the + * Calendar protected constants should be used. + * Motivation: With + * the addition of the {@link #JULIAN_DAY} field, Julian day + * numbers must be restricted to a 32-bit int. This + * restricts the overall supported range. Furthermore, restricting + * the supported range simplifies the computations by removing + * special case code that was used to accomodate arithmetic overflow + * at millis near Long.MIN_VALUE and + * Long.MAX_VALUE.
      • + * + *
      • New fields are implemented: {@link #JULIAN_DAY} defines + * single-field specification of the + * date. {@link #MILLISECONDS_IN_DAY} defines a single-field + * specification of the wall time. {@link #DOW_LOCAL} and + * {@link #YEAR_WOY} implement localized day-of-week and + * week-of-year behavior.
      • + * + *
      • Subclasses can access protected millisecond constants + * defined in Calendar.
      • + * + *
      • New API has been added to support calendar-specific subclasses + * of DateFormat.
      • + * + *
      • Several subclasses have been implemented, representing + * various international calendar systems.
      • + * + *
      + * + *

      Subclass API

      + * + *

      The original Calendar API was based on the experience + * of implementing a only a single subclass, + * GregorianCalendar. As a result, all of the subclassing + * kinks had not been worked out. The new subclassing API has been + * refined based on several implemented subclasses. This includes methods + * that must be overridden and methods for subclasses to call. Subclasses + * no longer have direct access to fields and + * stamp. Instead, they have new API to access + * these. Subclasses are able to allocate the fields array + * through a protected framework method; this allows subclasses to + * specify additional fields.

      + * + *

      More functionality has been moved into the base class. The base + * class now contains much of the computational machinery to support the + * Gregorian calendar. This is based on two things: (1) Many calendars + * are based on the Gregorian calendar (such as the Buddhist and Japanese + * imperial calendars). (2) All calendars require basic + * Gregorian support in order to handle timezone computations.

      + * + *

      Common computations have been moved into + * Calendar. Subclasses no longer compute the week related + * fields and the time related fields. These are commonly handled for all + * calendars by the base class.

      + * + *

      Subclass computation of time => fields + * + *

      The {@link #ERA}, {@link #YEAR}, + * {@link #EXTENDED_YEAR}, {@link #MONTH}, + * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are + * computed by the subclass, based on the Julian day. All other fields + * are computed by Calendar. + * + *

        + * + *
      • Subclasses should implement {@link #handleComputeFields} + * to compute the {@link #ERA}, {@link #YEAR}, + * {@link #EXTENDED_YEAR}, {@link #MONTH}, + * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields, + * based on the value of the {@link #JULIAN_DAY} field. If there + * are calendar-specific fields not defined by Calendar, + * they must also be computed. These are the only fields that the + * subclass should compute. All other fields are computed by the base + * class, so time and week fields behave in a consistent way across + * all calendars. The default version of this method in + * Calendar implements a proleptic Gregorian + * calendar. Within this method, subclasses may call + * getGregorianXxx() to obtain the Gregorian calendar + * month, day of month, and extended year for the given date.
      • + * + *
      + * + *

      Subclass computation of fields => time + * + *

      The interpretation of most field values is handled entirely by + * Calendar. Calendar determines which fields + * are set, which are not, which are set more recently, and so on. In + * addition, Calendar handles the computation of the time + * from the time fields and handles the week-related fields. The only + * thing the subclass must do is determine the extended year, based on + * the year fields, and then, given an extended year and a month, it must + * return a Julian day number. + * + *

        + * + *
      • Subclasses should implement {@link #handleGetExtendedYear} + * to return the extended year for this calendar system, based on the + * {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that + * the calendar system uses that are larger than a year, such as + * {@link #ERA}.
      • + * + *
      • Subclasses should implement {@link #handleComputeMonthStart} + * to return the Julian day number + * associated with a month and extended year. This is the Julian day + * number of the day before the first day of the month. The month + * number is zero-based. This computation should not depend on any + * field values.
      • + * + *
      + * + *

      Other methods + * + *

        + * + *
      • Subclasses should implement {@link #handleGetMonthLength} + * to return the number of days in a + * given month of a given extended year. The month number, as always, + * is zero-based.
      • + * + *
      • Subclasses should implement {@link #handleGetYearLength} + * to return the number of days in the given + * extended year. This method is used by + * computeWeekFields to compute the + * {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.
      • + * + *
      • Subclasses should implement {@link #handleGetLimit} + * to return the protected values of a field, depending on the value of + * limitType. This method only needs to handle the + * fields {@link #ERA}, {@link #YEAR}, {@link #MONTH}, + * {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH}, + * {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR}, + * {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and + * {@link #EXTENDED_YEAR}. Other fields are invariant (with + * respect to calendar system) and are handled by the base + * class.
      • + * + *
      • Optionally, subclasses may override {@link #validateField} + * to check any subclass-specific fields. If the + * field's value is out of range, the method should throw an + * IllegalArgumentException. The method may call + * super.validateField(field) to handle fields in a + * generic way, that is, to compare them to the range + * getMinimum(field)..getMaximum(field).
      • + * + *
      • Optionally, subclasses may override + * {@link #handleCreateFields} to create an int[] + * array large enough to hold the calendar's fields. This is only + * necessary if the calendar defines additional fields beyond those + * defined by Calendar. The length of the result must be + * be between the base and maximum field counts.
      • + * + *
      • Optionally, subclasses may override + * {@link #handleGetDateFormat} to create a + * DateFormat appropriate to this calendar. This is only + * required if a calendar subclass redefines the use of a field (for + * example, changes the {@link #ERA} field from a symbolic field + * to a numeric one) or defines an additional field.
      • + * + *
      • Optionally, subclasses may override {@link #roll roll} and + * {@link #add add} to handle fields that are discontinuous. For + * example, in the Hebrew calendar the month "Adar I" only + * occurs in leap years; in other years the calendar jumps from + * Shevat (month #4) to Adar (month #6). The {@link + * HebrewCalendar#add HebrewCalendar.add} and {@link + * HebrewCalendar#roll HebrewCalendar.roll} methods take this into + * account, so that adding 1 month to Shevat gives the proper result + * (Adar) in a non-leap year. The protected utility method {@link + * #pinField pinField} is often useful when implementing these two + * methods.
      • + * + *
      + * + *

      Normalized behavior + * + *

      The behavior of certain fields has been made consistent across all + * calendar systems and implemented in Calendar. + * + *

        + * + *
      • Time is normalized. Even though some calendar systems transition + * between days at sunset or at other times, all ICU4J calendars + * transition between days at local zone midnight. This + * allows ICU4J to centralize the time computations in + * Calendar and to maintain basic correpsondences + * between calendar systems. Affected fields: {@link #AM_PM}, + * {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE}, + * {@link #SECOND}, {@link #MILLISECOND}, + * {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.
      • + * + *
      • DST behavior is normalized. Daylight savings time behavior is + * computed the same for all calendar systems, and depends on the + * value of several GregorianCalendar fields: the + * {@link #YEAR}, {@link #MONTH}, and + * {@link #DAY_OF_MONTH}. As a result, Calendar + * always computes these fields, even for non-Gregorian calendar + * systems. These fields are available to subclasses.
      • + * + *
      • Weeks are normalized. Although locales define the week + * differently, in terms of the day on which it starts, and the + * designation of week number one of a month or year, they all use a + * common mechanism. Furthermore, the day of the week has a simple + * and consistent definition throughout history. For example, + * although the Gregorian calendar introduced a discontinuity when + * first instituted, the day of week was not disrupted. For this + * reason, the fields {@link #DAY_OF_WEEK}, WEEK_OF_YEAR, + * WEEK_OF_MONTH, {@link #DAY_OF_WEEK_IN_MONTH}, + * {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in + * a consistent way in the base class, based on the + * {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR}, + * {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are + * computed by the subclass.
      • + * + *
      + * + *

      Supported range + * + *

      The allowable range of Calendar has been + * narrowed. GregorianCalendar used to attempt to support + * the range of dates with millisecond values from + * Long.MIN_VALUE to Long.MAX_VALUE. This + * introduced awkward constructions (hacks) which slowed down + * performance. It also introduced non-uniform behavior at the + * boundaries. The new Calendar protocol specifies the + * maximum range of supportable dates as those having Julian day numbers + * of -0x7F000000 to +0x7F000000. This + * corresponds to years from ~5,000,000 BCE to ~5,000,000 CE. Programmers + * should use the protected constants in Calendar to + * specify an extremely early or extremely late date.

      + * + *

      General notes + * + *

        + * + *
      • Calendars implementations are proleptic. For example, + * even though the Gregorian calendar was not instituted until the + * 16th century, the GregorianCalendar class supports + * dates before the historical onset of the calendar by extending the + * calendar system backward in time. Similarly, the + * HebrewCalendar extends backward before the start of + * its epoch into zero and negative years. Subclasses do not throw + * exceptions because a date precedes the historical start of a + * calendar system. Instead, they implement + * {@link #handleGetLimit} to return appropriate limits on + * {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the + * calendar is set to not be lenient, out-of-range field values will + * trigger an exception.
      • + * + *
      • Calendar system subclasses compute a extended + * year. This differs from the {@link #YEAR} field in that + * it ranges over all integer values, including zero and negative + * values, and it encapsulates the information of the + * {@link #YEAR} field and all larger fields. Thus, for the + * Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as + * ERA==AD ? YEAR : 1-YEAR. Another example is the Mayan + * long count, which has years (KUN) and nested cycles + * of years (KATUN and BAKTUN). The Mayan + * {@link #EXTENDED_YEAR} is computed as TUN + 20 * (KATUN + * + 20 * BAKTUN). The Calendar base class uses + * the {@link #EXTENDED_YEAR} field to compute the week-related + * fields.
      • + * + *
      + * + * @see Date + * @see GregorianCalendar + * @see TimeZone + * @see DateFormat + * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner + * @stable ICU 2.0 + */ +public class Calendar implements Serializable, Cloneable, Comparable { + private static final long serialVersionUID = 1L; + + /** + * @internal + */ + public final java.util.Calendar calendar; + + /** + * @internal + * @param delegate the Calendar to which to delegate + */ + public Calendar(java.util.Calendar delegate) { + this.calendar = delegate; + } + + // Data flow in Calendar + // --------------------- + + // The current time is represented in two ways by Calendar: as UTC + // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local + // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the + // millis from the fields, and vice versa. The data needed to do this + // conversion is encapsulated by a TimeZone object owned by the Calendar. + // The data provided by the TimeZone object may also be overridden if the + // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class + // keeps track of what information was most recently set by the caller, and + // uses that to compute any other information as needed. + + // If the user sets the fields using set(), the data flow is as follows. + // This is implemented by the Calendar subclass's computeTime() method. + // During this process, certain fields may be ignored. The disambiguation + // algorithm for resolving which fields to pay attention to is described + // above. + + // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) + // | + // | Using Calendar-specific algorithm + // V + // local standard millis + // | + // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET + // V + // UTC millis (in time data member) + + // If the user sets the UTC millis using setTime(), the data flow is as + // follows. This is implemented by the Calendar subclass's computeFields() + // method. + + // UTC millis (in time data member) + // | + // | Using TimeZone getOffset() + // V + // local standard millis + // | + // | Using Calendar-specific algorithm + // V + // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) + + // In general, a round trip from fields, through local and UTC millis, and + // back out to fields is made when necessary. This is implemented by the + // complete() method. Resolving a partial set of fields into a UTC millis + // value allows all remaining fields to be generated from that value. If + // the Calendar is lenient, the fields are also renormalized to standard + // ranges when they are regenerated. + + /** + * Field number for get and set indicating the + * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific + * value; see subclass documentation. + * @see GregorianCalendar#AD + * @see GregorianCalendar#BC + * @stable ICU 2.0 + */ + public final static int ERA = 0; + + /** + * Field number for get and set indicating the + * year. This is a calendar-specific value; see subclass documentation. + * @stable ICU 2.0 + */ + public final static int YEAR = 1; + + /** + * Field number for get and set indicating the + * month. This is a calendar-specific value. The first month of the year is + * JANUARY; the last depends on the number of months in a year. + * @see #JANUARY + * @see #FEBRUARY + * @see #MARCH + * @see #APRIL + * @see #MAY + * @see #JUNE + * @see #JULY + * @see #AUGUST + * @see #SEPTEMBER + * @see #OCTOBER + * @see #NOVEMBER + * @see #DECEMBER + * @see #UNDECIMBER + * @stable ICU 2.0 + */ + public final static int MONTH = 2; + + /** + * Field number for get and set indicating the + * week number within the current year. The first week of the year, as + * defined by {@link #getFirstDayOfWeek()} and + * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define + * the value of {@link #WEEK_OF_YEAR} for days before the first week of + * the year. + * @see #getFirstDayOfWeek + * @see #getMinimalDaysInFirstWeek + * @stable ICU 2.0 + */ + public final static int WEEK_OF_YEAR = 3; + + /** + * Field number for get and set indicating the + * week number within the current month. The first week of the month, as + * defined by {@link #getFirstDayOfWeek()} and + * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define + * the value of {@link #WEEK_OF_MONTH} for days before the first week of + * the month. + * @see #getFirstDayOfWeek + * @see #getMinimalDaysInFirstWeek + * @stable ICU 2.0 + */ + public final static int WEEK_OF_MONTH = 4; + + /** + * Field number for get and set indicating the + * day of the month. This is a synonym for {@link #DAY_OF_MONTH}. + * The first day of the month has value 1. + * @see #DAY_OF_MONTH + * @stable ICU 2.0 + */ + public final static int DATE = 5; + + /** + * Field number for get and set indicating the + * day of the month. This is a synonym for {@link #DATE}. + * The first day of the month has value 1. + * @see #DATE + * @stable ICU 2.0 + */ + public final static int DAY_OF_MONTH = 5; + + /** + * Field number for get and set indicating the day + * number within the current year. The first day of the year has value 1. + * @stable ICU 2.0 + */ + public final static int DAY_OF_YEAR = 6; + + /** + * Field number for get and set indicating the day + * of the week. This field takes values {@link #SUNDAY}, + * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY}, + * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}. + * @see #SUNDAY + * @see #MONDAY + * @see #TUESDAY + * @see #WEDNESDAY + * @see #THURSDAY + * @see #FRIDAY + * @see #SATURDAY + * @stable ICU 2.0 + */ + public final static int DAY_OF_WEEK = 7; + + /** + * Field number for get and set indicating the + * ordinal number of the day of the week within the current month. Together + * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day + * within a month. Unlike {@link #WEEK_OF_MONTH} and + * {@link #WEEK_OF_YEAR}, this field's value does not depend on + * {@link #getFirstDayOfWeek()} or + * {@link #getMinimalDaysInFirstWeek()}. DAY_OF_MONTH 1 + * through 7 always correspond to DAY_OF_WEEK_IN_MONTH + * 1; 8 through 15 correspond to + * DAY_OF_WEEK_IN_MONTH 2, and so on. + * DAY_OF_WEEK_IN_MONTH 0 indicates the week before + * DAY_OF_WEEK_IN_MONTH 1. Negative values count back from the + * end of the month, so the last Sunday of a month is specified as + * DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1. Because + * negative values count backward they will usually be aligned differently + * within the month than positive values. For example, if a month has 31 + * days, DAY_OF_WEEK_IN_MONTH -1 will overlap + * DAY_OF_WEEK_IN_MONTH 5 and the end of 4. + * @see #DAY_OF_WEEK + * @see #WEEK_OF_MONTH + * @stable ICU 2.0 + */ + public final static int DAY_OF_WEEK_IN_MONTH = 8; + + /** + * Field number for get and set indicating + * whether the HOUR is before or after noon. + * E.g., at 10:04:15.250 PM the AM_PM is PM. + * @see #AM + * @see #PM + * @see #HOUR + * @stable ICU 2.0 + */ + public final static int AM_PM = 9; + + /** + * Field number for get and set indicating the + * hour of the morning or afternoon. HOUR is used for the 12-hour + * clock. + * E.g., at 10:04:15.250 PM the HOUR is 10. + * @see #AM_PM + * @see #HOUR_OF_DAY + * @stable ICU 2.0 + */ + public final static int HOUR = 10; + + /** + * Field number for get and set indicating the + * hour of the day. HOUR_OF_DAY is used for the 24-hour clock. + * E.g., at 10:04:15.250 PM the HOUR_OF_DAY is 22. + * @see #HOUR + * @stable ICU 2.0 + */ + public final static int HOUR_OF_DAY = 11; + + /** + * Field number for get and set indicating the + * minute within the hour. + * E.g., at 10:04:15.250 PM the MINUTE is 4. + * @stable ICU 2.0 + */ + public final static int MINUTE = 12; + + /** + * Field number for get and set indicating the + * second within the minute. + * E.g., at 10:04:15.250 PM the SECOND is 15. + * @stable ICU 2.0 + */ + public final static int SECOND = 13; + + /** + * Field number for get and set indicating the + * millisecond within the second. + * E.g., at 10:04:15.250 PM the MILLISECOND is 250. + * @stable ICU 2.0 + */ + public final static int MILLISECOND = 14; + + /** + * Field number for get and set indicating the + * raw offset from GMT in milliseconds. + * @stable ICU 2.0 + */ + public final static int ZONE_OFFSET = 15; + + /** + * Field number for get and set indicating the + * daylight savings offset in milliseconds. + * @stable ICU 2.0 + */ + public final static int DST_OFFSET = 16; + + /** + * {@icu} Field number for get() and set() + * indicating the extended year corresponding to the + * {@link #WEEK_OF_YEAR} field. This may be one greater or less + * than the value of {@link #EXTENDED_YEAR}. + * @stable ICU 2.0 + */ + public static final int YEAR_WOY = 17; + + /** + * {@icu} Field number for get() and set() + * indicating the localized day of week. This will be a value from 1 + * to 7 inclusive, with 1 being the localized first day of the week. + * @stable ICU 2.0 + */ + public static final int DOW_LOCAL = 18; + + /** + * {@icu} Field number for get() and set() + * indicating the extended year. This is a single number designating + * the year of this calendar system, encompassing all supra-year + * fields. For example, for the Julian calendar system, year numbers + * are positive, with an era of BCE or CE. An extended year value for + * the Julian calendar system assigns positive values to CE years and + * negative values to BCE years, with 1 BCE being year 0. + * @stable ICU 2.0 + */ + public static final int EXTENDED_YEAR = 19; + + /** + * {@icu} Field number for get() and set() + * indicating the modified Julian day number. This is different from + * the conventional Julian day number in two regards. First, it + * demarcates days at local zone midnight, rather than noon GMT. + * Second, it is a local number; that is, it depends on the local time + * zone. It can be thought of as a single number that encompasses all + * the date-related fields. + * @stable ICU 2.0 + */ + public static final int JULIAN_DAY = 20; + + /** + * {@icu} Field number for get() and set() + * indicating the milliseconds in the day. This ranges from 0 to + * 23:59:59.999 (regardless of DST). This field behaves + * exactly like a composite of all time-related fields, not + * including the zone fields. As such, it also reflects + * discontinuities of those fields on DST transition days. On a day of + * DST onset, it will jump forward. On a day of DST cessation, it will + * jump backward. This reflects the fact that is must be combined with + * the DST_OFFSET field to obtain a unique local time value. + * @stable ICU 2.0 + */ + public static final int MILLISECONDS_IN_DAY = 21; + + /** + * {@icu} Field indicating whether or not the current month is a leap month. + * Should have a value of 0 for non-leap months, and 1 for leap months. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int IS_LEAP_MONTH = 22; + + /** + * Value of the DAY_OF_WEEK field indicating + * Sunday. + * @stable ICU 2.0 + */ + public final static int SUNDAY = 1; + + /** + * Value of the DAY_OF_WEEK field indicating + * Monday. + * @stable ICU 2.0 + */ + public final static int MONDAY = 2; + + /** + * Value of the DAY_OF_WEEK field indicating + * Tuesday. + * @stable ICU 2.0 + */ + public final static int TUESDAY = 3; + + /** + * Value of the DAY_OF_WEEK field indicating + * Wednesday. + * @stable ICU 2.0 + */ + public final static int WEDNESDAY = 4; + + /** + * Value of the DAY_OF_WEEK field indicating + * Thursday. + * @stable ICU 2.0 + */ + public final static int THURSDAY = 5; + + /** + * Value of the DAY_OF_WEEK field indicating + * Friday. + * @stable ICU 2.0 + */ + public final static int FRIDAY = 6; + + /** + * Value of the DAY_OF_WEEK field indicating + * Saturday. + * @stable ICU 2.0 + */ + public final static int SATURDAY = 7; + + /** + * Value of the MONTH field indicating the + * first month of the year. + * @stable ICU 2.0 + */ + public final static int JANUARY = 0; + + /** + * Value of the MONTH field indicating the + * second month of the year. + * @stable ICU 2.0 + */ + public final static int FEBRUARY = 1; + + /** + * Value of the MONTH field indicating the + * third month of the year. + * @stable ICU 2.0 + */ + public final static int MARCH = 2; + + /** + * Value of the MONTH field indicating the + * fourth month of the year. + * @stable ICU 2.0 + */ + public final static int APRIL = 3; + + /** + * Value of the MONTH field indicating the + * fifth month of the year. + * @stable ICU 2.0 + */ + public final static int MAY = 4; + + /** + * Value of the MONTH field indicating the + * sixth month of the year. + * @stable ICU 2.0 + */ + public final static int JUNE = 5; + + /** + * Value of the MONTH field indicating the + * seventh month of the year. + * @stable ICU 2.0 + */ + public final static int JULY = 6; + + /** + * Value of the MONTH field indicating the + * eighth month of the year. + * @stable ICU 2.0 + */ + public final static int AUGUST = 7; + + /** + * Value of the MONTH field indicating the + * ninth month of the year. + * @stable ICU 2.0 + */ + public final static int SEPTEMBER = 8; + + /** + * Value of the MONTH field indicating the + * tenth month of the year. + * @stable ICU 2.0 + */ + public final static int OCTOBER = 9; + + /** + * Value of the MONTH field indicating the + * eleventh month of the year. + * @stable ICU 2.0 + */ + public final static int NOVEMBER = 10; + + /** + * Value of the MONTH field indicating the + * twelfth month of the year. + * @stable ICU 2.0 + */ + public final static int DECEMBER = 11; + + /** + * Value of the MONTH field indicating the + * thirteenth month of the year. Although {@link GregorianCalendar} + * does not use this value, lunar calendars do. + * @stable ICU 2.0 + */ + public final static int UNDECIMBER = 12; + + /** + * Value of the AM_PM field indicating the + * period of the day from midnight to just before noon. + * @stable ICU 2.0 + */ + public final static int AM = 0; + + /** + * Value of the AM_PM field indicating the + * period of the day from noon to just before midnight. + * @stable ICU 2.0 + */ + public final static int PM = 1; + + /** + * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a + * weekday. + * @see #WEEKEND + * @see #WEEKEND_ONSET + * @see #WEEKEND_CEASE + * @see #getDayOfWeekType + * @stable ICU 2.0 + */ + public static final int WEEKDAY = 0; + + /** + * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a + * weekend day. + * @see #WEEKDAY + * @see #WEEKEND_ONSET + * @see #WEEKEND_CEASE + * @see #getDayOfWeekType + * @stable ICU 2.0 + */ + public static final int WEEKEND = 1; + + /** + * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a + * day that starts as a weekday and transitions to the weekend. + * Call getWeekendTransition() to get the point of transition. + * @see #WEEKDAY + * @see #WEEKEND + * @see #WEEKEND_CEASE + * @see #getDayOfWeekType + * @stable ICU 2.0 + */ + public static final int WEEKEND_ONSET = 2; + + /** + * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a + * day that starts as the weekend and transitions to a weekday. + * Call getWeekendTransition() to get the point of transition. + * @see #WEEKDAY + * @see #WEEKEND + * @see #WEEKEND_ONSET + * @see #getDayOfWeekType + * @stable ICU 2.0 + */ + public static final int WEEKEND_CEASE = 3; + + /** + * Constructs a Calendar with the default time zone + * and locale. + * @see TimeZone#getDefault + * @stable ICU 2.0 + */ + protected Calendar() + { + this(TimeZone.getDefault(), ULocale.getDefault()); + } + + /** + * Constructs a calendar with the specified time zone and locale. + * @param zone the time zone to use + * @param aLocale the locale for the week data + * @stable ICU 2.0 + */ + protected Calendar(TimeZone zone, Locale aLocale) + { + this(zone, ULocale.forLocale(aLocale)); + } + + /** + * Constructs a calendar with the specified time zone and locale. + * @param zone the time zone to use + * @param locale the ulocale for the week data + * @stable ICU 3.2 + */ + protected Calendar(TimeZone zone, ULocale locale) + { + calendar = java.util.Calendar.getInstance(zone.timeZone, locale.toLocale()); + } + + /** + * Returns a calendar using the default time zone and locale. + * @return a Calendar. + * @stable ICU 2.0 + */ + public static synchronized Calendar getInstance() + { + return new Calendar(java.util.Calendar.getInstance()); + } + + /** + * Returns a calendar using the specified time zone and default locale. + * @param zone the time zone to use + * @return a Calendar. + * @stable ICU 2.0 + */ + public static synchronized Calendar getInstance(TimeZone zone) + { + return new Calendar(java.util.Calendar.getInstance(zone.timeZone)); + } + + /** + * Returns a calendar using the default time zone and specified locale. + * @param aLocale the locale for the week data + * @return a Calendar. + * @stable ICU 2.0 + */ + public static synchronized Calendar getInstance(Locale aLocale) + { + return new Calendar(java.util.Calendar.getInstance(aLocale)); + } + + /** + * Returns a calendar using the default time zone and specified locale. + * @param locale the ulocale for the week data + * @return a Calendar. + * @stable ICU 3.2 + */ + public static synchronized Calendar getInstance(ULocale locale) + { + return new Calendar(java.util.Calendar.getInstance(locale.toLocale())); + } + + /** + * Returns a calendar with the specified time zone and locale. + * @param zone the time zone to use + * @param aLocale the locale for the week data + * @return a Calendar. + * @stable ICU 2.0 + */ + public static synchronized Calendar getInstance(TimeZone zone, + Locale aLocale) { + return new Calendar(java.util.Calendar.getInstance(zone.timeZone, aLocale)); + } + + /** + * Returns a calendar with the specified time zone and locale. + * @param zone the time zone to use + * @param locale the ulocale for the week data + * @return a Calendar. + * @stable ICU 3.2 + */ + public static synchronized Calendar getInstance(TimeZone zone, + ULocale locale) { + return new Calendar(java.util.Calendar.getInstance(zone.timeZone, locale.toLocale())); + } + + /** + * Returns the list of locales for which Calendars are installed. + * @return the list of locales for which Calendars are installed. + * @stable ICU 2.0 + */ + public static Locale[] getAvailableLocales() + { + return java.util.Calendar.getAvailableLocales(); + } + + /** + * {@icu} Returns the list of locales for which Calendars are installed. + * @return the list of locales for which Calendars are installed. + * @draft ICU 3.2 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static ULocale[] getAvailableULocales() + { + if (availableLocales == null) { + synchronized (Calendar.class) { + if (availableLocales == null) { + Locale[] locales = Locale.getAvailableLocales(); + availableLocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; i++) { + availableLocales[i] = ULocale.forLocale(locales[i]); + } + } + } + } + return availableLocales.clone(); + } + private static volatile ULocale[] availableLocales; + + /** + * {@icu} Given a key and a locale, returns an array of string values in a preferred + * order that would make a difference. These are all and only those values where + * the open (creation) of the service with the locale formed from the input locale + * plus input keyword and that value has different behavior than creation with the + * input locale alone. + * @param key one of the keys supported by this service. For now, only + * "calendar" is supported. + * @param locale the locale + * @param commonlyUsed if set to true it will return only commonly used values + * with the given locale in preferred order. Otherwise, + * it will return all the available values for the locale. + * @return an array of string values for the given key and the locale. + * @stable ICU 4.2 + */ + public static final String[] getKeywordValuesForLocale(String key, ULocale locale, + boolean commonlyUsed) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns this Calendar's current time. + * @return the current time. + * @stable ICU 2.0 + */ + public final Date getTime() { + return calendar.getTime(); + } + + /** + * Sets this Calendar's current time with the given Date. + * + *

      Note: Calling setTime with + * Date(Long.MAX_VALUE) or Date(Long.MIN_VALUE) + * may yield incorrect field values from {@link #get(int)}. + * @param date the given Date. + * @stable ICU 2.0 + */ + public final void setTime(Date date) { + calendar.setTime(date); + } + + /** + * Returns this Calendar's current time as a long. + * @return the current time as UTC milliseconds from the epoch. + * @stable ICU 2.0 + */ + public long getTimeInMillis() { + return calendar.getTimeInMillis(); + } + + /** + * Sets this Calendar's current time from the given long value. + * @param millis the new time in UTC milliseconds from the epoch. + * @stable ICU 2.0 + */ + public void setTimeInMillis( long millis ) { + calendar.setTimeInMillis(millis); + } + + /** + * Returns the value for a given time field. + * @param field the given time field. + * @return the value for the given time field. + * @stable ICU 2.0 + */ + public final int get(int field) + { + return calendar.get(getJDKField(field)); + } + + /** + * Sets the time field with the given value. + * @param field the given time field. + * @param value the value to be set for the given time field. + * @stable ICU 2.0 + */ + public final void set(int field, int value) + { + calendar.set(getJDKField(field), value); + } + + /** + * Sets the values for the fields year, month, and date. + * Previous values of other fields are retained. If this is not desired, + * call {@link #clear()} first. + * @param year the value used to set the YEAR time field. + * @param month the value used to set the MONTH time field. + * Month value is 0-based. e.g., 0 for January. + * @param date the value used to set the DATE time field. + * @stable ICU 2.0 + */ + public final void set(int year, int month, int date) + { + calendar.set(getJDKField(YEAR), year); + calendar.set(getJDKField(MONTH), month); + calendar.set(getJDKField(DATE), date); + } + + /** + * Sets the values for the fields year, month, date, hour, and minute. + * Previous values of other fields are retained. If this is not desired, + * call {@link #clear()} first. + * @param year the value used to set the YEAR time field. + * @param month the value used to set the MONTH time field. + * Month value is 0-based. e.g., 0 for January. + * @param date the value used to set the DATE time field. + * @param hour the value used to set the HOUR_OF_DAY time field. + * @param minute the value used to set the MINUTE time field. + * @stable ICU 2.0 + */ + public final void set(int year, int month, int date, int hour, int minute) + { + calendar.set(getJDKField(YEAR), year); + calendar.set(getJDKField(MONTH), month); + calendar.set(getJDKField(DATE), date); + calendar.set(getJDKField(HOUR_OF_DAY), hour); + calendar.set(getJDKField(MINUTE), minute); + } + + /** + * Sets the values for the fields year, month, date, hour, minute, and second. + * Previous values of other fields are retained. If this is not desired, + * call {@link #clear} first. + * @param year the value used to set the YEAR time field. + * @param month the value used to set the MONTH time field. + * Month value is 0-based. e.g., 0 for January. + * @param date the value used to set the DATE time field. + * @param hour the value used to set the HOUR_OF_DAY time field. + * @param minute the value used to set the MINUTE time field. + * @param second the value used to set the SECOND time field. + * @stable ICU 2.0 + */ + public final void set(int year, int month, int date, int hour, int minute, + int second) + { + calendar.set(getJDKField(YEAR), year); + calendar.set(getJDKField(MONTH), month); + calendar.set(getJDKField(DATE), date); + calendar.set(getJDKField(HOUR_OF_DAY), hour); + calendar.set(getJDKField(MINUTE), minute); + calendar.set(getJDKField(SECOND), second); + } + + /** + * Clears the values of all the time fields. + * @stable ICU 2.0 + */ + public final void clear() + { + calendar.clear(); + } + + /** + * Clears the value in the given time field. + * @param field the time field to be cleared. + * @stable ICU 2.0 + */ + public final void clear(int field) + { + calendar.clear(getJDKField(field)); + } + + /** + * Determines if the given time field has a value set. + * @return true if the given time field has a value set; false otherwise. + * @stable ICU 2.0 + */ + public final boolean isSet(int field) + { + return calendar.isSet(getJDKField(field)); + } + + /** + * Compares this calendar to the specified object. + * The result is true if and only if the argument is + * not null and is a Calendar object that + * represents the same calendar as this object. + * @param obj the object to compare with. + * @return true if the objects are the same; + * false otherwise. + * @stable ICU 2.0 + */ + public boolean equals(Object obj) { + try { + return calendar.equals(((Calendar)obj).calendar); + } catch (Exception e) { + return false; + } + } + + /** + * {@icu} Returns true if the given Calendar object is equivalent to this + * one. An equivalent Calendar will behave exactly as this one + * does, but it may be set to a different time. By contrast, for + * the equals() method to return true, the other Calendar must + * be set to the same time. + * + * @param other the Calendar to be compared with this Calendar + * @stable ICU 2.4 + */ + public boolean isEquivalentTo(Calendar other) { + return calendar.getClass() == other.calendar.getClass() && + calendar.isLenient() == other.calendar.isLenient() && + calendar.getFirstDayOfWeek() == other.calendar.getFirstDayOfWeek() && + calendar.getMinimalDaysInFirstWeek() == other.calendar.getMinimalDaysInFirstWeek() && + calendar.getTimeZone().equals(other.calendar.getTimeZone()); + } + + /** + * Returns a hash code for this calendar. + * @return a hash code value for this object. + * @stable ICU 2.0 + */ + public int hashCode() { + return calendar.hashCode(); + } + + /** + * Returns the difference in milliseconds between the moment this + * calendar is set to and the moment the given calendar or Date object + * is set to. + */ + private long compare(Object that) { + long thatMs; + if (that instanceof Calendar) { + thatMs = ((Calendar)that).getTimeInMillis(); + } else if (that instanceof Date) { + thatMs = ((Date)that).getTime(); + } else { + throw new IllegalArgumentException(that + "is not a Calendar or Date"); + } + return getTimeInMillis() - thatMs; + } + + /** + * Compares the time field records. + * Equivalent to comparing result of conversion to UTC. + * @param when the Calendar to be compared with this Calendar. + * @return true if the current time of this Calendar is before + * the time of Calendar when; false otherwise. + * @stable ICU 2.0 + */ + public boolean before(Object when) { + return compare(when) < 0; + } + + /** + * Compares the time field records. + * Equivalent to comparing result of conversion to UTC. + * @param when the Calendar to be compared with this Calendar. + * @return true if the current time of this Calendar is after + * the time of Calendar when; false otherwise. + * @stable ICU 2.0 + */ + public boolean after(Object when) { + return compare(when) > 0; + } + + /** + * Returns the maximum value that this field could have, given the + * current date. For example, with the Gregorian date February 3, 1997 + * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum + * is 28; for February 3, 1996 it is 29. + * + *

      The actual maximum computation ignores smaller fields and the + * current value of like-sized fields. For example, the actual maximum + * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year + * fields. The actual maximum of the DAY_OF_MONTH depends, in + * addition, on the MONTH field and any other fields at that + * granularity (such as IS_LEAP_MONTH). The + * DAY_OF_WEEK_IN_MONTH field does not depend on the current + * DAY_OF_WEEK; it returns the maximum for any day of week in the + * current month. Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR + * fields. + * + * @param field the field whose maximum is desired + * @return the maximum of the given field for the current date of this calendar + * @see #getMaximum + * @see #getLeastMaximum + * @stable ICU 2.0 + */ + public int getActualMaximum(int field) { + return calendar.getActualMaximum(getJDKField(field)); + } + + /** + * Returns the minimum value that this field could have, given the current date. + * For most fields, this is the same as {@link #getMinimum getMinimum} + * and {@link #getGreatestMinimum getGreatestMinimum}. However, some fields, + * especially those related to week number, are more complicated. + *

      + * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} + * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY. + * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday + * there will be four or more days in the first week, so it will be week number 1, + * and getActualMinimum(WEEK_OF_MONTH) will return 1. However, + * if the first of the month is a Thursday, Friday, or Saturday, there are + * not four days in that week, so it is week number 0, and + * getActualMinimum(WEEK_OF_MONTH) will return 0. + *

      + * @param field the field whose actual minimum value is desired. + * @return the minimum of the given field for the current date of this calendar + * + * @see #getMinimum + * @see #getGreatestMinimum + * @stable ICU 2.0 + */ + public int getActualMinimum(int field) { + return calendar.getActualMinimum(getJDKField(field)); + } + + /** + * Rolls (up/down) a single unit of time on the given field. If the + * field is rolled past its maximum allowable value, it will "wrap" back + * to its minimum and continue rolling. For + * example, to roll the current date up by one day, you can call: + *

      + * roll({@link #DATE}, true) + *

      + * When rolling on the {@link #YEAR} field, it will roll the year + * value in the range between 1 and the value returned by calling + * {@link #getMaximum getMaximum}({@link #YEAR}). + *

      + * When rolling on certain fields, the values of other fields may conflict and + * need to be changed. For example, when rolling the MONTH field + * for the Gregorian date 1/31/96 upward, the DAY_OF_MONTH field + * must be adjusted so that the result is 2/29/96 rather than the invalid + * 2/31/96. + *

      + * Note: Calling roll(field, true) N times is not + * necessarily equivalent to calling roll(field, N). For example, + * imagine that you start with the date Gregorian date January 31, 1995. If you call + * roll(Calendar.MONTH, 2), the result will be March 31, 1995. + * But if you call roll(Calendar.MONTH, true), the result will be + * February 28, 1995. Calling it one more time will give March 28, 1995, which + * is usually not the desired result. + *

      + * Note: You should always use roll and add rather + * than attempting to perform arithmetic operations directly on the fields + * of a Calendar. It is quite possible for Calendar subclasses + * to have fields with non-linear behavior, for example missing months + * or days during non-leap years. The subclasses' add and roll + * methods will take this into account, while simple arithmetic manipulations + * may give invalid results. + *

      + * @param field the calendar field to roll. + * + * @param up indicates if the value of the specified time field is to be + * rolled up or rolled down. Use true if rolling up, + * false otherwise. + * + * @exception IllegalArgumentException if the field is invalid or refers + * to a field that cannot be handled by this method. + * @see #roll(int, int) + * @see #add + * @stable ICU 2.0 + */ + public final void roll(int field, boolean up) + { + calendar.roll(getJDKField(field), up); + } + + /** + * Rolls (up/down) a specified amount time on the given field. For + * example, to roll the current date up by three days, you can call + * roll(Calendar.DATE, 3). If the + * field is rolled past its maximum allowable value, it will "wrap" back + * to its minimum and continue rolling. + * For example, calling roll(Calendar.DATE, 10) + * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96. + *

      + * When rolling on certain fields, the values of other fields may conflict and + * need to be changed. For example, when rolling the {@link #MONTH MONTH} field + * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field + * must be adjusted so that the result is 2/29/96 rather than the invalid + * 2/31/96. + *

      + * {@icunote} the ICU implementation of this method is able to roll + * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, + * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for + * additional fields in their overrides of roll. + *

      + * Note: You should always use roll and add rather + * than attempting to perform arithmetic operations directly on the fields + * of a Calendar. It is quite possible for Calendar subclasses + * to have fields with non-linear behavior, for example missing months + * or days during non-leap years. The subclasses' add and roll + * methods will take this into account, while simple arithmetic manipulations + * may give invalid results. + *

      + * Subclassing:
      + * This implementation of roll assumes that the behavior of the + * field is continuous between its minimum and maximum, which are found by + * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}. + * For most such fields, simple addition, subtraction, and modulus operations + * are sufficient to perform the roll. For week-related fields, + * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and + * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary. + * Subclasses can override these two methods if their values differ from the defaults. + *

      + * Subclasses that have fields for which the assumption of continuity breaks + * down must overide roll to handle those fields specially. + * For example, in the Hebrew calendar the month "Adar I" + * only occurs in leap years; in other years the calendar jumps from + * Shevat (month #4) to Adar (month #6). The + * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account, + * so that rolling the month of Shevat by one gives the proper result (Adar) in a + * non-leap year. + *

      + * @param field the calendar field to roll. + * @param amount the amount by which the field should be rolled. + * + * @exception IllegalArgumentException if the field is invalid or refers + * to a field that cannot be handled by this method. + * @see #roll(int, boolean) + * @see #add + * @stable ICU 2.0 + */ + public void roll(int field, int amount) { + calendar.roll(getJDKField(field), amount); + } + + /** + * Add a signed amount to a specified field, using this calendar's rules. + * For example, to add three days to the current date, you can call + * add(Calendar.DATE, 3). + *

      + * When adding to certain fields, the values of other fields may conflict and + * need to be changed. For example, when adding one to the {@link #MONTH MONTH} field + * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field + * must be adjusted so that the result is 2/29/96 rather than the invalid + * 2/31/96. + *

      + * {@icunote} The ICU implementation of this method is able to add to + * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, + * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for + * additional fields in their overrides of add. + *

      + * Note: You should always use roll and add rather + * than attempting to perform arithmetic operations directly on the fields + * of a Calendar. It is quite possible for Calendar subclasses + * to have fields with non-linear behavior, for example missing months + * or days during non-leap years. The subclasses' add and roll + * methods will take this into account, while simple arithmetic manipulations + * may give invalid results. + *

      + * Subclassing:
      + * This implementation of add assumes that the behavior of the + * field is continuous between its minimum and maximum, which are found by + * calling {@link #getActualMinimum getActualMinimum} and + * {@link #getActualMaximum getActualMaximum}. + * For such fields, simple arithmetic operations are sufficient to + * perform the add. + *

      + * Subclasses that have fields for which this assumption of continuity breaks + * down must overide add to handle those fields specially. + * For example, in the Hebrew calendar the month "Adar I" + * only occurs in leap years; in other years the calendar jumps from + * Shevat (month #4) to Adar (month #6). The + * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account, + * so that adding one month + * to a date in Shevat gives the proper result (Adar) in a non-leap year. + *

      + * @param field the time field. + * @param amount the amount to add to the field. + * + * @exception IllegalArgumentException if the field is invalid or refers + * to a field that cannot be handled by this method. + * @see #roll(int, int) + * @stable ICU 2.0 + */ + public void add(int field, int amount) { + calendar.add(getJDKField(field), amount); + } + + private static String _getDisplayName(Calendar cal) { + String type = cal.getType(); + if (type.equals("japanese")) { + return "Japanese Calendar"; + } else if (type.equals("buddhist")) { + return "Buddhist Calendar"; + } + return "Gregorian Calendar"; + } + + /** + * Returns the name of this calendar in the language of the given locale. + * @stable ICU 2.0 + */ + public String getDisplayName(Locale loc) { + return _getDisplayName(this); + } + + /** + * Returns the name of this calendar in the language of the given locale. + * @stable ICU 3.2 + */ + public String getDisplayName(ULocale loc) { + return _getDisplayName(this); + } + + /** + * Compares the times (in millis) represented by two + * Calendar objects. + * + * @param that the Calendar to compare to this. + * @return 0 if the time represented by + * this Calendar is equal to the time represented + * by that Calendar, a value less than + * 0 if the time represented by this is before + * the time represented by that, and a value greater than + * 0 if the time represented by this + * is after the time represented by that. + * @throws NullPointerException if that + * Calendar is null. + * @throws IllegalArgumentException if the time of that + * Calendar can't be obtained because of invalid + * calendar values. + * @stable ICU 3.4 + */ + public int compareTo(Calendar that) { + return calendar.compareTo(that.calendar); + } + + //------------------------------------------------------------------------- + // Interface for creating custon DateFormats for different types of Calendars + //------------------------------------------------------------------------- + + /** + * {@icu} Returns a DateFormat appropriate to this calendar. + * Subclasses wishing to specialize this behavior should override + * {@link #handleGetDateFormat}. + * @stable ICU 2.0 + */ + public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) { + if (dateStyle != DateFormat.NONE) { + if (timeStyle == DateFormat.NONE) { + return DateFormat.getDateInstance((Calendar)this.clone(), dateStyle, loc); + } else { + return DateFormat.getDateTimeInstance((Calendar)this.clone(), dateStyle, timeStyle, loc); + } + } else if (timeStyle != DateFormat.NONE) { + return DateFormat.getTimeInstance((Calendar)this.clone(), timeStyle, loc); + } else { + return null; + } + } + + /** + * {@icu} Returns a DateFormat appropriate to this calendar. + * Subclasses wishing to specialize this behavior should override + * {@link #handleGetDateFormat}. + * @stable ICU 3.2 + */ + public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) { + return getDateTimeFormat(dateStyle, timeStyle, loc.toLocale()); + } + + //------------------------------------------------------------------------- + // Constants + //------------------------------------------------------------------------- + + /** + * {@icu} Returns the difference between the given time and the time this + * calendar object is set to. If this calendar is set + * before the given time, the returned value will be + * positive. If this calendar is set after the given + * time, the returned value will be negative. The + * field parameter specifies the units of the return + * value. For example, if fieldDifference(when, + * Calendar.MONTH) returns 3, then this calendar is set to + * 3 months before when, and possibly some additional + * time less than one month. + * + *

      As a side effect of this call, this calendar is advanced + * toward when by the given amount. That is, calling + * this method has the side effect of calling add(field, + * n), where n is the return value. + * + *

      Usage: To use this method, call it first with the largest + * field of interest, then with progressively smaller fields. For + * example: + * + *

      +     * int y = cal.fieldDifference(when, Calendar.YEAR);
      +     * int m = cal.fieldDifference(when, Calendar.MONTH);
      +     * int d = cal.fieldDifference(when, Calendar.DATE);
      + * + * computes the difference between cal and + * when in years, months, and days. + * + *

      Note: fieldDifference() is + * asymmetrical. That is, in the following code: + * + *

      +     * cal.setTime(date1);
      +     * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
      +     * int d1 = cal.fieldDifference(date2, Calendar.DATE);
      +     * cal.setTime(date2);
      +     * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
      +     * int d2 = cal.fieldDifference(date1, Calendar.DATE);
      + * + * one might expect that m1 == -m2 && d1 == -d2. + * However, this is not generally the case, because of + * irregularities in the underlying calendar system (e.g., the + * Gregorian calendar has a varying number of days per month). + * + * @param when the date to compare this calendar's time to + * @param field the field in which to compute the result + * @return the difference, either positive or negative, between + * this calendar's time and when, in terms of + * field. + * @stable ICU 2.0 + */ + public int fieldDifference(Date when, int field) { + int min = 0; + long startMs = getTimeInMillis(); + long targetMs = when.getTime(); + // Always add from the start millis. This accomodates + // operations like adding years from February 29, 2000 up to + // February 29, 2004. If 1, 1, 1, 1 is added to the year + // field, the DOM gets pinned to 28 and stays there, giving an + // incorrect DOM difference of 1. We have to add 1, reset, 2, + // reset, 3, reset, 4. + if (startMs < targetMs) { + int max = 1; + // Find a value that is too large + for (;;) { + setTimeInMillis(startMs); + add(field, max); + long ms = getTimeInMillis(); + if (ms == targetMs) { + return max; + } else if (ms > targetMs) { + break; + } else { + max <<= 1; + if (max < 0) { + // Field difference too large to fit into int + throw new RuntimeException(); + } + } + } + // Do a binary search + while ((max - min) > 1) { + int t = (min + max) / 2; + setTimeInMillis(startMs); + add(field, t); + long ms = getTimeInMillis(); + if (ms == targetMs) { + return t; + } else if (ms > targetMs) { + max = t; + } else { + min = t; + } + } + } else if (startMs > targetMs) { + //Eclipse stated the following is "dead code" + /*if (false) { + // This works, and makes the code smaller, but costs + // an extra object creation and an extra couple cycles + // of calendar computation. + setTimeInMillis(targetMs); + min = -fieldDifference(new Date(startMs), field); + }*/ + int max = -1; + // Find a value that is too small + for (;;) { + setTimeInMillis(startMs); + add(field, max); + long ms = getTimeInMillis(); + if (ms == targetMs) { + return max; + } else if (ms < targetMs) { + break; + } else { + max <<= 1; + if (max == 0) { + // Field difference too large to fit into int + throw new RuntimeException(); + } + } + } + // Do a binary search + while ((min - max) > 1) { + int t = (min + max) / 2; + setTimeInMillis(startMs); + add(field, t); + long ms = getTimeInMillis(); + if (ms == targetMs) { + return t; + } else if (ms < targetMs) { + max = t; + } else { + min = t; + } + } + } + // Set calendar to end point + setTimeInMillis(startMs); + add(field, min); + return min; + } + + /** + * Sets the time zone with the given time zone value. + * @param value the given time zone. + * @stable ICU 2.0 + */ + public void setTimeZone(TimeZone value) + { + calendar.setTimeZone(value.timeZone); + } + + /** + * Returns the time zone. + * @return the time zone object associated with this calendar. + * @stable ICU 2.0 + */ + public TimeZone getTimeZone() + { + return new TimeZone(calendar.getTimeZone()); + } + + /** + * Specify whether or not date/time interpretation is to be lenient. With + * lenient interpretation, a date such as "February 942, 1996" will be + * treated as being equivalent to the 941st day after February 1, 1996. + * With strict interpretation, such dates will cause an exception to be + * thrown. + * + * @see DateFormat#setLenient + * @stable ICU 2.0 + */ + public void setLenient(boolean lenient) + { + calendar.setLenient(lenient); + } + + /** + * Tell whether date/time interpretation is to be lenient. + * @stable ICU 2.0 + */ + public boolean isLenient() + { + return calendar.isLenient(); + } + + /** + * Sets what the first day of the week is; e.g., Sunday in US, + * Monday in France. + * @param value the given first day of the week. + * @stable ICU 2.0 + */ + public void setFirstDayOfWeek(int value) + { + calendar.setFirstDayOfWeek(value); + } + + /** + * Returns what the first day of the week is; e.g., Sunday in US, + * Monday in France. + * @return the first day of the week. + * @stable ICU 2.0 + */ + public int getFirstDayOfWeek() + { + return calendar.getFirstDayOfWeek(); + } + + /** + * Sets what the minimal days required in the first week of the year are. + * For example, if the first week is defined as one that contains the first + * day of the first month of a year, call the method with value 1. If it + * must be a full week, use value 7. + * @param value the given minimal days required in the first week + * of the year. + * @stable ICU 2.0 + */ + public void setMinimalDaysInFirstWeek(int value) + { + calendar.setMinimalDaysInFirstWeek(value); + } + + /** + * Returns what the minimal days required in the first week of the year are; + * e.g., if the first week is defined as one that contains the first day + * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If + * the minimal days required must be a full week, getMinimalDaysInFirstWeek + * returns 7. + * @return the minimal days required in the first week of the year. + * @stable ICU 2.0 + */ + public int getMinimalDaysInFirstWeek() + { + return calendar.getMinimalDaysInFirstWeek(); + } + + /** + * Returns the minimum value for the given time field. + * e.g., for Gregorian DAY_OF_MONTH, 1. + * @param field the given time field. + * @return the minimum value for the given time field. + * @stable ICU 2.0 + */ + public final int getMinimum(int field) { + return calendar.getMinimum(getJDKField(field)); + } + + /** + * Returns the maximum value for the given time field. + * e.g. for Gregorian DAY_OF_MONTH, 31. + * @param field the given time field. + * @return the maximum value for the given time field. + * @stable ICU 2.0 + */ + public final int getMaximum(int field) { + return calendar.getMaximum(getJDKField(field)); + } + + /** + * Returns the highest minimum value for the given field if varies. + * Otherwise same as getMinimum(). For Gregorian, no difference. + * @param field the given time field. + * @return the highest minimum value for the given time field. + * @stable ICU 2.0 + */ + public final int getGreatestMinimum(int field) { + return calendar.getGreatestMinimum(getJDKField(field)); + } + + /** + * Returns the lowest maximum value for the given field if varies. + * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28. + * @param field the given time field. + * @return the lowest maximum value for the given time field. + * @stable ICU 2.0 + */ + public final int getLeastMaximum(int field) { + return calendar.getLeastMaximum(getJDKField(field)); + } + + //------------------------------------------------------------------------- + // Weekend support -- determining which days of the week are the weekend + // in a given locale + //------------------------------------------------------------------------- + + /** + * {@icu} Returns whether the given day of the week is a weekday, a + * weekend day, or a day that transitions from one to the other, + * in this calendar system. If a transition occurs at midnight, + * then the days before and after the transition will have the + * type WEEKDAY or WEEKEND. If a transition occurs at a time + * other than midnight, then the day of the transition will have + * the type WEEKEND_ONSET or WEEKEND_CEASE. In this case, the + * method getWeekendTransition() will return the point of + * transition. + * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, + * THURSDAY, FRIDAY, or SATURDAY + * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or + * WEEKEND_CEASE + * @exception IllegalArgumentException if dayOfWeek is not + * between SUNDAY and SATURDAY, inclusive + * @see #WEEKDAY + * @see #WEEKEND + * @see #WEEKEND_ONSET + * @see #WEEKEND_CEASE + * @see #getWeekendTransition + * @see #isWeekend(Date) + * @see #isWeekend() + * @stable ICU 2.0 + */ + public int getDayOfWeekType(int dayOfWeek) { + // weekend always full saturday and sunday with com.ibm.icu.base + if (dayOfWeek < SUNDAY || dayOfWeek > 7) { + throw new IllegalArgumentException("illegal day of week: " + dayOfWeek); + } else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY) { + return WEEKEND; + } + return WEEKDAY;} + + /** + * {@icu} Returns the time during the day at which the weekend begins or end in this + * calendar system. If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time + * at which the weekend begins. If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE + * return the time at which the weekend ends. If getDayOfWeekType(dayOfWeek) has some + * other value, then throw an exception. + * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, + * THURSDAY, FRIDAY, or SATURDAY + * @return the milliseconds after midnight at which the + * weekend begins or ends + * @exception IllegalArgumentException if dayOfWeek is not + * WEEKEND_ONSET or WEEKEND_CEASE + * @see #getDayOfWeekType + * @see #isWeekend(Date) + * @see #isWeekend() + * @stable ICU 2.0 + */ + public int getWeekendTransition(int dayOfWeek) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns true if the given date and time is in the weekend in this calendar + * system. Equivalent to calling setTime() followed by isWeekend(). Note: This + * method changes the time this calendar is set to. + * @param date the date and time + * @return true if the given date and time is part of the + * weekend + * @see #getDayOfWeekType + * @see #getWeekendTransition + * @see #isWeekend() + * @stable ICU 2.0 + */ + public boolean isWeekend(Date date) { + calendar.setTime(date); + return isWeekend(); + } + + /** + * {@icu} Returns true if this Calendar's current date and time is in the weekend in + * this calendar system. + * @return true if the given date and time is part of the + * weekend + * @see #getDayOfWeekType + * @see #getWeekendTransition + * @see #isWeekend(Date) + * @stable ICU 2.0 + */ + public boolean isWeekend() { + // weekend always full saturday and sunday with com.ibm.icu.base + int dow = calendar.get(Calendar.DAY_OF_WEEK); + if (dow == SATURDAY || dow == SUNDAY) { + return true; + } + return false; + } + + //------------------------------------------------------------------------- + // End of weekend support + //------------------------------------------------------------------------- + + /** + * Overrides Cloneable + * @stable ICU 2.0 + */ + public Object clone() + { + return new Calendar((java.util.Calendar)calendar.clone()); + } + + /** + * Returns a string representation of this calendar. This method + * is intended to be used only for debugging purposes, and the + * format of the returned string may vary between implementations. + * The returned string may be empty but may not be null. + * + * @return a string representation of this calendar. + * @stable ICU 2.0 + */ + public String toString() { + return calendar.toString(); + } + + /** + * {@icu} Returns the number of fields defined by this calendar. Valid field + * arguments to set() and get() are + * 0..getFieldCount()-1. + * @stable ICU 2.0 + */ + public final int getFieldCount() { + return FIELD_COUNT; + } + private static final int FIELD_COUNT = IS_LEAP_MONTH + 1; + + /** + * {@icu} Returns the current Calendar type. Note, in 3.0 this function will return + * 'gregorian' in Calendar to emulate legacy behavior + * @return type of calendar (gregorian, etc) + * @stable ICU 3.8 + */ + public String getType() { + // JDK supports Gregorian, Japanese and Buddhist + String name = calendar.getClass().getSimpleName().toLowerCase(Locale.US); + if (name.contains("japanese")) { + return "japanese"; + } else if (name.contains("buddhist")) { + return "buddhist"; + } + return "gregorian"; + } + + // -------- BEGIN ULocale boilerplate -------- + + /** + * {@icu} Returns the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: This method will be implemented in ICU 3.0; ICU 2.8 + * contains a partial preview implementation. The * actual + * locale is returned correctly, but the valid locale is + * not, in most cases. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + // -------- END ULocale boilerplate -------- + + + private static int getJDKField(int icuField) { + switch (icuField) { + case ERA: + return java.util.Calendar.ERA; + case YEAR: + return java.util.Calendar.YEAR; + case MONTH: + return java.util.Calendar.MONTH; + case WEEK_OF_YEAR: + return java.util.Calendar.WEEK_OF_YEAR; + case WEEK_OF_MONTH: + return java.util.Calendar.WEEK_OF_MONTH; + case DATE: + return java.util.Calendar.DATE; +// case DAY_OF_MONTH: +// return java.util.Calendar.DAY_OF_MONTH; + case DAY_OF_YEAR: + return java.util.Calendar.DAY_OF_YEAR; + case DAY_OF_WEEK: + return java.util.Calendar.DAY_OF_WEEK; + case DAY_OF_WEEK_IN_MONTH: + return java.util.Calendar.DAY_OF_WEEK_IN_MONTH; + case AM_PM: + return java.util.Calendar.AM_PM; + case HOUR: + return java.util.Calendar.HOUR; + case HOUR_OF_DAY: + return java.util.Calendar.HOUR_OF_DAY; + case MINUTE: + return java.util.Calendar.MINUTE; + case SECOND: + return java.util.Calendar.SECOND; + case MILLISECOND: + return java.util.Calendar.MILLISECOND; + case ZONE_OFFSET: + return java.util.Calendar.ZONE_OFFSET; + case DST_OFFSET: + return java.util.Calendar.DST_OFFSET; + + case YEAR_WOY: + case DOW_LOCAL: + case EXTENDED_YEAR: + case JULIAN_DAY: + case MILLISECONDS_IN_DAY: + // Unmappable + throw new UnsupportedOperationException("Calendar field type not supported by com.ibm.icu.base"); + default: + // Illegal + throw new ArrayIndexOutOfBoundsException("Specified calendar field is out of range"); + } + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java index bac782055f6..d6350290174 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java @@ -1,420 +1,420 @@ -/** - ******************************************************************************* - * Copyright (C) 2001-2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.util; - -import java.io.Serializable; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; - -/** - * A class encapsulating a currency, as defined by ISO 4217. A - * Currency object can be created given a Locale or - * given an ISO 4217 code. Once created, the Currency object - * can return various data necessary to its proper display: - * - *

      • A display symbol, for a specific locale - *
      • The number of fraction digits to display - *
      • A rounding increment - *
      - * - * The DecimalFormat class uses these data to display - * currencies. - * - *

      Note: This class deliberately resembles - * java.util.Currency but it has a completely independent - * implementation, and adds features not present in the JDK. - * @author Alan Liu - * @stable ICU 2.2 - */ -public class Currency implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * @internal - */ - public final java.util.Currency currency; - - /** - * @internal - * @param delegate the NumberFormat to which to delegate - */ - public Currency(java.util.Currency delegate) { - this.currency = delegate; - } - - /** - * Selector for getName() indicating a symbolic name for a - * currency, such as "$" for USD. - * @stable ICU 2.6 - */ - public static final int SYMBOL_NAME = 0; - - /** - * Selector for ucurr_getName indicating the long name for a - * currency, such as "US Dollar" for USD. - * @stable ICU 2.6 - */ - public static final int LONG_NAME = 1; - - /** - * Selector for getName() indicating the plural long name for a - * currency, such as "US dollar" for USD in "1 US dollar", - * and "US dollars" for USD in "2 US dollars". - * @stable ICU 4.2 - */ - public static final int PLURAL_LONG_NAME = 2; - - /** - * Returns a currency object for the default currency in the given - * locale. - * @param locale the locale - * @return the currency object for this locale - * @stable ICU 2.2 - */ - public static Currency getInstance(Locale locale) { - return new Currency(java.util.Currency.getInstance(locale)); - } - - /** - * Returns a currency object for the default currency in the given - * locale. - * @stable ICU 3.2 - */ - public static Currency getInstance(ULocale locale) { - return new Currency(java.util.Currency.getInstance(locale.toLocale())); - } - - /** - * Returns an array of Strings which contain the currency - * identifiers that are valid for the given locale on the - * given date. If there are no such identifiers, returns null. - * Returned identifiers are in preference order. - * @param loc the locale for which to retrieve currency codes. - * @param d the date for which to retrieve currency codes for the given locale. - * @return The array of ISO currency codes. - * @stable ICU 4.0 - */ - public static String[] getAvailableCurrencyCodes(ULocale loc, Date d) { - throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); - } - - /** - * Returns a currency object given an ISO 4217 3-letter code. - * @param theISOCode the iso code - * @return the currency for this iso code - * @throws NullPointerException if theISOCode is null. - * @throws IllegalArgumentException if theISOCode is not a - * 3-letter alpha code. - * @stable ICU 2.2 - */ - public static Currency getInstance(String theISOCode) { - return new Currency(java.util.Currency.getInstance(theISOCode)); - } - - /** - * Registers a new currency for the provided locale. The returned object - * is a key that can be used to unregister this currency object. - * @param currency the currency to register - * @param locale the ulocale under which to register the currency - * @return a registry key that can be used to unregister this currency - * @see #unregister - * @stable ICU 3.2 - */ - public static Object registerInstance(Currency currency, ULocale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Unregister the currency associated with this key (obtained from - * registerInstance). - * @param registryKey the registry key returned from registerInstance - * @see #registerInstance - * @stable ICU 2.6 - */ - public static boolean unregister(Object registryKey) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Return an array of the locales for which a currency - * is defined. - * @return an array of the available locales - * @stable ICU 2.2 - */ - public static Locale[] getAvailableLocales() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Return an array of the ulocales for which a currency - * is defined. - * @return an array of the available ulocales - * @stable ICU 3.2 - */ - public static ULocale[] getAvailableULocales() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Given a key and a locale, returns an array of values for the key for which data - * exists. If commonlyUsed is true, these are the values that typically are used - * with this locale, otherwise these are all values for which data exists. - * This is a common service API. - *

      - * The only supported key is "currency", other values return an empty array. - *

      - * Currency information is based on the region of the locale. If the locale does not - * indicate a region, {@link ULocale#addLikelySubtags(ULocale)} is used to infer a region, - * except for the 'und' locale. - *

      - * If commonlyUsed is true, only the currencies known to be in use as of the current date - * are returned. When there are more than one, these are returned in preference order - * (typically, this occurs when a country is transitioning to a new currency, and the - * newer currency is preferred), see - * Unicode TR#35 Sec. C1. - * If commonlyUsed is false, all currencies ever used in any locale are returned, in no - * particular order. - * - * @param key key whose values to look up. the only recognized key is "currency" - * @param locale the locale - * @param commonlyUsed if true, return only values that are currently used in the locale. - * Otherwise returns all values. - * @return an array of values for the given key and the locale. If there is no data, the - * array will be empty. - * @stable ICU 4.2 - */ - public static final String[] getKeywordValuesForLocale(String key, ULocale locale, - boolean commonlyUsed) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Return a hashcode for this currency. - * @stable ICU 2.2 - */ - public int hashCode() { - return currency.hashCode(); - } - - /** - * Return true if rhs is a Currency instance, - * is non-null, and has the same currency code. - * @stable ICU 2.2 - */ - public boolean equals(Object rhs) { - try { - return currency.equals(((Currency)rhs).currency); - } - catch (Exception e) { - return false; - } - } - - /** - * Returns the ISO 4217 3-letter code for this currency object. - * @stable ICU 2.2 - */ - public String getCurrencyCode() { - return currency.getCurrencyCode(); - } - - /** - * Convenience and compatibility override of getName that - * requests the symbol name. - * @see #getName - * @stable ICU 3.4 - */ - public String getSymbol() { - return currency.getSymbol(); - } - - /** - * Convenience and compatibility override of getName that - * requests the symbol name. - * @param loc the Locale for the symbol - * @see #getName - * @stable ICU 3.4 - */ - public String getSymbol(Locale loc) { - return currency.getSymbol(loc); - } - - /** - * Convenience and compatibility override of getName that - * requests the symbol name. - * @param uloc the ULocale for the symbol - * @see #getName - * @stable ICU 3.4 - */ - public String getSymbol(ULocale uloc) { - return currency.getSymbol(uloc.toLocale()); - } - - /** - * Returns the display name for the given currency in the - * given locale. - * This is a convenient method for - * getName(ULocale, int, boolean[]); - * @stable ICU 3.2 - */ - public String getName(Locale locale, - int nameStyle, - boolean[] isChoiceFormat) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the display name for the given currency in the - * given locale. For example, the display name for the USD - * currency object in the en_US locale is "$". - * @param locale locale in which to display currency - * @param nameStyle selector for which kind of name to return. - * The nameStyle should be either SYMBOL_NAME or - * LONG_NAME. Otherwise, throw IllegalArgumentException. - * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true - * if the returned value is a ChoiceFormat pattern; otherwise it - * is set to false - * @return display string for this currency. If the resource data - * contains no entry for this currency, then the ISO 4217 code is - * returned. If isChoiceFormat[0] is true, then the result is a - * ChoiceFormat pattern. Otherwise it is a static string. Note: - * as of ICU 4.4, choice formats are not used, and the value returned - * in isChoiceFormat is always false. - *

      - * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME - * or LONG_NAME. - * @see #getName(ULocale, int, String, boolean[]) - * @stable ICU 3.2 - */ - public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the display name for the given currency in the given locale. - * This is a convenience overload of getName(ULocale, int, String, boolean[]); - * @stable ICU 4.2 - */ - public String getName(Locale locale, int nameStyle, String pluralCount, - boolean[] isChoiceFormat) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the display name for the given currency in the - * given locale. For example, the SYMBOL_NAME for the USD - * currency object in the en_US locale is "$". - * The PLURAL_LONG_NAME for the USD currency object when the currency - * amount is plural is "US dollars", such as in "3.00 US dollars"; - * while the PLURAL_LONG_NAME for the USD currency object when the currency - * amount is singular is "US dollar", such as in "1.00 US dollar". - * @param locale locale in which to display currency - * @param nameStyle selector for which kind of name to return - * @param pluralCount plural count string for this locale - * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true - * if the returned value is a ChoiceFormat pattern; otherwise it - * is set to false - * @return display string for this currency. If the resource data - * contains no entry for this currency, then the ISO 4217 code is - * returned. If isChoiceFormat[0] is true, then the result is a - * ChoiceFormat pattern. Otherwise it is a static string. Note: - * as of ICU 4.4, choice formats are not used, and the value returned - * in isChoiceFormat is always false. - * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME, - * LONG_NAME, or PLURAL_LONG_NAME. - * @stable ICU 4.2 - */ - public String getName(ULocale locale, int nameStyle, String pluralCount, - boolean[] isChoiceFormat) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Attempt to parse the given string as a currency, either as a - * display name in the given locale, or as a 3-letter ISO 4217 - * code. If multiple display names match, then the longest one is - * selected. If both a display name and a 3-letter ISO code - * match, then the display name is preferred, unless it's length - * is less than 3. - * - * @param locale the locale of the display names to match - * @param text the text to parse - * @param type parse against currency type: LONG_NAME only or not - * @param pos input-output position; on input, the position within - * text to match; must have 0 <= pos.getIndex() < text.length(); - * on output, the position after the last matched character. If - * the parse fails, the position in unchanged upon output. - * @return the ISO 4217 code, as a string, of the best match, or - * null if there is no match - * - * @internal - * @deprecated This API is ICU internal only. - */ - public static String parse(ULocale locale, String text, int type, ParsePosition pos) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the number of the number of fraction digits that should - * be displayed for this currency. - * @return a non-negative number of fraction digits to be - * displayed - * @stable ICU 2.2 - */ - public int getDefaultFractionDigits() { - return currency.getDefaultFractionDigits(); - } - - /** - * Returns the rounding increment for this currency, or 0.0 if no - * rounding is done by this currency. - * @return the non-negative rounding increment, or 0.0 if none - * @stable ICU 2.2 - */ - public double getRoundingIncrement() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns the ISO 4217 code for this currency. - * @stable ICU 2.2 - */ - public String toString() { - return currency.toString(); - } - - /** - * Return the locale that was used to create this object, or null. - * This may may differ from the locale requested at the time of - * this object's creation. For example, if an object is created - * for locale en_US_CALIFORNIA, the actual data may be - * drawn from en (the actual locale), and - * en_US may be the most specific locale that exists (the - * valid locale). - * - *

      Note: This method will be obsoleted. The implementation is - * no longer locale-specific and so there is no longer a valid or - * actual locale associated with the Currency object. Until - * it is removed, this method will return the root locale. - * @param type type of information requested, either {@link - * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link - * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. - * @return the information specified by type, or null if - * this object was not constructed from locale data. - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @obsolete ICU 3.2 to be removed - * @deprecated This API is obsolete. - */ - public final ULocale getLocale(ULocale.Type type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } -} - -//eof +/** + ******************************************************************************* + * Copyright (C) 2001-2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.util; + +import java.io.Serializable; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +/** + * A class encapsulating a currency, as defined by ISO 4217. A + * Currency object can be created given a Locale or + * given an ISO 4217 code. Once created, the Currency object + * can return various data necessary to its proper display: + * + *

      • A display symbol, for a specific locale + *
      • The number of fraction digits to display + *
      • A rounding increment + *
      + * + * The DecimalFormat class uses these data to display + * currencies. + * + *

      Note: This class deliberately resembles + * java.util.Currency but it has a completely independent + * implementation, and adds features not present in the JDK. + * @author Alan Liu + * @stable ICU 2.2 + */ +public class Currency implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * @internal + */ + public final java.util.Currency currency; + + /** + * @internal + * @param delegate the NumberFormat to which to delegate + */ + public Currency(java.util.Currency delegate) { + this.currency = delegate; + } + + /** + * Selector for getName() indicating a symbolic name for a + * currency, such as "$" for USD. + * @stable ICU 2.6 + */ + public static final int SYMBOL_NAME = 0; + + /** + * Selector for ucurr_getName indicating the long name for a + * currency, such as "US Dollar" for USD. + * @stable ICU 2.6 + */ + public static final int LONG_NAME = 1; + + /** + * Selector for getName() indicating the plural long name for a + * currency, such as "US dollar" for USD in "1 US dollar", + * and "US dollars" for USD in "2 US dollars". + * @stable ICU 4.2 + */ + public static final int PLURAL_LONG_NAME = 2; + + /** + * Returns a currency object for the default currency in the given + * locale. + * @param locale the locale + * @return the currency object for this locale + * @stable ICU 2.2 + */ + public static Currency getInstance(Locale locale) { + return new Currency(java.util.Currency.getInstance(locale)); + } + + /** + * Returns a currency object for the default currency in the given + * locale. + * @stable ICU 3.2 + */ + public static Currency getInstance(ULocale locale) { + return new Currency(java.util.Currency.getInstance(locale.toLocale())); + } + + /** + * Returns an array of Strings which contain the currency + * identifiers that are valid for the given locale on the + * given date. If there are no such identifiers, returns null. + * Returned identifiers are in preference order. + * @param loc the locale for which to retrieve currency codes. + * @param d the date for which to retrieve currency codes for the given locale. + * @return The array of ISO currency codes. + * @stable ICU 4.0 + */ + public static String[] getAvailableCurrencyCodes(ULocale loc, Date d) { + throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); + } + + /** + * Returns a currency object given an ISO 4217 3-letter code. + * @param theISOCode the iso code + * @return the currency for this iso code + * @throws NullPointerException if theISOCode is null. + * @throws IllegalArgumentException if theISOCode is not a + * 3-letter alpha code. + * @stable ICU 2.2 + */ + public static Currency getInstance(String theISOCode) { + return new Currency(java.util.Currency.getInstance(theISOCode)); + } + + /** + * Registers a new currency for the provided locale. The returned object + * is a key that can be used to unregister this currency object. + * @param currency the currency to register + * @param locale the ulocale under which to register the currency + * @return a registry key that can be used to unregister this currency + * @see #unregister + * @stable ICU 3.2 + */ + public static Object registerInstance(Currency currency, ULocale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Unregister the currency associated with this key (obtained from + * registerInstance). + * @param registryKey the registry key returned from registerInstance + * @see #registerInstance + * @stable ICU 2.6 + */ + public static boolean unregister(Object registryKey) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Return an array of the locales for which a currency + * is defined. + * @return an array of the available locales + * @stable ICU 2.2 + */ + public static Locale[] getAvailableLocales() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Return an array of the ulocales for which a currency + * is defined. + * @return an array of the available ulocales + * @stable ICU 3.2 + */ + public static ULocale[] getAvailableULocales() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Given a key and a locale, returns an array of values for the key for which data + * exists. If commonlyUsed is true, these are the values that typically are used + * with this locale, otherwise these are all values for which data exists. + * This is a common service API. + *

      + * The only supported key is "currency", other values return an empty array. + *

      + * Currency information is based on the region of the locale. If the locale does not + * indicate a region, {@link ULocale#addLikelySubtags(ULocale)} is used to infer a region, + * except for the 'und' locale. + *

      + * If commonlyUsed is true, only the currencies known to be in use as of the current date + * are returned. When there are more than one, these are returned in preference order + * (typically, this occurs when a country is transitioning to a new currency, and the + * newer currency is preferred), see + * Unicode TR#35 Sec. C1. + * If commonlyUsed is false, all currencies ever used in any locale are returned, in no + * particular order. + * + * @param key key whose values to look up. the only recognized key is "currency" + * @param locale the locale + * @param commonlyUsed if true, return only values that are currently used in the locale. + * Otherwise returns all values. + * @return an array of values for the given key and the locale. If there is no data, the + * array will be empty. + * @stable ICU 4.2 + */ + public static final String[] getKeywordValuesForLocale(String key, ULocale locale, + boolean commonlyUsed) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Return a hashcode for this currency. + * @stable ICU 2.2 + */ + public int hashCode() { + return currency.hashCode(); + } + + /** + * Return true if rhs is a Currency instance, + * is non-null, and has the same currency code. + * @stable ICU 2.2 + */ + public boolean equals(Object rhs) { + try { + return currency.equals(((Currency)rhs).currency); + } + catch (Exception e) { + return false; + } + } + + /** + * Returns the ISO 4217 3-letter code for this currency object. + * @stable ICU 2.2 + */ + public String getCurrencyCode() { + return currency.getCurrencyCode(); + } + + /** + * Convenience and compatibility override of getName that + * requests the symbol name. + * @see #getName + * @stable ICU 3.4 + */ + public String getSymbol() { + return currency.getSymbol(); + } + + /** + * Convenience and compatibility override of getName that + * requests the symbol name. + * @param loc the Locale for the symbol + * @see #getName + * @stable ICU 3.4 + */ + public String getSymbol(Locale loc) { + return currency.getSymbol(loc); + } + + /** + * Convenience and compatibility override of getName that + * requests the symbol name. + * @param uloc the ULocale for the symbol + * @see #getName + * @stable ICU 3.4 + */ + public String getSymbol(ULocale uloc) { + return currency.getSymbol(uloc.toLocale()); + } + + /** + * Returns the display name for the given currency in the + * given locale. + * This is a convenient method for + * getName(ULocale, int, boolean[]); + * @stable ICU 3.2 + */ + public String getName(Locale locale, + int nameStyle, + boolean[] isChoiceFormat) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the display name for the given currency in the + * given locale. For example, the display name for the USD + * currency object in the en_US locale is "$". + * @param locale locale in which to display currency + * @param nameStyle selector for which kind of name to return. + * The nameStyle should be either SYMBOL_NAME or + * LONG_NAME. Otherwise, throw IllegalArgumentException. + * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true + * if the returned value is a ChoiceFormat pattern; otherwise it + * is set to false + * @return display string for this currency. If the resource data + * contains no entry for this currency, then the ISO 4217 code is + * returned. If isChoiceFormat[0] is true, then the result is a + * ChoiceFormat pattern. Otherwise it is a static string. Note: + * as of ICU 4.4, choice formats are not used, and the value returned + * in isChoiceFormat is always false. + *

      + * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME + * or LONG_NAME. + * @see #getName(ULocale, int, String, boolean[]) + * @stable ICU 3.2 + */ + public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the display name for the given currency in the given locale. + * This is a convenience overload of getName(ULocale, int, String, boolean[]); + * @stable ICU 4.2 + */ + public String getName(Locale locale, int nameStyle, String pluralCount, + boolean[] isChoiceFormat) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the display name for the given currency in the + * given locale. For example, the SYMBOL_NAME for the USD + * currency object in the en_US locale is "$". + * The PLURAL_LONG_NAME for the USD currency object when the currency + * amount is plural is "US dollars", such as in "3.00 US dollars"; + * while the PLURAL_LONG_NAME for the USD currency object when the currency + * amount is singular is "US dollar", such as in "1.00 US dollar". + * @param locale locale in which to display currency + * @param nameStyle selector for which kind of name to return + * @param pluralCount plural count string for this locale + * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true + * if the returned value is a ChoiceFormat pattern; otherwise it + * is set to false + * @return display string for this currency. If the resource data + * contains no entry for this currency, then the ISO 4217 code is + * returned. If isChoiceFormat[0] is true, then the result is a + * ChoiceFormat pattern. Otherwise it is a static string. Note: + * as of ICU 4.4, choice formats are not used, and the value returned + * in isChoiceFormat is always false. + * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME, + * LONG_NAME, or PLURAL_LONG_NAME. + * @stable ICU 4.2 + */ + public String getName(ULocale locale, int nameStyle, String pluralCount, + boolean[] isChoiceFormat) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Attempt to parse the given string as a currency, either as a + * display name in the given locale, or as a 3-letter ISO 4217 + * code. If multiple display names match, then the longest one is + * selected. If both a display name and a 3-letter ISO code + * match, then the display name is preferred, unless it's length + * is less than 3. + * + * @param locale the locale of the display names to match + * @param text the text to parse + * @param type parse against currency type: LONG_NAME only or not + * @param pos input-output position; on input, the position within + * text to match; must have 0 <= pos.getIndex() < text.length(); + * on output, the position after the last matched character. If + * the parse fails, the position in unchanged upon output. + * @return the ISO 4217 code, as a string, of the best match, or + * null if there is no match + * + * @internal + * @deprecated This API is ICU internal only. + */ + public static String parse(ULocale locale, String text, int type, ParsePosition pos) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the number of the number of fraction digits that should + * be displayed for this currency. + * @return a non-negative number of fraction digits to be + * displayed + * @stable ICU 2.2 + */ + public int getDefaultFractionDigits() { + return currency.getDefaultFractionDigits(); + } + + /** + * Returns the rounding increment for this currency, or 0.0 if no + * rounding is done by this currency. + * @return the non-negative rounding increment, or 0.0 if none + * @stable ICU 2.2 + */ + public double getRoundingIncrement() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns the ISO 4217 code for this currency. + * @stable ICU 2.2 + */ + public String toString() { + return currency.toString(); + } + + /** + * Return the locale that was used to create this object, or null. + * This may may differ from the locale requested at the time of + * this object's creation. For example, if an object is created + * for locale en_US_CALIFORNIA, the actual data may be + * drawn from en (the actual locale), and + * en_US may be the most specific locale that exists (the + * valid locale). + * + *

      Note: This method will be obsoleted. The implementation is + * no longer locale-specific and so there is no longer a valid or + * actual locale associated with the Currency object. Until + * it is removed, this method will return the root locale. + * @param type type of information requested, either {@link + * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link + * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. + * @return the information specified by type, or null if + * this object was not constructed from locale data. + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @obsolete ICU 3.2 to be removed + * @deprecated This API is obsolete. + */ + public final ULocale getLocale(ULocale.Type type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } +} + +//eof diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/CurrencyAmount.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/CurrencyAmount.java index 22b32391339..229a400ebbd 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/CurrencyAmount.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/CurrencyAmount.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.util; - -/* - * Empty stub - */ -public class CurrencyAmount { - private CurrencyAmount() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.util; + +/* + * Empty stub + */ +public class CurrencyAmount { + private CurrencyAmount() {} +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java index f775d29a276..6f5d08c20c8 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java @@ -1,710 +1,710 @@ -/* - * @(#)TimeZone.java 1.51 00/01/19 - * - * Copyright (C) 1996-2011, International Business Machines - * Corporation and others. All Rights Reserved. - */ - -package com.ibm.icu.util; - -import java.io.Serializable; -import java.util.Date; -import java.util.Locale; -import java.util.MissingResourceException; - -/** - * {@icuenhanced java.util.TimeZone}.{@icu _usage_} - * - *

      TimeZone represents a time zone offset, and also computes daylight - * savings. - * - *

      Typically, you get a TimeZone using {@link #getDefault()} - * which creates a TimeZone based on the time zone where the program - * is running. For example, for a program running in Japan, getDefault - * creates a TimeZone object based on Japanese Standard Time. - * - *

      You can also get a TimeZone using {@link #getTimeZone(String)} - * along with a time zone ID. For instance, the time zone ID for the - * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a - * U.S. Pacific Time TimeZone object with: - * - *

      - *
      - * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
      - * 
      - *
      - * You can use the {@link #getAvailableIDs()} method to iterate through - * all the supported time zone IDs. You can then choose a - * supported ID to get a TimeZone. - * If the time zone you want is not represented by one of the - * supported IDs, then you can create a custom time zone ID with - * the following syntax: - * - *
      - *
      - * GMT[+|-]hh[[:]mm]
      - * 
      - *
      - * - * For example, you might specify GMT+14:00 as a custom - * time zone ID. The TimeZone that is returned - * when you specify a custom time zone ID does not include - * daylight savings time. - * - *

      For compatibility with JDK 1.1.x, some other three-letter time zone IDs - * (such as "PST", "CTT", "AST") are also supported. However, their - * use is deprecated because the same abbreviation is often used - * for multiple time zones (for example, "CST" could be U.S. "Central Standard - * Time" and "China Standard Time"), and the Java platform can then only - * recognize one of them. - * - *

      Note: Starting from ICU4J 4.0, you can optionally choose - * JDK TimeZone as the time zone implementation. The TimeZone factory - * method getTimeZone creates an instance of ICU's own TimeZone - * subclass by default. If you want to use the JDK implementation always, you can - * set the default time zone implementation type by the new method - * setDefaultTimeZoneType. Alternatively, you can change the initial - * default implementation type by setting a property below. - * - *

      - *
      - * #
      - * # The default TimeZone implementation type used by the ICU TimeZone
      - * # factory method. [ ICU | JDK ]
      - * #
      - * com.ibm.icu.util.TimeZone.DefaultTimeZoneType = ICU
      - * 
      - *
      - * - *

      This property is included in ICUConfig.properties in com.ibm.icu package. When the - * TimeZone class is loaded, the initialization code checks if the property - * com.ibm.icu.util.TimeZone.DefaultTimeZoneType=xxx is defined by the system - * properties. If not available, then it loads ICUConfig.properties to get the default - * time zone implementation type. The property setting is only used for the initial - * default value and you can change the default type by calling - * setDefaultTimeZoneType at runtime. - * - * @see Calendar - * @see GregorianCalendar - * @see SimpleTimeZone - * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu - * @stable ICU 2.0 - */ -public class TimeZone implements Serializable, Cloneable { - private static final long serialVersionUID = 1L; - - /** - * @internal - */ - public final java.util.TimeZone timeZone; - - /** - * @internal - * @param delegate the TimeZone to which to delegate - */ - public TimeZone(java.util.TimeZone delegate) { - this.timeZone = delegate; - } - -// /** -// * {@icu} A logger for TimeZone. Will be null if logging is not on by way of system -// * property: "icu4j.debug.logging" -// * @draft ICU 4.4 -// * @provisional This API might change or be removed in a future release. -// */ -// public static ICULogger TimeZoneLogger = ICULogger.getICULogger(TimeZone.class.getName()); - - /** - * Default constructor. (For invocation by subclass constructors, - * typically implicit.) - * @stable ICU 2.8 - */ - public TimeZone() { - this.timeZone = java.util.TimeZone.getDefault(); - } - - /** - * {@icu} A time zone implementation type indicating ICU's own TimeZone used by - * getTimeZone, setDefaultTimeZoneType - * and getDefaultTimeZoneType. - * @stable ICU 4.0 - */ - public static final int TIMEZONE_ICU = 0; - /** - * {@icu} A time zone implementation type indicating JDK TimeZone used by - * getTimeZone, setDefaultTimeZoneType - * and getDefaultTimeZoneType. - * @stable ICU 4.0 - */ - public static final int TIMEZONE_JDK = 1; - - /** - * A style specifier for getDisplayName() indicating - * a short name, such as "PST." - * @see #LONG - * @stable ICU 2.0 - */ - public static final int SHORT = 0; - - /** - * A style specifier for getDisplayName() indicating - * a long name, such as "Pacific Standard Time." - * @see #SHORT - * @stable ICU 2.0 - */ - public static final int LONG = 1; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a short generic name, such as "PT." - * @see #LONG_GENERIC - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int SHORT_GENERIC = 2; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a long generic name, such as "Pacific Time." - * @see #SHORT_GENERIC - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int LONG_GENERIC = 3; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a short name derived from the timezone's offset, such as "-0800." - * @see #LONG_GMT - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int SHORT_GMT = 4; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a long name derived from the timezone's offset, such as "GMT-08:00." - * @see #SHORT_GMT - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int LONG_GMT = 5; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a short name derived from the timezone's short standard or daylight - * timezone name ignoring commonlyUsed, such as "PDT." - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - - public static final int SHORT_COMMONLY_USED = 6; - - /** - * {@icu} A style specifier for getDisplayName() indicating - * a long name derived from the timezone's fallback name, such as - * "United States (Los Angeles)." - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static final int GENERIC_LOCATION = 7; - - /** - * Gets the time zone offset, for current date, modified in case of - * daylight savings. This is the offset to add *to* UTC to get local time. - * @param era the era of the given date. - * @param year the year in the given date. - * @param month the month in the given date. - * Month is 0-based. e.g., 0 for January. - * @param day the day-in-month of the given date. - * @param dayOfWeek the day-of-week of the given date. - * @param milliseconds the millis in day in standard local time. - * @return the offset to add *to* GMT to get local time. - * @stable ICU 2.0 - */ - public int getOffset(int era, int year, int month, int day, - int dayOfWeek, int milliseconds) { - return timeZone.getOffset(era, year, month, day, dayOfWeek, milliseconds); - } - - - /** - * Returns the offset of this time zone from UTC at the specified - * date. If Daylight Saving Time is in effect at the specified - * date, the offset value is adjusted with the amount of daylight - * saving. - * - * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT - * @return the amount of time in milliseconds to add to UTC to get local time. - * - * @see Calendar#ZONE_OFFSET - * @see Calendar#DST_OFFSET - * @see #getOffset(long, boolean, int[]) - * @stable ICU 2.8 - */ - public int getOffset(long date) { - return timeZone.getOffset(date); - } - - /** - * Returns the time zone raw and GMT offset for the given moment - * in time. Upon return, local-millis = GMT-millis + rawOffset + - * dstOffset. All computations are performed in the proleptic - * Gregorian calendar. The default implementation in the TimeZone - * class delegates to the 8-argument getOffset(). - * - * @param date moment in time for which to return offsets, in - * units of milliseconds from January 1, 1970 0:00 GMT, either GMT - * time or local wall time, depending on `local'. - * @param local if true, `date' is local wall time; otherwise it - * is in GMT time. - * @param offsets output parameter to receive the raw offset, that - * is, the offset not including DST adjustments, in offsets[0], - * and the DST offset, that is, the offset to be added to - * `rawOffset' to obtain the total offset between local and GMT - * time, in offsets[1]. If DST is not in effect, the DST offset is - * zero; otherwise it is a positive value, typically one hour. - * - * @stable ICU 2.8 - */ - public void getOffset(long date, boolean local, int[] offsets) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the base time zone offset to GMT. - * This is the offset to add *to* UTC to get local time. - * @param offsetMillis the given base time zone offset to GMT. - * @stable ICU 2.0 - */ - public void setRawOffset(int offsetMillis) { - timeZone.setRawOffset(offsetMillis); - } - - /** - * Gets unmodified offset, NOT modified in case of daylight savings. - * This is the offset to add *to* UTC to get local time. - * @return the unmodified offset to add *to* UTC to get local time. - * @stable ICU 2.0 - */ - public int getRawOffset() { - return timeZone.getRawOffset(); - } - - /** - * Gets the ID of this time zone. - * @return the ID of this time zone. - * @stable ICU 2.0 - */ - public String getID() { - return timeZone.getID(); - } - - /** - * Sets the time zone ID. This does not change any other data in - * the time zone object. - * @param ID the new time zone ID. - * @stable ICU 2.0 - */ - public void setID(String ID) { - timeZone.setID(ID); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the default locale. - * This method returns the long generic name. - * If the display name is not available for the locale, - * a fallback based on the country, city, or time zone id will be used. - * @return the human-readable name of this time zone in the default locale. - * @stable ICU 2.0 - */ - public final String getDisplayName() { - return timeZone.getDisplayName(); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the specified locale. - * This method returns the long generic name. - * If the display name is not available for the locale, - * a fallback based on the country, city, or time zone id will be used. - * @param locale the locale in which to supply the display name. - * @return the human-readable name of this time zone in the given locale - * or in the default locale if the given locale is not recognized. - * @stable ICU 2.0 - */ - public final String getDisplayName(Locale locale) { - return timeZone.getDisplayName(locale); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the specified locale. - * This method returns the long name, not including daylight savings. - * If the display name is not available for the locale, - * a fallback based on the country, city, or time zone id will be used. - * @param locale the ulocale in which to supply the display name. - * @return the human-readable name of this time zone in the given locale - * or in the default ulocale if the given ulocale is not recognized. - * @stable ICU 3.2 - */ - public final String getDisplayName(ULocale locale) { - return timeZone.getDisplayName(locale.toLocale()); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the default locale. - * If the display name is not available for the locale, - * then this method returns a string in the format - * GMT[+-]hh:mm. - * @param daylight if true, return the daylight savings name. - * @param style the output style of the display name. Valid styles are - * SHORT, LONG, SHORT_GENERIC, - * LONG_GENERIC, SHORT_GMT, LONG_GMT, - * SHORT_COMMONLY_USED or GENERIC_LOCATION. - * @return the human-readable name of this time zone in the default locale. - * @stable ICU 2.0 - */ - public final String getDisplayName(boolean daylight, int style) { - return getDisplayName(daylight, style, ULocale.getDefault()); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the specified locale. - * If the display name is not available for the locale, - * then this method returns a string in the format - * GMT[+-]hh:mm. - * @param daylight if true, return the daylight savings name. - * @param style the output style of the display name. Valid styles are - * SHORT, LONG, SHORT_GENERIC, - * LONG_GENERIC, SHORT_GMT, LONG_GMT, - * SHORT_COMMONLY_USED or GENERIC_LOCATION. - * @param locale the locale in which to supply the display name. - * @return the human-readable name of this time zone in the given locale - * or in the default locale if the given locale is not recognized. - * @exception IllegalArgumentException style is invalid. - * @stable ICU 2.0 - */ - public String getDisplayName(boolean daylight, int style, Locale locale) { - return getDisplayName(daylight, style, ULocale.forLocale(locale)); - } - - /** - * Returns a name of this time zone suitable for presentation to the user - * in the specified locale. - * If the display name is not available for the locale, - * then this method returns a string in the format - * GMT[+-]hh:mm. - * @param daylight if true, return the daylight savings name. - * @param style the output style of the display name. Valid styles are - * SHORT, LONG, SHORT_GENERIC, - * LONG_GENERIC, SHORT_GMT, LONG_GMT, - * SHORT_COMMONLY_USED or GENERIC_LOCATION. - * @param locale the locale in which to supply the display name. - * @return the human-readable name of this time zone in the given locale - * or in the default locale if the given locale is not recognized. - * @exception IllegalArgumentException style is invalid. - * @stable ICU 3.2 - */ - public String getDisplayName(boolean daylight, int style, ULocale locale) { - if (style == SHORT) { - return timeZone.getDisplayName(daylight, java.util.TimeZone.SHORT, locale.toLocale()); - } else if (style == LONG) { - return timeZone.getDisplayName(daylight, java.util.TimeZone.LONG, locale.toLocale()); - } else { - throw new UnsupportedOperationException("Specified time zone format style is not supported by com.ibm.icu.base"); - } - } - - /** - * Returns the amount of time to be added to local standard time - * to get local wall clock time. - *

      - * The default implementation always returns 3600000 milliseconds - * (i.e., one hour) if this time zone observes Daylight Saving - * Time. Otherwise, 0 (zero) is returned. - *

      - * If an underlying TimeZone implementation subclass supports - * historical Daylight Saving Time changes, this method returns - * the known latest daylight saving value. - * - * @return the amount of saving time in milliseconds - * @stable ICU 2.8 - */ - public int getDSTSavings() { - return timeZone.getDSTSavings(); - } - - /** - * Queries if this time zone uses daylight savings time. - * @return true if this time zone uses daylight savings time, - * false, otherwise. - * @stable ICU 2.0 - */ - public boolean useDaylightTime() { - return timeZone.useDaylightTime(); - } - - /** - * Queries if the given date is in daylight savings time in - * this time zone. - * @param date the given Date. - * @return true if the given date is in daylight savings time, - * false, otherwise. - * @stable ICU 2.0 - */ - public boolean inDaylightTime(Date date) { - return timeZone.inDaylightTime(date); - } - - /** - * Gets the TimeZone for the given ID. - * - * @param ID the ID for a TimeZone, such as "America/Los_Angeles", - * or a custom ID such as "GMT-8:00". Note that the support of abbreviations, - * such as "PST", is for JDK 1.1.x compatibility only and full names should be used. - * - * @return the specified TimeZone, or the GMT zone if the given ID - * cannot be understood. - * @stable ICU 2.0 - */ - public static synchronized TimeZone getTimeZone(String ID) { - return new TimeZone(java.util.TimeZone.getTimeZone(ID)); - } - - /** - * Gets the TimeZone for the given ID and the timezone type. - * @param ID the ID for a TimeZone, such as "America/Los_Angeles", or a - * custom ID such as "GMT-8:00". Note that the support of abbreviations, such as - * "PST", is for JDK 1.1.x compatibility only and full names should be used. - * @param type Time zone type, either TIMEZONE_ICU or - * TIMEZONE_JDK. - * @return the specified TimeZone, or the GMT zone if the given ID - * cannot be understood. - * @stable ICU 4.0 - */ - public static synchronized TimeZone getTimeZone(String ID, int type) { - if (type == TIMEZONE_JDK) { - return new TimeZone(java.util.TimeZone.getTimeZone(ID)); - } - throw new UnsupportedOperationException("TIMEZONE_ICU not supported by com.ibm.icu.base"); - } - - /** - * Sets the default time zone type used by getTimeZone. - * @param type time zone type, either TIMEZONE_ICU or - * TIMEZONE_JDK. - * @stable ICU 4.0 - */ - public static synchronized void setDefaultTimeZoneType(int type) { - if (type != TIMEZONE_JDK) { - throw new UnsupportedOperationException("TimeZone type other than TIMEZONE_JDK is not supported by com.ibm.icu.base"); - } - } - - /** - * {@icu} Returns the default time zone type currently used. - * @return The default time zone type, either TIMEZONE_ICU or - * TIMEZONE_JDK. - * @stable ICU 4.0 - */ - public static int getDefaultTimeZoneType() { - return TIMEZONE_JDK; - } - - /** - * Return a new String array containing all system TimeZone IDs - * with the given raw offset from GMT. These IDs may be passed to - * get() to construct the corresponding TimeZone - * object. - * @param rawOffset the offset in milliseconds from GMT - * @return an array of IDs for system TimeZones with the given - * raw offset. If there are none, return a zero-length array. - * @stable ICU 2.0 - */ - public static String[] getAvailableIDs(int rawOffset) { - return java.util.TimeZone.getAvailableIDs(rawOffset); - - } - - - /** - * Return a new String array containing all system TimeZone IDs - * associated with the given country. These IDs may be passed to - * get() to construct the corresponding TimeZone - * object. - * @param country a two-letter ISO 3166 country code, or null - * to return zones not associated with any country - * @return an array of IDs for system TimeZones in the given - * country. If there are none, return a zero-length array. - * @stable ICU 2.0 - */ - public static String[] getAvailableIDs(String country) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Return a new String array containing all system TimeZone IDs. - * These IDs (and only these IDs) may be passed to - * get() to construct the corresponding TimeZone - * object. - * @return an array of all system TimeZone IDs - * @stable ICU 2.0 - */ - public static String[] getAvailableIDs() { - return java.util.TimeZone.getAvailableIDs(); - } - - /** - * {@icu} Returns the number of IDs in the equivalency group that - * includes the given ID. An equivalency group contains zones - * that have the same GMT offset and rules. - * - *

      The returned count includes the given ID; it is always >= 1 - * for valid IDs. The given ID must be a system time zone. If it - * is not, returns zero. - * @param id a system time zone ID - * @return the number of zones in the equivalency group containing - * 'id', or zero if 'id' is not a valid system ID - * @see #getEquivalentID - * @stable ICU 2.0 - */ - public static int countEquivalentIDs(String id) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns an ID in the equivalency group that - * includes the given ID. An equivalency group contains zones - * that have the same GMT offset and rules. - * - *

      The given index must be in the range 0..n-1, where n is the - * value returned by countEquivalentIDs(id). For - * some value of 'index', the returned value will be equal to the - * given id. If the given id is not a valid system time zone, or - * if 'index' is out of range, then returns an empty string. - * @param id a system time zone ID - * @param index a value from 0 to n-1, where n is the value - * returned by countEquivalentIDs(id) - * @return the ID of the index-th zone in the equivalency group - * containing 'id', or an empty string if 'id' is not a valid - * system ID or 'index' is out of range - * @see #countEquivalentIDs - * @stable ICU 2.0 - */ - public static String getEquivalentID(String id, int index) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Gets the default TimeZone for this host. - * The source of the default TimeZone - * may vary with implementation. - * @return a default TimeZone. - * @stable ICU 2.0 - */ - public static TimeZone getDefault() { - return new TimeZone(java.util.TimeZone.getDefault()); - } - - /** - * Sets the TimeZone that is - * returned by the getDefault method. If zone - * is null, reset the default to the value it had originally when the - * VM first started. - * @param tz the new default time zone - * @stable ICU 2.0 - */ - public static void setDefault(TimeZone tz) { - java.util.TimeZone.setDefault(tz.timeZone); - } - - /** - * Returns true if this zone has the same rule and offset as another zone. - * That is, if this zone differs only in ID, if at all. Returns false - * if the other zone is null. - * @param other the TimeZone object to be compared with - * @return true if the other zone is not null and is the same as this one, - * with the possible exception of the ID - * @stable ICU 2.0 - */ - public boolean hasSameRules(TimeZone other) { - return timeZone.hasSameRules(other.timeZone); - } - - /** - * Overrides clone. - * @stable ICU 2.0 - */ - public Object clone() { - return new TimeZone((java.util.TimeZone)timeZone.clone()); - } - - /** - * Overrides equals. - * @stable ICU 3.6 - */ - public boolean equals(Object obj){ - try { - return timeZone.equals(((TimeZone)obj).timeZone); - } catch (Exception e) { - return false; - } - } - - /** - * Overrides hashCode. - * @stable ICU 3.6 - */ - public int hashCode(){ - return timeZone.hashCode(); - } - - /** - * {@icu} Returns the time zone data version currently used by ICU. - * - * @return the version string, such as "2007f" - * @throws MissingResourceException if ICU time zone resource bundle - * is missing or the version information is not available. - * - * @stable ICU 3.8 - */ - public static synchronized String getTZDataVersion() { - throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the canonical system time zone ID or the normalized - * custom time zone ID for the given time zone ID. - * @param id The input time zone ID to be canonicalized. - * @return The canonical system time zone ID or the custom time zone ID - * in normalized format for the given time zone ID. When the given time zone ID - * is neither a known system time zone ID nor a valid custom time zone ID, - * null is returned. - * @stable ICU 4.0 - */ - public static String getCanonicalID(String id) { - throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the canonical system time zone ID or the normalized - * custom time zone ID for the given time zone ID. - * @param id The input time zone ID to be canonicalized. - * @param isSystemID When non-null boolean array is specified and - * the given ID is a known system time zone ID, true is set to isSystemID[0] - * @return The canonical system time zone ID or the custom time zone ID - * in normalized format for the given time zone ID. When the given time zone ID - * is neither a known system time zone ID nor a valid custom time zone ID, - * null is returned. - * @stable ICU 4.0 - */ - public static String getCanonicalID(String id, boolean[] isSystemID) { - throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); - } -} - -//eof +/* + * @(#)TimeZone.java 1.51 00/01/19 + * + * Copyright (C) 1996-2011, International Business Machines + * Corporation and others. All Rights Reserved. + */ + +package com.ibm.icu.util; + +import java.io.Serializable; +import java.util.Date; +import java.util.Locale; +import java.util.MissingResourceException; + +/** + * {@icuenhanced java.util.TimeZone}.{@icu _usage_} + * + *

      TimeZone represents a time zone offset, and also computes daylight + * savings. + * + *

      Typically, you get a TimeZone using {@link #getDefault()} + * which creates a TimeZone based on the time zone where the program + * is running. For example, for a program running in Japan, getDefault + * creates a TimeZone object based on Japanese Standard Time. + * + *

      You can also get a TimeZone using {@link #getTimeZone(String)} + * along with a time zone ID. For instance, the time zone ID for the + * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a + * U.S. Pacific Time TimeZone object with: + * + *

      + *
      + * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
      + * 
      + *
      + * You can use the {@link #getAvailableIDs()} method to iterate through + * all the supported time zone IDs. You can then choose a + * supported ID to get a TimeZone. + * If the time zone you want is not represented by one of the + * supported IDs, then you can create a custom time zone ID with + * the following syntax: + * + *
      + *
      + * GMT[+|-]hh[[:]mm]
      + * 
      + *
      + * + * For example, you might specify GMT+14:00 as a custom + * time zone ID. The TimeZone that is returned + * when you specify a custom time zone ID does not include + * daylight savings time. + * + *

      For compatibility with JDK 1.1.x, some other three-letter time zone IDs + * (such as "PST", "CTT", "AST") are also supported. However, their + * use is deprecated because the same abbreviation is often used + * for multiple time zones (for example, "CST" could be U.S. "Central Standard + * Time" and "China Standard Time"), and the Java platform can then only + * recognize one of them. + * + *

      Note: Starting from ICU4J 4.0, you can optionally choose + * JDK TimeZone as the time zone implementation. The TimeZone factory + * method getTimeZone creates an instance of ICU's own TimeZone + * subclass by default. If you want to use the JDK implementation always, you can + * set the default time zone implementation type by the new method + * setDefaultTimeZoneType. Alternatively, you can change the initial + * default implementation type by setting a property below. + * + *

      + *
      + * #
      + * # The default TimeZone implementation type used by the ICU TimeZone
      + * # factory method. [ ICU | JDK ]
      + * #
      + * com.ibm.icu.util.TimeZone.DefaultTimeZoneType = ICU
      + * 
      + *
      + * + *

      This property is included in ICUConfig.properties in com.ibm.icu package. When the + * TimeZone class is loaded, the initialization code checks if the property + * com.ibm.icu.util.TimeZone.DefaultTimeZoneType=xxx is defined by the system + * properties. If not available, then it loads ICUConfig.properties to get the default + * time zone implementation type. The property setting is only used for the initial + * default value and you can change the default type by calling + * setDefaultTimeZoneType at runtime. + * + * @see Calendar + * @see GregorianCalendar + * @see SimpleTimeZone + * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu + * @stable ICU 2.0 + */ +public class TimeZone implements Serializable, Cloneable { + private static final long serialVersionUID = 1L; + + /** + * @internal + */ + public final java.util.TimeZone timeZone; + + /** + * @internal + * @param delegate the TimeZone to which to delegate + */ + public TimeZone(java.util.TimeZone delegate) { + this.timeZone = delegate; + } + +// /** +// * {@icu} A logger for TimeZone. Will be null if logging is not on by way of system +// * property: "icu4j.debug.logging" +// * @draft ICU 4.4 +// * @provisional This API might change or be removed in a future release. +// */ +// public static ICULogger TimeZoneLogger = ICULogger.getICULogger(TimeZone.class.getName()); + + /** + * Default constructor. (For invocation by subclass constructors, + * typically implicit.) + * @stable ICU 2.8 + */ + public TimeZone() { + this.timeZone = java.util.TimeZone.getDefault(); + } + + /** + * {@icu} A time zone implementation type indicating ICU's own TimeZone used by + * getTimeZone, setDefaultTimeZoneType + * and getDefaultTimeZoneType. + * @stable ICU 4.0 + */ + public static final int TIMEZONE_ICU = 0; + /** + * {@icu} A time zone implementation type indicating JDK TimeZone used by + * getTimeZone, setDefaultTimeZoneType + * and getDefaultTimeZoneType. + * @stable ICU 4.0 + */ + public static final int TIMEZONE_JDK = 1; + + /** + * A style specifier for getDisplayName() indicating + * a short name, such as "PST." + * @see #LONG + * @stable ICU 2.0 + */ + public static final int SHORT = 0; + + /** + * A style specifier for getDisplayName() indicating + * a long name, such as "Pacific Standard Time." + * @see #SHORT + * @stable ICU 2.0 + */ + public static final int LONG = 1; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a short generic name, such as "PT." + * @see #LONG_GENERIC + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int SHORT_GENERIC = 2; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a long generic name, such as "Pacific Time." + * @see #SHORT_GENERIC + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int LONG_GENERIC = 3; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a short name derived from the timezone's offset, such as "-0800." + * @see #LONG_GMT + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int SHORT_GMT = 4; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a long name derived from the timezone's offset, such as "GMT-08:00." + * @see #SHORT_GMT + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int LONG_GMT = 5; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a short name derived from the timezone's short standard or daylight + * timezone name ignoring commonlyUsed, such as "PDT." + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + + public static final int SHORT_COMMONLY_USED = 6; + + /** + * {@icu} A style specifier for getDisplayName() indicating + * a long name derived from the timezone's fallback name, such as + * "United States (Los Angeles)." + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static final int GENERIC_LOCATION = 7; + + /** + * Gets the time zone offset, for current date, modified in case of + * daylight savings. This is the offset to add *to* UTC to get local time. + * @param era the era of the given date. + * @param year the year in the given date. + * @param month the month in the given date. + * Month is 0-based. e.g., 0 for January. + * @param day the day-in-month of the given date. + * @param dayOfWeek the day-of-week of the given date. + * @param milliseconds the millis in day in standard local time. + * @return the offset to add *to* GMT to get local time. + * @stable ICU 2.0 + */ + public int getOffset(int era, int year, int month, int day, + int dayOfWeek, int milliseconds) { + return timeZone.getOffset(era, year, month, day, dayOfWeek, milliseconds); + } + + + /** + * Returns the offset of this time zone from UTC at the specified + * date. If Daylight Saving Time is in effect at the specified + * date, the offset value is adjusted with the amount of daylight + * saving. + * + * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT + * @return the amount of time in milliseconds to add to UTC to get local time. + * + * @see Calendar#ZONE_OFFSET + * @see Calendar#DST_OFFSET + * @see #getOffset(long, boolean, int[]) + * @stable ICU 2.8 + */ + public int getOffset(long date) { + return timeZone.getOffset(date); + } + + /** + * Returns the time zone raw and GMT offset for the given moment + * in time. Upon return, local-millis = GMT-millis + rawOffset + + * dstOffset. All computations are performed in the proleptic + * Gregorian calendar. The default implementation in the TimeZone + * class delegates to the 8-argument getOffset(). + * + * @param date moment in time for which to return offsets, in + * units of milliseconds from January 1, 1970 0:00 GMT, either GMT + * time or local wall time, depending on `local'. + * @param local if true, `date' is local wall time; otherwise it + * is in GMT time. + * @param offsets output parameter to receive the raw offset, that + * is, the offset not including DST adjustments, in offsets[0], + * and the DST offset, that is, the offset to be added to + * `rawOffset' to obtain the total offset between local and GMT + * time, in offsets[1]. If DST is not in effect, the DST offset is + * zero; otherwise it is a positive value, typically one hour. + * + * @stable ICU 2.8 + */ + public void getOffset(long date, boolean local, int[] offsets) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the base time zone offset to GMT. + * This is the offset to add *to* UTC to get local time. + * @param offsetMillis the given base time zone offset to GMT. + * @stable ICU 2.0 + */ + public void setRawOffset(int offsetMillis) { + timeZone.setRawOffset(offsetMillis); + } + + /** + * Gets unmodified offset, NOT modified in case of daylight savings. + * This is the offset to add *to* UTC to get local time. + * @return the unmodified offset to add *to* UTC to get local time. + * @stable ICU 2.0 + */ + public int getRawOffset() { + return timeZone.getRawOffset(); + } + + /** + * Gets the ID of this time zone. + * @return the ID of this time zone. + * @stable ICU 2.0 + */ + public String getID() { + return timeZone.getID(); + } + + /** + * Sets the time zone ID. This does not change any other data in + * the time zone object. + * @param ID the new time zone ID. + * @stable ICU 2.0 + */ + public void setID(String ID) { + timeZone.setID(ID); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the default locale. + * This method returns the long generic name. + * If the display name is not available for the locale, + * a fallback based on the country, city, or time zone id will be used. + * @return the human-readable name of this time zone in the default locale. + * @stable ICU 2.0 + */ + public final String getDisplayName() { + return timeZone.getDisplayName(); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the specified locale. + * This method returns the long generic name. + * If the display name is not available for the locale, + * a fallback based on the country, city, or time zone id will be used. + * @param locale the locale in which to supply the display name. + * @return the human-readable name of this time zone in the given locale + * or in the default locale if the given locale is not recognized. + * @stable ICU 2.0 + */ + public final String getDisplayName(Locale locale) { + return timeZone.getDisplayName(locale); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the specified locale. + * This method returns the long name, not including daylight savings. + * If the display name is not available for the locale, + * a fallback based on the country, city, or time zone id will be used. + * @param locale the ulocale in which to supply the display name. + * @return the human-readable name of this time zone in the given locale + * or in the default ulocale if the given ulocale is not recognized. + * @stable ICU 3.2 + */ + public final String getDisplayName(ULocale locale) { + return timeZone.getDisplayName(locale.toLocale()); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the default locale. + * If the display name is not available for the locale, + * then this method returns a string in the format + * GMT[+-]hh:mm. + * @param daylight if true, return the daylight savings name. + * @param style the output style of the display name. Valid styles are + * SHORT, LONG, SHORT_GENERIC, + * LONG_GENERIC, SHORT_GMT, LONG_GMT, + * SHORT_COMMONLY_USED or GENERIC_LOCATION. + * @return the human-readable name of this time zone in the default locale. + * @stable ICU 2.0 + */ + public final String getDisplayName(boolean daylight, int style) { + return getDisplayName(daylight, style, ULocale.getDefault()); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the specified locale. + * If the display name is not available for the locale, + * then this method returns a string in the format + * GMT[+-]hh:mm. + * @param daylight if true, return the daylight savings name. + * @param style the output style of the display name. Valid styles are + * SHORT, LONG, SHORT_GENERIC, + * LONG_GENERIC, SHORT_GMT, LONG_GMT, + * SHORT_COMMONLY_USED or GENERIC_LOCATION. + * @param locale the locale in which to supply the display name. + * @return the human-readable name of this time zone in the given locale + * or in the default locale if the given locale is not recognized. + * @exception IllegalArgumentException style is invalid. + * @stable ICU 2.0 + */ + public String getDisplayName(boolean daylight, int style, Locale locale) { + return getDisplayName(daylight, style, ULocale.forLocale(locale)); + } + + /** + * Returns a name of this time zone suitable for presentation to the user + * in the specified locale. + * If the display name is not available for the locale, + * then this method returns a string in the format + * GMT[+-]hh:mm. + * @param daylight if true, return the daylight savings name. + * @param style the output style of the display name. Valid styles are + * SHORT, LONG, SHORT_GENERIC, + * LONG_GENERIC, SHORT_GMT, LONG_GMT, + * SHORT_COMMONLY_USED or GENERIC_LOCATION. + * @param locale the locale in which to supply the display name. + * @return the human-readable name of this time zone in the given locale + * or in the default locale if the given locale is not recognized. + * @exception IllegalArgumentException style is invalid. + * @stable ICU 3.2 + */ + public String getDisplayName(boolean daylight, int style, ULocale locale) { + if (style == SHORT) { + return timeZone.getDisplayName(daylight, java.util.TimeZone.SHORT, locale.toLocale()); + } else if (style == LONG) { + return timeZone.getDisplayName(daylight, java.util.TimeZone.LONG, locale.toLocale()); + } else { + throw new UnsupportedOperationException("Specified time zone format style is not supported by com.ibm.icu.base"); + } + } + + /** + * Returns the amount of time to be added to local standard time + * to get local wall clock time. + *

      + * The default implementation always returns 3600000 milliseconds + * (i.e., one hour) if this time zone observes Daylight Saving + * Time. Otherwise, 0 (zero) is returned. + *

      + * If an underlying TimeZone implementation subclass supports + * historical Daylight Saving Time changes, this method returns + * the known latest daylight saving value. + * + * @return the amount of saving time in milliseconds + * @stable ICU 2.8 + */ + public int getDSTSavings() { + return timeZone.getDSTSavings(); + } + + /** + * Queries if this time zone uses daylight savings time. + * @return true if this time zone uses daylight savings time, + * false, otherwise. + * @stable ICU 2.0 + */ + public boolean useDaylightTime() { + return timeZone.useDaylightTime(); + } + + /** + * Queries if the given date is in daylight savings time in + * this time zone. + * @param date the given Date. + * @return true if the given date is in daylight savings time, + * false, otherwise. + * @stable ICU 2.0 + */ + public boolean inDaylightTime(Date date) { + return timeZone.inDaylightTime(date); + } + + /** + * Gets the TimeZone for the given ID. + * + * @param ID the ID for a TimeZone, such as "America/Los_Angeles", + * or a custom ID such as "GMT-8:00". Note that the support of abbreviations, + * such as "PST", is for JDK 1.1.x compatibility only and full names should be used. + * + * @return the specified TimeZone, or the GMT zone if the given ID + * cannot be understood. + * @stable ICU 2.0 + */ + public static synchronized TimeZone getTimeZone(String ID) { + return new TimeZone(java.util.TimeZone.getTimeZone(ID)); + } + + /** + * Gets the TimeZone for the given ID and the timezone type. + * @param ID the ID for a TimeZone, such as "America/Los_Angeles", or a + * custom ID such as "GMT-8:00". Note that the support of abbreviations, such as + * "PST", is for JDK 1.1.x compatibility only and full names should be used. + * @param type Time zone type, either TIMEZONE_ICU or + * TIMEZONE_JDK. + * @return the specified TimeZone, or the GMT zone if the given ID + * cannot be understood. + * @stable ICU 4.0 + */ + public static synchronized TimeZone getTimeZone(String ID, int type) { + if (type == TIMEZONE_JDK) { + return new TimeZone(java.util.TimeZone.getTimeZone(ID)); + } + throw new UnsupportedOperationException("TIMEZONE_ICU not supported by com.ibm.icu.base"); + } + + /** + * Sets the default time zone type used by getTimeZone. + * @param type time zone type, either TIMEZONE_ICU or + * TIMEZONE_JDK. + * @stable ICU 4.0 + */ + public static synchronized void setDefaultTimeZoneType(int type) { + if (type != TIMEZONE_JDK) { + throw new UnsupportedOperationException("TimeZone type other than TIMEZONE_JDK is not supported by com.ibm.icu.base"); + } + } + + /** + * {@icu} Returns the default time zone type currently used. + * @return The default time zone type, either TIMEZONE_ICU or + * TIMEZONE_JDK. + * @stable ICU 4.0 + */ + public static int getDefaultTimeZoneType() { + return TIMEZONE_JDK; + } + + /** + * Return a new String array containing all system TimeZone IDs + * with the given raw offset from GMT. These IDs may be passed to + * get() to construct the corresponding TimeZone + * object. + * @param rawOffset the offset in milliseconds from GMT + * @return an array of IDs for system TimeZones with the given + * raw offset. If there are none, return a zero-length array. + * @stable ICU 2.0 + */ + public static String[] getAvailableIDs(int rawOffset) { + return java.util.TimeZone.getAvailableIDs(rawOffset); + + } + + + /** + * Return a new String array containing all system TimeZone IDs + * associated with the given country. These IDs may be passed to + * get() to construct the corresponding TimeZone + * object. + * @param country a two-letter ISO 3166 country code, or null + * to return zones not associated with any country + * @return an array of IDs for system TimeZones in the given + * country. If there are none, return a zero-length array. + * @stable ICU 2.0 + */ + public static String[] getAvailableIDs(String country) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Return a new String array containing all system TimeZone IDs. + * These IDs (and only these IDs) may be passed to + * get() to construct the corresponding TimeZone + * object. + * @return an array of all system TimeZone IDs + * @stable ICU 2.0 + */ + public static String[] getAvailableIDs() { + return java.util.TimeZone.getAvailableIDs(); + } + + /** + * {@icu} Returns the number of IDs in the equivalency group that + * includes the given ID. An equivalency group contains zones + * that have the same GMT offset and rules. + * + *

      The returned count includes the given ID; it is always >= 1 + * for valid IDs. The given ID must be a system time zone. If it + * is not, returns zero. + * @param id a system time zone ID + * @return the number of zones in the equivalency group containing + * 'id', or zero if 'id' is not a valid system ID + * @see #getEquivalentID + * @stable ICU 2.0 + */ + public static int countEquivalentIDs(String id) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns an ID in the equivalency group that + * includes the given ID. An equivalency group contains zones + * that have the same GMT offset and rules. + * + *

      The given index must be in the range 0..n-1, where n is the + * value returned by countEquivalentIDs(id). For + * some value of 'index', the returned value will be equal to the + * given id. If the given id is not a valid system time zone, or + * if 'index' is out of range, then returns an empty string. + * @param id a system time zone ID + * @param index a value from 0 to n-1, where n is the value + * returned by countEquivalentIDs(id) + * @return the ID of the index-th zone in the equivalency group + * containing 'id', or an empty string if 'id' is not a valid + * system ID or 'index' is out of range + * @see #countEquivalentIDs + * @stable ICU 2.0 + */ + public static String getEquivalentID(String id, int index) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Gets the default TimeZone for this host. + * The source of the default TimeZone + * may vary with implementation. + * @return a default TimeZone. + * @stable ICU 2.0 + */ + public static TimeZone getDefault() { + return new TimeZone(java.util.TimeZone.getDefault()); + } + + /** + * Sets the TimeZone that is + * returned by the getDefault method. If zone + * is null, reset the default to the value it had originally when the + * VM first started. + * @param tz the new default time zone + * @stable ICU 2.0 + */ + public static void setDefault(TimeZone tz) { + java.util.TimeZone.setDefault(tz.timeZone); + } + + /** + * Returns true if this zone has the same rule and offset as another zone. + * That is, if this zone differs only in ID, if at all. Returns false + * if the other zone is null. + * @param other the TimeZone object to be compared with + * @return true if the other zone is not null and is the same as this one, + * with the possible exception of the ID + * @stable ICU 2.0 + */ + public boolean hasSameRules(TimeZone other) { + return timeZone.hasSameRules(other.timeZone); + } + + /** + * Overrides clone. + * @stable ICU 2.0 + */ + public Object clone() { + return new TimeZone((java.util.TimeZone)timeZone.clone()); + } + + /** + * Overrides equals. + * @stable ICU 3.6 + */ + public boolean equals(Object obj){ + try { + return timeZone.equals(((TimeZone)obj).timeZone); + } catch (Exception e) { + return false; + } + } + + /** + * Overrides hashCode. + * @stable ICU 3.6 + */ + public int hashCode(){ + return timeZone.hashCode(); + } + + /** + * {@icu} Returns the time zone data version currently used by ICU. + * + * @return the version string, such as "2007f" + * @throws MissingResourceException if ICU time zone resource bundle + * is missing or the version information is not available. + * + * @stable ICU 3.8 + */ + public static synchronized String getTZDataVersion() { + throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the canonical system time zone ID or the normalized + * custom time zone ID for the given time zone ID. + * @param id The input time zone ID to be canonicalized. + * @return The canonical system time zone ID or the custom time zone ID + * in normalized format for the given time zone ID. When the given time zone ID + * is neither a known system time zone ID nor a valid custom time zone ID, + * null is returned. + * @stable ICU 4.0 + */ + public static String getCanonicalID(String id) { + throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the canonical system time zone ID or the normalized + * custom time zone ID for the given time zone ID. + * @param id The input time zone ID to be canonicalized. + * @param isSystemID When non-null boolean array is specified and + * the given ID is a known system time zone ID, true is set to isSystemID[0] + * @return The canonical system time zone ID or the custom time zone ID + * in normalized format for the given time zone ID. When the given time zone ID + * is neither a known system time zone ID nor a valid custom time zone ID, + * null is returned. + * @stable ICU 4.0 + */ + public static String getCanonicalID(String id, boolean[] isSystemID) { + throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base"); + } +} + +//eof diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java index 7ffd3222221..4d49adf54df 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java @@ -1,2493 +1,2493 @@ -/* -****************************************************************************** -* Copyright (C) 2003-2011, International Business Machines Corporation and * -* others. All Rights Reserved. * -****************************************************************************** -*/ - -package com.ibm.icu.util; - -import java.io.Serializable; -import java.text.ParseException; -import java.util.Iterator; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.Set; -import java.util.TreeMap; - -import com.ibm.icu.impl.ICUCache; -import com.ibm.icu.impl.LocaleIDParser; -import com.ibm.icu.impl.LocaleIDs; -import com.ibm.icu.impl.LocaleUtility; -import com.ibm.icu.impl.SimpleCache; -import com.ibm.icu.impl.locale.AsciiUtil; - -/** - * {@icuenhanced java.util.Locale}.{@icu _usage_} - * - * A class analogous to {@link java.util.Locale} that provides additional - * support for ICU protocol. In ICU 3.0 this class is enhanced to support - * RFC 3066 language identifiers. - * - *

      Many classes and services in ICU follow a factory idiom, in - * which a factory method or object responds to a client request with - * an object. The request includes a locale (the requested - * locale), and the returned object is constructed using data for that - * locale. The system may lack data for the requested locale, in - * which case the locale fallback mechanism will be invoked until a - * populated locale is found (the valid locale). Furthermore, - * even when a populated locale is found (the valid locale), - * further fallback may be required to reach a locale containing the - * specific data required by the service (the actual locale). - * - *

      ULocale performs 'normalization' and 'canonicalization' of locale ids. - * Normalization 'cleans up' ICU locale ids as follows: - *

        - *
      • language, script, country, variant, and keywords are properly cased
        - * (lower, title, upper, upper, and lower case respectively)
      • - *
      • hyphens used as separators are converted to underscores
      • - *
      • three-letter language and country ids are converted to two-letter - * equivalents where available
      • - *
      • surrounding spaces are removed from keywords and values
      • - *
      • if there are multiple keywords, they are put in sorted order
      • - *
      - * Canonicalization additionally performs the following: - *
        - *
      • POSIX ids are converted to ICU format IDs
      • - *
      • 'grandfathered' 3066 ids are converted to ICU standard form
      • - *
      • 'PREEURO' and 'EURO' variants are converted to currency keyword form, - * with the currency - * id appropriate to the country of the locale (for PREEURO) or EUR (for EURO). - *
      - * All ULocale constructors automatically normalize the locale id. To handle - * POSIX ids, canonicalize can be called to convert the id - * to canonical form, or the canonicalInstance factory method - * can be called.

      - * - *

      This class provides selectors {@link #VALID_LOCALE} and {@link - * #ACTUAL_LOCALE} intended for use in methods named - * getLocale(). These methods exist in several ICU classes, - * including {@link com.ibm.icu.util.Calendar}, {@link - * com.ibm.icu.util.Currency}, {@link com.ibm.icu.text.UFormat}, - * {@link com.ibm.icu.text.BreakIterator}, - * Collator, - * {@link com.ibm.icu.text.DateFormatSymbols}, and {@link - * com.ibm.icu.text.DecimalFormatSymbols} and their subclasses, if - * any. Once an object of one of these classes has been created, - * getLocale() may be called on it to determine the valid and - * actual locale arrived at during the object's construction. - * - *

      Note: The actual locale is returned correctly, but the valid - * locale is not, in most cases. - * - * @see java.util.Locale - * @author weiv - * @author Alan Liu - * @author Ram Viswanadha - * @stable ICU 2.8 - */ -public final class ULocale implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale FRENCH = new ULocale("fr", Locale.FRENCH); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale GERMAN = new ULocale("de", Locale.GERMAN); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale ITALIAN = new ULocale("it", Locale.ITALIAN); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale JAPANESE = new ULocale("ja", Locale.JAPANESE); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale KOREAN = new ULocale("ko", Locale.KOREAN); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale CHINESE = new ULocale("zh", Locale.CHINESE); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale SIMPLIFIED_CHINESE = new ULocale("zh_Hans", Locale.CHINESE); - - /** - * Useful constant for language. - * @stable ICU 3.0 - */ - public static final ULocale TRADITIONAL_CHINESE = new ULocale("zh_Hant", Locale.CHINESE); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale FRANCE = new ULocale("fr_FR", Locale.FRANCE); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale GERMANY = new ULocale("de_DE", Locale.GERMANY); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale ITALY = new ULocale("it_IT", Locale.ITALY); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale JAPAN = new ULocale("ja_JP", Locale.JAPAN); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale KOREA = new ULocale("ko_KR", Locale.KOREA); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale CHINA = new ULocale("zh_Hans_CN", Locale.CHINA); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale PRC = CHINA; - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale TAIWAN = new ULocale("zh_Hant_TW", Locale.TAIWAN); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale UK = new ULocale("en_GB", Locale.UK); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale US = new ULocale("en_US", Locale.US); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale CANADA = new ULocale("en_CA", Locale.CANADA); - - /** - * Useful constant for country/region. - * @stable ICU 3.0 - */ - public static final ULocale CANADA_FRENCH = new ULocale("fr_CA", Locale.CANADA_FRENCH); - - /** - * Handy constant. - */ - private static final String EMPTY_STRING = ""; - - // Used in both ULocale and LocaleIDParser, so moved up here. - private static final char UNDERSCORE = '_'; - - // default empty locale - private static final Locale EMPTY_LOCALE = new Locale("", ""); - - /** - * The root ULocale. - * @stable ICU 2.8 - */ - public static final ULocale ROOT = new ULocale("", EMPTY_LOCALE); - - private static final SimpleCache CACHE = new SimpleCache(); - - /** - * Cache the locale. - */ - private transient volatile Locale locale; - - /** - * The raw localeID that we were passed in. - */ - private String localeID; - - private static String[][] CANONICALIZE_MAP; - private static String[][] variantsToKeywords; - - private static void initCANONICALIZE_MAP() { - if (CANONICALIZE_MAP == null) { - /** - * This table lists pairs of locale ids for canonicalization. The - * The 1st item is the normalized id. The 2nd item is the - * canonicalized id. The 3rd is the keyword. The 4th is the keyword value. - */ - String[][] tempCANONICALIZE_MAP = { -// { EMPTY_STRING, "en_US_POSIX", null, null }, /* .NET name */ - { "C", "en_US_POSIX", null, null }, /* POSIX name */ - { "art_LOJBAN", "jbo", null, null }, /* registered name */ - { "az_AZ_CYRL", "az_Cyrl_AZ", null, null }, /* .NET name */ - { "az_AZ_LATN", "az_Latn_AZ", null, null }, /* .NET name */ - { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, - { "cel_GAULISH", "cel__GAULISH", null, null }, /* registered name */ - { "de_1901", "de__1901", null, null }, /* registered name */ - { "de_1906", "de__1906", null, null }, /* registered name */ - { "de__PHONEBOOK", "de", "collation", "phonebook" }, /* Old ICU name */ - { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, - { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, - { "de_LU_PREEURO", "de_LU", "currency", "EUR" }, - { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, - { "en_BOONT", "en__BOONT", null, null }, /* registered name */ - { "en_SCOUSE", "en__SCOUSE", null, null }, /* registered name */ - { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, - { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, - { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */ - { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, - { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, - { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, - { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, - { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, - { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, - { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, - { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, - { "hi__DIRECT", "hi", "collation", "direct" }, /* Old ICU name */ - { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, - { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, -// { "nb_NO_NY", "nn_NO", null, null }, - { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, - { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, - { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, - { "sl_ROZAJ", "sl__ROZAJ", null, null }, /* registered name */ - { "sr_SP_CYRL", "sr_Cyrl_RS", null, null }, /* .NET name */ - { "sr_SP_LATN", "sr_Latn_RS", null, null }, /* .NET name */ - { "sr_YU_CYRILLIC", "sr_Cyrl_RS", null, null }, /* Linux name */ - { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */ - { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", null, null }, /* Linux name */ - { "uz_UZ_CYRL", "uz_Cyrl_UZ", null, null }, /* .NET name */ - { "uz_UZ_LATN", "uz_Latn_UZ", null, null }, /* .NET name */ - { "zh_CHS", "zh_Hans", null, null }, /* .NET name */ - { "zh_CHT", "zh_Hant", null, null }, /* .NET name */ - { "zh_GAN", "zh__GAN", null, null }, /* registered name */ - { "zh_GUOYU", "zh", null, null }, /* registered name */ - { "zh_HAKKA", "zh__HAKKA", null, null }, /* registered name */ - { "zh_MIN", "zh__MIN", null, null }, /* registered name */ - { "zh_MIN_NAN", "zh__MINNAN", null, null }, /* registered name */ - { "zh_WUU", "zh__WUU", null, null }, /* registered name */ - { "zh_XIANG", "zh__XIANG", null, null }, /* registered name */ - { "zh_YUE", "zh__YUE", null, null } /* registered name */ - }; - - synchronized (ULocale.class) { - if (CANONICALIZE_MAP == null) { - CANONICALIZE_MAP = tempCANONICALIZE_MAP; - } - } - } - if (variantsToKeywords == null) { - /** - * This table lists pairs of locale ids for canonicalization. The - * The first item is the normalized variant id. - */ - String[][] tempVariantsToKeywords = { - { "EURO", "currency", "EUR" }, - { "PINYIN", "collation", "pinyin" }, /* Solaris variant */ - { "STROKE", "collation", "stroke" } /* Solaris variant */ - }; - - synchronized (ULocale.class) { - if (variantsToKeywords == null) { - variantsToKeywords = tempVariantsToKeywords; - } - } - } - } - - /* - * This table is used for mapping between ICU and special Java - * locales. When an ICU locale matches with - * /, the ICU locale is mapped to locale. - * For example, both ja_JP@calendar=japanese and ja@calendar=japanese - * are mapped to Java locale "ja_JP_JP". ICU locale "nn" is mapped - * to Java locale "no_NO_NY". - */ - private static final String[][] _javaLocaleMap = { - // { , , , , - { "ja_JP_JP", "ja_JP", "calendar", "japanese", "ja"}, - { "no_NO_NY", "nn_NO", null, null, "nn"}, - { "th_TH_TH", "th_TH", "numbers", "thai", "th"}, - }; - - /** - * Private constructor used by static initializers. - */ - private ULocale(String localeID, Locale locale) { - this.localeID = localeID; - this.locale = locale; - } - - /** - * Construct a ULocale object from a {@link java.util.Locale}. - * @param loc a JDK locale - */ - private ULocale(Locale loc) { - this.localeID = getName(forLocale(loc).toString()); - this.locale = loc; - } - - /** - * {@icu} Returns a ULocale object for a {@link java.util.Locale}. - * The ULocale is canonicalized. - * @param loc a JDK locale - * @stable ICU 3.2 - */ - public static ULocale forLocale(Locale loc) { - if (loc == null) { - return null; - } - ULocale result = CACHE.get(loc); - if (result == null) { - if (defaultULocale != null && loc == defaultULocale.locale) { - result = defaultULocale; - } else { - String locStr = loc.toString(); - if (locStr.length() == 0) { - result = ROOT; - } else { - for (int i = 0; i < _javaLocaleMap.length; i++) { - if (_javaLocaleMap[i][0].equals(locStr)) { - LocaleIDParser p = new LocaleIDParser(_javaLocaleMap[i][1]); - p.setKeywordValue(_javaLocaleMap[i][2], _javaLocaleMap[i][3]); - locStr = p.getName(); - break; - } - } - result = new ULocale(locStr, loc); - } - } - CACHE.put(loc, result); - } - return result; - } - - /** - * {@icu} Constructs a ULocale from a RFC 3066 locale ID. The locale ID consists - * of optional language, script, country, and variant fields in that order, - * separated by underscores, followed by an optional keyword list. The - * script, if present, is four characters long-- this distinguishes it - * from a country code, which is two characters long. Other fields - * are distinguished by position as indicated by the underscores. The - * start of the keyword list is indicated by '@', and consists of two - * or more keyword/value pairs separated by semicolons(';'). - * - *

      This constructor does not canonicalize the localeID. So, for - * example, "zh__pinyin" remains unchanged instead of converting - * to "zh@collation=pinyin". By default ICU only recognizes the - * latter as specifying pinyin collation. Use {@link #createCanonical} - * or {@link #canonicalize} if you need to canonicalize the localeID. - * - * @param localeID string representation of the locale, e.g: - * "en_US", "sy_Cyrl_YU", "zh__pinyin", "es_ES@currency=EUR;collation=traditional" - * @stable ICU 2.8 - */ - public ULocale(String localeID) { - this.localeID = getName(localeID); - } - - /** - * Convenience overload of ULocale(String, String, String) for - * compatibility with java.util.Locale. - * @see #ULocale(String, String, String) - * @stable ICU 3.4 - */ - public ULocale(String a, String b) { - this(a, b, null); - } - - /** - * Constructs a ULocale from a localeID constructed from the three 'fields' a, b, and - * c. These fields are concatenated using underscores to form a localeID of the form - * a_b_c, which is then handled like the localeID passed to ULocale(String - * localeID). - * - *

      Java locale strings consisting of language, country, and - * variant will be handled by this form, since the country code - * (being shorter than four letters long) will not be interpreted - * as a script code. If a script code is present, the final - * argument ('c') will be interpreted as the country code. It is - * recommended that this constructor only be used to ease porting, - * and that clients instead use the single-argument constructor - * when constructing a ULocale from a localeID. - * @param a first component of the locale id - * @param b second component of the locale id - * @param c third component of the locale id - * @see #ULocale(String) - * @stable ICU 3.0 - */ - public ULocale(String a, String b, String c) { - localeID = getName(lscvToID(a, b, c, EMPTY_STRING)); - } - - /** - * {@icu} Creates a ULocale from the id by first canonicalizing the id. - * @param nonCanonicalID the locale id to canonicalize - * @return the locale created from the canonical version of the ID. - * @stable ICU 3.0 - */ - public static ULocale createCanonical(String nonCanonicalID) { - return new ULocale(canonicalize(nonCanonicalID), (Locale)null); - } - - private static String lscvToID(String lang, String script, String country, String variant) { - StringBuilder buf = new StringBuilder(); - - if (lang != null && lang.length() > 0) { - buf.append(lang); - } - if (script != null && script.length() > 0) { - buf.append(UNDERSCORE); - buf.append(script); - } - if (country != null && country.length() > 0) { - buf.append(UNDERSCORE); - buf.append(country); - } - if (variant != null && variant.length() > 0) { - if (country == null || country.length() == 0) { - buf.append(UNDERSCORE); - } - buf.append(UNDERSCORE); - buf.append(variant); - } - return buf.toString(); - } - - /** - * {@icu} Converts this ULocale object to a {@link java.util.Locale}. - * @return a JDK locale that either exactly represents this object - * or is the closest approximation. - * @stable ICU 2.8 - */ - public Locale toLocale() { - if (locale == null) { - LocaleIDParser p = new LocaleIDParser(localeID); - String base = p.getBaseName(); - for (int i = 0; i < _javaLocaleMap.length; i++) { - if (base.equals(_javaLocaleMap[i][1]) || base.equals(_javaLocaleMap[i][4])) { - if (_javaLocaleMap[i][2] != null) { - String val = p.getKeywordValue(_javaLocaleMap[i][2]); - if (val != null && val.equals(_javaLocaleMap[i][3])) { - p = new LocaleIDParser(_javaLocaleMap[i][0]); - break; - } - } else { - p = new LocaleIDParser(_javaLocaleMap[i][0]); - break; - } - } - } - String[] names = p.getLanguageScriptCountryVariant(); - locale = new Locale(names[0], names[2], names[3]); - } - return locale; - } - - private static ICUCache nameCache = new SimpleCache(); - /** - * Keep our own default ULocale. - */ - private static Locale defaultLocale = Locale.getDefault(); - private static ULocale defaultULocale = new ULocale(defaultLocale); - - /** - * Returns the current default ULocale. - * @stable ICU 2.8 - */ - public static ULocale getDefault() { - synchronized (ULocale.class) { - Locale currentDefault = Locale.getDefault(); - if (!defaultLocale.equals(currentDefault)) { - defaultLocale = currentDefault; - defaultULocale = new ULocale(defaultLocale); - } - return defaultULocale; - } - } - - /** - * {@icu} Sets the default ULocale. This also sets the default Locale. - * If the caller does not have write permission to the - * user.language property, a security exception will be thrown, - * and the default ULocale will remain unchanged. - * @param newLocale the new default locale - * @throws SecurityException if a security manager exists and its - * checkPermission method doesn't allow the operation. - * @throws NullPointerException if newLocale is null - * @see SecurityManager#checkPermission(java.security.Permission) - * @see java.util.PropertyPermission - * @stable ICU 3.0 - */ - public static synchronized void setDefault(ULocale newLocale){ - Locale.setDefault(newLocale.toLocale()); - defaultULocale = newLocale; - } - - /** - * This is for compatibility with Locale-- in actuality, since ULocale is - * immutable, there is no reason to clone it, so this API returns 'this'. - * @stable ICU 3.0 - */ - public Object clone() { - return this; - } - - /** - * Returns the hashCode. - * @stable ICU 3.0 - */ - public int hashCode() { - return localeID.hashCode(); - } - - /** - * Returns true if the other object is another ULocale with the - * same full name, or is a String localeID that matches the full name. - * Note that since names are not canonicalized, two ULocales that - * function identically might not compare equal. - * - * @return true if this Locale is equal to the specified object. - * @stable ICU 3.0 - */ - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof String) { - return localeID.equals((String)obj); - } - if (obj instanceof ULocale) { - return localeID.equals(((ULocale)obj).localeID); - } - return false; - } - - /** - * {@icunote} Unlike the Locale API, this returns an array of ULocale, - * not Locale. Returns a list of all installed locales. - * @stable ICU 3.0 - */ - public static ULocale[] getAvailableLocales() { - if (availableLocales == null) { - synchronized (ULocale.class) { - if (availableLocales == null) { - Locale[] locales = Locale.getAvailableLocales(); - availableLocales = new ULocale[locales.length]; - for (int i = 0; i < locales.length; i++) { - availableLocales[i] = ULocale.forLocale(locales[i]); - } - } - } - } - return availableLocales.clone(); - } - private static volatile ULocale[] availableLocales = null; - - /** - * Returns a list of all 2-letter country codes defined in ISO 3166. - * Can be used to create Locales. - * @stable ICU 3.0 - */ - public static String[] getISOCountries() { - return LocaleIDs.getISOCountries(); - } - - /** - * Returns a list of all 2-letter language codes defined in ISO 639. - * Can be used to create Locales. - * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed. - * The list this function returns includes both the new and the old codes for the - * languages whose codes have changed.] - * @stable ICU 3.0 - */ - public static String[] getISOLanguages() { - return LocaleIDs.getISOLanguages(); - } - - /** - * Returns the language code for this locale, which will either be the empty string - * or a lowercase ISO 639 code. - * @see #getDisplayLanguage() - * @see #getDisplayLanguage(ULocale) - * @stable ICU 3.0 - */ - public String getLanguage() { - return getLanguage(localeID); - } - - /** - * Returns the language code for the locale ID, - * which will either be the empty string - * or a lowercase ISO 639 code. - * @see #getDisplayLanguage() - * @see #getDisplayLanguage(ULocale) - * @stable ICU 3.0 - */ - public static String getLanguage(String localeID) { - return new LocaleIDParser(localeID).getLanguage(); - } - - /** - * {@icu} Returns the script code for this locale, which might be the empty string. - * @see #getDisplayScript() - * @see #getDisplayScript(ULocale) - * @stable ICU 3.0 - */ - public String getScript() { - return getScript(localeID); - } - - /** - * {@icu} Returns the script code for the specified locale, which might be the empty - * string. - * @see #getDisplayScript() - * @see #getDisplayScript(ULocale) - * @stable ICU 3.0 - */ - public static String getScript(String localeID) { - return new LocaleIDParser(localeID).getScript(); - } - - /** - * Returns the country/region code for this locale, which will either be the empty string - * or an uppercase ISO 3166 2-letter code. - * @see #getDisplayCountry() - * @see #getDisplayCountry(ULocale) - * @stable ICU 3.0 - */ - public String getCountry() { - return getCountry(localeID); - } - - /** - * Returns the country/region code for this locale, which will either be the empty string - * or an uppercase ISO 3166 2-letter code. - * @param localeID The locale identification string. - * @see #getDisplayCountry() - * @see #getDisplayCountry(ULocale) - * @stable ICU 3.0 - */ - public static String getCountry(String localeID) { - return new LocaleIDParser(localeID).getCountry(); - } - - /** - * Returns the variant code for this locale, which might be the empty string. - * @see #getDisplayVariant() - * @see #getDisplayVariant(ULocale) - * @stable ICU 3.0 - */ - public String getVariant() { - return getVariant(localeID); - } - - /** - * Returns the variant code for the specified locale, which might be the empty string. - * @see #getDisplayVariant() - * @see #getDisplayVariant(ULocale) - * @stable ICU 3.0 - */ - public static String getVariant(String localeID) { - return new LocaleIDParser(localeID).getVariant(); - } - - /** - * {@icu} Returns the fallback locale for the specified locale, which might be the - * empty string. - * @stable ICU 3.2 - */ - public static String getFallback(String localeID) { - return getFallbackString(getName(localeID)); - } - - /** - * {@icu} Returns the fallback locale for this locale. If this locale is root, - * returns null. - * @stable ICU 3.2 - */ - public ULocale getFallback() { - if (localeID.length() == 0 || localeID.charAt(0) == '@') { - return null; - } - return new ULocale(getFallbackString(localeID), (Locale)null); - } - - /** - * Returns the given (canonical) locale id minus the last part before the tags. - */ - private static String getFallbackString(String fallback) { - int extStart = fallback.indexOf('@'); - if (extStart == -1) { - extStart = fallback.length(); - } - int last = fallback.lastIndexOf('_', extStart); - if (last == -1) { - last = 0; - } else { - // truncate empty segment - while (last > 0) { - if (fallback.charAt(last - 1) != '_') { - break; - } - last--; - } - } - return fallback.substring(0, last) + fallback.substring(extStart); - } - - /** - * {@icu} Returns the (normalized) base name for this locale. - * @return the base name as a String. - * @stable ICU 3.0 - */ - public String getBaseName() { - return getBaseName(localeID); - } - - /** - * {@icu} Returns the (normalized) base name for the specified locale. - * @param localeID the locale ID as a string - * @return the base name as a String. - * @stable ICU 3.0 - */ - public static String getBaseName(String localeID){ - if (localeID.indexOf('@') == -1) { - return localeID; - } - return new LocaleIDParser(localeID).getBaseName(); - } - - /** - * {@icu} Returns the (normalized) full name for this locale. - * - * @return String the full name of the localeID - * @stable ICU 3.0 - */ - public String getName() { - return localeID; // always normalized - } - - /** - * {@icu} Returns the (normalized) full name for the specified locale. - * - * @param localeID the localeID as a string - * @return String the full name of the localeID - * @stable ICU 3.0 - */ - public static String getName(String localeID){ - String name = nameCache.get(localeID); - if (name == null) { - name = new LocaleIDParser(localeID).getName(); - nameCache.put(localeID, name); - } - return name; - } - - /** - * Returns a string representation of this object. - * @stable ICU 3.0 - */ - public String toString() { - return localeID; - } - - /** - * {@icu} Returns an iterator over keywords for this locale. If there - * are no keywords, returns null. - * @return iterator over keywords, or null if there are no keywords. - * @stable ICU 3.0 - */ - public Iterator getKeywords() { - return getKeywords(localeID); - } - - /** - * {@icu} Returns an iterator over keywords for the specified locale. If there - * are no keywords, returns null. - * @return an iterator over the keywords in the specified locale, or null - * if there are no keywords. - * @stable ICU 3.0 - */ - public static Iterator getKeywords(String localeID){ - return new LocaleIDParser(localeID).getKeywords(); - } - - /** - * {@icu} Returns the value for a keyword in this locale. If the keyword is not - * defined, returns null. - * @param keywordName name of the keyword whose value is desired. Case insensitive. - * @return the value of the keyword, or null. - * @stable ICU 3.0 - */ - public String getKeywordValue(String keywordName){ - return getKeywordValue(localeID, keywordName); - } - - /** - * {@icu} Returns the value for a keyword in the specified locale. If the keyword is - * not defined, returns null. The locale name does not need to be normalized. - * @param keywordName name of the keyword whose value is desired. Case insensitive. - * @return String the value of the keyword as a string - * @stable ICU 3.0 - */ - public static String getKeywordValue(String localeID, String keywordName) { - return new LocaleIDParser(localeID).getKeywordValue(keywordName); - } - - /** - * {@icu} Returns the canonical name for the specified locale ID. This is used to - * convert POSIX and other grandfathered IDs to standard ICU form. - * @param localeID the locale id - * @return the canonicalized id - * @stable ICU 3.0 - */ - public static String canonicalize(String localeID){ - LocaleIDParser parser = new LocaleIDParser(localeID, true); - String baseName = parser.getBaseName(); - boolean foundVariant = false; - - // formerly, we always set to en_US_POSIX if the basename was empty, but - // now we require that the entire id be empty, so that "@foo=bar" - // will pass through unchanged. - // {dlf} I'd rather keep "" unchanged. - if (localeID.equals("")) { - return ""; -// return "en_US_POSIX"; - } - - // we have an ID in the form xx_Yyyy_ZZ_KKKKK - - initCANONICALIZE_MAP(); - - /* convert the variants to appropriate ID */ - for (int i = 0; i < variantsToKeywords.length; i++) { - String[] vals = variantsToKeywords[i]; - int idx = baseName.lastIndexOf("_" + vals[0]); - if (idx > -1) { - foundVariant = true; - - baseName = baseName.substring(0, idx); - if (baseName.endsWith("_")) { - baseName = baseName.substring(0, --idx); - } - parser.setBaseName(baseName); - parser.defaultKeywordValue(vals[1], vals[2]); - break; - } - } - - /* See if this is an already known locale */ - for (int i = 0; i < CANONICALIZE_MAP.length; i++) { - if (CANONICALIZE_MAP[i][0].equals(baseName)) { - foundVariant = true; - - String[] vals = CANONICALIZE_MAP[i]; - parser.setBaseName(vals[1]); - if (vals[2] != null) { - parser.defaultKeywordValue(vals[2], vals[3]); - } - break; - } - } - - /* total mondo hack for Norwegian, fortunately the main NY case is handled earlier */ - if (!foundVariant) { - if (parser.getLanguage().equals("nb") && parser.getVariant().equals("NY")) { - parser.setBaseName(lscvToID("nn", parser.getScript(), parser.getCountry(), null)); - } - } - - return parser.getName(); - } - - /** - * Given a keyword and a value, return a new locale with an updated - * keyword and value. If keyword is null, this removes all keywords from the locale id. - * Otherwise, if the value is null, this removes the value for this keyword from the - * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. - * The keyword and value must not be empty. - * @param keyword the keyword to add/remove, or null to remove all keywords. - * @param value the value to add/set, or null to remove this particular keyword. - * @return the updated locale - * @stable ICU 3.2 - */ - public ULocale setKeywordValue(String keyword, String value) { - return new ULocale(setKeywordValue(localeID, keyword, value), (Locale)null); - } - - /** - * Given a locale id, a keyword, and a value, return a new locale id with an updated - * keyword and value. If keyword is null, this removes all keywords from the locale id. - * Otherwise, if the value is null, this removes the value for this keyword from the - * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. - * The keyword and value must not be empty. - * @param localeID the locale id to modify - * @param keyword the keyword to add/remove, or null to remove all keywords. - * @param value the value to add/set, or null to remove this particular keyword. - * @return the updated locale id - * @stable ICU 3.2 - */ - public static String setKeywordValue(String localeID, String keyword, String value) { - LocaleIDParser parser = new LocaleIDParser(localeID); - parser.setKeywordValue(keyword, value); - return parser.getName(); - } - - /* - * Given a locale id, a keyword, and a value, return a new locale id with an updated - * keyword and value, if the keyword does not already have a value. The keyword and - * value must not be null or empty. - * @param localeID the locale id to modify - * @param keyword the keyword to add, if not already present - * @param value the value to add, if not already present - * @return the updated locale id - */ -/* private static String defaultKeywordValue(String localeID, String keyword, String value) { - LocaleIDParser parser = new LocaleIDParser(localeID); - parser.defaultKeywordValue(keyword, value); - return parser.getName(); - }*/ - - /** - * Returns a three-letter abbreviation for this locale's language. If the locale - * doesn't specify a language, returns the empty string. Otherwise, returns - * a lowercase ISO 639-2/T language code. - * The ISO 639-2 language codes can be found on-line at - * ftp://dkuug.dk/i18n/iso-639-2.txt - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter language abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public String getISO3Language(){ - return getISO3Language(localeID); - } - - /** - * Returns a three-letter abbreviation for this locale's language. If the locale - * doesn't specify a language, returns the empty string. Otherwise, returns - * a lowercase ISO 639-2/T language code. - * The ISO 639-2 language codes can be found on-line at - * ftp://dkuug.dk/i18n/iso-639-2.txt - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter language abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public static String getISO3Language(String localeID) { - return LocaleIDs.getISO3Language(getLanguage(localeID)); - } - - /** - * Returns a three-letter abbreviation for this locale's country/region. If the locale - * doesn't specify a country, returns the empty string. Otherwise, returns - * an uppercase ISO 3166 3-letter country code. - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter country abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public String getISO3Country() { - return getISO3Country(localeID); - } - - /** - * Returns a three-letter abbreviation for this locale's country/region. If the locale - * doesn't specify a country, returns the empty string. Otherwise, returns - * an uppercase ISO 3166 3-letter country code. - * @exception MissingResourceException Throws MissingResourceException if the - * three-letter country abbreviation is not available for this locale. - * @stable ICU 3.0 - */ - public static String getISO3Country(String localeID) { - return LocaleIDs.getISO3Country(getCountry(localeID)); - } - - // display names - - /** - * Returns this locale's language localized for display in the default locale. - * @return the localized language name. - * @stable ICU 3.0 - */ - public String getDisplayLanguage() { - return getDisplayLanguageInternal(this, getDefault(), false); - } - - /** - * {@icu} Returns this locale's language localized for display in the provided locale. - * @param displayLocale the locale in which to display the name. - * @return the localized language name. - * @stable ICU 3.0 - */ - public String getDisplayLanguage(ULocale displayLocale) { - return getDisplayLanguageInternal(this, displayLocale, false); - } - - /** - * Returns a locale's language localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose language will be displayed - * @param displayLocaleID the id of the locale in which to display the name. - * @return the localized language name. - * @stable ICU 3.0 - */ - public static String getDisplayLanguage(String localeID, String displayLocaleID) { - return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), - false); - } - - /** - * Returns a locale's language localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose language will be displayed. - * @param displayLocale the locale in which to display the name. - * @return the localized language name. - * @stable ICU 3.0 - */ - public static String getDisplayLanguage(String localeID, ULocale displayLocale) { - return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, false); - } - /** - * {@icu} Returns this locale's language localized for display in the default locale. - * If a dialect name is present in the data, then it is returned. - * @return the localized language name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public String getDisplayLanguageWithDialect() { - return getDisplayLanguageInternal(this, getDefault(), true); - } - - /** - * {@icu} Returns this locale's language localized for display in the provided locale. - * If a dialect name is present in the data, then it is returned. - * @param displayLocale the locale in which to display the name. - * @return the localized language name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public String getDisplayLanguageWithDialect(ULocale displayLocale) { - return getDisplayLanguageInternal(this, displayLocale, true); - } - - /** - * {@icu} Returns a locale's language localized for display in the provided locale. - * If a dialect name is present in the data, then it is returned. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose language will be displayed - * @param displayLocaleID the id of the locale in which to display the name. - * @return the localized language name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static String getDisplayLanguageWithDialect(String localeID, String displayLocaleID) { - return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), - true); - } - - /** - * {@icu} Returns a locale's language localized for display in the provided locale. - * If a dialect name is present in the data, then it is returned. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose language will be displayed. - * @param displayLocale the locale in which to display the name. - * @return the localized language name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static String getDisplayLanguageWithDialect(String localeID, ULocale displayLocale) { - return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, true); - } - - private static String getDisplayLanguageInternal(ULocale locale, ULocale displayLocale, - boolean useDialect) { - // No dialect support - return locale.toLocale().getDisplayLanguage(displayLocale.toLocale()); - } - - /** - * {@icu} Returns this locale's script localized for display in the default locale. - * @return the localized script name. - * @stable ICU 3.0 - */ - public String getDisplayScript() { - return getDisplayScriptInternal(this, getDefault()); - } - - /** - * {@icu} Returns this locale's script localized for display in the provided locale. - * @param displayLocale the locale in which to display the name. - * @return the localized script name. - * @stable ICU 3.0 - */ - public String getDisplayScript(ULocale displayLocale) { - return getDisplayScriptInternal(this, displayLocale); - } - - /** - * {@icu} Returns a locale's script localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose script will be displayed - * @param displayLocaleID the id of the locale in which to display the name. - * @return the localized script name. - * @stable ICU 3.0 - */ - public static String getDisplayScript(String localeID, String displayLocaleID) { - return getDisplayScriptInternal(new ULocale(localeID), new ULocale(displayLocaleID)); - } - - /** - * {@icu} Returns a locale's script localized for display in the provided locale. - * @param localeID the id of the locale whose script will be displayed. - * @param displayLocale the locale in which to display the name. - * @return the localized script name. - * @stable ICU 3.0 - */ - public static String getDisplayScript(String localeID, ULocale displayLocale) { - return getDisplayScriptInternal(new ULocale(localeID), displayLocale); - } - - // displayLocaleID is canonical, localeID need not be since parsing will fix this. - private static String getDisplayScriptInternal(ULocale locale, ULocale displayLocale) { - // No localization, just return the script code - return locale.getScript(); - } - - /** - * Returns this locale's country localized for display in the default locale. - * @return the localized country name. - * @stable ICU 3.0 - */ - public String getDisplayCountry() { - return getDisplayCountryInternal(this, getDefault()); - } - - /** - * Returns this locale's country localized for display in the provided locale. - * @param displayLocale the locale in which to display the name. - * @return the localized country name. - * @stable ICU 3.0 - */ - public String getDisplayCountry(ULocale displayLocale){ - return getDisplayCountryInternal(this, displayLocale); - } - - /** - * Returns a locale's country localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose country will be displayed - * @param displayLocaleID the id of the locale in which to display the name. - * @return the localized country name. - * @stable ICU 3.0 - */ - public static String getDisplayCountry(String localeID, String displayLocaleID) { - return getDisplayCountryInternal(new ULocale(localeID), new ULocale(displayLocaleID)); - } - - /** - * Returns a locale's country localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose country will be displayed. - * @param displayLocale the locale in which to display the name. - * @return the localized country name. - * @stable ICU 3.0 - */ - public static String getDisplayCountry(String localeID, ULocale displayLocale) { - return getDisplayCountryInternal(new ULocale(localeID), displayLocale); - } - - // displayLocaleID is canonical, localeID need not be since parsing will fix this. - private static String getDisplayCountryInternal(ULocale locale, ULocale displayLocale) { - return locale.toLocale().getDisplayCountry(displayLocale.toLocale()); - } - - /** - * Returns this locale's variant localized for display in the default locale. - * @return the localized variant name. - * @stable ICU 3.0 - */ - public String getDisplayVariant() { - return getDisplayVariantInternal(this, getDefault()); - } - - /** - * Returns this locale's variant localized for display in the provided locale. - * @param displayLocale the locale in which to display the name. - * @return the localized variant name. - * @stable ICU 3.0 - */ - public String getDisplayVariant(ULocale displayLocale) { - return getDisplayVariantInternal(this, displayLocale); - } - - /** - * Returns a locale's variant localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose variant will be displayed - * @param displayLocaleID the id of the locale in which to display the name. - * @return the localized variant name. - * @stable ICU 3.0 - */ - public static String getDisplayVariant(String localeID, String displayLocaleID){ - return getDisplayVariantInternal(new ULocale(localeID), new ULocale(displayLocaleID)); - } - - /** - * Returns a locale's variant localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose variant will be displayed. - * @param displayLocale the locale in which to display the name. - * @return the localized variant name. - * @stable ICU 3.0 - */ - public static String getDisplayVariant(String localeID, ULocale displayLocale) { - return getDisplayVariantInternal(new ULocale(localeID), displayLocale); - } - - private static String getDisplayVariantInternal(ULocale locale, ULocale displayLocale) { - return locale.toLocale().getDisplayVariant(displayLocale.toLocale()); - } - - /** - * {@icu} Returns a keyword localized for display in the default locale. - * @param keyword the keyword to be displayed. - * @return the localized keyword name. - * @see #getKeywords() - * @stable ICU 3.0 - */ - public static String getDisplayKeyword(String keyword) { - return getDisplayKeywordInternal(keyword, getDefault()); - } - - /** - * {@icu} Returns a keyword localized for display in the specified locale. - * @param keyword the keyword to be displayed. - * @param displayLocaleID the id of the locale in which to display the keyword. - * @return the localized keyword name. - * @see #getKeywords(String) - * @stable ICU 3.0 - */ - public static String getDisplayKeyword(String keyword, String displayLocaleID) { - return getDisplayKeywordInternal(keyword, new ULocale(displayLocaleID)); - } - - /** - * {@icu} Returns a keyword localized for display in the specified locale. - * @param keyword the keyword to be displayed. - * @param displayLocale the locale in which to display the keyword. - * @return the localized keyword name. - * @see #getKeywords(String) - * @stable ICU 3.0 - */ - public static String getDisplayKeyword(String keyword, ULocale displayLocale) { - return getDisplayKeywordInternal(keyword, displayLocale); - } - - private static String getDisplayKeywordInternal(String keyword, ULocale displayLocale) { - // No localization - return keyword; - } - - /** - * {@icu} Returns a keyword value localized for display in the default locale. - * @param keyword the keyword whose value is to be displayed. - * @return the localized value name. - * @stable ICU 3.0 - */ - public String getDisplayKeywordValue(String keyword) { - return getDisplayKeywordValueInternal(this, keyword, getDefault()); - } - - /** - * {@icu} Returns a keyword value localized for display in the specified locale. - * @param keyword the keyword whose value is to be displayed. - * @param displayLocale the locale in which to display the value. - * @return the localized value name. - * @stable ICU 3.0 - */ - public String getDisplayKeywordValue(String keyword, ULocale displayLocale) { - return getDisplayKeywordValueInternal(this, keyword, displayLocale); - } - - /** - * {@icu} Returns a keyword value localized for display in the specified locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose keyword value is to be displayed. - * @param keyword the keyword whose value is to be displayed. - * @param displayLocaleID the id of the locale in which to display the value. - * @return the localized value name. - * @stable ICU 3.0 - */ - public static String getDisplayKeywordValue(String localeID, String keyword, - String displayLocaleID) { - return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, - new ULocale(displayLocaleID)); - } - - /** - * {@icu} Returns a keyword value localized for display in the specified locale. - * This is a cover for the ICU4C API. - * @param localeID the id of the locale whose keyword value is to be displayed. - * @param keyword the keyword whose value is to be displayed. - * @param displayLocale the id of the locale in which to display the value. - * @return the localized value name. - * @stable ICU 3.0 - */ - public static String getDisplayKeywordValue(String localeID, String keyword, - ULocale displayLocale) { - return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, displayLocale); - } - - // displayLocaleID is canonical, localeID need not be since parsing will fix this. - private static String getDisplayKeywordValueInternal(ULocale locale, String keyword, - ULocale displayLocale) { - keyword = AsciiUtil.toLowerString(keyword.trim()); - String value = locale.getKeywordValue(keyword); - return value; - } - - /** - * Returns this locale name localized for display in the default locale. - * @return the localized locale name. - * @stable ICU 3.0 - */ - public String getDisplayName() { - return getDisplayNameInternal(this, getDefault()); - } - - /** - * Returns this locale name localized for display in the provided locale. - * @param displayLocale the locale in which to display the locale name. - * @return the localized locale name. - * @stable ICU 3.0 - */ - public String getDisplayName(ULocale displayLocale) { - return getDisplayNameInternal(this, displayLocale); - } - - /** - * Returns the locale ID localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the locale whose name is to be displayed. - * @param displayLocaleID the id of the locale in which to display the locale name. - * @return the localized locale name. - * @stable ICU 3.0 - */ - public static String getDisplayName(String localeID, String displayLocaleID) { - return getDisplayNameInternal(new ULocale(localeID), new ULocale(displayLocaleID)); - } - - /** - * Returns the locale ID localized for display in the provided locale. - * This is a cover for the ICU4C API. - * @param localeID the locale whose name is to be displayed. - * @param displayLocale the locale in which to display the locale name. - * @return the localized locale name. - * @stable ICU 3.0 - */ - public static String getDisplayName(String localeID, ULocale displayLocale) { - return getDisplayNameInternal(new ULocale(localeID), displayLocale); - } - - private static String getDisplayNameInternal(ULocale locale, ULocale displayLocale) { - // No localization, no script and keywords - return locale.toLocale().getDisplayName(displayLocale.toLocale()); - } - - /** - * {@icu} Returns this locale name localized for display in the default locale. - * If a dialect name is present in the locale data, then it is returned. - * @return the localized locale name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public String getDisplayNameWithDialect() { - return getDisplayNameWithDialectInternal(this, getDefault()); - } - - /** - * {@icu} Returns this locale name localized for display in the provided locale. - * If a dialect name is present in the locale data, then it is returned. - * @param displayLocale the locale in which to display the locale name. - * @return the localized locale name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public String getDisplayNameWithDialect(ULocale displayLocale) { - return getDisplayNameWithDialectInternal(this, displayLocale); - } - - /** - * {@icu} Returns the locale ID localized for display in the provided locale. - * If a dialect name is present in the locale data, then it is returned. - * This is a cover for the ICU4C API. - * @param localeID the locale whose name is to be displayed. - * @param displayLocaleID the id of the locale in which to display the locale name. - * @return the localized locale name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static String getDisplayNameWithDialect(String localeID, String displayLocaleID) { - return getDisplayNameWithDialectInternal(new ULocale(localeID), - new ULocale(displayLocaleID)); - } - - /** - * {@icu} Returns the locale ID localized for display in the provided locale. - * If a dialect name is present in the locale data, then it is returned. - * This is a cover for the ICU4C API. - * @param localeID the locale whose name is to be displayed. - * @param displayLocale the locale in which to display the locale name. - * @return the localized locale name. - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public static String getDisplayNameWithDialect(String localeID, ULocale displayLocale) { - return getDisplayNameWithDialectInternal(new ULocale(localeID), displayLocale); - } - - private static String getDisplayNameWithDialectInternal(ULocale locale, ULocale displayLocale) { - // No dialect support, no script and keyword support - return locale.toLocale().getDisplayName(displayLocale.toLocale()); - } - - /** - * {@icu} Returns this locale's layout orientation for characters. The possible - * values are "left-to-right", "right-to-left", "top-to-bottom" or - * "bottom-to-top". - * @return The locale's layout orientation for characters. - * @stable ICU 4.0 - */ - public String getCharacterOrientation() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns this locale's layout orientation for lines. The possible - * values are "left-to-right", "right-to-left", "top-to-bottom" or - * "bottom-to-top". - * @return The locale's layout orientation for lines. - * @stable ICU 4.0 - */ - public String getLineOrientation() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Selector for getLocale() indicating the locale of the - * resource containing the data. This is always at or above the - * valid locale. If the valid locale does not contain the - * specific data being requested, then the actual locale will be - * above the valid locale. If the object was not constructed from - * locale data, then the valid locale is null. - * - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static Type ACTUAL_LOCALE = new Type(); - - /** - * {@icu} Selector for getLocale() indicating the most specific - * locale for which any data exists. This is always at or above - * the requested locale, and at or below the actual locale. If - * the requested locale does not correspond to any resource data, - * then the valid locale will be above the requested locale. If - * the object was not constructed from locale data, then the - * actual locale is null. - * - *

      Note: The valid locale will be returned correctly in ICU - * 3.0 or later. In ICU 2.8, it is not returned correctly. - * @draft ICU 2.8 (retain) - * @provisional This API might change or be removed in a future release. - */ - public static Type VALID_LOCALE = new Type(); - - /** - * Opaque selector enum for getLocale(). - * @see com.ibm.icu.util.ULocale - * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE - * @see com.ibm.icu.util.ULocale#VALID_LOCALE - * @draft ICU 2.8 (retainAll) - * @provisional This API might change or be removed in a future release. - */ - public static final class Type { - private Type() {} - } - - /** - * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available - * locale for the user. NullPointerException is thrown if acceptLanguageList or - * availableLocales is null. If fallback is non-null, it will contain true if a - * fallback locale (one not in the acceptLanguageList) was returned. The value on - * entry is ignored. ULocale will be one of the locales in availableLocales, or the - * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in - * availableLocales matched). No ULocale array element should be null; behavior is - * undefined if this is the case. - * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales - * @param availableLocales list of available locales. One of these will be returned. - * @param fallback if non-null, a 1-element array containing a boolean to be set with - * the fallback status - * @return one of the locales from the availableLocales list, or null if none match - * @stable ICU 3.4 - */ - public static ULocale acceptLanguage(String acceptLanguageList, ULocale[] availableLocales, - boolean[] fallback) { - if (acceptLanguageList == null) { - throw new NullPointerException(); - } - ULocale acceptList[] = null; - try { - acceptList = parseAcceptLanguage(acceptLanguageList, true); - } catch (ParseException pe) { - acceptList = null; - } - if (acceptList == null) { - return null; - } - return acceptLanguage(acceptList, availableLocales, fallback); - } - - /** - * {@icu} Based on a list of acceptable locales, determine an available locale for the - * user. NullPointerException is thrown if acceptLanguageList or availableLocales is - * null. If fallback is non-null, it will contain true if a fallback locale (one not - * in the acceptLanguageList) was returned. The value on entry is ignored. ULocale - * will be one of the locales in availableLocales, or the ROOT ULocale if if a ROOT - * locale was used as a fallback (because nothing else in availableLocales matched). - * No ULocale array element should be null; behavior is undefined if this is the case. - * @param acceptLanguageList list of acceptable locales - * @param availableLocales list of available locales. One of these will be returned. - * @param fallback if non-null, a 1-element array containing a boolean to be set with - * the fallback status - * @return one of the locales from the availableLocales list, or null if none match - * @stable ICU 3.4 - */ - - public static ULocale acceptLanguage(ULocale[] acceptLanguageList, ULocale[] - availableLocales, boolean[] fallback) { - // fallbacklist - int i,j; - if(fallback != null) { - fallback[0]=true; - } - for(i=0;i { - private double q; - private double serial; - public ULocaleAcceptLanguageQ(double theq, int theserial) { - q = theq; - serial = theserial; - } - public int compareTo(ULocaleAcceptLanguageQ other) { - if (q > other.q) { // reverse - to sort in descending order - return -1; - } else if (q < other.q) { - return 1; - } - if (serial < other.serial) { - return -1; - } else if (serial > other.serial) { - return 1; - } else { - return 0; // same object - } - } - } - - // parse out the acceptLanguage into an array - TreeMap map = - new TreeMap(); - StringBuilder languageRangeBuf = new StringBuilder(); - StringBuilder qvalBuf = new StringBuilder(); - int state = 0; - acceptLanguage += ","; // append comma to simplify the parsing code - int n; - boolean subTag = false; - boolean q1 = false; - for (n = 0; n < acceptLanguage.length(); n++) { - boolean gotLanguageQ = false; - char c = acceptLanguage.charAt(n); - switch (state) { - case 0: // before language-range start - if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { - // in language-range - languageRangeBuf.append(c); - state = 1; - subTag = false; - } else if (c == '*') { - languageRangeBuf.append(c); - state = 2; - } else if (c != ' ' && c != '\t') { - // invalid character - state = -1; - } - break; - case 1: // in language-range - if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { - languageRangeBuf.append(c); - } else if (c == '-') { - subTag = true; - languageRangeBuf.append(c); - } else if (c == '_') { - if (isLenient) { - subTag = true; - languageRangeBuf.append(c); - } else { - state = -1; - } - } else if ('0' <= c && c <= '9') { - if (subTag) { - languageRangeBuf.append(c); - } else { - // DIGIT is allowed only in language sub tag - state = -1; - } - } else if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c == ' ' || c == '\t') { - // language-range end - state = 3; - } else if (c == ';') { - // before q - state = 4; - } else { - // invalid character for language-range - state = -1; - } - break; - case 2: // saw wild card range - if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c == ' ' || c == '\t') { - // language-range end - state = 3; - } else if (c == ';') { - // before q - state = 4; - } else { - // invalid - state = -1; - } - break; - case 3: // language-range end - if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c == ';') { - // before q - state =4; - } else if (c != ' ' && c != '\t') { - // invalid - state = -1; - } - break; - case 4: // before q - if (c == 'q') { - // before equal - state = 5; - } else if (c != ' ' && c != '\t') { - // invalid - state = -1; - } - break; - case 5: // before equal - if (c == '=') { - // before q value - state = 6; - } else if (c != ' ' && c != '\t') { - // invalid - state = -1; - } - break; - case 6: // before q value - if (c == '0') { - // q value start with 0 - q1 = false; - qvalBuf.append(c); - state = 7; - } else if (c == '1') { - // q value start with 1 - qvalBuf.append(c); - state = 7; - } else if (c == '.') { - if (isLenient) { - qvalBuf.append(c); - state = 8; - } else { - state = -1; - } - } else if (c != ' ' && c != '\t') { - // invalid - state = -1; - } - break; - case 7: // q value start - if (c == '.') { - // before q value fraction part - qvalBuf.append(c); - state = 8; - } else if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c == ' ' || c == '\t') { - // after q value - state = 10; - } else { - // invalid - state = -1; - } - break; - case 8: // before q value fraction part - if ('0' <= c || c <= '9') { - if (q1 && c != '0' && !isLenient) { - // if q value starts with 1, the fraction part must be 0 - state = -1; - } else { - // in q value fraction part - qvalBuf.append(c); - state = 9; - } - } else { - // invalid - state = -1; - } - break; - case 9: // in q value fraction part - if ('0' <= c && c <= '9') { - if (q1 && c != '0') { - // if q value starts with 1, the fraction part must be 0 - state = -1; - } else { - qvalBuf.append(c); - } - } else if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c == ' ' || c == '\t') { - // after q value - state = 10; - } else { - // invalid - state = -1; - } - break; - case 10: // after q value - if (c == ',') { - // language-q end - gotLanguageQ = true; - } else if (c != ' ' && c != '\t') { - // invalid - state = -1; - } - break; - } - if (state == -1) { - // error state - throw new ParseException("Invalid Accept-Language", n); - } - if (gotLanguageQ) { - double q = 1.0; - if (qvalBuf.length() != 0) { - try { - q = Double.parseDouble(qvalBuf.toString()); - } catch (NumberFormatException nfe) { - // Already validated, so it should never happen - q = 1.0; - } - if (q > 1.0) { - q = 1.0; - } - } - if (languageRangeBuf.charAt(0) != '*') { - int serial = map.size(); - ULocaleAcceptLanguageQ entry = new ULocaleAcceptLanguageQ(q, serial); - // sort in reverse order.. 1.0, 0.9, 0.8 .. etc - map.put(entry, new ULocale(canonicalize(languageRangeBuf.toString()))); - } - - // reset buffer and parse state - languageRangeBuf.setLength(0); - qvalBuf.setLength(0); - state = 0; - } - } - if (state != 0) { - // Well, the parser should handle all cases. So just in case. - throw new ParseException("Invalid AcceptlLanguage", n); - } - - // pull out the map - ULocale acceptList[] = map.values().toArray(new ULocale[map.size()]); - return acceptList; - } - - /** - * {@icu} Adds the likely subtags for a provided locale ID, per the algorithm - * described in the following CLDR technical report: - * - * http://www.unicode.org/reports/tr35/#Likely_Subtags - * - * If the provided ULocale instance is already in the maximal form, or there is no - * data available available for maximization, it will be returned. For example, - * "und-Zzzz" cannot be maximized, since there is no reasonable maximization. - * Otherwise, a new ULocale instance with the maximal form is returned. - * - * Examples: - * - * "en" maximizes to "en_Latn_US" - * - * "de" maximizes to "de_Latn_US" - * - * "sr" maximizes to "sr_Cyrl_RS" - * - * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.) - * - * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.) - * - * @param loc The ULocale to maximize - * @return The maximized ULocale instance. - * @stable ICU 4.0 - */ - public static ULocale addLikelySubtags(ULocale loc) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Minimizes the subtags for a provided locale ID, per the algorithm described - * in the following CLDR technical report:

      - * - * http://www.unicode.org/reports/tr35/#Likely_Subtags
      - * - * If the provided ULocale instance is already in the minimal form, or there - * is no data available for minimization, it will be returned. Since the - * minimization algorithm relies on proper maximization, see the comments - * for addLikelySubtags for reasons why there might not be any data. - * - * Examples:
      -     *
      -     * "en_Latn_US" minimizes to "en"
      -     *
      -     * "de_Latn_US" minimizes to "de"
      -     *
      -     * "sr_Cyrl_RS" minimizes to "sr"
      -     *
      -     * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the
      -     * script, and minimizing to "zh" would imply "zh_Hans_CN".) 
      - * - * @param loc The ULocale to minimize - * @return The minimized ULocale instance. - * @stable ICU 4.0 - */ - public static ULocale minimizeSubtags(ULocale loc) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - // -------------------------------- - // BCP47/OpenJDK APIs - // -------------------------------- - - /** - * {@icu} The key for the private use locale extension ('x'). - * - * @see #getExtension(char) - * @see Builder#setExtension(char, String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public static final char PRIVATE_USE_EXTENSION = 'x'; - - /** - * {@icu} The key for Unicode locale extension ('u'). - * - * @see #getExtension(char) - * @see Builder#setExtension(char, String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public static final char UNICODE_LOCALE_EXTENSION = 'u'; - - /** - * {@icu} Returns the extension (or private use) value associated with - * the specified singleton key, or null if there is no extension - * associated with the key. To be valid, the key must be one - * of [0-9A-Za-z]. Keys are case-insensitive, so - * for example 'z' and 'Z' represent the same extension. - * - * @param key the extension key - * @return the extension, or null if this locale defines no - * extension for the specified key - * @throws IllegalArgumentException if the key is not valid - * @see #PRIVATE_USE_EXTENSION - * @see #UNICODE_LOCALE_EXTENSION - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public String getExtension(char key) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the set of extension keys associated with this locale, or the - * empty set if it has no extensions. The returned set is unmodifiable. - * - * @return the set of extension keys, or the empty set if this locale has - * no extensions - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Set getExtensionKeys() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the Unicode locale type associated with the specified Unicode - * locale key for this locale. Unicode locale keywrods are specified - * by the 'u' extension and consist of key/type pairs. The key must be - * two alphanumeric characters in length, or an IllegalArgumentException - * is thrown. - * @param key the Unicode locale key - * @return the Unicode locale type associated with the key, or null if the - * locale does not define a value for the key. - * @throws IllegalArgumentException if the key is not valid. - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public String getUnicodeLocaleType(String key) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns the set of keys for Unicode locale keywords defined by this locale, - * or null if this locale has no locale extension. The returned set is - * immutable. - * - * @return the set of the Unicode locale keys, or null - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public Set getUnicodeLocaleKeys() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns a well-formed IETF BCP 47 language tag representing - * this locale. - * - *

      - * If this ULocale object has language, country, or variant - * that does not satisfy the IETF BCP 47 language tag syntax requirements, - * this method handles these fields as described below: - *

      - * Language: If language is empty or ill-formed (for example "a" or "e2"), - * it will be emitted as "und" (Undetermined). - *

      - * Country: If country is ill-formed (for example "12" or "USA"), it - * will be omitted. - *

      - * Variant: Variant is treated as consisting of subtags separated by - * underscore and converted to lower case letters. 'Well-formed' subtags - * consist of either an ASCII letter followed by 4-7 ASCII characters, or an - * ASCII digit followed by 3-7 ASCII characters. If well-formed, the variant - * is emitted as each subtag in order (separated by hyphen). Otherwise: - *

        - *
      • if all sub-segments consist of 1 to 8 ASCII alphanumerics (for example - * "WIN", "WINDOWS_XP", "SOLARIS_10"), the first ill-formed variant subtag - * and all following sub-segments will be emitted as private use subtags prefixed - * by the special private use subtag "variant" followed by each subtag in order - * (separated by hyphen). For example, locale "en_US_WIN" is converted to language - * tag "en-US-x-variant-win", locale "de_WINDOWS_XP" is converted to language tag - * "de-windows-x-variant-xp". If this locale has a private use extension value, - * the special private use subtags prefixed by "variant" are appended after the - * locale's private use value. - *
      • if any subtag does not consist of 1 to 8 ASCII alphanumerics, the - * variant will be truncated and the problematic subtag and all following - * sub-segments will be omitted. If the remainder is non-empty, it will be - * emitted as a private use subtag as above (even if the remainder turns out - * to be well-formed). For example, "Solaris_isjustthecoolestthing" is emitted - * as "x-jvariant-Solaris", not as "solaris".
      • - *
      - * - *

      Note: Although the language tag created by this method - * satisfies the syntax requirements defined by the IETF BCP 47 - * specification, it is not always a valid BCP 47 language tag. - * For example, - *

      -     *   new ULocale("xx_YY").toLanguageTag();
      -     * 
      - * will return "xx-YY", but the language subtag "xx" and the region subtag "YY" - * are invalid because they are not registered in the - * - * IANA Language Subtag Registry. - * - * @return a BCP47 language tag representing the locale - * @see #forLanguageTag(String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public String toLanguageTag() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * {@icu} Returns a locale for the specified IETF BCP 47 language tag string. - * If the specified language tag contains any ill-formed subtags, - * the first such subtag and all following subtags are ignored. - * - *

      This implements the 'Language-Tag' production of BCP47, and - * so supports grandfathered (regular and irregular) as well as - * private use language tags. Stand alone private use tags are - * represented as empty language and extension 'x-whatever', - * and grandfathered tags are converted to their canonical replacements - * where they exist. Note that a few grandfathered tags have no - * modern replacement; these will be converted using the fallback - * described above so some information might be lost. - * - *

      For a list of grandfathered tags, see the - * - * IANA Language Subtag Registry. - * - *

      Notes: This method converts private use subtags prefixed - * by "variant" to variant field in the result locale. For example, - * the code below will return "POSIX". - *

      -     *   ULocale.forLanguageTag("en-US-x-variant-posix).getVariant();
      -     * 
      - * - * @param languageTag the language tag - * @return the locale that best represents the language tag - * @exception NullPointerException if languageTag is null - * @see #toLanguageTag() - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public static ULocale forLanguageTag(String languageTag) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - - /** - * Builder is used to build instances of ULocale - * from values configured by the setter. Unlike the ULocale - * constructors, the Builder checks if a value configured by a - * setter satisfies the syntactical requirements defined by the ULocale - * class. A ULocale object created by a Builder is - * well-formed and can be transformed to a well-formed IETF BCP 47 language tag - * without losing information. - * - *

      - * Note: The ULocale class does not provide - * any syntactical restrictions on variant, while BCP 47 - * requires each variant subtag to be 5 to 8 alphanumeric letters or a single - * numeric letter followed by 3 alphanumeric letters. By default, - * the setVariant method throws IllformedLocaleException - * for a variant that does not satisfy the syntax above. If it is - * necessary to support such a variant, you could use the constructor - * Builder(boolean isLenientVariant) passing true to - * skip the syntax validation for variant. However, you should keep in - * mind that a Locale object created this way might lose - * the variant information when transformed to a BCP 47 language tag. - * - *

      - * The following example shows how to create a ULocale object - * with the Builder. - *

      - *
      -     *     ULocale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
      -     * 
      - *
      - * - *

      Builders can be reused; clear() resets all - * fields to their default values. - * - * @see ULocale#toLanguageTag() - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public static final class Builder { - - /** - * Constructs an empty Builder. The default value of all - * fields, extensions, and private use information is the - * empty string. - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder() { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Constructs an empty Builder with an option whether to allow - * setVariant to accept a value that does not - * conform to the IETF BCP 47 variant subtag's syntax requirements. - * - * @param isLenientVariant When true, this Builder - * will accept an ill-formed variant. - * @see #setVariant(String) - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public Builder(boolean isLenientVariant) { - throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); - } - - /** - * Returns true if this Builder accepts a value that does - * not conform to the IETF BCP 47 variant subtag's syntax requirements - * in setVariant - * - * @return true if this Build accepts an ill-formed variant. - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public boolean isLenientVariant() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - - /** - * Resets the Builder to match the provided locale. - * The previous state of the builder is discarded. Fields that do - * not conform to the ULocale class specification, for example, - * a single letter language, are ill-formed. - * - * @param locale the locale - * @return this builder - * @throws IllformedLocaleException if locale has - * any ill-formed fields. - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setLocale(ULocale locale) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Resets the builder to match the provided IETF BCP 47 language tag. - * The previous state of the builder is discarded. - * - * @param languageTag the language tag - * @return this builder - * @throws IllformedLocaleException if languageTag is ill-formed. - * @throws NullPointerException if languageTag is null. - * @see ULocale#forLanguageTag(String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setLanguageTag(String languageTag) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the language. If language is the empty string, - * the language in this Builder will be removed. - * Typical language value is a two or three-letter language - * code as defined in ISO639. - * Well-formed values are any string of two to eight alpha - * letters. This method accepts upper case alpha letters - * [A-Z], but the language value in the ULocale - * created by the Builder is always normalized - * to lower case letters. - * - * @param language the language - * @return this builder - * @throws IllformedLocaleException if language is ill-formed - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setLanguage(String language) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the script. If script is the empty string, - * the script in this Builder is removed. - * Typical script value is a four-letter script code as defined by ISO 15924. - * Well-formed values are any string of four alpha letters. - * This method accepts both upper and lower case alpha letters [a-zA-Z], - * but the script value in the ULocale created by the - * Builder is always normalized to title case - * (the first letter is upper case and the rest of letters are lower case). - * - * @param script the script - * @return this builder - * @throws IllformedLocaleException if script is ill-formed - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setScript(String script) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the region. If region is the empty string, the region - * in this Builder is removed. - * Typical region value is a two-letter ISO 3166 code or a three-digit UN M.49 - * area code. Well-formed values are any two-letter or three-digit string. - * This method accepts lower case letters [a-z], but the country value in - * the ULocale created by the Builder is always - * normalized to upper case. - * - * @param region the region - * @return this builder - * @throws IllformedLocaleException if region is ill-formed - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setRegion(String region) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the variant. If variant is the empty string, the - * variant in this Builder is removed. - *

      - * Note: By default, this method checks if variant - * satisfies the IETF BCP 47 variant subtag's syntax requirements. - * However, the ULocale class itself does not impose any syntactical - * restriction on variant. When a Builder is created by the - * constructor Builder(boolean isLenientVariant) - * with true, this method skips the syntax check. - * - * @param variant the variant - * @return this builder - * @throws IllformedLocaleException if variant is ill-formed - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setVariant(String variant) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the extension for the given key. If the value is the - * empty string, the extension is removed. Legal keys are - * characters in the ranges [0-9A-Za-z]. Keys - * are case-insensitive, so for example 'z' and 'Z' represent - * the same extension. In general, well-formed values are any - * series of fields of two to eight alphanumeric characters, - * separated by hyphen or underscore. - * - *

      Note: The key {@link ULocale#UNICODE_LOCALE_EXTENSION - * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension. - * Setting a value for this key replaces any existing Unicode locale key/type - * pairs with those defined in the extension. - * To be well-formed, a value for this extension must meet the additional - * constraints that each locale key is two alphanumeric characters, - * followed by at least one locale type subtag represented by - * three to eight alphanumeric characters, and that the keys and types - * be legal Unicode locale keys and values. - * - *

      Note: The key {@link ULocale#PRIVATE_USE_EXTENSION - * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be - * well-formed, the value for this key needs only to have fields of one to - * eight alphanumeric characters, not two to eight as in the general case. - * - * @param key the extension key - * @param value the extension value - * @return this builder - * @throws IllformedLocaleException if key is illegal - * or value is ill-formed - * @see #setUnicodeLocaleKeyword(String, String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder setExtension(char key, String value) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Sets the Unicode locale keyword type for the given key. If the - * value is the empty string, the Unicode keyword is removed. - * Well-formed keys are strings of two alphanumeric characters. - * Well-formed types are one or more subtags where each of them is - * three to eight alphanumeric characters. - *

      - * Note:Setting the 'u' extension replaces all Unicode locale - * keywords with those defined in the extension. - * @param key the Unicode locale key - * @param type the Unicode locale type - * @return this builder - * @throws IllformedLocaleException if key or type - * is ill-formed - * @see #setExtension(char, String) - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public Builder setUnicodeLocaleKeyword(String key, String type) { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Resets the builder to its initial, empty state. - * - * @return this builder - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder clear() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Resets the extensions to their initial, empty state. - * Language, script, region and variant are unchanged. - * - * @return this builder - * @see #setExtension(char, String) - * - * @draft ICU 4.2 - * @provisional This API might change or be removed in a future release. - */ - public Builder clearExtensions() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - - /** - * Returns an instance of Locale created from the fields set - * on this builder. - * - * @return a new Locale - * - * @draft ICU 4.4 - * @provisional This API might change or be removed in a future release. - */ - public ULocale build() { - throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); - } - } -} +/* +****************************************************************************** +* Copyright (C) 2003-2011, International Business Machines Corporation and * +* others. All Rights Reserved. * +****************************************************************************** +*/ + +package com.ibm.icu.util; + +import java.io.Serializable; +import java.text.ParseException; +import java.util.Iterator; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.Set; +import java.util.TreeMap; + +import com.ibm.icu.impl.ICUCache; +import com.ibm.icu.impl.LocaleIDParser; +import com.ibm.icu.impl.LocaleIDs; +import com.ibm.icu.impl.LocaleUtility; +import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.locale.AsciiUtil; + +/** + * {@icuenhanced java.util.Locale}.{@icu _usage_} + * + * A class analogous to {@link java.util.Locale} that provides additional + * support for ICU protocol. In ICU 3.0 this class is enhanced to support + * RFC 3066 language identifiers. + * + *

      Many classes and services in ICU follow a factory idiom, in + * which a factory method or object responds to a client request with + * an object. The request includes a locale (the requested + * locale), and the returned object is constructed using data for that + * locale. The system may lack data for the requested locale, in + * which case the locale fallback mechanism will be invoked until a + * populated locale is found (the valid locale). Furthermore, + * even when a populated locale is found (the valid locale), + * further fallback may be required to reach a locale containing the + * specific data required by the service (the actual locale). + * + *

      ULocale performs 'normalization' and 'canonicalization' of locale ids. + * Normalization 'cleans up' ICU locale ids as follows: + *

        + *
      • language, script, country, variant, and keywords are properly cased
        + * (lower, title, upper, upper, and lower case respectively)
      • + *
      • hyphens used as separators are converted to underscores
      • + *
      • three-letter language and country ids are converted to two-letter + * equivalents where available
      • + *
      • surrounding spaces are removed from keywords and values
      • + *
      • if there are multiple keywords, they are put in sorted order
      • + *
      + * Canonicalization additionally performs the following: + *
        + *
      • POSIX ids are converted to ICU format IDs
      • + *
      • 'grandfathered' 3066 ids are converted to ICU standard form
      • + *
      • 'PREEURO' and 'EURO' variants are converted to currency keyword form, + * with the currency + * id appropriate to the country of the locale (for PREEURO) or EUR (for EURO). + *
      + * All ULocale constructors automatically normalize the locale id. To handle + * POSIX ids, canonicalize can be called to convert the id + * to canonical form, or the canonicalInstance factory method + * can be called.

      + * + *

      This class provides selectors {@link #VALID_LOCALE} and {@link + * #ACTUAL_LOCALE} intended for use in methods named + * getLocale(). These methods exist in several ICU classes, + * including {@link com.ibm.icu.util.Calendar}, {@link + * com.ibm.icu.util.Currency}, {@link com.ibm.icu.text.UFormat}, + * {@link com.ibm.icu.text.BreakIterator}, + * Collator, + * {@link com.ibm.icu.text.DateFormatSymbols}, and {@link + * com.ibm.icu.text.DecimalFormatSymbols} and their subclasses, if + * any. Once an object of one of these classes has been created, + * getLocale() may be called on it to determine the valid and + * actual locale arrived at during the object's construction. + * + *

      Note: The actual locale is returned correctly, but the valid + * locale is not, in most cases. + * + * @see java.util.Locale + * @author weiv + * @author Alan Liu + * @author Ram Viswanadha + * @stable ICU 2.8 + */ +public final class ULocale implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale FRENCH = new ULocale("fr", Locale.FRENCH); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale GERMAN = new ULocale("de", Locale.GERMAN); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale ITALIAN = new ULocale("it", Locale.ITALIAN); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale JAPANESE = new ULocale("ja", Locale.JAPANESE); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale KOREAN = new ULocale("ko", Locale.KOREAN); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale CHINESE = new ULocale("zh", Locale.CHINESE); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale SIMPLIFIED_CHINESE = new ULocale("zh_Hans", Locale.CHINESE); + + /** + * Useful constant for language. + * @stable ICU 3.0 + */ + public static final ULocale TRADITIONAL_CHINESE = new ULocale("zh_Hant", Locale.CHINESE); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale FRANCE = new ULocale("fr_FR", Locale.FRANCE); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale GERMANY = new ULocale("de_DE", Locale.GERMANY); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale ITALY = new ULocale("it_IT", Locale.ITALY); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale JAPAN = new ULocale("ja_JP", Locale.JAPAN); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale KOREA = new ULocale("ko_KR", Locale.KOREA); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale CHINA = new ULocale("zh_Hans_CN", Locale.CHINA); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale PRC = CHINA; + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale TAIWAN = new ULocale("zh_Hant_TW", Locale.TAIWAN); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale UK = new ULocale("en_GB", Locale.UK); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale US = new ULocale("en_US", Locale.US); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale CANADA = new ULocale("en_CA", Locale.CANADA); + + /** + * Useful constant for country/region. + * @stable ICU 3.0 + */ + public static final ULocale CANADA_FRENCH = new ULocale("fr_CA", Locale.CANADA_FRENCH); + + /** + * Handy constant. + */ + private static final String EMPTY_STRING = ""; + + // Used in both ULocale and LocaleIDParser, so moved up here. + private static final char UNDERSCORE = '_'; + + // default empty locale + private static final Locale EMPTY_LOCALE = new Locale("", ""); + + /** + * The root ULocale. + * @stable ICU 2.8 + */ + public static final ULocale ROOT = new ULocale("", EMPTY_LOCALE); + + private static final SimpleCache CACHE = new SimpleCache(); + + /** + * Cache the locale. + */ + private transient volatile Locale locale; + + /** + * The raw localeID that we were passed in. + */ + private String localeID; + + private static String[][] CANONICALIZE_MAP; + private static String[][] variantsToKeywords; + + private static void initCANONICALIZE_MAP() { + if (CANONICALIZE_MAP == null) { + /** + * This table lists pairs of locale ids for canonicalization. The + * The 1st item is the normalized id. The 2nd item is the + * canonicalized id. The 3rd is the keyword. The 4th is the keyword value. + */ + String[][] tempCANONICALIZE_MAP = { +// { EMPTY_STRING, "en_US_POSIX", null, null }, /* .NET name */ + { "C", "en_US_POSIX", null, null }, /* POSIX name */ + { "art_LOJBAN", "jbo", null, null }, /* registered name */ + { "az_AZ_CYRL", "az_Cyrl_AZ", null, null }, /* .NET name */ + { "az_AZ_LATN", "az_Latn_AZ", null, null }, /* .NET name */ + { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, + { "cel_GAULISH", "cel__GAULISH", null, null }, /* registered name */ + { "de_1901", "de__1901", null, null }, /* registered name */ + { "de_1906", "de__1906", null, null }, /* registered name */ + { "de__PHONEBOOK", "de", "collation", "phonebook" }, /* Old ICU name */ + { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, + { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, + { "de_LU_PREEURO", "de_LU", "currency", "EUR" }, + { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, + { "en_BOONT", "en__BOONT", null, null }, /* registered name */ + { "en_SCOUSE", "en__SCOUSE", null, null }, /* registered name */ + { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, + { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, + { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */ + { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, + { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, + { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, + { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, + { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, + { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, + { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, + { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, + { "hi__DIRECT", "hi", "collation", "direct" }, /* Old ICU name */ + { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, + { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, +// { "nb_NO_NY", "nn_NO", null, null }, + { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, + { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, + { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, + { "sl_ROZAJ", "sl__ROZAJ", null, null }, /* registered name */ + { "sr_SP_CYRL", "sr_Cyrl_RS", null, null }, /* .NET name */ + { "sr_SP_LATN", "sr_Latn_RS", null, null }, /* .NET name */ + { "sr_YU_CYRILLIC", "sr_Cyrl_RS", null, null }, /* Linux name */ + { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */ + { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", null, null }, /* Linux name */ + { "uz_UZ_CYRL", "uz_Cyrl_UZ", null, null }, /* .NET name */ + { "uz_UZ_LATN", "uz_Latn_UZ", null, null }, /* .NET name */ + { "zh_CHS", "zh_Hans", null, null }, /* .NET name */ + { "zh_CHT", "zh_Hant", null, null }, /* .NET name */ + { "zh_GAN", "zh__GAN", null, null }, /* registered name */ + { "zh_GUOYU", "zh", null, null }, /* registered name */ + { "zh_HAKKA", "zh__HAKKA", null, null }, /* registered name */ + { "zh_MIN", "zh__MIN", null, null }, /* registered name */ + { "zh_MIN_NAN", "zh__MINNAN", null, null }, /* registered name */ + { "zh_WUU", "zh__WUU", null, null }, /* registered name */ + { "zh_XIANG", "zh__XIANG", null, null }, /* registered name */ + { "zh_YUE", "zh__YUE", null, null } /* registered name */ + }; + + synchronized (ULocale.class) { + if (CANONICALIZE_MAP == null) { + CANONICALIZE_MAP = tempCANONICALIZE_MAP; + } + } + } + if (variantsToKeywords == null) { + /** + * This table lists pairs of locale ids for canonicalization. The + * The first item is the normalized variant id. + */ + String[][] tempVariantsToKeywords = { + { "EURO", "currency", "EUR" }, + { "PINYIN", "collation", "pinyin" }, /* Solaris variant */ + { "STROKE", "collation", "stroke" } /* Solaris variant */ + }; + + synchronized (ULocale.class) { + if (variantsToKeywords == null) { + variantsToKeywords = tempVariantsToKeywords; + } + } + } + } + + /* + * This table is used for mapping between ICU and special Java + * locales. When an ICU locale matches with + * /, the ICU locale is mapped to locale. + * For example, both ja_JP@calendar=japanese and ja@calendar=japanese + * are mapped to Java locale "ja_JP_JP". ICU locale "nn" is mapped + * to Java locale "no_NO_NY". + */ + private static final String[][] _javaLocaleMap = { + // { , , , , + { "ja_JP_JP", "ja_JP", "calendar", "japanese", "ja"}, + { "no_NO_NY", "nn_NO", null, null, "nn"}, + { "th_TH_TH", "th_TH", "numbers", "thai", "th"}, + }; + + /** + * Private constructor used by static initializers. + */ + private ULocale(String localeID, Locale locale) { + this.localeID = localeID; + this.locale = locale; + } + + /** + * Construct a ULocale object from a {@link java.util.Locale}. + * @param loc a JDK locale + */ + private ULocale(Locale loc) { + this.localeID = getName(forLocale(loc).toString()); + this.locale = loc; + } + + /** + * {@icu} Returns a ULocale object for a {@link java.util.Locale}. + * The ULocale is canonicalized. + * @param loc a JDK locale + * @stable ICU 3.2 + */ + public static ULocale forLocale(Locale loc) { + if (loc == null) { + return null; + } + ULocale result = CACHE.get(loc); + if (result == null) { + if (defaultULocale != null && loc == defaultULocale.locale) { + result = defaultULocale; + } else { + String locStr = loc.toString(); + if (locStr.length() == 0) { + result = ROOT; + } else { + for (int i = 0; i < _javaLocaleMap.length; i++) { + if (_javaLocaleMap[i][0].equals(locStr)) { + LocaleIDParser p = new LocaleIDParser(_javaLocaleMap[i][1]); + p.setKeywordValue(_javaLocaleMap[i][2], _javaLocaleMap[i][3]); + locStr = p.getName(); + break; + } + } + result = new ULocale(locStr, loc); + } + } + CACHE.put(loc, result); + } + return result; + } + + /** + * {@icu} Constructs a ULocale from a RFC 3066 locale ID. The locale ID consists + * of optional language, script, country, and variant fields in that order, + * separated by underscores, followed by an optional keyword list. The + * script, if present, is four characters long-- this distinguishes it + * from a country code, which is two characters long. Other fields + * are distinguished by position as indicated by the underscores. The + * start of the keyword list is indicated by '@', and consists of two + * or more keyword/value pairs separated by semicolons(';'). + * + *

      This constructor does not canonicalize the localeID. So, for + * example, "zh__pinyin" remains unchanged instead of converting + * to "zh@collation=pinyin". By default ICU only recognizes the + * latter as specifying pinyin collation. Use {@link #createCanonical} + * or {@link #canonicalize} if you need to canonicalize the localeID. + * + * @param localeID string representation of the locale, e.g: + * "en_US", "sy_Cyrl_YU", "zh__pinyin", "es_ES@currency=EUR;collation=traditional" + * @stable ICU 2.8 + */ + public ULocale(String localeID) { + this.localeID = getName(localeID); + } + + /** + * Convenience overload of ULocale(String, String, String) for + * compatibility with java.util.Locale. + * @see #ULocale(String, String, String) + * @stable ICU 3.4 + */ + public ULocale(String a, String b) { + this(a, b, null); + } + + /** + * Constructs a ULocale from a localeID constructed from the three 'fields' a, b, and + * c. These fields are concatenated using underscores to form a localeID of the form + * a_b_c, which is then handled like the localeID passed to ULocale(String + * localeID). + * + *

      Java locale strings consisting of language, country, and + * variant will be handled by this form, since the country code + * (being shorter than four letters long) will not be interpreted + * as a script code. If a script code is present, the final + * argument ('c') will be interpreted as the country code. It is + * recommended that this constructor only be used to ease porting, + * and that clients instead use the single-argument constructor + * when constructing a ULocale from a localeID. + * @param a first component of the locale id + * @param b second component of the locale id + * @param c third component of the locale id + * @see #ULocale(String) + * @stable ICU 3.0 + */ + public ULocale(String a, String b, String c) { + localeID = getName(lscvToID(a, b, c, EMPTY_STRING)); + } + + /** + * {@icu} Creates a ULocale from the id by first canonicalizing the id. + * @param nonCanonicalID the locale id to canonicalize + * @return the locale created from the canonical version of the ID. + * @stable ICU 3.0 + */ + public static ULocale createCanonical(String nonCanonicalID) { + return new ULocale(canonicalize(nonCanonicalID), (Locale)null); + } + + private static String lscvToID(String lang, String script, String country, String variant) { + StringBuilder buf = new StringBuilder(); + + if (lang != null && lang.length() > 0) { + buf.append(lang); + } + if (script != null && script.length() > 0) { + buf.append(UNDERSCORE); + buf.append(script); + } + if (country != null && country.length() > 0) { + buf.append(UNDERSCORE); + buf.append(country); + } + if (variant != null && variant.length() > 0) { + if (country == null || country.length() == 0) { + buf.append(UNDERSCORE); + } + buf.append(UNDERSCORE); + buf.append(variant); + } + return buf.toString(); + } + + /** + * {@icu} Converts this ULocale object to a {@link java.util.Locale}. + * @return a JDK locale that either exactly represents this object + * or is the closest approximation. + * @stable ICU 2.8 + */ + public Locale toLocale() { + if (locale == null) { + LocaleIDParser p = new LocaleIDParser(localeID); + String base = p.getBaseName(); + for (int i = 0; i < _javaLocaleMap.length; i++) { + if (base.equals(_javaLocaleMap[i][1]) || base.equals(_javaLocaleMap[i][4])) { + if (_javaLocaleMap[i][2] != null) { + String val = p.getKeywordValue(_javaLocaleMap[i][2]); + if (val != null && val.equals(_javaLocaleMap[i][3])) { + p = new LocaleIDParser(_javaLocaleMap[i][0]); + break; + } + } else { + p = new LocaleIDParser(_javaLocaleMap[i][0]); + break; + } + } + } + String[] names = p.getLanguageScriptCountryVariant(); + locale = new Locale(names[0], names[2], names[3]); + } + return locale; + } + + private static ICUCache nameCache = new SimpleCache(); + /** + * Keep our own default ULocale. + */ + private static Locale defaultLocale = Locale.getDefault(); + private static ULocale defaultULocale = new ULocale(defaultLocale); + + /** + * Returns the current default ULocale. + * @stable ICU 2.8 + */ + public static ULocale getDefault() { + synchronized (ULocale.class) { + Locale currentDefault = Locale.getDefault(); + if (!defaultLocale.equals(currentDefault)) { + defaultLocale = currentDefault; + defaultULocale = new ULocale(defaultLocale); + } + return defaultULocale; + } + } + + /** + * {@icu} Sets the default ULocale. This also sets the default Locale. + * If the caller does not have write permission to the + * user.language property, a security exception will be thrown, + * and the default ULocale will remain unchanged. + * @param newLocale the new default locale + * @throws SecurityException if a security manager exists and its + * checkPermission method doesn't allow the operation. + * @throws NullPointerException if newLocale is null + * @see SecurityManager#checkPermission(java.security.Permission) + * @see java.util.PropertyPermission + * @stable ICU 3.0 + */ + public static synchronized void setDefault(ULocale newLocale){ + Locale.setDefault(newLocale.toLocale()); + defaultULocale = newLocale; + } + + /** + * This is for compatibility with Locale-- in actuality, since ULocale is + * immutable, there is no reason to clone it, so this API returns 'this'. + * @stable ICU 3.0 + */ + public Object clone() { + return this; + } + + /** + * Returns the hashCode. + * @stable ICU 3.0 + */ + public int hashCode() { + return localeID.hashCode(); + } + + /** + * Returns true if the other object is another ULocale with the + * same full name, or is a String localeID that matches the full name. + * Note that since names are not canonicalized, two ULocales that + * function identically might not compare equal. + * + * @return true if this Locale is equal to the specified object. + * @stable ICU 3.0 + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof String) { + return localeID.equals((String)obj); + } + if (obj instanceof ULocale) { + return localeID.equals(((ULocale)obj).localeID); + } + return false; + } + + /** + * {@icunote} Unlike the Locale API, this returns an array of ULocale, + * not Locale. Returns a list of all installed locales. + * @stable ICU 3.0 + */ + public static ULocale[] getAvailableLocales() { + if (availableLocales == null) { + synchronized (ULocale.class) { + if (availableLocales == null) { + Locale[] locales = Locale.getAvailableLocales(); + availableLocales = new ULocale[locales.length]; + for (int i = 0; i < locales.length; i++) { + availableLocales[i] = ULocale.forLocale(locales[i]); + } + } + } + } + return availableLocales.clone(); + } + private static volatile ULocale[] availableLocales = null; + + /** + * Returns a list of all 2-letter country codes defined in ISO 3166. + * Can be used to create Locales. + * @stable ICU 3.0 + */ + public static String[] getISOCountries() { + return LocaleIDs.getISOCountries(); + } + + /** + * Returns a list of all 2-letter language codes defined in ISO 639. + * Can be used to create Locales. + * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed. + * The list this function returns includes both the new and the old codes for the + * languages whose codes have changed.] + * @stable ICU 3.0 + */ + public static String[] getISOLanguages() { + return LocaleIDs.getISOLanguages(); + } + + /** + * Returns the language code for this locale, which will either be the empty string + * or a lowercase ISO 639 code. + * @see #getDisplayLanguage() + * @see #getDisplayLanguage(ULocale) + * @stable ICU 3.0 + */ + public String getLanguage() { + return getLanguage(localeID); + } + + /** + * Returns the language code for the locale ID, + * which will either be the empty string + * or a lowercase ISO 639 code. + * @see #getDisplayLanguage() + * @see #getDisplayLanguage(ULocale) + * @stable ICU 3.0 + */ + public static String getLanguage(String localeID) { + return new LocaleIDParser(localeID).getLanguage(); + } + + /** + * {@icu} Returns the script code for this locale, which might be the empty string. + * @see #getDisplayScript() + * @see #getDisplayScript(ULocale) + * @stable ICU 3.0 + */ + public String getScript() { + return getScript(localeID); + } + + /** + * {@icu} Returns the script code for the specified locale, which might be the empty + * string. + * @see #getDisplayScript() + * @see #getDisplayScript(ULocale) + * @stable ICU 3.0 + */ + public static String getScript(String localeID) { + return new LocaleIDParser(localeID).getScript(); + } + + /** + * Returns the country/region code for this locale, which will either be the empty string + * or an uppercase ISO 3166 2-letter code. + * @see #getDisplayCountry() + * @see #getDisplayCountry(ULocale) + * @stable ICU 3.0 + */ + public String getCountry() { + return getCountry(localeID); + } + + /** + * Returns the country/region code for this locale, which will either be the empty string + * or an uppercase ISO 3166 2-letter code. + * @param localeID The locale identification string. + * @see #getDisplayCountry() + * @see #getDisplayCountry(ULocale) + * @stable ICU 3.0 + */ + public static String getCountry(String localeID) { + return new LocaleIDParser(localeID).getCountry(); + } + + /** + * Returns the variant code for this locale, which might be the empty string. + * @see #getDisplayVariant() + * @see #getDisplayVariant(ULocale) + * @stable ICU 3.0 + */ + public String getVariant() { + return getVariant(localeID); + } + + /** + * Returns the variant code for the specified locale, which might be the empty string. + * @see #getDisplayVariant() + * @see #getDisplayVariant(ULocale) + * @stable ICU 3.0 + */ + public static String getVariant(String localeID) { + return new LocaleIDParser(localeID).getVariant(); + } + + /** + * {@icu} Returns the fallback locale for the specified locale, which might be the + * empty string. + * @stable ICU 3.2 + */ + public static String getFallback(String localeID) { + return getFallbackString(getName(localeID)); + } + + /** + * {@icu} Returns the fallback locale for this locale. If this locale is root, + * returns null. + * @stable ICU 3.2 + */ + public ULocale getFallback() { + if (localeID.length() == 0 || localeID.charAt(0) == '@') { + return null; + } + return new ULocale(getFallbackString(localeID), (Locale)null); + } + + /** + * Returns the given (canonical) locale id minus the last part before the tags. + */ + private static String getFallbackString(String fallback) { + int extStart = fallback.indexOf('@'); + if (extStart == -1) { + extStart = fallback.length(); + } + int last = fallback.lastIndexOf('_', extStart); + if (last == -1) { + last = 0; + } else { + // truncate empty segment + while (last > 0) { + if (fallback.charAt(last - 1) != '_') { + break; + } + last--; + } + } + return fallback.substring(0, last) + fallback.substring(extStart); + } + + /** + * {@icu} Returns the (normalized) base name for this locale. + * @return the base name as a String. + * @stable ICU 3.0 + */ + public String getBaseName() { + return getBaseName(localeID); + } + + /** + * {@icu} Returns the (normalized) base name for the specified locale. + * @param localeID the locale ID as a string + * @return the base name as a String. + * @stable ICU 3.0 + */ + public static String getBaseName(String localeID){ + if (localeID.indexOf('@') == -1) { + return localeID; + } + return new LocaleIDParser(localeID).getBaseName(); + } + + /** + * {@icu} Returns the (normalized) full name for this locale. + * + * @return String the full name of the localeID + * @stable ICU 3.0 + */ + public String getName() { + return localeID; // always normalized + } + + /** + * {@icu} Returns the (normalized) full name for the specified locale. + * + * @param localeID the localeID as a string + * @return String the full name of the localeID + * @stable ICU 3.0 + */ + public static String getName(String localeID){ + String name = nameCache.get(localeID); + if (name == null) { + name = new LocaleIDParser(localeID).getName(); + nameCache.put(localeID, name); + } + return name; + } + + /** + * Returns a string representation of this object. + * @stable ICU 3.0 + */ + public String toString() { + return localeID; + } + + /** + * {@icu} Returns an iterator over keywords for this locale. If there + * are no keywords, returns null. + * @return iterator over keywords, or null if there are no keywords. + * @stable ICU 3.0 + */ + public Iterator getKeywords() { + return getKeywords(localeID); + } + + /** + * {@icu} Returns an iterator over keywords for the specified locale. If there + * are no keywords, returns null. + * @return an iterator over the keywords in the specified locale, or null + * if there are no keywords. + * @stable ICU 3.0 + */ + public static Iterator getKeywords(String localeID){ + return new LocaleIDParser(localeID).getKeywords(); + } + + /** + * {@icu} Returns the value for a keyword in this locale. If the keyword is not + * defined, returns null. + * @param keywordName name of the keyword whose value is desired. Case insensitive. + * @return the value of the keyword, or null. + * @stable ICU 3.0 + */ + public String getKeywordValue(String keywordName){ + return getKeywordValue(localeID, keywordName); + } + + /** + * {@icu} Returns the value for a keyword in the specified locale. If the keyword is + * not defined, returns null. The locale name does not need to be normalized. + * @param keywordName name of the keyword whose value is desired. Case insensitive. + * @return String the value of the keyword as a string + * @stable ICU 3.0 + */ + public static String getKeywordValue(String localeID, String keywordName) { + return new LocaleIDParser(localeID).getKeywordValue(keywordName); + } + + /** + * {@icu} Returns the canonical name for the specified locale ID. This is used to + * convert POSIX and other grandfathered IDs to standard ICU form. + * @param localeID the locale id + * @return the canonicalized id + * @stable ICU 3.0 + */ + public static String canonicalize(String localeID){ + LocaleIDParser parser = new LocaleIDParser(localeID, true); + String baseName = parser.getBaseName(); + boolean foundVariant = false; + + // formerly, we always set to en_US_POSIX if the basename was empty, but + // now we require that the entire id be empty, so that "@foo=bar" + // will pass through unchanged. + // {dlf} I'd rather keep "" unchanged. + if (localeID.equals("")) { + return ""; +// return "en_US_POSIX"; + } + + // we have an ID in the form xx_Yyyy_ZZ_KKKKK + + initCANONICALIZE_MAP(); + + /* convert the variants to appropriate ID */ + for (int i = 0; i < variantsToKeywords.length; i++) { + String[] vals = variantsToKeywords[i]; + int idx = baseName.lastIndexOf("_" + vals[0]); + if (idx > -1) { + foundVariant = true; + + baseName = baseName.substring(0, idx); + if (baseName.endsWith("_")) { + baseName = baseName.substring(0, --idx); + } + parser.setBaseName(baseName); + parser.defaultKeywordValue(vals[1], vals[2]); + break; + } + } + + /* See if this is an already known locale */ + for (int i = 0; i < CANONICALIZE_MAP.length; i++) { + if (CANONICALIZE_MAP[i][0].equals(baseName)) { + foundVariant = true; + + String[] vals = CANONICALIZE_MAP[i]; + parser.setBaseName(vals[1]); + if (vals[2] != null) { + parser.defaultKeywordValue(vals[2], vals[3]); + } + break; + } + } + + /* total mondo hack for Norwegian, fortunately the main NY case is handled earlier */ + if (!foundVariant) { + if (parser.getLanguage().equals("nb") && parser.getVariant().equals("NY")) { + parser.setBaseName(lscvToID("nn", parser.getScript(), parser.getCountry(), null)); + } + } + + return parser.getName(); + } + + /** + * Given a keyword and a value, return a new locale with an updated + * keyword and value. If keyword is null, this removes all keywords from the locale id. + * Otherwise, if the value is null, this removes the value for this keyword from the + * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. + * The keyword and value must not be empty. + * @param keyword the keyword to add/remove, or null to remove all keywords. + * @param value the value to add/set, or null to remove this particular keyword. + * @return the updated locale + * @stable ICU 3.2 + */ + public ULocale setKeywordValue(String keyword, String value) { + return new ULocale(setKeywordValue(localeID, keyword, value), (Locale)null); + } + + /** + * Given a locale id, a keyword, and a value, return a new locale id with an updated + * keyword and value. If keyword is null, this removes all keywords from the locale id. + * Otherwise, if the value is null, this removes the value for this keyword from the + * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. + * The keyword and value must not be empty. + * @param localeID the locale id to modify + * @param keyword the keyword to add/remove, or null to remove all keywords. + * @param value the value to add/set, or null to remove this particular keyword. + * @return the updated locale id + * @stable ICU 3.2 + */ + public static String setKeywordValue(String localeID, String keyword, String value) { + LocaleIDParser parser = new LocaleIDParser(localeID); + parser.setKeywordValue(keyword, value); + return parser.getName(); + } + + /* + * Given a locale id, a keyword, and a value, return a new locale id with an updated + * keyword and value, if the keyword does not already have a value. The keyword and + * value must not be null or empty. + * @param localeID the locale id to modify + * @param keyword the keyword to add, if not already present + * @param value the value to add, if not already present + * @return the updated locale id + */ +/* private static String defaultKeywordValue(String localeID, String keyword, String value) { + LocaleIDParser parser = new LocaleIDParser(localeID); + parser.defaultKeywordValue(keyword, value); + return parser.getName(); + }*/ + + /** + * Returns a three-letter abbreviation for this locale's language. If the locale + * doesn't specify a language, returns the empty string. Otherwise, returns + * a lowercase ISO 639-2/T language code. + * The ISO 639-2 language codes can be found on-line at + * ftp://dkuug.dk/i18n/iso-639-2.txt + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter language abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public String getISO3Language(){ + return getISO3Language(localeID); + } + + /** + * Returns a three-letter abbreviation for this locale's language. If the locale + * doesn't specify a language, returns the empty string. Otherwise, returns + * a lowercase ISO 639-2/T language code. + * The ISO 639-2 language codes can be found on-line at + * ftp://dkuug.dk/i18n/iso-639-2.txt + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter language abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public static String getISO3Language(String localeID) { + return LocaleIDs.getISO3Language(getLanguage(localeID)); + } + + /** + * Returns a three-letter abbreviation for this locale's country/region. If the locale + * doesn't specify a country, returns the empty string. Otherwise, returns + * an uppercase ISO 3166 3-letter country code. + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter country abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public String getISO3Country() { + return getISO3Country(localeID); + } + + /** + * Returns a three-letter abbreviation for this locale's country/region. If the locale + * doesn't specify a country, returns the empty string. Otherwise, returns + * an uppercase ISO 3166 3-letter country code. + * @exception MissingResourceException Throws MissingResourceException if the + * three-letter country abbreviation is not available for this locale. + * @stable ICU 3.0 + */ + public static String getISO3Country(String localeID) { + return LocaleIDs.getISO3Country(getCountry(localeID)); + } + + // display names + + /** + * Returns this locale's language localized for display in the default locale. + * @return the localized language name. + * @stable ICU 3.0 + */ + public String getDisplayLanguage() { + return getDisplayLanguageInternal(this, getDefault(), false); + } + + /** + * {@icu} Returns this locale's language localized for display in the provided locale. + * @param displayLocale the locale in which to display the name. + * @return the localized language name. + * @stable ICU 3.0 + */ + public String getDisplayLanguage(ULocale displayLocale) { + return getDisplayLanguageInternal(this, displayLocale, false); + } + + /** + * Returns a locale's language localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose language will be displayed + * @param displayLocaleID the id of the locale in which to display the name. + * @return the localized language name. + * @stable ICU 3.0 + */ + public static String getDisplayLanguage(String localeID, String displayLocaleID) { + return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), + false); + } + + /** + * Returns a locale's language localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose language will be displayed. + * @param displayLocale the locale in which to display the name. + * @return the localized language name. + * @stable ICU 3.0 + */ + public static String getDisplayLanguage(String localeID, ULocale displayLocale) { + return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, false); + } + /** + * {@icu} Returns this locale's language localized for display in the default locale. + * If a dialect name is present in the data, then it is returned. + * @return the localized language name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public String getDisplayLanguageWithDialect() { + return getDisplayLanguageInternal(this, getDefault(), true); + } + + /** + * {@icu} Returns this locale's language localized for display in the provided locale. + * If a dialect name is present in the data, then it is returned. + * @param displayLocale the locale in which to display the name. + * @return the localized language name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public String getDisplayLanguageWithDialect(ULocale displayLocale) { + return getDisplayLanguageInternal(this, displayLocale, true); + } + + /** + * {@icu} Returns a locale's language localized for display in the provided locale. + * If a dialect name is present in the data, then it is returned. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose language will be displayed + * @param displayLocaleID the id of the locale in which to display the name. + * @return the localized language name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static String getDisplayLanguageWithDialect(String localeID, String displayLocaleID) { + return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), + true); + } + + /** + * {@icu} Returns a locale's language localized for display in the provided locale. + * If a dialect name is present in the data, then it is returned. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose language will be displayed. + * @param displayLocale the locale in which to display the name. + * @return the localized language name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static String getDisplayLanguageWithDialect(String localeID, ULocale displayLocale) { + return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, true); + } + + private static String getDisplayLanguageInternal(ULocale locale, ULocale displayLocale, + boolean useDialect) { + // No dialect support + return locale.toLocale().getDisplayLanguage(displayLocale.toLocale()); + } + + /** + * {@icu} Returns this locale's script localized for display in the default locale. + * @return the localized script name. + * @stable ICU 3.0 + */ + public String getDisplayScript() { + return getDisplayScriptInternal(this, getDefault()); + } + + /** + * {@icu} Returns this locale's script localized for display in the provided locale. + * @param displayLocale the locale in which to display the name. + * @return the localized script name. + * @stable ICU 3.0 + */ + public String getDisplayScript(ULocale displayLocale) { + return getDisplayScriptInternal(this, displayLocale); + } + + /** + * {@icu} Returns a locale's script localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose script will be displayed + * @param displayLocaleID the id of the locale in which to display the name. + * @return the localized script name. + * @stable ICU 3.0 + */ + public static String getDisplayScript(String localeID, String displayLocaleID) { + return getDisplayScriptInternal(new ULocale(localeID), new ULocale(displayLocaleID)); + } + + /** + * {@icu} Returns a locale's script localized for display in the provided locale. + * @param localeID the id of the locale whose script will be displayed. + * @param displayLocale the locale in which to display the name. + * @return the localized script name. + * @stable ICU 3.0 + */ + public static String getDisplayScript(String localeID, ULocale displayLocale) { + return getDisplayScriptInternal(new ULocale(localeID), displayLocale); + } + + // displayLocaleID is canonical, localeID need not be since parsing will fix this. + private static String getDisplayScriptInternal(ULocale locale, ULocale displayLocale) { + // No localization, just return the script code + return locale.getScript(); + } + + /** + * Returns this locale's country localized for display in the default locale. + * @return the localized country name. + * @stable ICU 3.0 + */ + public String getDisplayCountry() { + return getDisplayCountryInternal(this, getDefault()); + } + + /** + * Returns this locale's country localized for display in the provided locale. + * @param displayLocale the locale in which to display the name. + * @return the localized country name. + * @stable ICU 3.0 + */ + public String getDisplayCountry(ULocale displayLocale){ + return getDisplayCountryInternal(this, displayLocale); + } + + /** + * Returns a locale's country localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose country will be displayed + * @param displayLocaleID the id of the locale in which to display the name. + * @return the localized country name. + * @stable ICU 3.0 + */ + public static String getDisplayCountry(String localeID, String displayLocaleID) { + return getDisplayCountryInternal(new ULocale(localeID), new ULocale(displayLocaleID)); + } + + /** + * Returns a locale's country localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose country will be displayed. + * @param displayLocale the locale in which to display the name. + * @return the localized country name. + * @stable ICU 3.0 + */ + public static String getDisplayCountry(String localeID, ULocale displayLocale) { + return getDisplayCountryInternal(new ULocale(localeID), displayLocale); + } + + // displayLocaleID is canonical, localeID need not be since parsing will fix this. + private static String getDisplayCountryInternal(ULocale locale, ULocale displayLocale) { + return locale.toLocale().getDisplayCountry(displayLocale.toLocale()); + } + + /** + * Returns this locale's variant localized for display in the default locale. + * @return the localized variant name. + * @stable ICU 3.0 + */ + public String getDisplayVariant() { + return getDisplayVariantInternal(this, getDefault()); + } + + /** + * Returns this locale's variant localized for display in the provided locale. + * @param displayLocale the locale in which to display the name. + * @return the localized variant name. + * @stable ICU 3.0 + */ + public String getDisplayVariant(ULocale displayLocale) { + return getDisplayVariantInternal(this, displayLocale); + } + + /** + * Returns a locale's variant localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose variant will be displayed + * @param displayLocaleID the id of the locale in which to display the name. + * @return the localized variant name. + * @stable ICU 3.0 + */ + public static String getDisplayVariant(String localeID, String displayLocaleID){ + return getDisplayVariantInternal(new ULocale(localeID), new ULocale(displayLocaleID)); + } + + /** + * Returns a locale's variant localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose variant will be displayed. + * @param displayLocale the locale in which to display the name. + * @return the localized variant name. + * @stable ICU 3.0 + */ + public static String getDisplayVariant(String localeID, ULocale displayLocale) { + return getDisplayVariantInternal(new ULocale(localeID), displayLocale); + } + + private static String getDisplayVariantInternal(ULocale locale, ULocale displayLocale) { + return locale.toLocale().getDisplayVariant(displayLocale.toLocale()); + } + + /** + * {@icu} Returns a keyword localized for display in the default locale. + * @param keyword the keyword to be displayed. + * @return the localized keyword name. + * @see #getKeywords() + * @stable ICU 3.0 + */ + public static String getDisplayKeyword(String keyword) { + return getDisplayKeywordInternal(keyword, getDefault()); + } + + /** + * {@icu} Returns a keyword localized for display in the specified locale. + * @param keyword the keyword to be displayed. + * @param displayLocaleID the id of the locale in which to display the keyword. + * @return the localized keyword name. + * @see #getKeywords(String) + * @stable ICU 3.0 + */ + public static String getDisplayKeyword(String keyword, String displayLocaleID) { + return getDisplayKeywordInternal(keyword, new ULocale(displayLocaleID)); + } + + /** + * {@icu} Returns a keyword localized for display in the specified locale. + * @param keyword the keyword to be displayed. + * @param displayLocale the locale in which to display the keyword. + * @return the localized keyword name. + * @see #getKeywords(String) + * @stable ICU 3.0 + */ + public static String getDisplayKeyword(String keyword, ULocale displayLocale) { + return getDisplayKeywordInternal(keyword, displayLocale); + } + + private static String getDisplayKeywordInternal(String keyword, ULocale displayLocale) { + // No localization + return keyword; + } + + /** + * {@icu} Returns a keyword value localized for display in the default locale. + * @param keyword the keyword whose value is to be displayed. + * @return the localized value name. + * @stable ICU 3.0 + */ + public String getDisplayKeywordValue(String keyword) { + return getDisplayKeywordValueInternal(this, keyword, getDefault()); + } + + /** + * {@icu} Returns a keyword value localized for display in the specified locale. + * @param keyword the keyword whose value is to be displayed. + * @param displayLocale the locale in which to display the value. + * @return the localized value name. + * @stable ICU 3.0 + */ + public String getDisplayKeywordValue(String keyword, ULocale displayLocale) { + return getDisplayKeywordValueInternal(this, keyword, displayLocale); + } + + /** + * {@icu} Returns a keyword value localized for display in the specified locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose keyword value is to be displayed. + * @param keyword the keyword whose value is to be displayed. + * @param displayLocaleID the id of the locale in which to display the value. + * @return the localized value name. + * @stable ICU 3.0 + */ + public static String getDisplayKeywordValue(String localeID, String keyword, + String displayLocaleID) { + return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, + new ULocale(displayLocaleID)); + } + + /** + * {@icu} Returns a keyword value localized for display in the specified locale. + * This is a cover for the ICU4C API. + * @param localeID the id of the locale whose keyword value is to be displayed. + * @param keyword the keyword whose value is to be displayed. + * @param displayLocale the id of the locale in which to display the value. + * @return the localized value name. + * @stable ICU 3.0 + */ + public static String getDisplayKeywordValue(String localeID, String keyword, + ULocale displayLocale) { + return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, displayLocale); + } + + // displayLocaleID is canonical, localeID need not be since parsing will fix this. + private static String getDisplayKeywordValueInternal(ULocale locale, String keyword, + ULocale displayLocale) { + keyword = AsciiUtil.toLowerString(keyword.trim()); + String value = locale.getKeywordValue(keyword); + return value; + } + + /** + * Returns this locale name localized for display in the default locale. + * @return the localized locale name. + * @stable ICU 3.0 + */ + public String getDisplayName() { + return getDisplayNameInternal(this, getDefault()); + } + + /** + * Returns this locale name localized for display in the provided locale. + * @param displayLocale the locale in which to display the locale name. + * @return the localized locale name. + * @stable ICU 3.0 + */ + public String getDisplayName(ULocale displayLocale) { + return getDisplayNameInternal(this, displayLocale); + } + + /** + * Returns the locale ID localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the locale whose name is to be displayed. + * @param displayLocaleID the id of the locale in which to display the locale name. + * @return the localized locale name. + * @stable ICU 3.0 + */ + public static String getDisplayName(String localeID, String displayLocaleID) { + return getDisplayNameInternal(new ULocale(localeID), new ULocale(displayLocaleID)); + } + + /** + * Returns the locale ID localized for display in the provided locale. + * This is a cover for the ICU4C API. + * @param localeID the locale whose name is to be displayed. + * @param displayLocale the locale in which to display the locale name. + * @return the localized locale name. + * @stable ICU 3.0 + */ + public static String getDisplayName(String localeID, ULocale displayLocale) { + return getDisplayNameInternal(new ULocale(localeID), displayLocale); + } + + private static String getDisplayNameInternal(ULocale locale, ULocale displayLocale) { + // No localization, no script and keywords + return locale.toLocale().getDisplayName(displayLocale.toLocale()); + } + + /** + * {@icu} Returns this locale name localized for display in the default locale. + * If a dialect name is present in the locale data, then it is returned. + * @return the localized locale name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public String getDisplayNameWithDialect() { + return getDisplayNameWithDialectInternal(this, getDefault()); + } + + /** + * {@icu} Returns this locale name localized for display in the provided locale. + * If a dialect name is present in the locale data, then it is returned. + * @param displayLocale the locale in which to display the locale name. + * @return the localized locale name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public String getDisplayNameWithDialect(ULocale displayLocale) { + return getDisplayNameWithDialectInternal(this, displayLocale); + } + + /** + * {@icu} Returns the locale ID localized for display in the provided locale. + * If a dialect name is present in the locale data, then it is returned. + * This is a cover for the ICU4C API. + * @param localeID the locale whose name is to be displayed. + * @param displayLocaleID the id of the locale in which to display the locale name. + * @return the localized locale name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static String getDisplayNameWithDialect(String localeID, String displayLocaleID) { + return getDisplayNameWithDialectInternal(new ULocale(localeID), + new ULocale(displayLocaleID)); + } + + /** + * {@icu} Returns the locale ID localized for display in the provided locale. + * If a dialect name is present in the locale data, then it is returned. + * This is a cover for the ICU4C API. + * @param localeID the locale whose name is to be displayed. + * @param displayLocale the locale in which to display the locale name. + * @return the localized locale name. + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public static String getDisplayNameWithDialect(String localeID, ULocale displayLocale) { + return getDisplayNameWithDialectInternal(new ULocale(localeID), displayLocale); + } + + private static String getDisplayNameWithDialectInternal(ULocale locale, ULocale displayLocale) { + // No dialect support, no script and keyword support + return locale.toLocale().getDisplayName(displayLocale.toLocale()); + } + + /** + * {@icu} Returns this locale's layout orientation for characters. The possible + * values are "left-to-right", "right-to-left", "top-to-bottom" or + * "bottom-to-top". + * @return The locale's layout orientation for characters. + * @stable ICU 4.0 + */ + public String getCharacterOrientation() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns this locale's layout orientation for lines. The possible + * values are "left-to-right", "right-to-left", "top-to-bottom" or + * "bottom-to-top". + * @return The locale's layout orientation for lines. + * @stable ICU 4.0 + */ + public String getLineOrientation() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Selector for getLocale() indicating the locale of the + * resource containing the data. This is always at or above the + * valid locale. If the valid locale does not contain the + * specific data being requested, then the actual locale will be + * above the valid locale. If the object was not constructed from + * locale data, then the valid locale is null. + * + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static Type ACTUAL_LOCALE = new Type(); + + /** + * {@icu} Selector for getLocale() indicating the most specific + * locale for which any data exists. This is always at or above + * the requested locale, and at or below the actual locale. If + * the requested locale does not correspond to any resource data, + * then the valid locale will be above the requested locale. If + * the object was not constructed from locale data, then the + * actual locale is null. + * + *

      Note: The valid locale will be returned correctly in ICU + * 3.0 or later. In ICU 2.8, it is not returned correctly. + * @draft ICU 2.8 (retain) + * @provisional This API might change or be removed in a future release. + */ + public static Type VALID_LOCALE = new Type(); + + /** + * Opaque selector enum for getLocale(). + * @see com.ibm.icu.util.ULocale + * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE + * @see com.ibm.icu.util.ULocale#VALID_LOCALE + * @draft ICU 2.8 (retainAll) + * @provisional This API might change or be removed in a future release. + */ + public static final class Type { + private Type() {} + } + + /** + * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available + * locale for the user. NullPointerException is thrown if acceptLanguageList or + * availableLocales is null. If fallback is non-null, it will contain true if a + * fallback locale (one not in the acceptLanguageList) was returned. The value on + * entry is ignored. ULocale will be one of the locales in availableLocales, or the + * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in + * availableLocales matched). No ULocale array element should be null; behavior is + * undefined if this is the case. + * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales + * @param availableLocales list of available locales. One of these will be returned. + * @param fallback if non-null, a 1-element array containing a boolean to be set with + * the fallback status + * @return one of the locales from the availableLocales list, or null if none match + * @stable ICU 3.4 + */ + public static ULocale acceptLanguage(String acceptLanguageList, ULocale[] availableLocales, + boolean[] fallback) { + if (acceptLanguageList == null) { + throw new NullPointerException(); + } + ULocale acceptList[] = null; + try { + acceptList = parseAcceptLanguage(acceptLanguageList, true); + } catch (ParseException pe) { + acceptList = null; + } + if (acceptList == null) { + return null; + } + return acceptLanguage(acceptList, availableLocales, fallback); + } + + /** + * {@icu} Based on a list of acceptable locales, determine an available locale for the + * user. NullPointerException is thrown if acceptLanguageList or availableLocales is + * null. If fallback is non-null, it will contain true if a fallback locale (one not + * in the acceptLanguageList) was returned. The value on entry is ignored. ULocale + * will be one of the locales in availableLocales, or the ROOT ULocale if if a ROOT + * locale was used as a fallback (because nothing else in availableLocales matched). + * No ULocale array element should be null; behavior is undefined if this is the case. + * @param acceptLanguageList list of acceptable locales + * @param availableLocales list of available locales. One of these will be returned. + * @param fallback if non-null, a 1-element array containing a boolean to be set with + * the fallback status + * @return one of the locales from the availableLocales list, or null if none match + * @stable ICU 3.4 + */ + + public static ULocale acceptLanguage(ULocale[] acceptLanguageList, ULocale[] + availableLocales, boolean[] fallback) { + // fallbacklist + int i,j; + if(fallback != null) { + fallback[0]=true; + } + for(i=0;i { + private double q; + private double serial; + public ULocaleAcceptLanguageQ(double theq, int theserial) { + q = theq; + serial = theserial; + } + public int compareTo(ULocaleAcceptLanguageQ other) { + if (q > other.q) { // reverse - to sort in descending order + return -1; + } else if (q < other.q) { + return 1; + } + if (serial < other.serial) { + return -1; + } else if (serial > other.serial) { + return 1; + } else { + return 0; // same object + } + } + } + + // parse out the acceptLanguage into an array + TreeMap map = + new TreeMap(); + StringBuilder languageRangeBuf = new StringBuilder(); + StringBuilder qvalBuf = new StringBuilder(); + int state = 0; + acceptLanguage += ","; // append comma to simplify the parsing code + int n; + boolean subTag = false; + boolean q1 = false; + for (n = 0; n < acceptLanguage.length(); n++) { + boolean gotLanguageQ = false; + char c = acceptLanguage.charAt(n); + switch (state) { + case 0: // before language-range start + if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { + // in language-range + languageRangeBuf.append(c); + state = 1; + subTag = false; + } else if (c == '*') { + languageRangeBuf.append(c); + state = 2; + } else if (c != ' ' && c != '\t') { + // invalid character + state = -1; + } + break; + case 1: // in language-range + if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { + languageRangeBuf.append(c); + } else if (c == '-') { + subTag = true; + languageRangeBuf.append(c); + } else if (c == '_') { + if (isLenient) { + subTag = true; + languageRangeBuf.append(c); + } else { + state = -1; + } + } else if ('0' <= c && c <= '9') { + if (subTag) { + languageRangeBuf.append(c); + } else { + // DIGIT is allowed only in language sub tag + state = -1; + } + } else if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c == ' ' || c == '\t') { + // language-range end + state = 3; + } else if (c == ';') { + // before q + state = 4; + } else { + // invalid character for language-range + state = -1; + } + break; + case 2: // saw wild card range + if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c == ' ' || c == '\t') { + // language-range end + state = 3; + } else if (c == ';') { + // before q + state = 4; + } else { + // invalid + state = -1; + } + break; + case 3: // language-range end + if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c == ';') { + // before q + state =4; + } else if (c != ' ' && c != '\t') { + // invalid + state = -1; + } + break; + case 4: // before q + if (c == 'q') { + // before equal + state = 5; + } else if (c != ' ' && c != '\t') { + // invalid + state = -1; + } + break; + case 5: // before equal + if (c == '=') { + // before q value + state = 6; + } else if (c != ' ' && c != '\t') { + // invalid + state = -1; + } + break; + case 6: // before q value + if (c == '0') { + // q value start with 0 + q1 = false; + qvalBuf.append(c); + state = 7; + } else if (c == '1') { + // q value start with 1 + qvalBuf.append(c); + state = 7; + } else if (c == '.') { + if (isLenient) { + qvalBuf.append(c); + state = 8; + } else { + state = -1; + } + } else if (c != ' ' && c != '\t') { + // invalid + state = -1; + } + break; + case 7: // q value start + if (c == '.') { + // before q value fraction part + qvalBuf.append(c); + state = 8; + } else if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c == ' ' || c == '\t') { + // after q value + state = 10; + } else { + // invalid + state = -1; + } + break; + case 8: // before q value fraction part + if ('0' <= c || c <= '9') { + if (q1 && c != '0' && !isLenient) { + // if q value starts with 1, the fraction part must be 0 + state = -1; + } else { + // in q value fraction part + qvalBuf.append(c); + state = 9; + } + } else { + // invalid + state = -1; + } + break; + case 9: // in q value fraction part + if ('0' <= c && c <= '9') { + if (q1 && c != '0') { + // if q value starts with 1, the fraction part must be 0 + state = -1; + } else { + qvalBuf.append(c); + } + } else if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c == ' ' || c == '\t') { + // after q value + state = 10; + } else { + // invalid + state = -1; + } + break; + case 10: // after q value + if (c == ',') { + // language-q end + gotLanguageQ = true; + } else if (c != ' ' && c != '\t') { + // invalid + state = -1; + } + break; + } + if (state == -1) { + // error state + throw new ParseException("Invalid Accept-Language", n); + } + if (gotLanguageQ) { + double q = 1.0; + if (qvalBuf.length() != 0) { + try { + q = Double.parseDouble(qvalBuf.toString()); + } catch (NumberFormatException nfe) { + // Already validated, so it should never happen + q = 1.0; + } + if (q > 1.0) { + q = 1.0; + } + } + if (languageRangeBuf.charAt(0) != '*') { + int serial = map.size(); + ULocaleAcceptLanguageQ entry = new ULocaleAcceptLanguageQ(q, serial); + // sort in reverse order.. 1.0, 0.9, 0.8 .. etc + map.put(entry, new ULocale(canonicalize(languageRangeBuf.toString()))); + } + + // reset buffer and parse state + languageRangeBuf.setLength(0); + qvalBuf.setLength(0); + state = 0; + } + } + if (state != 0) { + // Well, the parser should handle all cases. So just in case. + throw new ParseException("Invalid AcceptlLanguage", n); + } + + // pull out the map + ULocale acceptList[] = map.values().toArray(new ULocale[map.size()]); + return acceptList; + } + + /** + * {@icu} Adds the likely subtags for a provided locale ID, per the algorithm + * described in the following CLDR technical report: + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags + * + * If the provided ULocale instance is already in the maximal form, or there is no + * data available available for maximization, it will be returned. For example, + * "und-Zzzz" cannot be maximized, since there is no reasonable maximization. + * Otherwise, a new ULocale instance with the maximal form is returned. + * + * Examples: + * + * "en" maximizes to "en_Latn_US" + * + * "de" maximizes to "de_Latn_US" + * + * "sr" maximizes to "sr_Cyrl_RS" + * + * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.) + * + * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.) + * + * @param loc The ULocale to maximize + * @return The maximized ULocale instance. + * @stable ICU 4.0 + */ + public static ULocale addLikelySubtags(ULocale loc) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Minimizes the subtags for a provided locale ID, per the algorithm described + * in the following CLDR technical report:

      + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags
      + * + * If the provided ULocale instance is already in the minimal form, or there + * is no data available for minimization, it will be returned. Since the + * minimization algorithm relies on proper maximization, see the comments + * for addLikelySubtags for reasons why there might not be any data. + * + * Examples:
      +     *
      +     * "en_Latn_US" minimizes to "en"
      +     *
      +     * "de_Latn_US" minimizes to "de"
      +     *
      +     * "sr_Cyrl_RS" minimizes to "sr"
      +     *
      +     * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the
      +     * script, and minimizing to "zh" would imply "zh_Hans_CN".) 
      + * + * @param loc The ULocale to minimize + * @return The minimized ULocale instance. + * @stable ICU 4.0 + */ + public static ULocale minimizeSubtags(ULocale loc) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + // -------------------------------- + // BCP47/OpenJDK APIs + // -------------------------------- + + /** + * {@icu} The key for the private use locale extension ('x'). + * + * @see #getExtension(char) + * @see Builder#setExtension(char, String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public static final char PRIVATE_USE_EXTENSION = 'x'; + + /** + * {@icu} The key for Unicode locale extension ('u'). + * + * @see #getExtension(char) + * @see Builder#setExtension(char, String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public static final char UNICODE_LOCALE_EXTENSION = 'u'; + + /** + * {@icu} Returns the extension (or private use) value associated with + * the specified singleton key, or null if there is no extension + * associated with the key. To be valid, the key must be one + * of [0-9A-Za-z]. Keys are case-insensitive, so + * for example 'z' and 'Z' represent the same extension. + * + * @param key the extension key + * @return the extension, or null if this locale defines no + * extension for the specified key + * @throws IllegalArgumentException if the key is not valid + * @see #PRIVATE_USE_EXTENSION + * @see #UNICODE_LOCALE_EXTENSION + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public String getExtension(char key) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the set of extension keys associated with this locale, or the + * empty set if it has no extensions. The returned set is unmodifiable. + * + * @return the set of extension keys, or the empty set if this locale has + * no extensions + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Set getExtensionKeys() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the Unicode locale type associated with the specified Unicode + * locale key for this locale. Unicode locale keywrods are specified + * by the 'u' extension and consist of key/type pairs. The key must be + * two alphanumeric characters in length, or an IllegalArgumentException + * is thrown. + * @param key the Unicode locale key + * @return the Unicode locale type associated with the key, or null if the + * locale does not define a value for the key. + * @throws IllegalArgumentException if the key is not valid. + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public String getUnicodeLocaleType(String key) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns the set of keys for Unicode locale keywords defined by this locale, + * or null if this locale has no locale extension. The returned set is + * immutable. + * + * @return the set of the Unicode locale keys, or null + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public Set getUnicodeLocaleKeys() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns a well-formed IETF BCP 47 language tag representing + * this locale. + * + *

      + * If this ULocale object has language, country, or variant + * that does not satisfy the IETF BCP 47 language tag syntax requirements, + * this method handles these fields as described below: + *

      + * Language: If language is empty or ill-formed (for example "a" or "e2"), + * it will be emitted as "und" (Undetermined). + *

      + * Country: If country is ill-formed (for example "12" or "USA"), it + * will be omitted. + *

      + * Variant: Variant is treated as consisting of subtags separated by + * underscore and converted to lower case letters. 'Well-formed' subtags + * consist of either an ASCII letter followed by 4-7 ASCII characters, or an + * ASCII digit followed by 3-7 ASCII characters. If well-formed, the variant + * is emitted as each subtag in order (separated by hyphen). Otherwise: + *

        + *
      • if all sub-segments consist of 1 to 8 ASCII alphanumerics (for example + * "WIN", "WINDOWS_XP", "SOLARIS_10"), the first ill-formed variant subtag + * and all following sub-segments will be emitted as private use subtags prefixed + * by the special private use subtag "variant" followed by each subtag in order + * (separated by hyphen). For example, locale "en_US_WIN" is converted to language + * tag "en-US-x-variant-win", locale "de_WINDOWS_XP" is converted to language tag + * "de-windows-x-variant-xp". If this locale has a private use extension value, + * the special private use subtags prefixed by "variant" are appended after the + * locale's private use value. + *
      • if any subtag does not consist of 1 to 8 ASCII alphanumerics, the + * variant will be truncated and the problematic subtag and all following + * sub-segments will be omitted. If the remainder is non-empty, it will be + * emitted as a private use subtag as above (even if the remainder turns out + * to be well-formed). For example, "Solaris_isjustthecoolestthing" is emitted + * as "x-jvariant-Solaris", not as "solaris".
      • + *
      + * + *

      Note: Although the language tag created by this method + * satisfies the syntax requirements defined by the IETF BCP 47 + * specification, it is not always a valid BCP 47 language tag. + * For example, + *

      +     *   new ULocale("xx_YY").toLanguageTag();
      +     * 
      + * will return "xx-YY", but the language subtag "xx" and the region subtag "YY" + * are invalid because they are not registered in the + * + * IANA Language Subtag Registry. + * + * @return a BCP47 language tag representing the locale + * @see #forLanguageTag(String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public String toLanguageTag() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * {@icu} Returns a locale for the specified IETF BCP 47 language tag string. + * If the specified language tag contains any ill-formed subtags, + * the first such subtag and all following subtags are ignored. + * + *

      This implements the 'Language-Tag' production of BCP47, and + * so supports grandfathered (regular and irregular) as well as + * private use language tags. Stand alone private use tags are + * represented as empty language and extension 'x-whatever', + * and grandfathered tags are converted to their canonical replacements + * where they exist. Note that a few grandfathered tags have no + * modern replacement; these will be converted using the fallback + * described above so some information might be lost. + * + *

      For a list of grandfathered tags, see the + * + * IANA Language Subtag Registry. + * + *

      Notes: This method converts private use subtags prefixed + * by "variant" to variant field in the result locale. For example, + * the code below will return "POSIX". + *

      +     *   ULocale.forLanguageTag("en-US-x-variant-posix).getVariant();
      +     * 
      + * + * @param languageTag the language tag + * @return the locale that best represents the language tag + * @exception NullPointerException if languageTag is null + * @see #toLanguageTag() + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public static ULocale forLanguageTag(String languageTag) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + + /** + * Builder is used to build instances of ULocale + * from values configured by the setter. Unlike the ULocale + * constructors, the Builder checks if a value configured by a + * setter satisfies the syntactical requirements defined by the ULocale + * class. A ULocale object created by a Builder is + * well-formed and can be transformed to a well-formed IETF BCP 47 language tag + * without losing information. + * + *

      + * Note: The ULocale class does not provide + * any syntactical restrictions on variant, while BCP 47 + * requires each variant subtag to be 5 to 8 alphanumeric letters or a single + * numeric letter followed by 3 alphanumeric letters. By default, + * the setVariant method throws IllformedLocaleException + * for a variant that does not satisfy the syntax above. If it is + * necessary to support such a variant, you could use the constructor + * Builder(boolean isLenientVariant) passing true to + * skip the syntax validation for variant. However, you should keep in + * mind that a Locale object created this way might lose + * the variant information when transformed to a BCP 47 language tag. + * + *

      + * The following example shows how to create a ULocale object + * with the Builder. + *

      + *
      +     *     ULocale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
      +     * 
      + *
      + * + *

      Builders can be reused; clear() resets all + * fields to their default values. + * + * @see ULocale#toLanguageTag() + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public static final class Builder { + + /** + * Constructs an empty Builder. The default value of all + * fields, extensions, and private use information is the + * empty string. + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder() { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Constructs an empty Builder with an option whether to allow + * setVariant to accept a value that does not + * conform to the IETF BCP 47 variant subtag's syntax requirements. + * + * @param isLenientVariant When true, this Builder + * will accept an ill-formed variant. + * @see #setVariant(String) + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public Builder(boolean isLenientVariant) { + throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); + } + + /** + * Returns true if this Builder accepts a value that does + * not conform to the IETF BCP 47 variant subtag's syntax requirements + * in setVariant + * + * @return true if this Build accepts an ill-formed variant. + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public boolean isLenientVariant() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + + /** + * Resets the Builder to match the provided locale. + * The previous state of the builder is discarded. Fields that do + * not conform to the ULocale class specification, for example, + * a single letter language, are ill-formed. + * + * @param locale the locale + * @return this builder + * @throws IllformedLocaleException if locale has + * any ill-formed fields. + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setLocale(ULocale locale) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Resets the builder to match the provided IETF BCP 47 language tag. + * The previous state of the builder is discarded. + * + * @param languageTag the language tag + * @return this builder + * @throws IllformedLocaleException if languageTag is ill-formed. + * @throws NullPointerException if languageTag is null. + * @see ULocale#forLanguageTag(String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setLanguageTag(String languageTag) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the language. If language is the empty string, + * the language in this Builder will be removed. + * Typical language value is a two or three-letter language + * code as defined in ISO639. + * Well-formed values are any string of two to eight alpha + * letters. This method accepts upper case alpha letters + * [A-Z], but the language value in the ULocale + * created by the Builder is always normalized + * to lower case letters. + * + * @param language the language + * @return this builder + * @throws IllformedLocaleException if language is ill-formed + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setLanguage(String language) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the script. If script is the empty string, + * the script in this Builder is removed. + * Typical script value is a four-letter script code as defined by ISO 15924. + * Well-formed values are any string of four alpha letters. + * This method accepts both upper and lower case alpha letters [a-zA-Z], + * but the script value in the ULocale created by the + * Builder is always normalized to title case + * (the first letter is upper case and the rest of letters are lower case). + * + * @param script the script + * @return this builder + * @throws IllformedLocaleException if script is ill-formed + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setScript(String script) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the region. If region is the empty string, the region + * in this Builder is removed. + * Typical region value is a two-letter ISO 3166 code or a three-digit UN M.49 + * area code. Well-formed values are any two-letter or three-digit string. + * This method accepts lower case letters [a-z], but the country value in + * the ULocale created by the Builder is always + * normalized to upper case. + * + * @param region the region + * @return this builder + * @throws IllformedLocaleException if region is ill-formed + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setRegion(String region) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the variant. If variant is the empty string, the + * variant in this Builder is removed. + *

      + * Note: By default, this method checks if variant + * satisfies the IETF BCP 47 variant subtag's syntax requirements. + * However, the ULocale class itself does not impose any syntactical + * restriction on variant. When a Builder is created by the + * constructor Builder(boolean isLenientVariant) + * with true, this method skips the syntax check. + * + * @param variant the variant + * @return this builder + * @throws IllformedLocaleException if variant is ill-formed + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setVariant(String variant) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the extension for the given key. If the value is the + * empty string, the extension is removed. Legal keys are + * characters in the ranges [0-9A-Za-z]. Keys + * are case-insensitive, so for example 'z' and 'Z' represent + * the same extension. In general, well-formed values are any + * series of fields of two to eight alphanumeric characters, + * separated by hyphen or underscore. + * + *

      Note: The key {@link ULocale#UNICODE_LOCALE_EXTENSION + * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension. + * Setting a value for this key replaces any existing Unicode locale key/type + * pairs with those defined in the extension. + * To be well-formed, a value for this extension must meet the additional + * constraints that each locale key is two alphanumeric characters, + * followed by at least one locale type subtag represented by + * three to eight alphanumeric characters, and that the keys and types + * be legal Unicode locale keys and values. + * + *

      Note: The key {@link ULocale#PRIVATE_USE_EXTENSION + * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be + * well-formed, the value for this key needs only to have fields of one to + * eight alphanumeric characters, not two to eight as in the general case. + * + * @param key the extension key + * @param value the extension value + * @return this builder + * @throws IllformedLocaleException if key is illegal + * or value is ill-formed + * @see #setUnicodeLocaleKeyword(String, String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder setExtension(char key, String value) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Sets the Unicode locale keyword type for the given key. If the + * value is the empty string, the Unicode keyword is removed. + * Well-formed keys are strings of two alphanumeric characters. + * Well-formed types are one or more subtags where each of them is + * three to eight alphanumeric characters. + *

      + * Note:Setting the 'u' extension replaces all Unicode locale + * keywords with those defined in the extension. + * @param key the Unicode locale key + * @param type the Unicode locale type + * @return this builder + * @throws IllformedLocaleException if key or type + * is ill-formed + * @see #setExtension(char, String) + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public Builder setUnicodeLocaleKeyword(String key, String type) { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Resets the builder to its initial, empty state. + * + * @return this builder + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder clear() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Resets the extensions to their initial, empty state. + * Language, script, region and variant are unchanged. + * + * @return this builder + * @see #setExtension(char, String) + * + * @draft ICU 4.2 + * @provisional This API might change or be removed in a future release. + */ + public Builder clearExtensions() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + + /** + * Returns an instance of Locale created from the fields set + * on this builder. + * + * @return a new Locale + * + * @draft ICU 4.4 + * @provisional This API might change or be removed in a future release. + */ + public ULocale build() { + throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); + } + } +} diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/VersionInfo.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/VersionInfo.java index 0bac81d1453..22af59379aa 100644 --- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/VersionInfo.java +++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/VersionInfo.java @@ -1,14 +1,14 @@ -/* - ******************************************************************************* - * Copyright (C) 2011, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* - */ -package com.ibm.icu.util; - -/* - * Empty stub - */ -public final class VersionInfo { - private VersionInfo() {} -} +/* + ******************************************************************************* + * Copyright (C) 2011, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.util; + +/* + * Empty stub + */ +public final class VersionInfo { + private VersionInfo() {} +}