diff --git a/icu4j/src/com/ibm/icu/text/BreakIterator.java b/icu4j/src/com/ibm/icu/text/BreakIterator.java index 51db3037c4..af4cecebc9 100755 --- a/icu4j/src/com/ibm/icu/text/BreakIterator.java +++ b/icu4j/src/com/ibm/icu/text/BreakIterator.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/BreakIterator.java,v $ - * $Date: 2003/12/01 23:39:13 $ - * $Revision: 1.25 $ + * $Date: 2004/01/08 22:26:54 $ + * $Revision: 1.26 $ * ***************************************************************************************** */ @@ -227,9 +227,9 @@ public abstract class BreakIterator implements Cloneable return super.clone(); } catch (CloneNotSupportedException e) { - ///CLOVER:OFF + ///CLOVER:OFF throw new InternalError(); - ///CLOVER:ON + ///CLOVER:ON } } @@ -410,15 +410,6 @@ public abstract class BreakIterator implements Cloneable * @stable ICU 2.0 */ public abstract void setText(CharacterIterator newText); - - /** Get the locale for this break iterator object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return new ULocale(""); - } /** @draft ICU 2.4 */ public static final int KIND_CHARACTER = 0; @@ -587,20 +578,20 @@ public abstract class BreakIterator implements Cloneable if (key == null) { throw new IllegalArgumentException("registry key must not be null"); } - // TODO: we don't do code coverage for the following lines - // because in getBreakInstance we always instantiate the shim, - // and test execution is such that we always instantiate a - // breakiterator before we get to the break iterator tests. - // this is for modularization, and we could remove the - // dependencies in getBreakInstance by rewriting part of the - // LocaleData code, or perhaps by accepting it into the - // module. - ///CLOVER:OFF + // TODO: we don't do code coverage for the following lines + // because in getBreakInstance we always instantiate the shim, + // and test execution is such that we always instantiate a + // breakiterator before we get to the break iterator tests. + // this is for modularization, and we could remove the + // dependencies in getBreakInstance by rewriting part of the + // LocaleData code, or perhaps by accepting it into the + // module. + ///CLOVER:OFF if (shim != null) { return shim.unregister(key); } return false; - ///CLOVER:ON + ///CLOVER:ON } // end of registration @@ -675,12 +666,84 @@ public abstract class BreakIterator implements Cloneable shim = (BreakIteratorServiceShim)cls.newInstance(); } catch (Exception e) { - ///CLOVER:OFF + ///CLOVER:OFF e.printStackTrace(); throw new RuntimeException(e.getMessage()); - ///CLOVER:ON + ///CLOVER:ON } } return shim; } + + // -------- BEGIN ULocale boilerplate -------- + + /** + * 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). + * @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 + */ + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; + } + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- } diff --git a/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java b/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java index 0bafecb7af..45b2a87427 100644 --- a/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java +++ b/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java,v $ - * $Date: 2003/06/04 20:24:14 $ - * $Revision: 1.6 $ + * $Date: 2004/01/08 22:26:56 $ + * $Revision: 1.7 $ * ***************************************************************************************** */ @@ -23,6 +23,8 @@ import com.ibm.icu.impl.ICULocaleData; import com.ibm.icu.impl.ICULocaleService; import com.ibm.icu.impl.ICUService; import com.ibm.icu.impl.ICUService.Factory; +import com.ibm.icu.util.ULocale; + /** * @author Ram * @@ -96,8 +98,10 @@ final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim String rules = bundle.getString(rulesName); + BreakIterator iter = null; + if (classNames[kind].equals("RuleBasedBreakIterator")) { - return new RuleBasedBreakIterator(rules); + iter = new RuleBasedBreakIterator(rules); } else if (classNames[kind].equals("DictionaryBasedBreakIterator")) { try { @@ -106,7 +110,7 @@ final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim // System.out.println(t); URL url = (URL)t; InputStream dictionary = url.openStream(); - return new DictionaryBasedBreakIterator(rules, dictionary); + iter = new DictionaryBasedBreakIterator(rules, dictionary); } catch(IOException e) { } @@ -115,7 +119,9 @@ final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim // TODO: we don't have 'bad' resource data, so this should never happen // in our current tests. ///CLOVER:OFF - return new RuleBasedBreakIterator(rules); + if (iter == null) { + iter = new RuleBasedBreakIterator(rules); + } ///CLOVER:ON } else { @@ -126,5 +132,10 @@ final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim classNames[kind] + "\""); ///CLOVER:ON } + + // TODO: Determine valid and actual locale correctly. + ULocale uloc = new ULocale(bundle.getLocale()); + iter.setLocale(uloc, uloc); + return iter; } } diff --git a/icu4j/src/com/ibm/icu/text/Collator.java b/icu4j/src/com/ibm/icu/text/Collator.java index 0d9cb9d05d..7732ffa25a 100755 --- a/icu4j/src/com/ibm/icu/text/Collator.java +++ b/icu4j/src/com/ibm/icu/text/Collator.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/Collator.java,v $ -* $Date: 2003/12/01 23:39:13 $ -* $Revision: 1.39 $ +* $Date: 2004/01/08 22:26:56 $ +* $Revision: 1.40 $ * ******************************************************************************* */ @@ -428,10 +428,15 @@ public abstract class Collator implements Comparator, Cloneable */ public static final Collator getInstance(Locale locale) { + Collator coll = null; if (shim == null) { - return new RuleBasedCollator(locale); + coll = new RuleBasedCollator(locale); + } else { + // TODO: If the shim creates the collator, it is responsible + // for calling setLocale() on the new object. + coll = shim.getInstance(locale); } - return shim.getInstance(locale); + return coll; } /** @@ -729,15 +734,6 @@ public abstract class Collator implements Comparator, Cloneable */ public abstract void setVariableTop(int varTop); - /** Get the locale for this collator object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return ULocale.ROOT; - } - /** Get the version of this collator object. * @return the version object associated with this collator * @draft ICU 2.8 @@ -781,5 +777,76 @@ public abstract class Collator implements Comparator, Cloneable // private methods ------------------------------------------------------- // end registry stuff -} + // -------- BEGIN ULocale boilerplate -------- + + /** + * 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). + * @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 + */ + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; + } + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- +} diff --git a/icu4j/src/com/ibm/icu/text/DateFormat.java b/icu4j/src/com/ibm/icu/text/DateFormat.java index 7662b975a8..90822eddbc 100755 --- a/icu4j/src/com/ibm/icu/text/DateFormat.java +++ b/icu4j/src/com/ibm/icu/text/DateFormat.java @@ -8,7 +8,6 @@ package com.ibm.icu.text; import com.ibm.icu.impl.ICULocaleData; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; import com.ibm.icu.text.UFormat; import java.text.FieldPosition; @@ -730,15 +729,6 @@ public abstract class DateFormat extends UFormat { return calendar.isLenient(); } - /** Get the locale for this date format object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return ULocale.ROOT; - } - /** * Overrides hashCode * @stable ICU 2.0 diff --git a/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java b/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java index 886a49e0f7..0f2cf898fb 100755 --- a/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java +++ b/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java,v $ - * $Date: 2003/12/13 00:30:56 $ - * $Revision: 1.22 $ + * $Date: 2004/01/08 22:26:58 $ + * $Revision: 1.23 $ * ***************************************************************************************** */ @@ -18,6 +18,7 @@ import com.ibm.icu.impl.Utility; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.GregorianCalendar; import com.ibm.icu.impl.ZoneMeta; +import com.ibm.icu.util.ULocale; import java.io.Serializable; import java.util.Locale; @@ -443,6 +444,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { } localPatternChars = rb.getString("localPatternChars"); + + // TODO: obtain correct actual/valid locale later + ULocale uloc = new ULocale(rb.getLocale()); + setLocale(uloc, uloc); } /** @@ -690,6 +695,10 @@ public class DateFormatSymbols implements Serializable, Cloneable { String[] temp = bundle.getStringArray("Eras"); setEras( temp ); } catch (MissingResourceException e) {} + + // TODO: obtain correct actual/valid locale later + ULocale uloc = new ULocale(bundle.getLocale()); + setLocale(uloc, uloc); } } @@ -743,4 +752,76 @@ public class DateFormatSymbols implements Serializable, Cloneable { throws MissingResourceException { return getDateFormatBundle(cal.getClass(), locale); } + + // -------- BEGIN ULocale boilerplate -------- + + /** + * 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). + * @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 + */ + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; + } + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- } diff --git a/icu4j/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/src/com/ibm/icu/text/DecimalFormat.java index aad4f30928..cc7f75f69e 100755 --- a/icu4j/src/com/ibm/icu/text/DecimalFormat.java +++ b/icu4j/src/com/ibm/icu/text/DecimalFormat.java @@ -5,15 +5,14 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DecimalFormat.java,v $ - * $Date: 2003/11/21 22:52:05 $ - * $Revision: 1.39 $ + * $Date: 2004/01/08 22:26:59 $ + * $Revision: 1.40 $ * ***************************************************************************************** */ package com.ibm.icu.text; import com.ibm.icu.util.Currency; -import com.ibm.icu.util.ULocale; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.impl.UCharacterProperty; import java.text.ParsePosition; @@ -3389,6 +3388,8 @@ public class DecimalFormat extends NumberFormat { if (formatWidth > 0) { formatWidth += positivePrefix.length() + positiveSuffix.length(); } + + setLocale(null, null); } /*Rewrite the following 4 "set" methods @@ -3467,15 +3468,6 @@ public class DecimalFormat extends NumberFormat { super.setMinimumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS)); } - /** Get the locale for this decimal format object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return symbols.getLocale(type); - } - /** * First, read the default serializable fields from the stream. Then * if serialVersionOnStream is less than 1, indicating that diff --git a/icu4j/src/com/ibm/icu/text/DecimalFormatSymbols.java b/icu4j/src/com/ibm/icu/text/DecimalFormatSymbols.java index 58975e8208..f25b0bc36f 100755 --- a/icu4j/src/com/ibm/icu/text/DecimalFormatSymbols.java +++ b/icu4j/src/com/ibm/icu/text/DecimalFormatSymbols.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DecimalFormatSymbols.java,v $ - * $Date: 2003/12/13 00:30:56 $ - * $Revision: 1.14 $ + * $Date: 2004/01/08 22:27:01 $ + * $Revision: 1.15 $ * ***************************************************************************************** */ @@ -421,7 +421,7 @@ final public class DecimalFormatSymbols implements Cloneable, Serializable { */ public Object clone() { try { - return (DecimalFormatSymbols)super.clone(); + return (DecimalFormatSymbols) super.clone(); // other fields are bit-copied } catch (CloneNotSupportedException e) { ///CLOVER:OFF @@ -487,7 +487,10 @@ final public class DecimalFormatSymbols implements Cloneable, Serializable { numberElements = data[0]; ResourceBundle r = ICULocaleData.getLocaleElements(locale); - validLocale = new ULocale(r.getLocale()); + + // TODO: Determine actual and valid locale correctly. + ULocale uloc = new ULocale(r.getLocale()); + setLocale(uloc, uloc); // {dlf} clean up below now that we have our own resource data decimalSeparator = numberElements[0].charAt(0); @@ -765,14 +768,76 @@ final public class DecimalFormatSymbols implements Cloneable, Serializable { * cache to hold the NumberElements of a Locale. */ private static final Hashtable cachedLocaleData = new Hashtable(3); - - private ULocale validLocale; - - ///CLOVER:OFF - // temporarily off (2.8d1) until tests are completed - ULocale getLocale(ULocale.ULocaleDataType type) { - return validLocale; + + // -------- BEGIN ULocale boilerplate -------- + + /** + * 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). + * @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 + */ + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; } - ///CLOVER:ON - ///CLOVER:ON + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- } diff --git a/icu4j/src/com/ibm/icu/text/NumberFormat.java b/icu4j/src/com/ibm/icu/text/NumberFormat.java index 85229f8c2b..4869af3b7c 100755 --- a/icu4j/src/com/ibm/icu/text/NumberFormat.java +++ b/icu4j/src/com/ibm/icu/text/NumberFormat.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/NumberFormat.java,v $ - * $Date: 2003/12/13 00:30:56 $ - * $Revision: 1.34 $ + * $Date: 2004/01/08 22:27:02 $ + * $Revision: 1.35 $ * ***************************************************************************************** */ @@ -917,16 +917,6 @@ public abstract class NumberFormat extends UFormat { return currency; } - - /** Get the locale for this date format object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return ULocale.getDefault(); - } - // =======================privates=============================== // Hook for service @@ -934,6 +924,7 @@ public abstract class NumberFormat extends UFormat { if (shim == null) { return createInstance(desiredLocale, choice); } else { + // TODO: shims must call setLocale() on object they create return getShim().createInstance(desiredLocale, choice); } } @@ -949,11 +940,21 @@ public abstract class NumberFormat extends UFormat { /*Bug 4408066 Add codes for the new method getIntegerInstance() [Richard/GCL] */ + // TODO: revisit this -- this is almost certainly not the way we want + // to do this. aliu 1/6/2004 if (choice == INTEGERSTYLE) { format.setMaximumFractionDigits(0); format.setDecimalSeparatorAlwaysShown(false); format.setParseIntegerOnly(true); } + + // TODO: the actual locale of the *pattern* may differ from that + // for the *symbols*. For now, we use the data for the symbols. + // Revisit this. + ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE); + ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE); + format.setLocale(valid, actual); + return format; } diff --git a/icu4j/src/com/ibm/icu/text/RuleBasedCollator.java b/icu4j/src/com/ibm/icu/text/RuleBasedCollator.java index 4cdbaa632c..00496e9515 100755 --- a/icu4j/src/com/ibm/icu/text/RuleBasedCollator.java +++ b/icu4j/src/com/ibm/icu/text/RuleBasedCollator.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/RuleBasedCollator.java,v $ -* $Date: 2003/12/02 01:34:31 $ -* $Revision: 1.53 $ +* $Date: 2004/01/08 22:27:03 $ +* $Revision: 1.54 $ * ******************************************************************************* */ @@ -20,6 +20,7 @@ import java.util.ResourceBundle; import java.util.Arrays; import java.text.CharacterIterator; import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.util.ULocale; import com.ibm.icu.util.VersionInfo; import com.ibm.icu.impl.IntTrie; import com.ibm.icu.impl.Trie; @@ -1626,6 +1627,10 @@ public final class RuleBasedCollator extends Collator = ((ICUListResourceBundle)rb).getObjectWithFallback( "collations/" + collkey); if (elements != null) { + // TODO: Determine actual & valid locale correctly + ULocale uloc = new ULocale(rb.getLocale()); + setLocale(uloc, uloc); + Object[][] rules = (Object[][])elements; // %%CollationBin if(rules[0][1] instanceof byte[]){ diff --git a/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java b/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java index 0f9cdb985c..636aea77b7 100755 --- a/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java +++ b/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java,v $ - * $Date: 2003/11/21 22:52:05 $ - * $Revision: 1.18 $ + * $Date: 2004/01/08 22:27:08 $ + * $Revision: 1.19 $ * ***************************************************************************************** */ @@ -475,7 +475,7 @@ import java.util.ResourceBundle; * using these features.

* * @author Richard Gillam - * $RCSfile: RuleBasedNumberFormat.java,v $ $Revision: 1.18 $ $Date: 2003/11/21 22:52:05 $ + * $RCSfile: RuleBasedNumberFormat.java,v $ $Revision: 1.19 $ $Date: 2004/01/08 22:27:08 $ * @see NumberFormat * @see DecimalFormat * @stable ICU 2.0 @@ -556,8 +556,6 @@ public final class RuleBasedNumberFormat extends NumberFormat { */ private String lenientParseRules = null; - private ULocale validLocale; - //----------------------------------------------------------------------- // constructors //----------------------------------------------------------------------- @@ -612,7 +610,13 @@ public final class RuleBasedNumberFormat extends NumberFormat { // from the specified locale // ResourceBundle bundle = ICULocaleData.getResourceBundle("NumberFormatRules", locale); ResourceBundle bundle = ICULocaleData.getResourceBundle("LocaleElements", locale); - validLocale = new ULocale(bundle.getLocale()); + + // TODO: determine correct actual/valid locale. Note ambiguity + // here -- do actual/valid refer to pattern, DecimalFormatSymbols, + // or Collator? + ULocale uloc = new ULocale(bundle.getLocale()); + setLocale(uloc, uloc); + String description = ""; // pick a description from the resource bundle based on the @@ -1113,7 +1117,7 @@ public final class RuleBasedNumberFormat extends NumberFormat { * in the class docs. */ private void init(String description) { - validLocale = new ULocale(Locale.getDefault()); + // start by stripping the trailing whitespace from all the rules // (this is all the whitespace follwing each semicolon in the // description). This allows us to look for rule-set boundaries @@ -1339,14 +1343,5 @@ public final class RuleBasedNumberFormat extends NumberFormat { } throw new IllegalArgumentException("No rule set named " + name); } - /** Get the locale for this date format object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return validLocale; - } - } diff --git a/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java b/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java index 2e8c6c3037..6fea809816 100755 --- a/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java +++ b/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java,v $ - * $Date: 2003/12/17 00:50:33 $ - * $Revision: 1.27 $ + * $Date: 2004/01/08 22:27:09 $ + * $Revision: 1.28 $ * ***************************************************************************************** */ @@ -18,6 +18,7 @@ import com.ibm.icu.util.Calendar; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.impl.UCharacterProperty; import com.ibm.icu.util.TimeZone; +import com.ibm.icu.util.ULocale; import java.io.IOException; import java.io.ObjectInputStream; @@ -320,6 +321,11 @@ public class SimpleDateFormat extends DateFormat { String[] dateTimePatterns = (String[]) cachedLocaleData.get(loc); if (dateTimePatterns == null) { /* cache miss */ ResourceBundle r = ICULocaleData.getLocaleElements(loc); + + // TODO: get correct actual/valid locale here + ULocale uloc = new ULocale(r.getLocale()); + setLocale(uloc, uloc); + dateTimePatterns = r.getStringArray("DateTimePatterns"); /* update cache */ cachedLocaleData.put(loc, dateTimePatterns); @@ -1384,6 +1390,7 @@ public class SimpleDateFormat extends DateFormat { public void applyPattern (String pattern) { this.pattern = pattern; + setLocale(null, null); } /** @@ -1394,6 +1401,7 @@ public class SimpleDateFormat extends DateFormat { this.pattern = translatePattern(pattern, formatData.localPatternChars, DateFormatSymbols.patternChars); + setLocale(null, null); } /** diff --git a/icu4j/src/com/ibm/icu/text/UFormat.java b/icu4j/src/com/ibm/icu/text/UFormat.java index 5d4a73672b..7abdc8b38e 100644 --- a/icu4j/src/com/ibm/icu/text/UFormat.java +++ b/icu4j/src/com/ibm/icu/text/UFormat.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/UFormat.java,v $ - * $Date: 2003/12/02 01:34:31 $ - * $Revision: 1.5 $ + * $Date: 2004/01/08 22:27:10 $ + * $Revision: 1.6 $ * ******************************************************************************* */ @@ -16,24 +16,91 @@ import java.text.Format; import com.ibm.icu.util.ULocale; /** - * An abstract class that extends from java.text.Format class. This class is - * intended for adding additional functionality to the base class. + * 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 */ public abstract class UFormat extends Format { + /** * @draft ICU 2.8 */ public UFormat() {} + // -------- BEGIN ULocale boilerplate -------- + /** - * Return the locale used by the format object depending on the type - * - * @param type The type fo the locale that should returned. - * @return ULocale object for the type requested - * @see ULocale + * 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). + * @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 */ - public abstract ULocale getLocale(ULocale.ULocaleDataType type); + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; + } + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- } diff --git a/icu4j/src/com/ibm/icu/util/Calendar.java b/icu4j/src/com/ibm/icu/util/Calendar.java index a9dcb2d9c9..684cb33ff4 100755 --- a/icu4j/src/com/ibm/icu/util/Calendar.java +++ b/icu4j/src/com/ibm/icu/util/Calendar.java @@ -1603,7 +1603,11 @@ public abstract class Calendar implements Serializable, Cloneable { return new GregorianCalendar(zone, locale); } else { Calendar result = factory.create(zone, locale); - result.validLocale = new ULocale(actualReturn[0]); + + // TODO: get the actual/valid locale properly + ULocale uloc = new ULocale(actualReturn[0]); + result.setLocale(uloc, uloc); + return result; } } @@ -3592,7 +3596,6 @@ public abstract class Calendar implements Serializable, Cloneable { private void setWeekendData(Locale loc) { ResourceBundle resource = ICULocaleData.getResourceBundle("CalendarData", loc); - validLocale = new ULocale(resource.getLocale()); String[] data = resource.getStringArray("Weekend"); weekendOnset = Integer.parseInt(data[0]); weekendOnsetMillis = Integer.parseInt(data[1]); @@ -3604,17 +3607,6 @@ public abstract class Calendar implements Serializable, Cloneable { // End of weekend support //------------------------------------------------------------------------- - private ULocale validLocale; - - /** Get the locale for this calendar object. You can choose between valid and actual locale. - * @param type type of the locale we're looking for (valid or actual) - * @return the locale - * @draft ICU 2.8 - */ - public ULocale getLocale(ULocale.ULocaleDataType type) { - return validLocale; - } - /** * Overrides Cloneable * @stable ICU 2.0 @@ -3674,6 +3666,20 @@ public abstract class Calendar implements Serializable, Cloneable { // =======================privates=============================== + /** + * Internal class that holds cached locale data. + */ + private static class WeekData { + public int firstDayOfWeek; + public int minimalDaysInFirstWeek; + public Locale actualLocale; + public WeekData(int fdow, int mdifw, Locale actualLoc) { + this.firstDayOfWeek = fdow; + this.minimalDaysInFirstWeek = mdifw; + this.actualLocale = actualLoc; + } + } + /** * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. * They are used to figure out the week count for a specific date for @@ -3682,20 +3688,24 @@ public abstract class Calendar implements Serializable, Cloneable { */ private void setWeekCountData(Locale desiredLocale) { - /* try to get the Locale data from the cache */ - int[] data = (int[]) cachedLocaleData.get(desiredLocale); + /* try to get the Locale data from the cache */ + WeekData data = (WeekData) cachedLocaleData.get(desiredLocale); + + if (data == null) { /* cache miss */ + ResourceBundle resource = ICULocaleData.getLocaleElements(desiredLocale); + String[] dateTimePatterns = resource.getStringArray("DateTimeElements"); + data = new WeekData(Integer.parseInt(dateTimePatterns[0]), + Integer.parseInt(dateTimePatterns[1]), + resource.getLocale()); + /* cache update */ + cachedLocaleData.put(desiredLocale, data); + } + setFirstDayOfWeek(data.firstDayOfWeek); + setMinimalDaysInFirstWeek(data.minimalDaysInFirstWeek); - if (data == null) { /* cache miss */ - ResourceBundle resource = ICULocaleData.getLocaleElements(desiredLocale); - String[] dateTimePatterns = resource.getStringArray("DateTimeElements"); - data = new int[2]; - data[0] = Integer.parseInt(dateTimePatterns[0]); - data[1] = Integer.parseInt(dateTimePatterns[1]); - /* cache update */ - cachedLocaleData.put(desiredLocale, data); - } - setFirstDayOfWeek(data[0]); - setMinimalDaysInFirstWeek(data[1]); + // TODO: determine the actual/valid locale + ULocale uloc = new ULocale(data.actualLocale); + setLocale(uloc, uloc); } /** @@ -4871,4 +4881,76 @@ public abstract class Calendar implements Serializable, Cloneable { protected final long internalGetTimeInMillis() { return time; } + + // -------- BEGIN ULocale boilerplate -------- + + /** + * 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). + * @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 + */ + public final ULocale getLocale(ULocale.Type type) { + return type == ULocale.ACTUAL_LOCALE ? + this.actualLocale : this.validLocale; + } + + /** + * 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 + * @internal + */ + final void setLocale(ULocale valid, ULocale actual) { + // Change the following to an assertion later + if ((valid == null) != (actual == null)) { + ///CLOVER:OFF + throw new IllegalArgumentException(); + ///CLOVER:ON + } + // Another check we could do is that the actual locale is at + // the same level or less specific than the valid locale. + this.validLocale = valid; + this.actualLocale = actual; + } + + /** + * The most specific locale containing any resource data, or null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale validLocale; + + /** + * The locale containing data used to construct this object, or + * null. + * @see com.ibm.icu.util.ULocale + * @internal + */ + private ULocale actualLocale; + + // -------- END ULocale boilerplate -------- } diff --git a/icu4j/src/com/ibm/icu/util/ULocale.java b/icu4j/src/com/ibm/icu/util/ULocale.java index ededf57cc1..debaeae2be 100644 --- a/icu4j/src/com/ibm/icu/util/ULocale.java +++ b/icu4j/src/com/ibm/icu/util/ULocale.java @@ -5,8 +5,8 @@ ****************************************************************************** * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/ULocale.java,v $ -* $Date: 2003/12/01 21:23:07 $ -* $Revision: 1.7 $ +* $Date: 2004/01/08 22:27:14 $ +* $Revision: 1.8 $ * ****************************************************************************** */ @@ -18,95 +18,135 @@ import java.io.Serializable; import java.io.IOException; /** - * A class for replacing the java.util.Locale. This class provides all the - * functionality that java.util.Locale has and in ICU 3.0 will be enhanced for - * supporting RFC 3066 language identifiers. + * A class that extends {@link java.util.Locale} to provide additional + * ICU protocol. In ICU 3.0 this class will be 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 valid locale is found, further fallback may be required + * to reach a locale containing the specific data required by the + * service (the actual locale). + * + *

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.text.UFormat}, {@link com.ibm.icu.text.BreakIterator}, + * {@link com.ibm.icu.text.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. + * + * @see java.util.Locale * @author weiv + * @author Alan Liu * @draft ICU 2.8 */ public final class ULocale implements Serializable { + private transient Locale locale; + private String locName; - /** - * Actual locale where data is coming from - * Actual locale will make sense only after the alternate - * ICU data handling framework is implemented in ICU 3.0 - * @draft ICU 2.8 - */ - public static final ULocaleDataType ACTUAL_LOCALE = new ULocaleDataType(0); - - /** - * Valid locale for an object + /** + * The root ULocale. * @draft ICU 2.8 */ - public static final ULocaleDataType VALID_LOCALE = new ULocaleDataType(1); - + public static final ULocale ROOT = new ULocale(""); + /** - * Type safe enum for representing the type of locale + * Construct a ULocale object from a {@link java.util.Locale}. + * @param loc a JDK locale * @draft ICU 2.8 */ - public static final class ULocaleDataType{ - - private int localeType; - - private ULocaleDataType(int id){ - localeType = id; - } - private boolean equals(int id){ - return localeType == id; - } + public ULocale(Locale loc) { + this.locName = loc.toString(); + this.locale = loc; } - + /** - * Convert this ULocale object to java.util.Locale object - * @return Locale object that represents the information in this object + * Construct a ULocale from a string of the form "no_NO_NY". + * @param locName string representation of the locale, e.g: + * "en_US", "sy-Cyrl-YU" + * @draft ICU 2.8 + */ + public ULocale(String locName) { + this.locName = locName; + this.locale = new Locale(locName, ""); + } + + /** + * Convert this ULocale object to a {@link java.util.Locale}. + * @return a JDK locale that either exactly represents this object + * or is the closest approximation. * @draft ICU 2.8 */ public Locale toLocale() { return locale; } - /** - * Construct a ULocale object from java.util.Locale object. - * @param loc The locale object to be converted - * @draft ICU 2.8 - */ - public ULocale(Locale loc) { - this.locName = loc.toString(); - this.locale = loc; - } - - /** - * Construct a ULocale object from a string representing the locale - * @param locName String representation of the locale, e.g: en_US, sy-Cyrl-YU - * @draft ICU 2.8 - */ - public ULocale(String locName) { - this.locName = locName; - this.locale = new Locale(locName, ""); - } - /** * Return the current default ULocale. * @draft ICU 2.8 */ public static ULocale getDefault() { - return new ULocale(Locale.getDefault()); + return new ULocale(Locale.getDefault()); } - /** - * Return the root ULocale. + /** + * 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. + * + *

Note: The actual locale will be returned correctly in ICU + * 3.0 or later. + * @draft ICU 2.8 + */ + public static final Type ACTUAL_LOCALE = new Type(0); + + /** + * 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. * @draft ICU 2.8 */ - public static final ULocale ROOT = new ULocale(""); - - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.writeObject(locName); + public static final Type VALID_LOCALE = new Type(1); + + /** + * 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 + */ + public static final class Type { + private int localeType; + private Type(int type) { localeType = type; } + } + + private void writeObject(java.io.ObjectOutputStream out) + throws IOException { + out.writeObject(locName); } - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - locName = (String)in.readObject(); - locale = new Locale(locName, ""); + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException { + locName = (String)in.readObject(); + locale = new Locale(locName, ""); } }