/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* An instance of this class holds a set of the third party implementations of a particular
* locale sensitive service, such as {@link java.util.spi.LocaleNameProvider}.
*
*/
public final class LocaleServiceProviderPool {
/**
* A Map that holds singleton instances of this class. Each instance holds a
* set of provider implementations of a particular locale sensitive service.
*/
private static ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProviderPool> poolOfPools =
new ConcurrentHashMap<>();
/**
* A Set containing locale service providers that implement the
* specified provider SPI
*/
new LinkedHashSet<LocaleServiceProvider>();
/**
* A Map that retains Locale->provider mapping
*/
/**
* Available locales for this locale sensitive service. This also contains
* JRE's available locales
*/
/**
* Available locales within this JRE. Currently this is declared as
* static. This could be non-static later, so that they could have
* different sets for each locale sensitive services.
*/
/**
* Provider locales for this locale sensitive service.
*/
/**
* Special locale for ja_JP with Japanese calendar
*/
/**
* Special locale for th_TH with Thai numbering system
*/
/**
* A factory method that returns a singleton instance
*/
public static LocaleServiceProviderPool getPool(Class<? extends LocaleServiceProvider> providerClass) {
}
}
return pool;
}
/**
* The sole constructor.
*
* @param c class of the locale sensitive service
*/
try {
}
return null;
}
});
} catch (PrivilegedActionException e) {
}
}
}
/**
* Lazy loaded set of available locales.
* Loading all locales is a very long operation.
*
* We know "providerClasses" contains classes that extends LocaleServiceProvider,
* but generic array creation is not allowed, thus the "unchecked" warning
* is suppressed here.
*/
private static class AllAvailableLocales {
/**
* Available locales for all locale sensitive services.
* This also contains JRE's available locales
*/
static {
@SuppressWarnings("unchecked")
// Normalize locales for look up
}
}
}
}
/**
* Returns an array of available locales for all the provider classes.
* This array is a merged array of all the locales that are provided by each
* provider, including the JRE.
*
* @return an array of the available locales for all provider classes
*/
}
/**
* Returns an array of available locales. This array is a
* merged array of all the locales that are provided by each
* provider, including the JRE.
*
* @return an array of the available locales
*/
if (availableLocales == null) {
if (hasProviders()) {
}
}
return tmp;
}
/**
* Returns an array of available locales (already normalized
* for service lookup) from providers.
* Note that this method does not return a defensive copy.
*
* @return list of the provider locales
*/
if (providerLocales == null) {
if (hasProviders()) {
}
}
}
}
return providerLocales;
}
/**
* Returns whether any provider for this locale sensitive
* service is available or not.
*
* @return true if any provider is available
*/
public boolean hasProviders() {
}
/**
* Returns an array of available locales (already normalized for
* service lookup) supported by the JRE.
* Note that this method does not return a defensive copy.
*
* @return list of the available JRE locales
*/
if (availableJRELocales == null) {
synchronized (LocaleServiceProviderPool.class) {
if (availableJRELocales == null) {
}
}
}
}
return availableJRELocales;
}
/**
* Returns whether the given locale is supported by the JRE.
*
* @param locale the locale to test.
* @return true, if the locale is supported by the JRE. false
* otherwise.
*/
}
/**
* Returns the provider's localized object for the specified
* locale.
*
* @param getter an object on which getObject() method
* is called to obtain the provider's instance.
* @param locale the given locale that is used as the starting one
* @param params provider specific parameters
* @return provider's instance, or null.
*/
}
/**
* Returns the provider's localized name for the specified
* locale.
*
* @param getter an object on which getObject() method
* is called to obtain the provider's instance.
* @param locale the given locale that is used as the starting one
* @param bundle JRE resource bundle that contains
* the localized names, or null for localized objects.
* @param key the key string if bundle is supplied, otherwise null.
* @param params provider specific parameters
* @return provider's instance, or null.
*/
}
/**
* Returns the provider's localized name for the specified
* locale.
*
* @param getter an object on which getObject() method
* is called to obtain the provider's instance.
* @param locale the given locale that is used as the starting one
* @param bundleKey JRE specific bundle key. e.g., "USD" is for currency
symbol and "usd" is for currency display name in the JRE bundle.
* @param bundle JRE resource bundle that contains
* the localized names, or null for localized objects.
* @param key the key string if bundle is supplied, otherwise null.
* @param params provider specific parameters
* @return provider's instance, or null.
*/
}
boolean isObjectProvider,
if (hasProviders()) {
}
S providersObj = null;
// check whether a provider has an implementation that's closer
// to the requested locale than the bundle we've found (for
// localized names), or Java runtime's supported locale
// (for localized objects)
if (bundleLocale != null) {
break;
}
} else {
if (isJRESupported(current)) {
break;
}
}
// It is safe to assume that findProvider() returns the instance of type P.
@SuppressWarnings("unchecked")
if (providersObj != null) {
return providersObj;
} else if (isObjectProvider) {
"A locale sensitive service provider returned null for a localized objects, which should not happen. provider: " + lsp + " locale: " + locale);
}
}
}
}
// look up the JRE bundle and its parent chain. Only
// providers for localized names are checked hereafter.
// JRE has it.
return null;
} else {
// It is safe to assume that findProvider() returns the instance of type P.
@SuppressWarnings("unchecked")
if (providersObj != null) {
return providersObj;
}
}
}
// try parent bundle
}
}
// not found.
return null;
}
/**
* Returns a locale service provider instance that supports
* the specified locale.
*
* @param locale the given locale
* @return the provider, or null if there is
* no provider available.
*/
if (!hasProviders()) {
return null;
}
return provider;
}
} else {
// normalize
return (providerInCache != null ?
lsp);
}
}
}
}
return null;
}
/**
* Returns a list of candidate locales for service look up.
* @param locale the input locale
* @return the list of candiate locales for the given locale
*/
// Note: We currently use the default implementation of
// ResourceBundle.Control.getCandidateLocales. The result
// returned by getCandidateLocales are already normalized
// (no extensions) for service look up.
return lookupLocales;
}
/**
* Returns an instance of Locale used for service look up.
* The result Locale has no extensions except for ja_JP_JP
* and th_TH_TH
*
* @param locale the locale
* @return the locale used for service look up
*/
if (!extensions.isEmpty()
// remove extensions
try {
} catch (IllformedLocaleException e) {
// A Locale with non-empty extensions
// should have well-formed fields except
// for ja_JP_JP and th_TH_TH. Therefore,
// it should never enter in this catch clause.
// Fallback - script field will be lost.
}
}
return lookupLocale;
}
/**
* A dummy locale service provider that indicates there is no
* provider available
*/
throw new RuntimeException("Should not get called.");
}
}
/**
* An interface to get a localized object for each locale sensitve
* service class.
*/
public interface LocalizedObjectGetter<P, S> {
/**
* Returns an object from the provider
*
* @param lsp the provider
* @param locale the locale
* @param key key string to localize, or null if the provider is not
* a name provider
* @param params provider specific params
* @return localized object from the provider
*/
}
}