This patch begins the addition of the locale
service providers by adding the main superclass
and the one for Currency.

Changelog:

2007-01-02  Andrew John Hughes  <[EMAIL PROTECTED]>

        * gnu/java/locale/LocaleHelper.java:
        (getLocalizedString(Locale,String,String,boolean,
        boolean)): Removed, no longer needed.
        (getFallbackLocale(Locale)): Implemented.
        * java/lang/String.java:
        (isEmpty()): Implemented.
        * java/util/Currency.java:
        (getSymbol(Locale)): Reimplemented to use SPI.
        * java/util/Locale.java:
        (ROOT): Added.
        * java/util/spi/CurrencyNameProvider.java:
        New file.
        * java/util/spi/LocaleServiceProvider.java:
        Likewise.
        * java/util/spi/package.html: Likewise.

-- 
Andrew :-)

Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: gnu/java/locale/LocaleHelper.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/locale/LocaleHelper.java,v
retrieving revision 1.5
diff -u -3 -p -u -r1.5 LocaleHelper.java
--- gnu/java/locale/LocaleHelper.java   24 Mar 2006 17:04:21 -0000      1.5
+++ gnu/java/locale/LocaleHelper.java   2 Jan 2007 00:44:46 -0000
@@ -55,105 +55,44 @@ import java.util.ResourceBundle;
 public class LocaleHelper
 {
   /**
-   * This method is used by the localized name lookup methods to retrieve
-   * the localized name of a particular piece of locale data.    
-   * If the display name can not be localized to the supplied
-   * locale, it will fall back on other output in the following order:
-   *
-   * <ul>
-   * <li>the localized name in the default locale</li>
-   * <li>the localized name in English (optional)</li>
-   * <li>the localized name in the root locale bundle (optional)</li>
-   * <li>the localized input string</li>
-   * </ul>
    * <p>
-   * If the supplied key is merely the empty string, then the empty string is
-   * returned.
+   * This method is used by the localized name lookup methods to
+   * retrieve the next locale to try.  The next locale is derived
+   * from the supplied locale by applying the first applicable
+   * rule from the following:
+   * </p>
+   * <ol>
+   * <li>If the variant contains a <code>'_'</code>, then
+   * this and everything following it is trimmed.</li>
+   * <li>If the variant is non-empty, it is converted to
+   * an empty string.</li>
+   * <li>If the country is non-empty, it is converted to
+   * an empty string.</li>
+   * <li>If the language is non-empty, it is converted to
+   * an empty string (forming [EMAIL PROTECTED] java.util.Locale#ROOT})</li>
+   * </ol>
+   * <p>
+   * The base fallback locale is [EMAIL PROTECTED] java.util.Locale#ROOT}.
    * </p>
    *
-   * @param inLocale the locale to use for formatting the display string.
-   * @param key the locale data used as a key to the localized lookup tables.
-   * @param name the name of the hashtable containing the localized data.
-   * @param checkEnglish true if the method should fall back on data
-   *        from the English locale.
-   * @param checkRoot true if the method should fall back on data from the
-   *        unlocalized root locale.
-   * @return a <code>String</code>, hopefully containing the localized
-   *         variant of the input data.
-   * @throws NullPointerException if <code>inLocale</code> is null. 
+   * @param locale the locale for which a localized piece of
+   *               data could not be obtained.
+   * @return the next fallback locale to try.
    */
-  public static String getLocalizedString(Locale inLocale, String key,
-                                         String name, boolean checkEnglish,
-                                         boolean checkRoot)
+  public static Locale getFallbackLocale(Locale locale)
   {
-    String localizedString;
-    String property;
-
-    if (key.equals(""))
-      return "";
-    property = name + "." + key;
-    /* Localize to inLocale */
-    try
-      {
-        localizedString =
-         ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
-                                  inLocale).getString(property);
-      }
-    catch (MissingResourceException exception)
-      {
-       localizedString = null;
-      }
-    /* Localize to default locale */
-    if (localizedString == null)
-      {
-       try 
-         {
-           ResourceBundle bundle;
-           
-           bundle = 
-             ResourceBundle.getBundle("gnu.java.locale.LocaleInformation");
-           localizedString = bundle.getString(property);
-         }
-       catch (MissingResourceException exception)
-         {
-           localizedString = null;
-         }
-      }
-    /* Localize to English */
-    if (localizedString == null && checkEnglish)
-      {
-       try
-         {
-           localizedString = 
-             ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
-                                      Locale.ENGLISH).getString(property);
-         }
-       catch (MissingResourceException exception)
-         {
-           localizedString = null;
-         }
-      }
-    /* Return unlocalized version */
-    if (localizedString == null && checkRoot)
-      {
-       try
-         {
-           localizedString = 
-             ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
-                                      new Locale("","","")
-                                      ).getString(property);
-         }
-       catch (MissingResourceException exception)
-         {
-           localizedString = null;
-         }
-      }
-    /* Return original input string */
-    if (localizedString == null)
-      {
-       localizedString = key;
-      }
-    return localizedString;
+    String language = locale.getLanguage();
+    String country = locale.getCountry();
+    String variant = locale.getVariant();
+    int uscore = variant.indexOf('_');
+    if (uscore != -1)
+      return new Locale(language, country,
+                       variant.substring(0, uscore));
+    if (!variant.isEmpty())
+      return new Locale(language, country, "");
+    if (!country.isEmpty())
+      return new Locale(language, "", "");
+    return Locale.ROOT;
   }
 
   /**
Index: java/lang/String.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v
retrieving revision 1.85
diff -u -3 -p -u -r1.85 String.java
--- java/lang/String.java       21 Dec 2006 13:02:51 -0000      1.85
+++ java/lang/String.java       2 Jan 2007 00:44:48 -0000
@@ -1990,4 +1990,17 @@ public final class String
     return Character.offsetByCodePoints(value, offset, count, offset + index,
                                         codePointOffset);
   }
+
+  /**
+   * Returns true if, and only if, [EMAIL PROTECTED] #length()}
+   * is <code>0</code>.
+   *
+   * @return true if the length of the string is zero.
+   * @since 1.6
+   */
+  public boolean isEmpty()
+  {
+    return count == 0;
+  }
+
 }
