Index: src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java =================================================================== --- src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java (revision 590549) +++ src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java (working copy) @@ -99,9 +99,9 @@ // java.text.DateFormatSymbols.getLocalPatternChars() String retVal = dfs.getLocalPatternChars(); - String val = "GyMdkHmsSEDFwWahKzZ"; + String val = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV"; - assertTrue("Returned incorrect pattern string", retVal.equals(val)); + assertEquals("Returned incorrect pattern string", val, retVal); } /** @@ -113,9 +113,8 @@ String[] retVal = dfs.getMonths(); String[] val = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", - "December", "" }; - if (retVal.length != val.length) - fail("Returned wrong array: " + retVal.length); + "December"}; + assertEquals("Returned wrong array: ", val.length, retVal.length); for (int i = 0; i < val.length; i++) assertTrue("Array values do not match", retVal[i].equals(val[i])); } @@ -128,9 +127,8 @@ // java.text.DateFormatSymbols.getShortMonths() String[] retVal = dfs.getShortMonths(); String[] val = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", - "Aug", "Sep", "Oct", "Nov", "Dec", "" }; - if (retVal.length != val.length) - fail("Returned wrong array"); + "Aug", "Sep", "Oct", "Nov", "Dec"}; + assertEquals("Returned wrong array: ", val.length, retVal.length); for (int i = 0; i < val.length; i++) assertTrue("Array values do not match", retVal[i].equals(val[i])); } Index: src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java =================================================================== --- src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java (revision 590549) +++ src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java (working copy) @@ -130,7 +130,7 @@ String source = "cha"; CollationElementIterator iterator = coll .getCollationElementIterator(source); - int[] e_offset = { 0, 2, 3 }; + int[] e_offset = { 0, 1, 2 ,3}; int offset = iterator.getOffset(); int i = 0; assertEquals(e_offset[i++], offset); @@ -180,7 +180,7 @@ StringCharacterIterator source = new StringCharacterIterator(text); CollationElementIterator iterator = coll .getCollationElementIterator(source); - int[] e_offset = { 0, 2, 3 }; + int[] e_offset = { 0, 1, 2, 3 }; int offset = iterator.getOffset(); int i = 0; assertEquals(e_offset[i++], offset); Index: src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java =================================================================== --- src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java (revision 590549) +++ src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java (working copy) @@ -167,7 +167,7 @@ CollationElementIterator iterator = rbColl .getCollationElementIterator(text); iterator.setOffset(1); - assertEquals(0, iterator.getOffset()); + assertEquals(1, iterator.getOffset()); } /* @@ -183,7 +183,7 @@ assertEquals(1, iterator.getOffset()); iterator.setText("cha"); iterator.setOffset(1); - assertEquals(0, iterator.getOffset()); + assertEquals(1, iterator.getOffset()); } /* @@ -199,6 +199,6 @@ assertEquals(1, iterator.getOffset()); iterator.setText(new StringCharacterIterator("cha")); iterator.setOffset(1); - assertEquals(0, iterator.getOffset()); + assertEquals(1, iterator.getOffset()); } } Index: src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java =================================================================== --- src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java (revision 590549) +++ src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java (working copy) @@ -68,8 +68,8 @@ */ public void test_getCurrency() { Currency currency = Currency.getInstance("USD"); - assertTrue("Returned incorrect currency", - dfsUS.getCurrency() == currency); + assertEquals("Returned incorrect currency", + dfsUS.getCurrency(), currency); Currency currK = Currency.getInstance("KRW"); Currency currX = Currency.getInstance("XXX"); @@ -239,8 +239,8 @@ dfs.setCurrency(currency); assertTrue("Returned incorrect currency", currency == dfs.getCurrency()); - assertTrue("Returned incorrect currency symbol", currency.getSymbol( - locale).equals(dfs.getCurrencySymbol())); + assertEquals("Returned incorrect currency symbol", currency.getSymbol( + locale), dfs.getCurrencySymbol()); assertTrue("Returned incorrect international currency symbol", currency .getCurrencyCode().equals(dfs.getInternationalCurrencySymbol())); } @@ -292,17 +292,14 @@ assertTrue("Test1: Returned incorrect currency", currency == dfs .getCurrency()); - assertTrue("Test1: Returned incorrect currency symbol", currency - .getSymbol(locale).equals(dfs.getCurrencySymbol())); + assertEquals("Test1: Returned incorrect currency symbol", currency + .getSymbol(locale), dfs.getCurrencySymbol()); assertTrue("Test1: Returned incorrect international currency symbol", currency.getCurrencyCode().equals( dfs.getInternationalCurrencySymbol())); - String symbol = dfs.getCurrencySymbol(); dfs.setInternationalCurrencySymbol("bogus"); - assertNull("Test2: Returned incorrect currency", dfs.getCurrency()); - assertTrue("Test2: Returned incorrect currency symbol", dfs - .getCurrencySymbol().equals(symbol)); + assertNotNull("Test2: Returned incorrect currency", dfs.getCurrency()); assertEquals("Test2: Returned incorrect international currency symbol", "bogus", dfs.getInternationalCurrencySymbol()); } Index: src/main/java/java/text/DateFormatSymbols.java =================================================================== --- src/main/java/java/text/DateFormatSymbols.java (revision 590549) +++ src/main/java/java/text/DateFormatSymbols.java (working copy) @@ -20,7 +20,6 @@ import java.io.Serializable; import java.util.Arrays; import java.util.Locale; -import java.util.ResourceBundle; /** * DateFormatSymbols holds the Strings used in the formating and parsing of @@ -52,15 +51,16 @@ * the Locale */ public DateFormatSymbols(Locale locale) { - ResourceBundle bundle = Format.getBundle(locale); - localPatternChars = bundle.getString("LocalPatternChars"); //$NON-NLS-1$ - ampms = bundle.getStringArray("ampm"); //$NON-NLS-1$ - eras = bundle.getStringArray("eras"); //$NON-NLS-1$ - months = bundle.getStringArray("months"); //$NON-NLS-1$ - shortMonths = bundle.getStringArray("shortMonths"); //$NON-NLS-1$ - shortWeekdays = bundle.getStringArray("shortWeekdays"); //$NON-NLS-1$ - weekdays = bundle.getStringArray("weekdays"); //$NON-NLS-1$ - zoneStrings = (String[][]) bundle.getObject("timezones"); //$NON-NLS-1$ + com.ibm.icu.text.DateFormatSymbols icuSymbols = new com.ibm.icu.text.DateFormatSymbols(locale); + + localPatternChars = icuSymbols.getLocalPatternChars(); + ampms = icuSymbols.getAmPmStrings(); + eras = icuSymbols.getEras(); + months = icuSymbols.getMonths(); + shortMonths = icuSymbols.getShortMonths(); + shortWeekdays = icuSymbols.getShortWeekdays(); + weekdays = icuSymbols.getWeekdays(); + zoneStrings = icuSymbols.getZoneStrings(); } /** @@ -273,7 +273,9 @@ } for (String[] element : zoneStrings) { for (int j = 0; j < element.length; j++) { - hashCode += element[j].hashCode(); + if (element[j] != null) { + hashCode += element[j].hashCode(); + } } } return hashCode; Index: src/main/java/java/text/SimpleDateFormat.java =================================================================== --- src/main/java/java/text/SimpleDateFormat.java (revision 590549) +++ src/main/java/java/text/SimpleDateFormat.java (working copy) @@ -25,10 +25,6 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; -import java.util.ResourceBundle; -import java.util.SimpleTimeZone; -import java.util.TimeZone; -import java.util.Vector; import org.apache.harmony.text.internal.nls.Messages; @@ -44,7 +40,7 @@ private static final long serialVersionUID = 4774881970558875024L; - private static final String patternChars = "GyMdkHmsSEDFwWahKzZ"; //$NON-NLS-1$ + private static final String patternChars = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV"; //$NON-NLS-1$ private String pattern; @@ -54,13 +50,16 @@ private Date defaultCenturyStart; + private transient com.ibm.icu.text.SimpleDateFormat icuFormat; + /** * Constructs a new SimpleDateFormat for formatting and parsing dates and * times in the SHORT style for the default Locale. */ public SimpleDateFormat() { this(Locale.getDefault()); - pattern = defaultPattern(); + icuFormat = new com.ibm.icu.text.SimpleDateFormat(); + pattern = (String)getInternalField("pattern",icuFormat); formatData = new DateFormatSymbols(Locale.getDefault()); } @@ -81,7 +80,86 @@ public SimpleDateFormat(String pattern) { this(pattern, Locale.getDefault()); } + + /** + * Validate the format character. + * + * @param format + * the format character + * + * @throws IllegalArgumentException + * when the format character is invalid + */ + private void validateFormat(char format) { + int index = patternChars.indexOf(format); + if (index == -1) { + // text.03=Unknown pattern character - '{0}' + throw new IllegalArgumentException(Messages.getString( + "text.03", format)); //$NON-NLS-1$ + } + } + + /** + * Validate the pattern. + * + * @param template + * the pattern to validate. + * + * @throws NullPointerException + * if the pattern is null + * @throws IllegalArgumentException + * if the pattern is invalid + */ + private void validatePattern(String template) { + boolean quote = false; + int next, last = -1, count = 0; + + final int patternLength = template.length(); + for (int i = 0; i < patternLength; i++) { + next = (template.charAt(i)); + if (next == '\'') { + if (count > 0) { + validateFormat((char) last); + count = 0; + } + if (last == next) { + last = -1; + } else { + last = next; + } + quote = !quote; + continue; + } + if (!quote + && (last == next || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) { + if (last == next) { + count++; + } else { + if (count > 0) { + validateFormat((char) last); + } + last = next; + count = 1; + } + } else { + if (count > 0) { + validateFormat((char) last); + count = 0; + } + last = -1; + } + } + if (count > 0) { + validateFormat((char) last); + } + + if (quote) { + // text.04=Unterminated quote {0} + throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$ + } + } + /** * Constructs a new SimpleDateFormat using the specified non-localized * pattern and DateFormatSymbols and the Calendar for the default Locale. @@ -99,10 +177,22 @@ public SimpleDateFormat(String template, DateFormatSymbols value) { this(Locale.getDefault()); validatePattern(template); + icuFormat = new com.ibm.icu.text.SimpleDateFormat(template, Locale.getDefault()); pattern = template; formatData = (DateFormatSymbols) value.clone(); } + private void copySymbols(DateFormatSymbols value, com.ibm.icu.text.DateFormatSymbols icuSymbols) { + icuSymbols.setAmPmStrings(value.getAmPmStrings()); + icuSymbols.setEras(value.getEras()); + icuSymbols.setLocalPatternChars(value.getLocalPatternChars()); + icuSymbols.setMonths(value.getMonths()); + icuSymbols.setShortMonths(value.getShortMonths()); + icuSymbols.setShortWeekdays(value.getShortWeekdays()); + icuSymbols.setWeekdays(value.getWeekdays()); + icuSymbols.setZoneStrings(value.getZoneStrings()); + } + /** * Constructs a new SimpleDateFormat using the specified non-localized * pattern and the DateFormatSymbols and Calendar for the specified Locale. @@ -120,10 +210,18 @@ public SimpleDateFormat(String template, Locale locale) { this(locale); validatePattern(template); + icuFormat = new com.ibm.icu.text.SimpleDateFormat(template, locale); pattern = template; formatData = new DateFormatSymbols(locale); } + SimpleDateFormat(Locale locale, com.ibm.icu.text.SimpleDateFormat icuFormat){ + this(locale); + this.icuFormat = icuFormat; + pattern = (String)Format.getInternalField("pattern", icuFormat); + formatData = new DateFormatSymbols(locale); + } + private SimpleDateFormat(Locale locale) { numberFormat = NumberFormat.getInstance(locale); numberFormat.setParseIntegerOnly(true); @@ -134,194 +232,6 @@ defaultCenturyStart = calendar.getTime(); } - private void append(StringBuffer buffer, FieldPosition position, - Vector fields, char format, int count) { - int field = -1; - int index = patternChars.indexOf(format); - if (index == -1) { - // text.03=Unknown pattern character - '{0}' - throw new IllegalArgumentException(Messages.getString( - "text.03", format)); //$NON-NLS-1$ - } - - int beginPosition = buffer.length(); - Field dateFormatField = null; - - switch (index) { - case ERA_FIELD: - dateFormatField = Field.ERA; - buffer.append(formatData.eras[calendar.get(Calendar.ERA)]); - break; - case YEAR_FIELD: - dateFormatField = Field.YEAR; - int year = calendar.get(Calendar.YEAR); - if (count < 4) { - appendNumber(buffer, 2, year %= 100); - } else { - appendNumber(buffer, count, year); - } - break; - case MONTH_FIELD: - dateFormatField = Field.MONTH; - int month = calendar.get(Calendar.MONTH); - if (count <= 2) { - appendNumber(buffer, count, month + 1); - } else if (count == 3) { - buffer.append(formatData.shortMonths[month]); - } else { - buffer.append(formatData.months[month]); - } - break; - case DATE_FIELD: - dateFormatField = Field.DAY_OF_MONTH; - field = Calendar.DATE; - break; - case HOUR_OF_DAY1_FIELD: // k - dateFormatField = Field.HOUR_OF_DAY1; - int hour = calendar.get(Calendar.HOUR_OF_DAY); - appendNumber(buffer, count, hour == 0 ? 24 : hour); - break; - case HOUR_OF_DAY0_FIELD: // H - dateFormatField = Field.HOUR_OF_DAY0; - field = Calendar.HOUR_OF_DAY; - break; - case MINUTE_FIELD: - dateFormatField = Field.MINUTE; - field = Calendar.MINUTE; - break; - case SECOND_FIELD: - dateFormatField = Field.SECOND; - field = Calendar.SECOND; - break; - case MILLISECOND_FIELD: - dateFormatField = Field.MILLISECOND; - int value = calendar.get(Calendar.MILLISECOND); - appendNumber(buffer, count, value); - break; - case DAY_OF_WEEK_FIELD: - dateFormatField = Field.DAY_OF_WEEK; - int day = calendar.get(Calendar.DAY_OF_WEEK); - if (count < 4) { - buffer.append(formatData.shortWeekdays[day]); - } else { - buffer.append(formatData.weekdays[day]); - } - break; - case DAY_OF_YEAR_FIELD: - dateFormatField = Field.DAY_OF_YEAR; - field = Calendar.DAY_OF_YEAR; - break; - case DAY_OF_WEEK_IN_MONTH_FIELD: - dateFormatField = Field.DAY_OF_WEEK_IN_MONTH; - field = Calendar.DAY_OF_WEEK_IN_MONTH; - break; - case WEEK_OF_YEAR_FIELD: - dateFormatField = Field.WEEK_OF_YEAR; - field = Calendar.WEEK_OF_YEAR; - break; - case WEEK_OF_MONTH_FIELD: - dateFormatField = Field.WEEK_OF_MONTH; - field = Calendar.WEEK_OF_MONTH; - break; - case AM_PM_FIELD: - dateFormatField = Field.AM_PM; - buffer.append(formatData.ampms[calendar.get(Calendar.AM_PM)]); - break; - case HOUR1_FIELD: // h - dateFormatField = Field.HOUR1; - hour = calendar.get(Calendar.HOUR); - appendNumber(buffer, count, hour == 0 ? 12 : hour); - break; - case HOUR0_FIELD: // K - dateFormatField = Field.HOUR0; - field = Calendar.HOUR; - break; - case TIMEZONE_FIELD: // z - dateFormatField = Field.TIME_ZONE; - appendTimeZone(buffer, count, true); - break; - case (TIMEZONE_FIELD + 1): // Z - dateFormatField = Field.TIME_ZONE; - appendTimeZone(buffer, count, false); - break; - } - if (field != -1) { - appendNumber(buffer, count, calendar.get(field)); - } - - if (fields != null) { - position = new FieldPosition(dateFormatField); - position.setBeginIndex(beginPosition); - position.setEndIndex(buffer.length()); - fields.add(position); - } else { - // Set to the first occurrence - if ((position.getFieldAttribute() == dateFormatField || (position - .getFieldAttribute() == null && position.getField() == index)) - && position.getEndIndex() == 0) { - position.setBeginIndex(beginPosition); - position.setEndIndex(buffer.length()); - } - } - } - - private void appendTimeZone(StringBuffer buffer, int count, - boolean generalTimezone) { - // cannot call TimeZone.getDisplayName() because it would not use - // the DateFormatSymbols of this SimpleDateFormat - - if (generalTimezone) { - String id = calendar.getTimeZone().getID(); - String[][] zones = formatData.zoneStrings; - String[] zone = null; - for (String[] element : zones) { - if (id.equals(element[0])) { - zone = element; - break; - } - } - if (zone == null) { - int offset = calendar.get(Calendar.ZONE_OFFSET) - + calendar.get(Calendar.DST_OFFSET); - char sign = '+'; - if (offset < 0) { - sign = '-'; - offset = -offset; - } - buffer.append("GMT"); //$NON-NLS-1$ - buffer.append(sign); - appendNumber(buffer, 2, offset / 3600000); - buffer.append(':'); - appendNumber(buffer, 2, (offset % 3600000) / 60000); - } else { - int daylight = calendar.get(Calendar.DST_OFFSET) == 0 ? 0 : 2; - if (count < 4) { - buffer.append(zone[2 + daylight]); - } else { - buffer.append(zone[1 + daylight]); - } - } - } else { - int offset = calendar.get(Calendar.ZONE_OFFSET) - + calendar.get(Calendar.DST_OFFSET); - char sign = '+'; - if (offset < 0) { - sign = '-'; - offset = -offset; - } - buffer.append(sign); - appendNumber(buffer, 2, offset / 3600000); - appendNumber(buffer, 2, (offset % 3600000) / 60000); - } - } - - private void appendNumber(StringBuffer buffer, int count, int value) { - int minimumIntegerDigits = numberFormat.getMinimumIntegerDigits(); - numberFormat.setMinimumIntegerDigits(count); - numberFormat.format(new Integer(value), buffer, new FieldPosition(0)); - numberFormat.setMinimumIntegerDigits(minimumIntegerDigits); - } - /** * Changes the pattern of this SimpleDateFormat to the specified pattern * which uses localized pattern characters. @@ -330,8 +240,8 @@ * the localized pattern */ public void applyLocalizedPattern(String template) { - pattern = convertPattern(template, formatData.getLocalPatternChars(), - patternChars, true); + icuFormat.applyLocalizedPattern(template); + pattern = icuFormat.toPattern(); } /** @@ -348,6 +258,7 @@ */ public void applyPattern(String template) { validatePattern(template); + icuFormat.applyPattern(template); pattern = template; } @@ -367,13 +278,6 @@ return clone; } - private static String defaultPattern() { - ResourceBundle bundle = getBundle(Locale.getDefault()); - String styleName = getStyleName(SHORT); - return bundle.getString("Date_" + styleName) + " " //$NON-NLS-1$ //$NON-NLS-2$ - + bundle.getString("Time_" + styleName); //$NON-NLS-1$ - } - /** * Compares the specified object to this SimpleDateFormat and answer if they * are equal. The object must be an instance of SimpleDateFormat and have @@ -400,12 +304,6 @@ && formatData.equals(simple.formatData); } - private Date error(ParsePosition position, int offset, TimeZone zone) { - position.setErrorIndex(offset); - calendar.setTimeZone(zone); - return null; - } - /** * Formats the specified object using the rules of this SimpleDateFormat and * returns an AttributedCharacterIterator with the formatted Date and @@ -423,39 +321,7 @@ */ @Override public AttributedCharacterIterator formatToCharacterIterator(Object object) { - if (object == null) { - throw new NullPointerException(); - } - if (object instanceof Date) { - return formatToCharacterIteratorImpl((Date) object); - } - if (object instanceof Number) { - return formatToCharacterIteratorImpl(new Date(((Number) object) - .longValue())); - } - throw new IllegalArgumentException(); - } - - private AttributedCharacterIterator formatToCharacterIteratorImpl(Date date) { - StringBuffer buffer = new StringBuffer(); - Vector fields = new Vector(); - - // format the date, and find fields - formatImpl(date, buffer, null, fields); - - // create and AttributedString with the formatted buffer - AttributedString as = new AttributedString(buffer.toString()); - - // add DateFormat field attributes to the AttributedString - for (int i = 0; i < fields.size(); i++) { - FieldPosition pos = fields.elementAt(i); - Format.Field attribute = pos.getFieldAttribute(); - as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos - .getEndIndex()); - } - - // return the CharacterIterator from AttributedString - return as.getIterator(); + return icuFormat.formatToCharacterIterator(object); } /** @@ -478,167 +344,11 @@ @Override public StringBuffer format(Date date, StringBuffer buffer, FieldPosition field) { - return formatImpl(date, buffer, field, null); + icuFormat.setTimeZone(com.ibm.icu.util.TimeZone.getTimeZone(calendar + .getTimeZone().getID())); + return icuFormat.format(date, buffer, field); } - /** - * Validate the format character. - * - * @param format - * the format character - * - * @throws IllegalArgumentException - * when the format character is invalid - */ - private void validateFormat(char format) { - int index = patternChars.indexOf(format); - if (index == -1) { - // text.03=Unknown pattern character - '{0}' - throw new IllegalArgumentException(Messages.getString( - "text.03", format)); //$NON-NLS-1$ - } - } - - /** - * Validate the pattern. - * - * @param template - * the pattern to validate. - * - * @throws NullPointerException - * if the pattern is null - * @throws IllegalArgumentException - * if the pattern is invalid - */ - private void validatePattern(String template) { - boolean quote = false; - int next, last = -1, count = 0; - - final int patternLength = template.length(); - for (int i = 0; i < patternLength; i++) { - next = (template.charAt(i)); - if (next == '\'') { - if (count > 0) { - validateFormat((char) last); - count = 0; - } - if (last == next) { - last = -1; - } else { - last = next; - } - quote = !quote; - continue; - } - if (!quote - && (last == next || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) { - if (last == next) { - count++; - } else { - if (count > 0) { - validateFormat((char) last); - } - last = next; - count = 1; - } - } else { - if (count > 0) { - validateFormat((char) last); - count = 0; - } - last = -1; - } - } - if (count > 0) { - validateFormat((char) last); - } - - if (quote) { - // text.04=Unterminated quote {0} - throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$ - } - - } - - /** - * Formats the date. - *

