1 /*
   2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.spi;
  27 
  28 import java.util.Locale;
  29 
  30 /**
  31  * <p>
  32  * This is the super class of all the locale sensitive service provider
  33  * interfaces (SPIs).
  34  * <p>
  35  * Locale sensitive  service provider interfaces are interfaces that
  36  * correspond to locale sensitive classes in the <code>java.text</code>
  37  * and <code>java.util</code> packages. The interfaces enable the
  38  * construction of locale sensitive objects and the retrieval of
  39  * localized names for these packages. Locale sensitive factory methods
  40  * and methods for name retrieval in the <code>java.text</code> and
  41  * <code>java.util</code> packages use implementations of the provider
  42  * interfaces to offer support for locales beyond the set of locales
  43  * supported by the Java runtime environment itself.
  44  *
  45  * <h3>Packaging of Locale Sensitive Service Provider Implementations</h3>
  46  * Implementations of these locale sensitive services can be made available
  47  * by adding them to the application's class path. A provider identifies itself with a
  48  * provider-configuration file in the resource directory META-INF/services,
  49  * using the fully qualified provider interface class name as the file name.
  50  * The file should contain a list of fully-qualified concrete provider class names,
  51  * one per line. A line is terminated by any one of a line feed ('\n'), a carriage
  52  * return ('\r'), or a carriage return followed immediately by a line feed. Space
  53  * and tab characters surrounding each name, as well as blank lines, are ignored.
  54  * The comment character is '#' ('\u0023'); on each line all characters following
  55  * the first comment character are ignored. The file must be encoded in UTF-8.
  56  * <p>
  57  * If a particular concrete provider class is named in more than one configuration
  58  * file, or is named in the same configuration file more than once, then the
  59  * duplicates will be ignored. The configuration file naming a particular provider
  60  * need not be in the same jar file or other distribution unit as the provider itself.
  61  * The provider must be accessible from the same class loader that was initially
  62  * queried to locate the configuration file; this is not necessarily the class loader
  63  * that loaded the file.
  64  * <p>
  65  * For example, an implementation of the
  66  * {@link java.text.spi.DateFormatProvider DateFormatProvider} class should
  67  * take the form of a jar file which contains the file:
  68  * <pre>
  69  * META-INF/services/java.text.spi.DateFormatProvider
  70  * </pre>
  71  * And the file <code>java.text.spi.DateFormatProvider</code> should have
  72  * a line such as:
  73  * <pre>
  74  * <code>com.foo.DateFormatProviderImpl</code>
  75  * </pre>
  76  * which is the fully qualified class name of the class implementing
  77  * <code>DateFormatProvider</code>.
  78  * <h4>Invocation of Locale Sensitive Services</h4>
  79  * <p>
  80  * Locale sensitive factory methods and methods for name retrieval in the
  81  * <code>java.text</code> and <code>java.util</code> packages invoke
  82  * service provider methods when needed to support the requested locale.
  83  * The methods first check whether the Java runtime environment itself
  84  * supports the requested locale, and use its support if available.
  85  * Otherwise, they call the {@link #isSupportedLocale(Locale) isSupportedLocale}
  86  * methods of installed providers for the appropriate interface to find one that
  87  * supports the requested locale. If such a provider is found, its other
  88  * methods are called to obtain the requested object or name.  When checking
  89  * whether a locale is supported, the <a href="../Locale.html#def_extensions">
  90  * locale's extensions</a> are ignored by default. (If locale's extensions should
  91  * also be checked, the {@code isSupportedLocale} method must be overridden.)
  92  * If neither the Java runtime environment itself nor an installed provider
  93  * supports the requested locale, the methods go through a list of candidate
  94  * locales and repeat the availability check for each until a match is found.
  95  * The algorithm used for creating a list of candidate locales is same as
  96  * the one used by <code>ResourceBundle</code> by default (see
  97  * {@link java.util.ResourceBundle.Control#getCandidateLocales getCandidateLocales}
  98  * for the details).  Even if a locale is resolved from the candidate list,
  99  * methods that return requested objects or names are invoked with the original
 100  * requested locale including {@code Locale} extensions. The Java runtime
 101  * environment must support the root locale for all locale sensitive services in
 102  * order to guarantee that this process terminates.
 103  * <p>
 104  * Providers of names (but not providers of other objects) are allowed to
 105  * return null for some name requests even for locales that they claim to
 106  * support by including them in their return value for
 107  * <code>getAvailableLocales</code>. Similarly, the Java runtime
 108  * environment itself may not have all names for all locales that it
 109  * supports. This is because the sets of objects for which names are
 110  * requested can be large and vary over time, so that it's not always
 111  * feasible to cover them completely. If the Java runtime environment or a
 112  * provider returns null instead of a name, the lookup will proceed as
 113  * described above as if the locale was not supported.
 114  * <p>
 115  * The search order of locale sensitive services can
 116  * be configured by using the "java.locale.providers" system property.
 117  * This system property declares the user's preferred order for looking up
 118  * the locale sensitive services separated by a comma. It is only read at
 119  * the Java runtime startup, so the later call to System.setProperty() won't
 120  * affect the order.
 121  * <p>
 122  * Java Runtime Environment provides the following four locale providers:
 123  * <ul>
 124  * <li> "CLDR": A provider based on Unicode Consortium's
 125  * <a href="http://cldr.unicode.org/">CLDR Project</a>.
 126  * <li> "JRE": represents the locale sensitive services that is compatible
 127  * with the prior JDK releases (same with JDK8's "JRE").
 128  * <li> "SPI": represents the locale sensitive services implementing the subclasses of
 129  * this {@code LocaleServiceProvider} class.
 130  * <li> "HOST": A provider that reflects the user's custom settings in the
 131  * underlying operating system. This provider may not be available, depending
 132  * on the Java Runtime Environment implementation.
 133  * </ul>
 134  * <p>
 135  * For example, if the following is specified in the property:
 136  * <pre>
 137  * java.locale.providers=SPI,CLDR,JRE
 138  * </pre>
 139  * the locale sensitive services in the SPI providers are looked up first. If the
 140  * desired locale sensitive service is not available, then the runtime looks for CLDR,
 141  * JRE in that order.
 142  * <p>
 143  * The default order for looking up the preferred locale providers is "CLDR,JRE,SPI",
 144  * so specifying "CLDR,JRE,SPI" is identical to the default behavior.
 145  *
 146  * @since        1.6
 147  */
 148 public abstract class LocaleServiceProvider {
 149 
 150     private static Void checkPermission() {
 151         SecurityManager sm = System.getSecurityManager();
 152         if (sm != null) {
 153             sm.checkPermission(new RuntimePermission("localeServiceProvider"));
 154         }
 155         return null;
 156     }
 157     private LocaleServiceProvider(Void ignore) { }
 158 
 159     /**
 160      * Initializes a new locale service provider.
 161      *
 162      * @throws  SecurityException
 163      *          If a security manager has been installed and it denies
 164      *          {@link RuntimePermission RuntimePermission("localeServiceProvider")}
 165      */
 166     protected LocaleServiceProvider() {
 167         this(checkPermission());
 168     }
 169 
 170     /**
 171      * Returns an array of all locales for which this locale service provider
 172      * can provide localized objects or names. This information is used to
 173      * compose {@code getAvailableLocales()} values of the locale-dependent
 174      * services, such as {@code DateFormat.getAvailableLocales()}.
 175      *
 176      * <p>The array returned by this method should not include two or more
 177      * {@code Locale} objects only differing in their extensions.
 178      *
 179      * @return An array of all locales for which this locale service provider
 180      * can provide localized objects or names.
 181      */
 182     public abstract Locale[] getAvailableLocales();
 183 
 184     /**
 185      * Returns {@code true} if the given {@code locale} is supported by
 186      * this locale service provider. The given {@code locale} may contain
 187      * <a href="../Locale.html#def_extensions">extensions</a> that should be
 188      * taken into account for the support determination.
 189      *
 190      * <p>The default implementation returns {@code true} if the given {@code locale}
 191      * is equal to any of the available {@code Locale}s returned by
 192      * {@link #getAvailableLocales()} with ignoring any extensions in both the
 193      * given {@code locale} and the available locales. Concrete locale service
 194      * provider implementations should override this method if those
 195      * implementations are {@code Locale} extensions-aware. For example,
 196      * {@code DecimalFormatSymbolsProvider} implementations will need to check
 197      * extensions in the given {@code locale} to see if any numbering system is
 198      * specified and can be supported. However, {@code CollatorProvider}
 199      * implementations may not be affected by any particular numbering systems,
 200      * and in that case, extensions for numbering systems should be ignored.
 201      *
 202      * @param locale a {@code Locale} to be tested
 203      * @return {@code true} if the given {@code locale} is supported by this
 204      *         provider; {@code false} otherwise.
 205      * @throws NullPointerException
 206      *         if the given {@code locale} is {@code null}
 207      * @see Locale#hasExtensions()
 208      * @see Locale#stripExtensions()
 209      * @since 1.8
 210      */
 211     public boolean isSupportedLocale(Locale locale) {
 212         locale = locale.stripExtensions(); // throws NPE if locale == null
 213         for (Locale available : getAvailableLocales()) {
 214             if (locale.equals(available.stripExtensions())) {
 215                 return true;
 216 }
 217         }
 218         return false;
 219     }
 220 }