Save This Page
Home » openjdk-7 » java » text » [javadoc | source]
    1   /*
    2    * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /*
   27    * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
   28    * (C) Copyright IBM Corp. 1996 - All Rights Reserved
   29    *
   30    *   The original version of this source code and documentation is copyrighted
   31    * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
   32    * materials are provided under terms of a License Agreement between Taligent
   33    * and Sun. This technology is protected by multiple US and International
   34    * patents. This notice and attribution to Taligent may not be removed.
   35    *   Taligent is a registered trademark of Taligent, Inc.
   36    *
   37    */
   38   
   39   package java.text;
   40   
   41   import java.io.IOException;
   42   import java.io.ObjectOutputStream;
   43   import java.io.Serializable;
   44   import java.lang.ref.SoftReference;
   45   import java.text.spi.DateFormatSymbolsProvider;
   46   import java.util.Arrays;
   47   import java.util.Hashtable;
   48   import java.util.List;
   49   import java.util.Locale;
   50   import java.util.ResourceBundle;
   51   import java.util.TimeZone;
   52   import java.util.spi.LocaleServiceProvider;
   53   import sun.util.LocaleServiceProviderPool;
   54   import sun.util.TimeZoneNameUtility;
   55   import sun.util.calendar.ZoneInfo;
   56   import sun.util.resources.LocaleData;
   57   
   58   /**
   59    * <code>DateFormatSymbols</code> is a public class for encapsulating
   60    * localizable date-time formatting data, such as the names of the
   61    * months, the names of the days of the week, and the time zone data.
   62    * <code>DateFormat</code> and <code>SimpleDateFormat</code> both use
   63    * <code>DateFormatSymbols</code> to encapsulate this information.
   64    *
   65    * <p>
   66    * Typically you shouldn't use <code>DateFormatSymbols</code> directly.
   67    * Rather, you are encouraged to create a date-time formatter with the
   68    * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
   69    * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>.
   70    * These methods automatically create a <code>DateFormatSymbols</code> for
   71    * the formatter so that you don't have to. After the
   72    * formatter is created, you may modify its format pattern using the
   73    * <code>setPattern</code> method. For more information about
   74    * creating formatters using <code>DateFormat</code>'s factory methods,
   75    * see {@link DateFormat}.
   76    *
   77    * <p>
   78    * If you decide to create a date-time formatter with a specific
   79    * format pattern for a specific locale, you can do so with:
   80    * <blockquote>
   81    * <pre>
   82    * new SimpleDateFormat(aPattern, DateFormatSymbols.getInstance(aLocale)).
   83    * </pre>
   84    * </blockquote>
   85    *
   86    * <p>
   87    * <code>DateFormatSymbols</code> objects are cloneable. When you obtain
   88    * a <code>DateFormatSymbols</code> object, feel free to modify the
   89    * date-time formatting data. For instance, you can replace the localized
   90    * date-time format pattern characters with the ones that you feel easy
   91    * to remember. Or you can change the representative cities
   92    * to your favorite ones.
   93    *
   94    * <p>
   95    * New <code>DateFormatSymbols</code> subclasses may be added to support
   96    * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
   97   
   98    * @see          DateFormat
   99    * @see          SimpleDateFormat
  100    * @see          java.util.SimpleTimeZone
  101    * @author       Chen-Lieh Huang
  102    */
  103   public class DateFormatSymbols implements Serializable, Cloneable {
  104   
  105       /**
  106        * Construct a DateFormatSymbols object by loading format data from
  107        * resources for the default locale. This constructor can only
  108        * construct instances for the locales supported by the Java
  109        * runtime environment, not for those supported by installed
  110        * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
  111        * implementations. For full locale coverage, use the
  112        * {@link #getInstance(Locale) getInstance} method.
  113        *
  114        * @see #getInstance()
  115        * @exception  java.util.MissingResourceException
  116        *             if the resources for the default locale cannot be
  117        *             found or cannot be loaded.
  118        */
  119       public DateFormatSymbols()
  120       {
  121           initializeData(Locale.getDefault());
  122       }
  123   
  124       /**
  125        * Construct a DateFormatSymbols object by loading format data from
  126        * resources for the given locale. This constructor can only
  127        * construct instances for the locales supported by the Java
  128        * runtime environment, not for those supported by installed
  129        * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
  130        * implementations. For full locale coverage, use the
  131        * {@link #getInstance(Locale) getInstance} method.
  132        *
  133        * @see #getInstance(Locale)
  134        * @exception  java.util.MissingResourceException
  135        *             if the resources for the specified locale cannot be
  136        *             found or cannot be loaded.
  137        */
  138       public DateFormatSymbols(Locale locale)
  139       {
  140           initializeData(locale);
  141       }
  142   
  143       /**
  144        * Era strings. For example: "AD" and "BC".  An array of 2 strings,
  145        * indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
  146        * @serial
  147        */
  148       String eras[] = null;
  149   
  150       /**
  151        * Month strings. For example: "January", "February", etc.  An array
  152        * of 13 strings (some calendars have 13 months), indexed by
  153        * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.
  154        * @serial
  155        */
  156       String months[] = null;
  157   
  158       /**
  159        * Short month strings. For example: "Jan", "Feb", etc.  An array of
  160        * 13 strings (some calendars have 13 months), indexed by
  161        * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.
  162   
  163        * @serial
  164        */
  165       String shortMonths[] = null;
  166   
  167       /**
  168        * Weekday strings. For example: "Sunday", "Monday", etc.  An array
  169        * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
  170        * <code>Calendar.MONDAY</code>, etc.
  171        * The element <code>weekdays[0]</code> is ignored.
  172        * @serial
  173        */
  174       String weekdays[] = null;
  175   
  176       /**
  177        * Short weekday strings. For example: "Sun", "Mon", etc.  An array
  178        * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
  179        * <code>Calendar.MONDAY</code>, etc.
  180        * The element <code>shortWeekdays[0]</code> is ignored.
  181        * @serial
  182        */
  183       String shortWeekdays[] = null;
  184   
  185       /**
  186        * AM and PM strings. For example: "AM" and "PM".  An array of
  187        * 2 strings, indexed by <code>Calendar.AM</code> and
  188        * <code>Calendar.PM</code>.
  189        * @serial
  190        */
  191       String ampms[] = null;
  192   
  193       /**
  194        * Localized names of time zones in this locale.  This is a
  195        * two-dimensional array of strings of size <em>n</em> by <em>m</em>,
  196        * where <em>m</em> is at least 5.  Each of the <em>n</em> rows is an
  197        * entry containing the localized names for a single <code>TimeZone</code>.
  198        * Each such row contains (with <code>i</code> ranging from
  199        * 0..<em>n</em>-1):
  200        * <ul>
  201        * <li><code>zoneStrings[i][0]</code> - time zone ID</li>
  202        * <li><code>zoneStrings[i][1]</code> - long name of zone in standard
  203        * time</li>
  204        * <li><code>zoneStrings[i][2]</code> - short name of zone in
  205        * standard time</li>
  206        * <li><code>zoneStrings[i][3]</code> - long name of zone in daylight
  207        * saving time</li>
  208        * <li><code>zoneStrings[i][4]</code> - short name of zone in daylight
  209        * saving time</li>
  210        * </ul>
  211        * The zone ID is <em>not</em> localized; it's one of the valid IDs of
  212        * the {@link java.util.TimeZone TimeZone} class that are not
  213        * <a href="../java/util/TimeZone.html#CustomID">custom IDs</a>.
  214        * All other entries are localized names.
  215        * @see java.util.TimeZone
  216        * @serial
  217        */
  218       String zoneStrings[][] = null;
  219   
  220       /**
  221        * Indicates that zoneStrings is set externally with setZoneStrings() method.
  222        */
  223       transient boolean isZoneStringsSet = false;
  224   
  225       /**
  226        * Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
  227        * All locales use the same these unlocalized pattern characters.
  228        */
  229       static final String  patternChars = "GyMdkHmsSEDFwWahKzZ";
  230   
  231       /**
  232        * Localized date-time pattern characters. For example, a locale may
  233        * wish to use 'u' rather than 'y' to represent years in its date format
  234        * pattern strings.
  235        * This string must be exactly 18 characters long, with the index of
  236        * the characters described by <code>DateFormat.ERA_FIELD</code>,
  237        * <code>DateFormat.YEAR_FIELD</code>, etc.  Thus, if the string were
  238        * "Xz...", then localized patterns would use 'X' for era and 'z' for year.
  239        * @serial
  240        */
  241       String  localPatternChars = null;
  242   
  243       /**
  244        * The locale which is used for initializing this DateFormatSymbols object.
  245        *
  246        * @since 1.6
  247        * @serial
  248        */
  249       Locale locale = null;
  250   
  251       /* use serialVersionUID from JDK 1.1.4 for interoperability */
  252       static final long serialVersionUID = -5987973545549424702L;
  253   
  254       /**
  255        * Returns an array of all locales for which the
  256        * <code>getInstance</code> methods of this class can return
  257        * localized instances.
  258        * The returned array represents the union of locales supported by the
  259        * Java runtime and by installed
  260        * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
  261        * implementations.  It must contain at least a <code>Locale</code>
  262        * instance equal to {@link java.util.Locale#US Locale.US}.
  263        *
  264        * @return An array of locales for which localized
  265        *         <code>DateFormatSymbols</code> instances are available.
  266        * @since 1.6
  267        */
  268       public static Locale[] getAvailableLocales() {
  269           LocaleServiceProviderPool pool=
  270               LocaleServiceProviderPool.getPool(DateFormatSymbolsProvider.class);
  271           return pool.getAvailableLocales();
  272       }
  273   
  274       /**
  275        * Gets the <code>DateFormatSymbols</code> instance for the default
  276        * locale.  This method provides access to <code>DateFormatSymbols</code>
  277        * instances for locales supported by the Java runtime itself as well
  278        * as for those supported by installed
  279        * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
  280        * implementations.
  281        * @return a <code>DateFormatSymbols</code> instance.
  282        * @since 1.6
  283        */
  284       public static final DateFormatSymbols getInstance() {
  285           return getInstance(Locale.getDefault());
  286       }
  287   
  288       /**
  289        * Gets the <code>DateFormatSymbols</code> instance for the specified
  290        * locale.  This method provides access to <code>DateFormatSymbols</code>
  291        * instances for locales supported by the Java runtime itself as well
  292        * as for those supported by installed
  293        * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
  294        * implementations.
  295        * @param locale the given locale.
  296        * @return a <code>DateFormatSymbols</code> instance.
  297        * @exception NullPointerException if <code>locale</code> is null
  298        * @since 1.6
  299        */
  300       public static final DateFormatSymbols getInstance(Locale locale) {
  301   
  302           // Check whether a provider can provide an implementation that's closer
  303           // to the requested locale than what the Java runtime itself can provide.
  304           LocaleServiceProviderPool pool =
  305               LocaleServiceProviderPool.getPool(DateFormatSymbolsProvider.class);
  306           if (pool.hasProviders()) {
  307               DateFormatSymbols providersInstance = pool.getLocalizedObject(
  308                                   DateFormatSymbolsGetter.INSTANCE, locale);
  309               if (providersInstance != null) {
  310                   return providersInstance;
  311               }
  312           }
  313   
  314           return new DateFormatSymbols(locale);
  315       }
  316   
  317       /**
  318        * Gets era strings. For example: "AD" and "BC".
  319        * @return the era strings.
  320        */
  321       public String[] getEras() {
  322           return Arrays.copyOf(eras, eras.length);
  323       }
  324   
  325       /**
  326        * Sets era strings. For example: "AD" and "BC".
  327        * @param newEras the new era strings.
  328        */
  329       public void setEras(String[] newEras) {
  330           eras = Arrays.copyOf(newEras, newEras.length);
  331       }
  332   
  333       /**
  334        * Gets month strings. For example: "January", "February", etc.
  335        * @return the month strings.
  336        */
  337       public String[] getMonths() {
  338           return Arrays.copyOf(months, months.length);
  339       }
  340   
  341       /**
  342        * Sets month strings. For example: "January", "February", etc.
  343        * @param newMonths the new month strings.
  344        */
  345       public void setMonths(String[] newMonths) {
  346           months = Arrays.copyOf(newMonths, newMonths.length);
  347       }
  348   
  349       /**
  350        * Gets short month strings. For example: "Jan", "Feb", etc.
  351        * @return the short month strings.
  352        */
  353       public String[] getShortMonths() {
  354           return Arrays.copyOf(shortMonths, shortMonths.length);
  355       }
  356   
  357       /**
  358        * Sets short month strings. For example: "Jan", "Feb", etc.
  359        * @param newShortMonths the new short month strings.
  360        */
  361       public void setShortMonths(String[] newShortMonths) {
  362           shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length);
  363       }
  364   
  365       /**
  366        * Gets weekday strings. For example: "Sunday", "Monday", etc.
  367        * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
  368        * <code>Calendar.MONDAY</code>, etc. to index the result array.
  369        */
  370       public String[] getWeekdays() {
  371           return Arrays.copyOf(weekdays, weekdays.length);
  372       }
  373   
  374       /**
  375        * Sets weekday strings. For example: "Sunday", "Monday", etc.
  376        * @param newWeekdays the new weekday strings. The array should
  377        * be indexed by <code>Calendar.SUNDAY</code>,
  378        * <code>Calendar.MONDAY</code>, etc.
  379        */
  380       public void setWeekdays(String[] newWeekdays) {
  381           weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length);
  382       }
  383   
  384       /**
  385        * Gets short weekday strings. For example: "Sun", "Mon", etc.
  386        * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
  387        * <code>Calendar.MONDAY</code>, etc. to index the result array.
  388        */
  389       public String[] getShortWeekdays() {
  390           return Arrays.copyOf(shortWeekdays, shortWeekdays.length);
  391       }
  392   
  393       /**
  394        * Sets short weekday strings. For example: "Sun", "Mon", etc.
  395        * @param newShortWeekdays the new short weekday strings. The array should
  396        * be indexed by <code>Calendar.SUNDAY</code>,
  397        * <code>Calendar.MONDAY</code>, etc.
  398        */
  399       public void setShortWeekdays(String[] newShortWeekdays) {
  400           shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);
  401       }
  402   
  403       /**
  404        * Gets ampm strings. For example: "AM" and "PM".
  405        * @return the ampm strings.
  406        */
  407       public String[] getAmPmStrings() {
  408           return Arrays.copyOf(ampms, ampms.length);
  409       }
  410   
  411       /**
  412        * Sets ampm strings. For example: "AM" and "PM".
  413        * @param newAmpms the new ampm strings.
  414        */
  415       public void setAmPmStrings(String[] newAmpms) {
  416           ampms = Arrays.copyOf(newAmpms, newAmpms.length);
  417       }
  418   
  419       /**
  420        * Gets time zone strings.  Use of this method is discouraged; use
  421        * {@link java.util.TimeZone#getDisplayName() TimeZone.getDisplayName()}
  422        * instead.
  423        * <p>
  424        * The value returned is a
  425        * two-dimensional array of strings of size <em>n</em> by <em>m</em>,
  426        * where <em>m</em> is at least 5.  Each of the <em>n</em> rows is an
  427        * entry containing the localized names for a single <code>TimeZone</code>.
  428        * Each such row contains (with <code>i</code> ranging from
  429        * 0..<em>n</em>-1):
  430        * <ul>
  431        * <li><code>zoneStrings[i][0]</code> - time zone ID</li>
  432        * <li><code>zoneStrings[i][1]</code> - long name of zone in standard
  433        * time</li>
  434        * <li><code>zoneStrings[i][2]</code> - short name of zone in
  435        * standard time</li>
  436        * <li><code>zoneStrings[i][3]</code> - long name of zone in daylight
  437        * saving time</li>
  438        * <li><code>zoneStrings[i][4]</code> - short name of zone in daylight
  439        * saving time</li>
  440        * </ul>
  441        * The zone ID is <em>not</em> localized; it's one of the valid IDs of
  442        * the {@link java.util.TimeZone TimeZone} class that are not
  443        * <a href="../util/TimeZone.html#CustomID">custom IDs</a>.
  444        * All other entries are localized names.  If a zone does not implement
  445        * daylight saving time, the daylight saving time names should not be used.
  446        * <p>
  447        * If {@link #setZoneStrings(String[][]) setZoneStrings} has been called
  448        * on this <code>DateFormatSymbols</code> instance, then the strings
  449        * provided by that call are returned. Otherwise, the returned array
  450        * contains names provided by the Java runtime and by installed
  451        * {@link java.util.spi.TimeZoneNameProvider TimeZoneNameProvider}
  452        * implementations.
  453        *
  454        * @return the time zone strings.
  455        * @see #setZoneStrings(String[][])
  456        */
  457       public String[][] getZoneStrings() {
  458           return getZoneStringsImpl(true);
  459       }
  460   
  461       /**
  462        * Sets time zone strings.  The argument must be a
  463        * two-dimensional array of strings of size <em>n</em> by <em>m</em>,
  464        * where <em>m</em> is at least 5.  Each of the <em>n</em> rows is an
  465        * entry containing the localized names for a single <code>TimeZone</code>.
  466        * Each such row contains (with <code>i</code> ranging from
  467        * 0..<em>n</em>-1):
  468        * <ul>
  469        * <li><code>zoneStrings[i][0]</code> - time zone ID</li>
  470        * <li><code>zoneStrings[i][1]</code> - long name of zone in standard
  471        * time</li>
  472        * <li><code>zoneStrings[i][2]</code> - short name of zone in
  473        * standard time</li>
  474        * <li><code>zoneStrings[i][3]</code> - long name of zone in daylight
  475        * saving time</li>
  476        * <li><code>zoneStrings[i][4]</code> - short name of zone in daylight
  477        * saving time</li>
  478        * </ul>
  479        * The zone ID is <em>not</em> localized; it's one of the valid IDs of
  480        * the {@link java.util.TimeZone TimeZone} class that are not
  481        * <a href="../util/TimeZone.html#CustomID">custom IDs</a>.
  482        * All other entries are localized names.
  483        *
  484        * @param newZoneStrings the new time zone strings.
  485        * @exception IllegalArgumentException if the length of any row in
  486        *    <code>newZoneStrings</code> is less than 5
  487        * @exception NullPointerException if <code>newZoneStrings</code> is null
  488        * @see #getZoneStrings()
  489        */
  490       public void setZoneStrings(String[][] newZoneStrings) {
  491           String[][] aCopy = new String[newZoneStrings.length][];
  492           for (int i = 0; i < newZoneStrings.length; ++i) {
  493               int len = newZoneStrings[i].length;
  494               if (len < 5) {
  495                   throw new IllegalArgumentException();
  496               }
  497               aCopy[i] = Arrays.copyOf(newZoneStrings[i], len);
  498           }
  499           zoneStrings = aCopy;
  500           isZoneStringsSet = true;
  501       }
  502   
  503       /**
  504        * Gets localized date-time pattern characters. For example: 'u', 't', etc.
  505        * @return the localized date-time pattern characters.
  506        */
  507       public String getLocalPatternChars() {
  508           return new String(localPatternChars);
  509       }
  510   
  511       /**
  512        * Sets localized date-time pattern characters. For example: 'u', 't', etc.
  513        * @param newLocalPatternChars the new localized date-time
  514        * pattern characters.
  515        */
  516       public void setLocalPatternChars(String newLocalPatternChars) {
  517           localPatternChars = new String(newLocalPatternChars);
  518       }
  519   
  520       /**
  521        * Overrides Cloneable
  522        */
  523       public Object clone()
  524       {
  525           try
  526           {
  527               DateFormatSymbols other = (DateFormatSymbols)super.clone();
  528               copyMembers(this, other);
  529               return other;
  530           } catch (CloneNotSupportedException e) {
  531               throw new InternalError();
  532           }
  533       }
  534   
  535       /**
  536        * Override hashCode.
  537        * Generates a hash code for the DateFormatSymbols object.
  538        */
  539       public int hashCode() {
  540           int hashcode = 0;
  541           String[][] zoneStrings = getZoneStringsWrapper();
  542           for (int index = 0; index < zoneStrings[0].length; ++index)
  543               hashcode ^= zoneStrings[0][index].hashCode();
  544           return hashcode;
  545       }
  546   
  547       /**
  548        * Override equals
  549        */
  550       public boolean equals(Object obj)
  551       {
  552           if (this == obj) return true;
  553           if (obj == null || getClass() != obj.getClass()) return false;
  554           DateFormatSymbols that = (DateFormatSymbols) obj;
  555           return (Arrays.equals(eras, that.eras)
  556                   && Arrays.equals(months, that.months)
  557                   && Arrays.equals(shortMonths, that.shortMonths)
  558                   && Arrays.equals(weekdays, that.weekdays)
  559                   && Arrays.equals(shortWeekdays, that.shortWeekdays)
  560                   && Arrays.equals(ampms, that.ampms)
  561                   && Arrays.deepEquals(getZoneStringsWrapper(), that.getZoneStringsWrapper())
  562                   && ((localPatternChars != null
  563                     && localPatternChars.equals(that.localPatternChars))
  564                    || (localPatternChars == null
  565                     && that.localPatternChars == null)));
  566       }
  567   
  568       // =======================privates===============================
  569   
  570       /**
  571        * Useful constant for defining time zone offsets.
  572        */
  573       static final int millisPerHour = 60*60*1000;
  574   
  575       /**
  576        * Cache to hold the FormatData and TimeZoneNames ResourceBundles
  577        * of a Locale.
  578        */
  579       private static Hashtable cachedLocaleData = new Hashtable(3);
  580   
  581       /**
  582        * Look up resource data for the desiredLocale in the cache; update the
  583        * cache if necessary.
  584        */
  585       private static ResourceBundle cacheLookup(Locale desiredLocale) {
  586           ResourceBundle rb;
  587           SoftReference data
  588               = (SoftReference)cachedLocaleData.get(desiredLocale);
  589           if (data == null) {
  590               rb = LocaleData.getDateFormatData(desiredLocale);
  591               data = new SoftReference(rb);
  592               cachedLocaleData.put(desiredLocale, data);
  593           } else {
  594               if ((rb = (ResourceBundle)data.get()) == null) {
  595                   rb = LocaleData.getDateFormatData(desiredLocale);
  596                   data = new SoftReference(rb);
  597               }
  598           }
  599           return rb;
  600       }
  601   
  602       private void initializeData(Locale desiredLocale) {
  603           int i;
  604           ResourceBundle resource = cacheLookup(desiredLocale);
  605   
  606           // FIXME: cache only ResourceBundle. Hence every time, will do
  607           // getObject(). This won't be necessary if the Resource itself
  608           // is cached.
  609           eras = (String[])resource.getObject("Eras");
  610           months = resource.getStringArray("MonthNames");
  611           shortMonths = resource.getStringArray("MonthAbbreviations");
  612           String[] lWeekdays = resource.getStringArray("DayNames");
  613           weekdays = new String[8];
  614           weekdays[0] = "";  // 1-based
  615           for (i=0; i<lWeekdays.length; i++)
  616               weekdays[i+1] = lWeekdays[i];
  617           String[] sWeekdays = resource.getStringArray("DayAbbreviations");
  618           shortWeekdays = new String[8];
  619           shortWeekdays[0] = "";  // 1-based
  620           for (i=0; i<sWeekdays.length; i++)
  621               shortWeekdays[i+1] = sWeekdays[i];
  622           ampms = resource.getStringArray("AmPmMarkers");
  623           localPatternChars = resource.getString("DateTimePatternChars");
  624   
  625           locale = desiredLocale;
  626       }
  627   
  628       /**
  629        * Package private: used by SimpleDateFormat
  630        * Gets the index for the given time zone ID to obtain the time zone
  631        * strings for formatting. The time zone ID is just for programmatic
  632        * lookup. NOT LOCALIZED!!!
  633        * @param ID the given time zone ID.
  634        * @return the index of the given time zone ID.  Returns -1 if
  635        * the given time zone ID can't be located in the DateFormatSymbols object.
  636        * @see java.util.SimpleTimeZone
  637        */
  638       final int getZoneIndex(String ID)
  639       {
  640           String[][] zoneStrings = getZoneStringsWrapper();
  641           for (int index=0; index<zoneStrings.length; index++)
  642           {
  643               if (ID.equals(zoneStrings[index][0])) return index;
  644           }
  645   
  646           return -1;
  647       }
  648   
  649       /**
  650        * Wrapper method to the getZoneStrings(), which is called from inside
  651        * the java.text package and not to mutate the returned arrays, so that
  652        * it does not need to create a defensive copy.
  653        */
  654       final String[][] getZoneStringsWrapper() {
  655           if (isSubclassObject()) {
  656               return getZoneStrings();
  657           } else {
  658               return getZoneStringsImpl(false);
  659           }
  660       }
  661   
  662       private final String[][] getZoneStringsImpl(boolean needsCopy) {
  663           if (zoneStrings == null) {
  664               zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
  665           }
  666   
  667           if (!needsCopy) {
  668               return zoneStrings;
  669           }
  670   
  671           int len = zoneStrings.length;
  672           String[][] aCopy = new String[len][];
  673           for (int i = 0; i < len; i++) {
  674               aCopy[i] = Arrays.copyOf(zoneStrings[i], zoneStrings[i].length);
  675           }
  676           return aCopy;
  677       }
  678   
  679       private final boolean isSubclassObject() {
  680           return !getClass().getName().equals("java.text.DateFormatSymbols");
  681       }
  682   
  683       /**
  684        * Clones all the data members from the source DateFormatSymbols to
  685        * the target DateFormatSymbols. This is only for subclasses.
  686        * @param src the source DateFormatSymbols.
  687        * @param dst the target DateFormatSymbols.
  688        */
  689       private final void copyMembers(DateFormatSymbols src, DateFormatSymbols dst)
  690       {
  691           dst.eras = Arrays.copyOf(src.eras, src.eras.length);
  692           dst.months = Arrays.copyOf(src.months, src.months.length);
  693           dst.shortMonths = Arrays.copyOf(src.shortMonths, src.shortMonths.length);
  694           dst.weekdays = Arrays.copyOf(src.weekdays, src.weekdays.length);
  695           dst.shortWeekdays = Arrays.copyOf(src.shortWeekdays, src.shortWeekdays.length);
  696           dst.ampms = Arrays.copyOf(src.ampms, src.ampms.length);
  697           if (src.zoneStrings != null) {
  698               dst.zoneStrings = src.getZoneStringsImpl(true);
  699           } else {
  700               dst.zoneStrings = null;
  701           }
  702           dst.localPatternChars = new String (src.localPatternChars);
  703       }
  704   
  705       /**
  706        * Write out the default serializable data, after ensuring the
  707        * <code>zoneStrings</code> field is initialized in order to make
  708        * sure the backward compatibility.
  709        *
  710        * @since 1.6
  711        */
  712       private void writeObject(ObjectOutputStream stream) throws IOException {
  713           if (zoneStrings == null) {
  714               zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
  715           }
  716           stream.defaultWriteObject();
  717       }
  718   
  719       /**
  720        * Obtains a DateFormatSymbols instance from a DateFormatSymbolsProvider
  721        * implementation.
  722        */
  723       private static class DateFormatSymbolsGetter
  724           implements LocaleServiceProviderPool.LocalizedObjectGetter<DateFormatSymbolsProvider,
  725                                                                      DateFormatSymbols> {
  726           private static final DateFormatSymbolsGetter INSTANCE =
  727               new DateFormatSymbolsGetter();
  728   
  729           public DateFormatSymbols getObject(DateFormatSymbolsProvider dateFormatSymbolsProvider,
  730                                   Locale locale,
  731                                   String key,
  732                                   Object... params) {
  733               assert params.length == 0;
  734               return dateFormatSymbolsProvider.getInstance(locale);
  735           }
  736       }
  737   }

Save This Page
Home » openjdk-7 » java » text » [javadoc | source]