- * If the FieldPosition field is not null, and the field - * specified by this FieldPosition is formatted, set the begin and end index - * of the formatted field in the FieldPosition. - *

- * If the Vector fields is not null, find fields of this - * date, set FieldPositions with these fields, and add them to the fields - * vector. - * - * @param date - * Date to Format - * @param buffer - * StringBuffer to store the resulting formatted String - * @param field - * FieldPosition to set begin and end index of the field - * specified, if it is part of the format for this date - * @param fields - * Vector used to store the FieldPositions for each field in this - * date - * - * @return the formatted Date - * - * @exception IllegalArgumentException - * when the object cannot be formatted by this Format - */ - private StringBuffer formatImpl(Date date, StringBuffer buffer, - FieldPosition field, Vector fields) { - - boolean quote = false; - int next, last = -1, count = 0; - calendar.setTime(date); - if (field != null) { - field.clear(); - } - - final int patternLength = pattern.length(); - for (int i = 0; i < patternLength; i++) { - next = (pattern.charAt(i)); - if (next == '\'') { - if (count > 0) { - append(buffer, field, fields, (char) last, count); - count = 0; - } - if (last == next) { - buffer.append('\''); - last = -1; - } else { - last = next; - } - quote = !quote; - continue; - } - if (!quote - && (last == next || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) { - if (last == next) { - count++; - } else { - if (count > 0) { - append(buffer, field, fields, (char) last, count); - } - last = next; - count = 1; - } - } else { - if (count > 0) { - append(buffer, field, fields, (char) last, count); - count = 0; - } - last = -1; - buffer.append((char) next); - } - } - if (count > 0) { - append(buffer, field, fields, (char) last, count); - } - return buffer; - } /** * Answers the Date which is the start of the one hundred year period for @@ -674,131 +384,6 @@ + creationYear; } - private int parse(String string, int offset, char format, int count) { - int index = patternChars.indexOf(format); - if (index == -1) { - // text.03=Unknown pattern character - '{0}' - throw new IllegalArgumentException(Messages.getString( - "text.03", format)); //$NON-NLS-1$ - } - int field = -1; - int absolute = 0; - if (count < 0) { - count = -count; - absolute = count; - } - switch (index) { - case ERA_FIELD: - return parseText(string, offset, formatData.eras, Calendar.ERA); - case YEAR_FIELD: - if (count >= 3) { - field = Calendar.YEAR; - } else { - ParsePosition position = new ParsePosition(offset); - Number result = parseNumber(absolute, string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - int year = result.intValue(); - // A two digit year must be exactly two digits, i.e. 01 - if ((position.getIndex() - offset) == 2 && year >= 0) { - year += creationYear / 100 * 100; - if (year < creationYear) { - year += 100; - } - } - calendar.set(Calendar.YEAR, year); - return position.getIndex(); - } - break; - case MONTH_FIELD: - if (count <= 2) { - return parseNumber(absolute, string, offset, - Calendar.MONTH, -1); - } - index = parseText(string, offset, formatData.months, - Calendar.MONTH); - if (index < 0) { - return parseText(string, offset, formatData.shortMonths, - Calendar.MONTH); - } - return index; - case DATE_FIELD: - field = Calendar.DATE; - break; - case HOUR_OF_DAY1_FIELD: - ParsePosition position = new ParsePosition(offset); - Number result = parseNumber(absolute, string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - int hour = result.intValue(); - if (hour == 24) { - hour = 0; - } - calendar.set(Calendar.HOUR_OF_DAY, hour); - return position.getIndex(); - case HOUR_OF_DAY0_FIELD: - field = Calendar.HOUR_OF_DAY; - break; - case MINUTE_FIELD: - field = Calendar.MINUTE; - break; - case SECOND_FIELD: - field = Calendar.SECOND; - break; - case MILLISECOND_FIELD: - field = Calendar.MILLISECOND; - break; - case DAY_OF_WEEK_FIELD: - index = parseText(string, offset, formatData.weekdays, - Calendar.DAY_OF_WEEK); - if (index < 0) { - return parseText(string, offset, formatData.shortWeekdays, - Calendar.DAY_OF_WEEK); - } - return index; - case DAY_OF_YEAR_FIELD: - field = Calendar.DAY_OF_YEAR; - break; - case DAY_OF_WEEK_IN_MONTH_FIELD: - field = Calendar.DAY_OF_WEEK_IN_MONTH; - break; - case WEEK_OF_YEAR_FIELD: - field = Calendar.WEEK_OF_YEAR; - break; - case WEEK_OF_MONTH_FIELD: - field = Calendar.WEEK_OF_MONTH; - break; - case AM_PM_FIELD: - return parseText(string, offset, formatData.ampms, - Calendar.AM_PM); - case HOUR1_FIELD: - position = new ParsePosition(offset); - result = parseNumber(absolute, string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - hour = result.intValue(); - if (hour == 12) { - hour = 0; - } - calendar.set(Calendar.HOUR, hour); - return position.getIndex(); - case HOUR0_FIELD: - field = Calendar.HOUR; - break; - case TIMEZONE_FIELD: - return parseTimeZone(string, offset); - case (TIMEZONE_FIELD + 1): - return parseTimeZone(string, offset); - } - if (field != -1) { - return parseNumber(absolute, string, offset, field, 0); - } - return offset; - } - /** * Parse a Date from the specified String starting at the index specified by * the ParsePosition. If the string is successfully parsed, the index of the @@ -818,192 +403,7 @@ */ @Override public Date parse(String string, ParsePosition position) { - boolean quote = false; - int next, last = -1, count = 0, offset = position.getIndex(); - int length = string.length(); - calendar.clear(); - TimeZone zone = calendar.getTimeZone(); - final int patternLength = pattern.length(); - for (int i = 0; i < patternLength; i++) { - next = pattern.charAt(i); - if (next == '\'') { - if (count > 0) { - if ((offset = parse(string, offset, (char) last, count)) < 0) { - return error(position, -offset - 1, zone); - } - count = 0; - } - if (last == next) { - if (offset >= length || string.charAt(offset) != '\'') { - return error(position, offset, zone); - } - offset++; - last = -1; - } else { - last = next; - } - quote = !quote; - continue; - } - if (!quote - && (last == next || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) { - if (last == next) { - count++; - } else { - if (count > 0) { - if ((offset = parse(string, offset, (char) last, -count)) < 0) { - return error(position, -offset - 1, zone); - } - } - last = next; - count = 1; - } - } else { - if (count > 0) { - if ((offset = parse(string, offset, (char) last, count)) < 0) { - return error(position, -offset - 1, zone); - } - count = 0; - } - last = -1; - if (offset >= length || string.charAt(offset) != next) { - return error(position, offset, zone); - } - offset++; - } - } - if (count > 0) { - if ((offset = parse(string, offset, (char) last, count)) < 0) { - return error(position, -offset - 1, zone); - } - } - Date date; - try { - date = calendar.getTime(); - } catch (IllegalArgumentException e) { - return error(position, offset, zone); - } - position.setIndex(offset); - calendar.setTimeZone(zone); - return date; - } - - private Number parseNumber(int max, String string, ParsePosition position) { - int digit, length = string.length(), result = 0; - int index = position.getIndex(); - if (max > 0 && max < length - index) { - length = index + max; - } - while (index < length - && (string.charAt(index) == ' ' || string.charAt(index) == '\t')) { - index++; - } - if (max == 0) { - position.setIndex(index); - return numberFormat.parse(string, position); - } - - while (index < length - && (digit = Character.digit(string.charAt(index), 10)) != -1) { - index++; - result = result * 10 + digit; - } - if (index == position.getIndex()) { - position.setErrorIndex(index); - return null; - } - position.setIndex(index); - return new Integer(result); - } - - private int parseNumber(int max, String string, int offset, int field, - int skew) { - ParsePosition position = new ParsePosition(offset); - Number result = parseNumber(max, string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - calendar.set(field, result.intValue() + skew); - return position.getIndex(); - } - - private int parseText(String string, int offset, String[] text, int field) { - int found = -1; - for (int i = 0; i < text.length; i++) { - if (text[i].length() == 0) { - continue; - } - if (string - .regionMatches(true, offset, text[i], 0, text[i].length())) { - // Search for the longest match, in case some fields are subsets - if (found == -1 || text[i].length() > text[found].length()) { - found = i; - } - } - } - if (found != -1) { - calendar.set(field, found); - return offset + text[found].length(); - } - return -offset - 1; - } - - private int parseTimeZone(String string, int offset) { - String[][] zones = formatData.zoneStrings; - boolean foundGMT = string.regionMatches(offset, "GMT", 0, 3); //$NON-NLS-1$ - if (foundGMT) { - offset += 3; - } - char sign; - if (offset < string.length() - && ((sign = string.charAt(offset)) == '+' || sign == '-')) { - ParsePosition position = new ParsePosition(offset + 1); - Number result = numberFormat.parse(string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - int hour = result.intValue(); - int raw = hour * 3600000; - int index = position.getIndex(); - if (index < string.length() && string.charAt(index) == ':') { - position.setIndex(index + 1); - result = numberFormat.parse(string, position); - if (result == null) { - return -position.getErrorIndex() - 1; - } - int minute = result.intValue(); - raw += minute * 60000; - } else if (hour >= 24) { - raw = (hour / 100 * 3600000) + (hour % 100 * 60000); - } - if (sign == '-') { - raw = -raw; - } - calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$ - return position.getIndex(); - } - if (foundGMT) { - calendar.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$ - return offset; - } - for (String[] element : zones) { - for (int j = 1; j < 5; j++) { - if (string.regionMatches(true, offset, element[j], 0, - element[j].length())) { - TimeZone zone = TimeZone.getTimeZone(element[0]); - if (zone == null) { - return -offset - 1; - } - int raw = zone.getRawOffset(); - if (j >= 3 && zone.useDaylightTime()) { - raw += 3600000; - } - calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$ - return offset + element[j].length(); - } - } - } - return -offset - 1; + return icuFormat.parse(string,position); } /** @@ -1014,6 +414,7 @@ * the Date */ public void set2DigitYearStart(Date date) { + icuFormat.set2DigitYearStart(date); defaultCenturyStart = date; Calendar cal = new GregorianCalendar(); cal.setTime(date); @@ -1027,6 +428,9 @@ * the DateFormatSymbols */ public void setDateFormatSymbols(DateFormatSymbols value) { + com.ibm.icu.text.DateFormatSymbols icuSymbols = new com.ibm.icu.text.DateFormatSymbols(); + copySymbols(value, icuSymbols); + icuFormat.setDateFormatSymbols(icuSymbols); formatData = (DateFormatSymbols) value.clone(); } @@ -1037,8 +441,7 @@ * @return the localized pattern */ public String toLocalizedPattern() { - return convertPattern(pattern, patternChars, formatData - .getLocalPatternChars(), false); + return icuFormat.toLocalizedPattern(); } /** Index: src/main/java/java/text/NumberFormat.java =================================================================== --- src/main/java/java/text/NumberFormat.java (revision 590549) +++ src/main/java/java/text/NumberFormat.java (working copy) @@ -24,7 +24,6 @@ import java.io.ObjectStreamField; import java.util.Currency; import java.util.Locale; -import java.util.ResourceBundle; import org.apache.harmony.text.internal.nls.Messages; @@ -230,7 +229,10 @@ * @return a NumberFormat */ public static NumberFormat getCurrencyInstance(Locale locale) { - return getInstance(locale, "Currency"); //$NON-NLS-1$ + com.ibm.icu.text.DecimalFormat icuFormat = (com.ibm.icu.text.DecimalFormat) com.ibm.icu.text.NumberFormat + .getCurrencyInstance(locale); + String pattern = icuFormat.toPattern(); + return new DecimalFormat(pattern, new DecimalFormatSymbols(locale)); } /** @@ -252,9 +254,13 @@ * @return a NumberFormat */ public static NumberFormat getIntegerInstance(Locale locale) { - NumberFormat format = getInstance(locale, "Integer"); //$NON-NLS-1$ + com.ibm.icu.text.DecimalFormat icuFormat = (com.ibm.icu.text.DecimalFormat) com.ibm.icu.text.NumberFormat + .getIntegerInstance(locale); + String pattern = icuFormat.toPattern(); + DecimalFormat format = new DecimalFormat(pattern, new DecimalFormatSymbols(locale)); format.setParseIntegerOnly(true); return format; + } /** @@ -279,11 +285,6 @@ return getNumberInstance(locale); } - static NumberFormat getInstance(Locale locale, String type) { - return new DecimalFormat(getPattern(locale, type), - new DecimalFormatSymbols(locale)); - } - /** * Answers the maximum number of fraction digits that are printed when * formatting. If the maximum is less than the number of fraction digits, @@ -345,12 +346,10 @@ * @return a NumberFormat */ public static NumberFormat getNumberInstance(Locale locale) { - return getInstance(locale, "Number"); //$NON-NLS-1$ - } - - static String getPattern(Locale locale, String type) { - ResourceBundle bundle = getBundle(locale); - return bundle.getString(type); + com.ibm.icu.text.DecimalFormat icuFormat = (com.ibm.icu.text.DecimalFormat) com.ibm.icu.text.NumberFormat + .getNumberInstance(locale); + String pattern = icuFormat.toPattern(); + return new DecimalFormat(pattern, new DecimalFormatSymbols(locale)); } /** @@ -372,7 +371,10 @@ * @return a NumberFormat */ public static NumberFormat getPercentInstance(Locale locale) { - return getInstance(locale, "Percent"); //$NON-NLS-1$ + com.ibm.icu.text.DecimalFormat icuFormat = (com.ibm.icu.text.DecimalFormat) com.ibm.icu.text.NumberFormat + .getPercentInstance(locale); + String pattern = icuFormat.toPattern(); + return new DecimalFormat(pattern, new DecimalFormatSymbols(locale)); } /** Index: src/main/java/java/text/DecimalFormat.java =================================================================== --- src/main/java/java/text/DecimalFormat.java (revision 590549) +++ src/main/java/java/text/DecimalFormat.java (working copy) @@ -54,7 +54,15 @@ * default Locale. */ public DecimalFormat() { - this(getPattern(Locale.getDefault(), "Number")); //$NON-NLS-1$ + Locale locale = Locale.getDefault(); + icuSymbols = new com.ibm.icu.text.DecimalFormatSymbols(locale); + symbols = new DecimalFormatSymbols(locale); + dform = new com.ibm.icu.text.DecimalFormat(); + + super.setMaximumFractionDigits(dform.getMaximumFractionDigits()); + super.setMaximumIntegerDigits(dform.getMaximumIntegerDigits()); + super.setMinimumFractionDigits(dform.getMinimumFractionDigits()); + super.setMinimumIntegerDigits(dform.getMinimumIntegerDigits()); } /** @@ -68,7 +76,15 @@ * when the pattern cannot be parsed */ public DecimalFormat(String pattern) { - this(pattern, new DecimalFormatSymbols()); + Locale locale = Locale.getDefault(); + icuSymbols = new com.ibm.icu.text.DecimalFormatSymbols(locale); + symbols = new DecimalFormatSymbols(locale); + dform = new com.ibm.icu.text.DecimalFormat(pattern, icuSymbols); + + super.setMaximumFractionDigits(dform.getMaximumFractionDigits()); + super.setMaximumIntegerDigits(dform.getMaximumIntegerDigits()); + super.setMinimumFractionDigits(dform.getMinimumFractionDigits()); + super.setMinimumIntegerDigits(dform.getMinimumIntegerDigits()); } /** @@ -85,7 +101,7 @@ */ public DecimalFormat(String pattern, DecimalFormatSymbols value) { symbols = (DecimalFormatSymbols) value.clone(); - Locale locale = (Locale) this.getInternalField("locale", symbols); //$NON-NLS-1$ + Locale locale = (Locale) Format.getInternalField("locale", symbols); //$NON-NLS-1$ icuSymbols = new com.ibm.icu.text.DecimalFormatSymbols(locale); copySymbols(icuSymbols, symbols); @@ -711,16 +727,16 @@ fields.put("positiveSuffix", dform.getPositiveSuffix()); fields.put("negativePrefix", dform.getNegativePrefix()); fields.put("negativeSuffix", dform.getNegativeSuffix()); - String posPrefixPattern = (String) this.getInternalField( + String posPrefixPattern = (String) Format.getInternalField( "posPrefixPattern", dform); fields.put("posPrefixPattern", posPrefixPattern); - String posSuffixPattern = (String) this.getInternalField( + String posSuffixPattern = (String) Format.getInternalField( "posSuffixPattern", dform); fields.put("posSuffixPattern", posSuffixPattern); - String negPrefixPattern = (String) this.getInternalField( + String negPrefixPattern = (String) Format.getInternalField( "negPrefixPattern", dform); fields.put("negPrefixPattern", negPrefixPattern); - String negSuffixPattern = (String) this.getInternalField( + String negSuffixPattern = (String) Format.getInternalField( "negSuffixPattern", dform); fields.put("negSuffixPattern", negSuffixPattern); fields.put("multiplier", dform.getMultiplier()); @@ -729,10 +745,10 @@ .isDecimalSeparatorAlwaysShown()); fields.put("parseBigDecimal", parseBigDecimal); fields.put("symbols", symbols); - boolean useExponentialNotation = ((Boolean) this.getInternalField( + boolean useExponentialNotation = ((Boolean) Format.getInternalField( "useExponentialNotation", dform)).booleanValue(); fields.put("useExponentialNotation", useExponentialNotation); - byte minExponentDigits = ((Byte) this.getInternalField( + byte minExponentDigits = ((Byte) Format.getInternalField( "minExponentDigits", dform)).byteValue(); fields.put("minExponentDigits", minExponentDigits); fields.put("maximumIntegerDigits", dform.getMaximumIntegerDigits()); @@ -786,7 +802,7 @@ int minimumFractionDigits = fields.get("minimumFractionDigits", 340); this.serialVersionOnStream = fields.get("serialVersionOnStream", 0); - Locale locale = (Locale) getInternalField("locale", symbols); + Locale locale = (Locale) Format.getInternalField("locale", symbols); dform = new com.ibm.icu.text.DecimalFormat("", new com.ibm.icu.text.DecimalFormatSymbols(locale)); setInternalField("useExponentialNotation", dform, Boolean @@ -831,8 +847,14 @@ */ private void copySymbols(final com.ibm.icu.text.DecimalFormatSymbols icu, final DecimalFormatSymbols dfs) { - icu.setCurrency(com.ibm.icu.util.Currency.getInstance(dfs.getCurrency() - .getCurrencyCode())); + Currency currency = dfs.getCurrency(); + if (currency == null) { + icu.setCurrency(com.ibm.icu.util.Currency.getInstance("XXX")); + } else { + icu.setCurrency(com.ibm.icu.util.Currency.getInstance(dfs + .getCurrency().getCurrencyCode())); + } + icu.setCurrencySymbol(dfs.getCurrencySymbol()); icu.setDecimalSeparator(dfs.getDecimalSeparator()); icu.setDigit(dfs.getDigit()); @@ -873,32 +895,6 @@ return field; } }); - } - - /* - * Gets private field value by reflection. - * - * @param fieldName the field name to be set @param target the object which - * field to be gotten - */ - private Object getInternalField(final String fieldName, final Object target) { - Object value = AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { - Object result = null; - java.lang.reflect.Field field = null; - try { - field = target.getClass().getDeclaredField( - fieldName); - field.setAccessible(true); - result = field.get(target); - } catch (Exception e1) { - return null; - } - return result; - } - }); - return value; } } Index: src/main/java/java/text/DecimalFormatSymbols.java =================================================================== --- src/main/java/java/text/DecimalFormatSymbols.java (revision 590549) +++ src/main/java/java/text/DecimalFormatSymbols.java (working copy) @@ -19,13 +19,9 @@ import java.io.IOException; import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.ObjectStreamField; import java.io.Serializable; -import java.util.Arrays; import java.util.Currency; import java.util.Locale; -import java.util.ResourceBundle; /** * DecimalFormatSymbols holds the symbols used in the formating and parsing of @@ -35,18 +31,26 @@ private static final long serialVersionUID = 5772796243397350300L; - private final int ZeroDigit = 0, Digit = 1, DecimalSeparator = 2, - GroupingSeparator = 3, PatternSeparator = 4, Percent = 5, - PerMill = 6, Exponent = 7, MonetaryDecimalSeparator = 8, - MinusSign = 9; - - transient char[] patternChars; - + private char zeroDigit; + private char groupingSeparator; + private char decimalSeparator; + private char perMill; + private char percent; + private char digit; + private char patternSeparator; + private String infinity; + private String NaN; + private char minusSign; + private String currencySymbol; + private String intlCurrencySymbol; + private char monetarySeparator; + private char exponential; + private Locale locale; + // 3 indicates version 5 and later + private int serialVersionOnStream = 3; private transient Currency currency; - private transient Locale locale; - - private String infinity, NaN, currencySymbol, intlCurrencySymbol; + private transient com.ibm.icu.text.DecimalFormatSymbols icuSymbols; /** * Constructs a new DecimalFormatSymbols containing the symbols for the @@ -64,20 +68,27 @@ * the Locale */ public DecimalFormatSymbols(Locale locale) { - ResourceBundle bundle = Format.getBundle(locale); - patternChars = bundle.getString("DecimalPatternChars").toCharArray(); //$NON-NLS-1$ - infinity = bundle.getString("Infinity"); //$NON-NLS-1$ - NaN = bundle.getString("NaN"); //$NON-NLS-1$ + icuSymbols = new com.ibm.icu.text.DecimalFormatSymbols(locale); + infinity = icuSymbols.getInfinity(); + NaN = icuSymbols.getNaN(); this.locale = locale; - try { + currencySymbol = icuSymbols.getCurrencySymbol(); + intlCurrencySymbol = icuSymbols.getInternationalCurrencySymbol(); + if (locale.getCountry().length() == 0) { + currency = Currency.getInstance("XXX"); + } else { currency = Currency.getInstance(locale); - currencySymbol = currency.getSymbol(locale); - intlCurrencySymbol = currency.getCurrencyCode(); - } catch (IllegalArgumentException e) { - currency = Currency.getInstance("XXX"); //$NON-NLS-1$ - currencySymbol = bundle.getString("CurrencySymbol"); //$NON-NLS-1$ - intlCurrencySymbol = bundle.getString("IntCurrencySymbol"); //$NON-NLS-1$ } + zeroDigit = icuSymbols.getZeroDigit(); + digit = icuSymbols.getDigit(); + decimalSeparator = icuSymbols.getDecimalSeparator(); + groupingSeparator = icuSymbols.getGroupingSeparator(); + patternSeparator = icuSymbols.getPatternSeparator(); + percent = icuSymbols.getPercent(); + perMill = icuSymbols.getPerMill(); + exponential = 'E'; + monetarySeparator = icuSymbols.getMonetaryDecimalSeparator(); + minusSign = icuSymbols.getMinusSign(); } /** @@ -92,7 +103,6 @@ public Object clone() { try { DecimalFormatSymbols symbols = (DecimalFormatSymbols) super.clone(); - symbols.patternChars = patternChars.clone(); return symbols; } catch (CloneNotSupportedException e) { return null; @@ -120,8 +130,15 @@ return false; } DecimalFormatSymbols obj = (DecimalFormatSymbols) object; - return Arrays.equals(patternChars, obj.patternChars) - && infinity.equals(obj.infinity) && NaN.equals(obj.NaN) + return zeroDigit == obj.zeroDigit && digit == obj.digit + && decimalSeparator == obj.decimalSeparator + && groupingSeparator == obj.groupingSeparator + && patternSeparator == obj.patternSeparator + && percent == obj.percent && perMill == obj.perMill + && exponential == obj.exponential + && monetarySeparator == obj.monetarySeparator + && minusSign == obj.minusSign && infinity.equals(obj.infinity) + && NaN.equals(obj.NaN) && currencySymbol.equals(obj.currencySymbol) && intlCurrencySymbol.equals(obj.intlCurrencySymbol); } @@ -134,8 +151,8 @@ * with a value that is not a valid ISO 4217 currency code. *

* - * @return the currency that was set in the constructor, setCurrency(), - * or setInternationalCurrencySymbol(), or null + * @return the currency that was set in the constructor, setCurrency(), + * or setInternationalCurrencySymbol(), or null * * @see #setCurrency(Currency) * @see #setInternationalCurrencySymbol(String) @@ -168,7 +185,7 @@ * @return a char */ public char getDecimalSeparator() { - return patternChars[DecimalSeparator]; + return decimalSeparator; } /** @@ -178,7 +195,7 @@ * @return a char */ public char getDigit() { - return patternChars[Digit]; + return digit; } /** @@ -187,7 +204,7 @@ * @return a char */ public char getGroupingSeparator() { - return patternChars[GroupingSeparator]; + return groupingSeparator; } /** @@ -201,7 +218,8 @@ String getLocalPatternChars() { // Don't include the MonetaryDecimalSeparator or the MinusSign - return new String(patternChars, 0, patternChars.length - 2); + return new String(new char[]{zeroDigit, digit, decimalSeparator, groupingSeparator, + patternSeparator, percent, perMill, exponential}); } /** @@ -210,7 +228,7 @@ * @return a char */ public char getMinusSign() { - return patternChars[MinusSign]; + return minusSign; } /** @@ -220,7 +238,7 @@ * @return a char */ public char getMonetaryDecimalSeparator() { - return patternChars[MonetaryDecimalSeparator]; + return monetarySeparator; } /** @@ -239,7 +257,7 @@ * @return a char */ public char getPatternSeparator() { - return patternChars[PatternSeparator]; + return patternSeparator; } /** @@ -248,7 +266,7 @@ * @return a char */ public char getPercent() { - return patternChars[Percent]; + return percent; } /** @@ -257,7 +275,7 @@ * @return a char */ public char getPerMill() { - return patternChars[PerMill]; + return perMill; } /** @@ -266,11 +284,11 @@ * @return a char */ public char getZeroDigit() { - return patternChars[ZeroDigit]; + return zeroDigit; } char getExponential() { - return patternChars[Exponent]; + return exponential; } /** @@ -283,9 +301,12 @@ */ @Override public int hashCode() { - return new String(patternChars).hashCode() + infinity.hashCode() - + NaN.hashCode() + currencySymbol.hashCode() - + intlCurrencySymbol.hashCode(); + return new String(new char[] { zeroDigit, digit, decimalSeparator, + groupingSeparator, patternSeparator, percent, perMill, + exponential, monetarySeparator, minusSign }).hashCode() + + infinity.hashCode() + + NaN.hashCode() + + currencySymbol.hashCode() + intlCurrencySymbol.hashCode(); } /** @@ -361,7 +382,7 @@ * the decimal separator character */ public void setDecimalSeparator(char value) { - patternChars[DecimalSeparator] = value; + decimalSeparator = value; } /** @@ -371,7 +392,7 @@ * the digit character */ public void setDigit(char value) { - patternChars[Digit] = value; + digit = value; } /** @@ -381,7 +402,7 @@ * the grouping separator character */ public void setGroupingSeparator(char value) { - patternChars[GroupingSeparator] = value; + groupingSeparator = value; } /** @@ -401,7 +422,7 @@ * the minus sign character */ public void setMinusSign(char value) { - patternChars[MinusSign] = value; + minusSign = value; } /** @@ -412,7 +433,7 @@ * the monetary decimal separator character */ public void setMonetaryDecimalSeparator(char value) { - patternChars[MonetaryDecimalSeparator] = value; + monetarySeparator = value; } /** @@ -433,7 +454,7 @@ * the pattern separator character */ public void setPatternSeparator(char value) { - patternChars[PatternSeparator] = value; + patternSeparator = value; } /** @@ -443,7 +464,7 @@ * the percent character */ public void setPercent(char value) { - patternChars[Percent] = value; + percent = value; } /** @@ -453,7 +474,7 @@ * the mille percent character */ public void setPerMill(char value) { - patternChars[PerMill] = value; + perMill = value; } /** @@ -463,56 +484,16 @@ * the zero digit character */ public void setZeroDigit(char value) { - patternChars[ZeroDigit] = value; + zeroDigit = value; } void setExponential(char value) { - patternChars[Exponent] = value; - } - - private static final ObjectStreamField[] serialPersistentFields = { - new ObjectStreamField("currencySymbol", String.class), //$NON-NLS-1$ - new ObjectStreamField("decimalSeparator", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("digit", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("exponential", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("groupingSeparator", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("infinity", String.class), //$NON-NLS-1$ - new ObjectStreamField("intlCurrencySymbol", String.class), //$NON-NLS-1$ - new ObjectStreamField("minusSign", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("monetarySeparator", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("NaN", String.class), //$NON-NLS-1$ - new ObjectStreamField("patternSeparator", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("percent", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("perMill", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("serialVersionOnStream", Integer.TYPE), //$NON-NLS-1$ - new ObjectStreamField("zeroDigit", Character.TYPE), //$NON-NLS-1$ - new ObjectStreamField("locale", Locale.class), }; //$NON-NLS-1$ - - private void writeObject(ObjectOutputStream stream) throws IOException { - ObjectOutputStream.PutField fields = stream.putFields(); - fields.put("currencySymbol", currencySymbol); //$NON-NLS-1$ - fields.put("decimalSeparator", getDecimalSeparator()); //$NON-NLS-1$ - fields.put("digit", getDigit()); //$NON-NLS-1$ - fields.put("exponential", getExponential()); //$NON-NLS-1$ - fields.put("groupingSeparator", getGroupingSeparator()); //$NON-NLS-1$ - fields.put("infinity", infinity); //$NON-NLS-1$ - fields.put("intlCurrencySymbol", intlCurrencySymbol); //$NON-NLS-1$ - fields.put("minusSign", getMinusSign()); //$NON-NLS-1$ - fields.put("monetarySeparator", getMonetaryDecimalSeparator()); //$NON-NLS-1$ - fields.put("NaN", NaN); //$NON-NLS-1$ - fields.put("patternSeparator", getPatternSeparator()); //$NON-NLS-1$ - fields.put("percent", getPercent()); //$NON-NLS-1$ - fields.put("perMill", getPerMill()); //$NON-NLS-1$ - fields.put("serialVersionOnStream", 1); //$NON-NLS-1$ - fields.put("zeroDigit", getZeroDigit()); //$NON-NLS-1$ - fields.put("locale", locale); //$NON-NLS-1$ - stream.writeFields(); + exponential = value; } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { ObjectInputStream.GetField fields = stream.readFields(); - patternChars = new char[10]; currencySymbol = (String) fields.get("currencySymbol", ""); //$NON-NLS-1$ //$NON-NLS-2$ setDecimalSeparator(fields.get("decimalSeparator", '.')); //$NON-NLS-1$ setDigit(fields.get("digit", '#')); //$NON-NLS-1$ @@ -539,5 +520,9 @@ } catch (IllegalArgumentException e) { currency = null; } + } + + Locale getLocale(){ + return locale; } } Index: src/main/java/java/text/DateFormat.java =================================================================== --- src/main/java/java/text/DateFormat.java (revision 590549) +++ src/main/java/java/text/DateFormat.java (working copy) @@ -22,7 +22,6 @@ import java.util.Date; import java.util.Hashtable; import java.util.Locale; -import java.util.ResourceBundle; import java.util.TimeZone; import org.apache.harmony.text.internal.nls.Messages; @@ -321,9 +320,8 @@ */ public final static DateFormat getDateInstance(int style, Locale locale) { checkDateStyle(style); - ResourceBundle bundle = getBundle(locale); - String pattern = bundle.getString("Date_" + getStyleName(style)); //$NON-NLS-1$ - return new SimpleDateFormat(pattern, locale); + com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateInstance(style, locale); + return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat)icuFormat); } /** @@ -370,10 +368,8 @@ int timeStyle, Locale locale) { checkTimeStyle(timeStyle); checkDateStyle(dateStyle); - ResourceBundle bundle = getBundle(locale); - String pattern = bundle.getString("Date_" + getStyleName(dateStyle)) //$NON-NLS-1$ - + " " + bundle.getString("Time_" + getStyleName(timeStyle)); //$NON-NLS-1$ //$NON-NLS-2$ - return new SimpleDateFormat(pattern, locale); + com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); + return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat)icuFormat); } /** @@ -451,9 +447,8 @@ */ public final static DateFormat getTimeInstance(int style, Locale locale) { checkTimeStyle(style); - ResourceBundle bundle = getBundle(locale); - String pattern = bundle.getString("Time_" + getStyleName(style)); //$NON-NLS-1$ - return new SimpleDateFormat(pattern, locale); + com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getTimeInstance(style, locale); + return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat)icuFormat); } /** Index: src/main/java/java/text/Format.java =================================================================== --- src/main/java/java/text/Format.java (revision 590549) +++ src/main/java/java/text/Format.java (working copy) @@ -20,8 +20,6 @@ import java.io.Serializable; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Locale; -import java.util.ResourceBundle; import org.apache.harmony.text.internal.nls.Messages; @@ -56,17 +54,6 @@ } } - static ResourceBundle getBundle(final Locale locale) { - return AccessController - .doPrivileged(new PrivilegedAction() { - public ResourceBundle run() { - return ResourceBundle - .getBundle( - "org.apache.harmony.luni.internal.locale.Locale", locale); //$NON-NLS-1$ - } - }); - } - String convertPattern(String template, String fromChars, String toChars, boolean check) { if (!check && fromChars.equals(toChars)) { @@ -189,6 +176,32 @@ * @return the object resulting from the parse, or null if there is an error */ public abstract Object parseObject(String string, ParsePosition position); + + /* + * Gets private field value by reflection. + * + * @param fieldName the field name to be set @param target the object which + * field to be gotten + */ + static Object getInternalField(final String fieldName, final Object target) { + Object value = AccessController + .doPrivileged(new PrivilegedAction() { + public Object run() { + Object result = null; + java.lang.reflect.Field field = null; + try { + field = target.getClass().getDeclaredField( + fieldName); + field.setAccessible(true); + result = field.get(target); + } catch (Exception e1) { + return null; + } + return result; + } + }); + return value; + } static boolean upTo(String string, ParsePosition position, StringBuffer buffer, char stop) {