Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java
38918 views
/*1* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.util.locale.provider;2627import java.security.AccessController;28import java.security.PrivilegedActionException;29import java.security.PrivilegedExceptionAction;30import java.text.BreakIterator;31import java.text.Collator;32import java.text.DateFormat;33import java.text.DateFormatSymbols;34import java.text.DecimalFormatSymbols;35import java.text.NumberFormat;36import java.text.spi.BreakIteratorProvider;37import java.text.spi.CollatorProvider;38import java.text.spi.DateFormatProvider;39import java.text.spi.DateFormatSymbolsProvider;40import java.text.spi.DecimalFormatSymbolsProvider;41import java.text.spi.NumberFormatProvider;42import java.util.Locale;43import java.util.Map;44import java.util.ServiceLoader;45import java.util.concurrent.ConcurrentHashMap;46import java.util.concurrent.ConcurrentMap;47import java.util.spi.CalendarDataProvider;48import java.util.spi.CalendarNameProvider;49import java.util.spi.CurrencyNameProvider;50import java.util.spi.LocaleNameProvider;51import java.util.spi.LocaleServiceProvider;52import java.util.spi.TimeZoneNameProvider;5354/**55* LocaleProviderAdapter implementation for the installed SPI implementations.56*57* @author Naoto Sato58* @author Masayoshi Okutsu59*/60public class SPILocaleProviderAdapter extends AuxLocaleProviderAdapter {6162/**63* Returns the type of this LocaleProviderAdapter64*/65@Override66public LocaleProviderAdapter.Type getAdapterType() {67return LocaleProviderAdapter.Type.SPI;68}6970@Override71protected <P extends LocaleServiceProvider> P findInstalledProvider(final Class<P> c) {72try {73return AccessController.doPrivileged(new PrivilegedExceptionAction<P>() {74@Override75@SuppressWarnings("unchecked")76public P run() {77P delegate = null;7879for (LocaleServiceProvider provider : ServiceLoader.loadInstalled(c)) {80if (delegate == null) {81try {82delegate =83(P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() +84"$" +85c.getSimpleName() +86"Delegate")87.newInstance();88} catch (ClassNotFoundException |89InstantiationException |90IllegalAccessException e) {91LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString());92return null;93}94}9596((Delegate)delegate).addImpl(provider);97}98return delegate;99}100});101} catch (PrivilegedActionException e) {102LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString());103}104return null;105}106107/*108* Delegate interface. All the implementations have to have the class name109* following "<provider class name>Delegate" convention.110*/111interface Delegate<P extends LocaleServiceProvider> {112public void addImpl(P impl);113public P getImpl(Locale locale);114}115116/*117* Obtain the real SPI implementation, using locale fallback118*/119private static <P extends LocaleServiceProvider> P getImpl(Map<Locale, P> map, Locale locale) {120for (Locale l : LocaleServiceProviderPool.getLookupLocales(locale)) {121P ret = map.get(l);122if (ret != null) {123return ret;124}125}126return null;127}128129/*130* Delegates for the actual SPI implementations.131*/132static class BreakIteratorProviderDelegate extends BreakIteratorProvider133implements Delegate<BreakIteratorProvider> {134private ConcurrentMap<Locale, BreakIteratorProvider> map = new ConcurrentHashMap<>();135136@Override137public void addImpl(BreakIteratorProvider impl) {138for (Locale l : impl.getAvailableLocales()) {139map.putIfAbsent(l, impl);140}141}142143@Override144public BreakIteratorProvider getImpl(Locale locale) {145return SPILocaleProviderAdapter.getImpl(map, locale);146}147148@Override149public Locale[] getAvailableLocales() {150return map.keySet().toArray(new Locale[0]);151}152153@Override154public boolean isSupportedLocale(Locale locale) {155return map.containsKey(locale);156}157158@Override159public BreakIterator getWordInstance(Locale locale) {160BreakIteratorProvider bip = getImpl(locale);161assert bip != null;162return bip.getWordInstance(locale);163}164165@Override166public BreakIterator getLineInstance(Locale locale) {167BreakIteratorProvider bip = getImpl(locale);168assert bip != null;169return bip.getLineInstance(locale);170}171172@Override173public BreakIterator getCharacterInstance(Locale locale) {174BreakIteratorProvider bip = getImpl(locale);175assert bip != null;176return bip.getCharacterInstance(locale);177}178179@Override180public BreakIterator getSentenceInstance(Locale locale) {181BreakIteratorProvider bip = getImpl(locale);182assert bip != null;183return bip.getSentenceInstance(locale);184}185186}187188static class CollatorProviderDelegate extends CollatorProvider implements Delegate<CollatorProvider> {189private ConcurrentMap<Locale, CollatorProvider> map = new ConcurrentHashMap<>();190191@Override192public void addImpl(CollatorProvider impl) {193for (Locale l : impl.getAvailableLocales()) {194map.putIfAbsent(l, impl);195}196}197198@Override199public CollatorProvider getImpl(Locale locale) {200return SPILocaleProviderAdapter.getImpl(map, locale);201}202203@Override204public Locale[] getAvailableLocales() {205return map.keySet().toArray(new Locale[0]);206}207208@Override209public boolean isSupportedLocale(Locale locale) {210return map.containsKey(locale);211}212213@Override214public Collator getInstance(Locale locale) {215CollatorProvider cp = getImpl(locale);216assert cp != null;217return cp.getInstance(locale);218}219}220221static class DateFormatProviderDelegate extends DateFormatProvider222implements Delegate<DateFormatProvider> {223private ConcurrentMap<Locale, DateFormatProvider> map = new ConcurrentHashMap<>();224225@Override226public void addImpl(DateFormatProvider impl) {227for (Locale l : impl.getAvailableLocales()) {228map.putIfAbsent(l, impl);229}230}231232@Override233public DateFormatProvider getImpl(Locale locale) {234return SPILocaleProviderAdapter.getImpl(map, locale);235}236237@Override238public Locale[] getAvailableLocales() {239return map.keySet().toArray(new Locale[0]);240}241242@Override243public boolean isSupportedLocale(Locale locale) {244return map.containsKey(locale);245}246247@Override248public DateFormat getTimeInstance(int style, Locale locale) {249DateFormatProvider dfp = getImpl(locale);250assert dfp != null;251return dfp.getTimeInstance(style, locale);252}253254@Override255public DateFormat getDateInstance(int style, Locale locale) {256DateFormatProvider dfp = getImpl(locale);257assert dfp != null;258return dfp.getDateInstance(style, locale);259}260261@Override262public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {263DateFormatProvider dfp = getImpl(locale);264assert dfp != null;265return dfp.getDateTimeInstance(dateStyle, timeStyle, locale);266}267}268269static class DateFormatSymbolsProviderDelegate extends DateFormatSymbolsProvider270implements Delegate<DateFormatSymbolsProvider> {271private ConcurrentMap<Locale, DateFormatSymbolsProvider> map = new ConcurrentHashMap<>();272273@Override274public void addImpl(DateFormatSymbolsProvider impl) {275for (Locale l : impl.getAvailableLocales()) {276map.putIfAbsent(l, impl);277}278}279280@Override281public DateFormatSymbolsProvider getImpl(Locale locale) {282return SPILocaleProviderAdapter.getImpl(map, locale);283}284285@Override286public Locale[] getAvailableLocales() {287return map.keySet().toArray(new Locale[0]);288}289290@Override291public boolean isSupportedLocale(Locale locale) {292return map.containsKey(locale);293}294295@Override296public DateFormatSymbols getInstance(Locale locale) {297DateFormatSymbolsProvider dfsp = getImpl(locale);298assert dfsp != null;299return dfsp.getInstance(locale);300}301}302303static class DecimalFormatSymbolsProviderDelegate extends DecimalFormatSymbolsProvider304implements Delegate<DecimalFormatSymbolsProvider> {305private ConcurrentMap<Locale, DecimalFormatSymbolsProvider> map = new ConcurrentHashMap<>();306307@Override308public void addImpl(DecimalFormatSymbolsProvider impl) {309for (Locale l : impl.getAvailableLocales()) {310map.putIfAbsent(l, impl);311}312}313314@Override315public DecimalFormatSymbolsProvider getImpl(Locale locale) {316return SPILocaleProviderAdapter.getImpl(map, locale);317}318319@Override320public Locale[] getAvailableLocales() {321return map.keySet().toArray(new Locale[0]);322}323324@Override325public boolean isSupportedLocale(Locale locale) {326return map.containsKey(locale);327}328329@Override330public DecimalFormatSymbols getInstance(Locale locale) {331DecimalFormatSymbolsProvider dfsp = getImpl(locale);332assert dfsp != null;333return dfsp.getInstance(locale);334}335}336337static class NumberFormatProviderDelegate extends NumberFormatProvider338implements Delegate<NumberFormatProvider> {339private ConcurrentMap<Locale, NumberFormatProvider> map = new ConcurrentHashMap<>();340341@Override342public void addImpl(NumberFormatProvider impl) {343for (Locale l : impl.getAvailableLocales()) {344map.putIfAbsent(l, impl);345}346}347348@Override349public NumberFormatProvider getImpl(Locale locale) {350return SPILocaleProviderAdapter.getImpl(map, locale);351}352353@Override354public Locale[] getAvailableLocales() {355return map.keySet().toArray(new Locale[0]);356}357358@Override359public boolean isSupportedLocale(Locale locale) {360return map.containsKey(locale);361}362363@Override364public NumberFormat getCurrencyInstance(Locale locale) {365NumberFormatProvider nfp = getImpl(locale);366assert nfp != null;367return nfp.getCurrencyInstance(locale);368}369370@Override371public NumberFormat getIntegerInstance(Locale locale) {372NumberFormatProvider nfp = getImpl(locale);373assert nfp != null;374return nfp.getIntegerInstance(locale);375}376377@Override378public NumberFormat getNumberInstance(Locale locale) {379NumberFormatProvider nfp = getImpl(locale);380assert nfp != null;381return nfp.getNumberInstance(locale);382}383384@Override385public NumberFormat getPercentInstance(Locale locale) {386NumberFormatProvider nfp = getImpl(locale);387assert nfp != null;388return nfp.getPercentInstance(locale);389}390}391392static class CalendarDataProviderDelegate extends CalendarDataProvider393implements Delegate<CalendarDataProvider> {394private ConcurrentMap<Locale, CalendarDataProvider> map = new ConcurrentHashMap<>();395396@Override397public void addImpl(CalendarDataProvider impl) {398for (Locale l : impl.getAvailableLocales()) {399map.putIfAbsent(l, impl);400}401}402403@Override404public CalendarDataProvider getImpl(Locale locale) {405return SPILocaleProviderAdapter.getImpl(map, locale);406}407408@Override409public Locale[] getAvailableLocales() {410return map.keySet().toArray(new Locale[0]);411}412413@Override414public boolean isSupportedLocale(Locale locale) {415return map.containsKey(locale);416}417418@Override419public int getFirstDayOfWeek(Locale locale) {420CalendarDataProvider cdp = getImpl(locale);421assert cdp != null;422return cdp.getFirstDayOfWeek(locale);423}424425@Override426public int getMinimalDaysInFirstWeek(Locale locale) {427CalendarDataProvider cdp = getImpl(locale);428assert cdp != null;429return cdp.getMinimalDaysInFirstWeek(locale);430}431}432433static class CalendarNameProviderDelegate extends CalendarNameProvider434implements Delegate<CalendarNameProvider> {435private ConcurrentMap<Locale, CalendarNameProvider> map = new ConcurrentHashMap<>();436437@Override438public void addImpl(CalendarNameProvider impl) {439for (Locale l : impl.getAvailableLocales()) {440map.putIfAbsent(l, impl);441}442}443444@Override445public CalendarNameProvider getImpl(Locale locale) {446return SPILocaleProviderAdapter.getImpl(map, locale);447}448449@Override450public Locale[] getAvailableLocales() {451return map.keySet().toArray(new Locale[0]);452}453454@Override455public boolean isSupportedLocale(Locale locale) {456return map.containsKey(locale);457}458459@Override460public String getDisplayName(String calendarType,461int field, int value,462int style, Locale locale) {463CalendarNameProvider cdp = getImpl(locale);464assert cdp != null;465return cdp.getDisplayName(calendarType, field, value, style, locale);466}467468@Override469public Map<String, Integer> getDisplayNames(String calendarType,470int field, int style,471Locale locale) {472CalendarNameProvider cdp = getImpl(locale);473assert cdp != null;474return cdp.getDisplayNames(calendarType, field, style, locale);475}476}477478static class CurrencyNameProviderDelegate extends CurrencyNameProvider479implements Delegate<CurrencyNameProvider> {480private ConcurrentMap<Locale, CurrencyNameProvider> map = new ConcurrentHashMap<>();481482@Override483public void addImpl(CurrencyNameProvider impl) {484for (Locale l : impl.getAvailableLocales()) {485map.putIfAbsent(l, impl);486}487}488489@Override490public CurrencyNameProvider getImpl(Locale locale) {491return SPILocaleProviderAdapter.getImpl(map, locale);492}493494@Override495public Locale[] getAvailableLocales() {496return map.keySet().toArray(new Locale[0]);497}498499@Override500public boolean isSupportedLocale(Locale locale) {501return map.containsKey(locale);502}503504@Override505public String getSymbol(String currencyCode, Locale locale) {506CurrencyNameProvider cnp = getImpl(locale);507assert cnp != null;508return cnp.getSymbol(currencyCode, locale);509}510511@Override512public String getDisplayName(String currencyCode, Locale locale) {513CurrencyNameProvider cnp = getImpl(locale);514assert cnp != null;515return cnp.getDisplayName(currencyCode, locale);516}517}518519static class LocaleNameProviderDelegate extends LocaleNameProvider520implements Delegate<LocaleNameProvider> {521private ConcurrentMap<Locale, LocaleNameProvider> map = new ConcurrentHashMap<>();522523@Override524public void addImpl(LocaleNameProvider impl) {525for (Locale l : impl.getAvailableLocales()) {526map.putIfAbsent(l, impl);527}528}529530@Override531public LocaleNameProvider getImpl(Locale locale) {532return SPILocaleProviderAdapter.getImpl(map, locale);533}534535@Override536public Locale[] getAvailableLocales() {537return map.keySet().toArray(new Locale[0]);538}539540@Override541public boolean isSupportedLocale(Locale locale) {542return map.containsKey(locale);543}544545@Override546public String getDisplayLanguage(String languageCode, Locale locale) {547LocaleNameProvider lnp = getImpl(locale);548assert lnp != null;549return lnp.getDisplayLanguage(languageCode, locale);550}551552@Override553public String getDisplayScript(String scriptCode, Locale locale) {554LocaleNameProvider lnp = getImpl(locale);555assert lnp != null;556return lnp.getDisplayScript(scriptCode, locale);557}558559@Override560public String getDisplayCountry(String countryCode, Locale locale) {561LocaleNameProvider lnp = getImpl(locale);562assert lnp != null;563return lnp.getDisplayCountry(countryCode, locale);564}565566@Override567public String getDisplayVariant(String variant, Locale locale) {568LocaleNameProvider lnp = getImpl(locale);569assert lnp != null;570return lnp.getDisplayVariant(variant, locale);571}572}573574static class TimeZoneNameProviderDelegate extends TimeZoneNameProvider575implements Delegate<TimeZoneNameProvider> {576private ConcurrentMap<Locale, TimeZoneNameProvider> map = new ConcurrentHashMap<>();577578@Override579public void addImpl(TimeZoneNameProvider impl) {580for (Locale l : impl.getAvailableLocales()) {581map.putIfAbsent(l, impl);582}583}584585@Override586public TimeZoneNameProvider getImpl(Locale locale) {587return SPILocaleProviderAdapter.getImpl(map, locale);588}589590@Override591public Locale[] getAvailableLocales() {592return map.keySet().toArray(new Locale[0]);593}594595@Override596public boolean isSupportedLocale(Locale locale) {597return map.containsKey(locale);598}599600@Override601public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {602TimeZoneNameProvider tznp = getImpl(locale);603assert tznp != null;604return tznp.getDisplayName(ID, daylight, style, locale);605}606607@Override608public String getGenericDisplayName(String ID, int style, Locale locale) {609TimeZoneNameProvider tznp = getImpl(locale);610assert tznp != null;611return tznp.getGenericDisplayName(ID, style, locale);612}613}614}615616617