Index: java/util/Currency.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/util/Currency.java,v
retrieving revision 1.16
diff -u -3 -p -u -r1.16 Currency.java
--- java/util/Currency.java     2 Jul 2005 20:32:41 -0000       1.16
+++ java/util/Currency.java     2 Jan 2007 00:44:48 -0000
@@ -44,6 +44,8 @@ import java.io.IOException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 
+import java.util.spi.CurrencyNameProvider;
+
 /**
  * Representation of a currency for a particular locale.  Each currency
  * is identified by its ISO 4217 code, and only one instance of this
@@ -402,8 +404,37 @@ public final class Currency 
    */
   public String getSymbol(Locale locale)
   {
-    return LocaleHelper.getLocalizedString(locale, currencyCode,
-                                          "currenciesSymbol", false, true);
+    String localizedString;
+    String property = "currenciesSymbol." + currencyCode;
+    try
+      {
+        localizedString =
+         ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+                                  locale).getString(property);
+      }
+    catch (MissingResourceException exception)
+      {
+       localizedString = null;
+      }
+    if (localizedString != null)
+      return localizedString;
+    for (CurrencyNameProvider p :
+          ServiceLoader.load(CurrencyNameProvider.class))
+      {
+       for (Locale loc : p.getAvailableLocales())
+         {
+           if (loc.equals(locale))
+             {
+               localizedString = p.getSymbol(currencyCode,
+                                             locale);
+               if (localizedString != null)
+                 return localizedString;
+             }
+         }
+      }
+    if (locale.equals(Locale.ROOT)) // Base case
+      return currencyCode;
+    return getSymbol(LocaleHelper.getFallbackLocale(locale));
   }
 
   /**
Index: java/util/Locale.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/util/Locale.java,v
retrieving revision 1.36
diff -u -3 -p -u -r1.36 Locale.java
--- java/util/Locale.java       3 Oct 2006 16:31:30 -0000       1.36
+++ java/util/Locale.java       2 Jan 2007 00:44:48 -0000
@@ -161,6 +161,11 @@ public final class Locale implements Ser
   /** Locale which represents the French speaking portion of Canada. */
   public static final Locale CANADA_FRENCH = getLocale("fr", "CA");
 
+  /** The root locale, used as the base case in lookups by
+   *  locale-sensitive operations.
+   */
+  public static final Locale ROOT = new Locale("","","");
+
   /**
    * Compatible with JDK 1.1+.
    */
Index: java/util/spi/CurrencyNameProvider.java
===================================================================
RCS file: java/util/spi/CurrencyNameProvider.java
diff -N java/util/spi/CurrencyNameProvider.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/util/spi/CurrencyNameProvider.java     2 Jan 2007 00:44:48 -0000
@@ -0,0 +1,100 @@
+/* CurrencyNameProvider.java -- Providers of localized currency symbols
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.util.spi;
+
+import java.util.Locale;
+
+/**
+ * A [EMAIL PROTECTED] CurrencyNameProvider} provides localized
+ * versions of the symbols that represent a particular
+ * currency.  Note that currency symbols are regarded
+ * as names, and thus a <code>null</code> value may
+ * be returned, which should be treated as a lack of
+ * support for the specified [EMAIL PROTECTED] Locale}.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.6
+ */
+public abstract class CurrencyNameProvider
+  extends LocaleServiceProvider
+{
+
+  /**
+   * Constructs a new [EMAIL PROTECTED] CurrencyNameProvider}.
+   * Provided for implicit invocation by subclasses.
+   */
+  protected CurrencyNameProvider()
+  {
+  }
+
+  /**
+   * <p>
+   * This method returns the symbol which precedes or follows a
+   * value in this particular currency.  The returned value is
+   * the symbol used to denote the currency in the specified locale.
+   * </p>
+   * <p>
+   * For example, a supplied locale may specify a different symbol
+   * for the currency, due to conflicts with its own currency.
+   * This would be the case with the American currency, the dollar.
+   * Locales that also use a dollar-based currency (e.g. Canada, Australia)
+   * need to differentiate the American dollar using 'US$' rather than '$'.
+   * So, supplying one of these locales to <code>getSymbol()</code> would
+   * return this value, rather than the standard '$'.
+   * </p>
+   * <p>
+   * In cases where there is no such symbol for a particular currency,
+   * <code>null</code> should be returned.
+   * </p>
+   *
+   * @param currencyCode the ISO 4217 currency code, consisting
+   *                     of three uppercase letters from 'A' to 'Z'
+   * @param locale the locale to express the symbol in.
+   * @return the currency symbol, or <code>null</code> if one is
+   *         unavailable.
+   * @throws NullPointerException if the locale is null.
+   * @throws IllegalArgumentException if the currency code is
+   *                                  not in the correct format
+   *                                  or the locale is not one
+   *                                  returned by
+   *                                  [EMAIL PROTECTED] getAvailableLocales()}
+   * @see java.util.Currency#getSymbol(java.util.Locale)
+   */
+  public abstract String getSymbol(String currencyCode, Locale locale);
+
+}
Index: java/util/spi/LocaleServiceProvider.java
===================================================================
RCS file: java/util/spi/LocaleServiceProvider.java
diff -N java/util/spi/LocaleServiceProvider.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/util/spi/LocaleServiceProvider.java    2 Jan 2007 00:44:48 -0000
@@ -0,0 +1,125 @@
+/* LocaleServiceProvider.java -- Superclass of locale SPIs
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.util.spi;
+
+import java.util.Locale;
+
+/**
+ * <p>
+ * This is the superclass of all the [EMAIL PROTECTED] Locale} service
+ * provider interfaces or SPIs.  The locale SPIs are used
+ * to allow for the provision of additional support for
+ * locale-specific data.  The runtime environment has its
+ * own collection of locale data, but these interfaces allow
+ * this to be extended by external classes.
+ * </p>
+ * <p>
+ * Service providers are created as concrete implementations
+ * of these interfaces, and accessed using the extension
+ * mechanism, realised by [EMAIL PROTECTED] ServiceLoader}.  When a factory
+ * method of one of the locale-specific classes (such as
+ * [EMAIL PROTECTED] java.text.DateFormatSymbols} or [EMAIL PROTECTED] 
java.util.Currency})
+ * is called, the runtime environment is first asked to
+ * provide data for the specified locale.  If the runtime
+ * environment fails to provide this, then the offer is
+ * made to service providers which implement the appropriate
+ * interface.
+ * </p>
+ * <p>
+ * Each provider implements the method specified by this
+ * class, [EMAIL PROTECTED] #getAvailableLocales()}.  This method is
+ * called first to determine whether the provider will be of
+ * any use in providing data for the specified locale.  If
+ * a provider is found to be capable, then a more specific
+ * method appropriate to the class requiring the data will
+ * be called.  In the case of [EMAIL PROTECTED] java.text.DateFormatSymbols},
+ * this would be
+ * [EMAIL PROTECTED] java.text.spi.DateFormatSymbols#getInstance(Locale)}.
+ * </p>
+ * <p>
+ * If neither a service provider nor the runtime environment
+ * itself can fulfill the request, a fallback procedure is
+ * engaged.  The locale is modified by applying the first
+ * applicable rule:
+ * </p>
+ * <ol>
+ * <li>If the variant contains a <code>'_'</code>, then
+ * this and everything following it is trimmed.</li>
+ * <li>If the variant is non-empty, it is converted to
+ * an empty string.</li>
+ * <li>If the country is non-empty, it is converted to
+ * an empty string.</li>
+ * <li>If the language is non-empty, it is converted to
+ * an empty string.</li>
+ * </ol>
+ * <p>
+ * The modified locale is then used to start the same
+ * process again.  The root locale (@link java.util.Locale#ROOT}
+ * must be supported by the runtime environment in order
+ * to terminate this cycle.
+ * </p>
+ * <p>
+ * Note that any names returned by the providers may
+ * be <code>null</code>.  Returning a <code>null</code>
+ * name is considered equivalent to not supporting a
+ * particular locale.
+ * </p>
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.6
+ */
+public abstract class LocaleServiceProvider
+{
+
+  /**
+   * Constructs a new [EMAIL PROTECTED] LocaleServiceProvider}.
+   * Provided for implicit invocation by subclasses.
+   */
+  protected LocaleServiceProvider()
+  {
+  }
+
+  /**
+   * Returns an array of [EMAIL PROTECTED] Locale} instances,
+   * for which the provider can supply localized data.
+   *
+   * @return an array of supported locales.
+   */
+  public abstract Locale[] getAvailableLocales();
+
+}
Index: java/util/spi/package.html
===================================================================
RCS file: java/util/spi/package.html
diff -N java/util/spi/package.html
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/util/spi/package.html  2 Jan 2007 00:44:48 -0000
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.util.spi package.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - java.util.spi</title></head>
+
+<body>
+
+<p>
+A series of service provider interfaces for use by the
+classes in <code>java.util</code>.
+</p>
+<p><span style="font-weight: bold;">Since</span>: 1.6</p>
+</body>
+</html>

Attachment: signature.asc
Description: Digital signature

Reply via email to