< prev index next >

src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java

Print this page
rev 59397 : imported patch 8245241
   1 /*
   2  * Copyright (c) 2012, 2018, 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


  26 package sun.util.locale.provider;
  27 
  28 import java.security.AccessController;
  29 import java.security.PrivilegedActionException;
  30 import java.security.PrivilegedExceptionAction;
  31 import java.text.BreakIterator;
  32 import java.text.Collator;
  33 import java.text.DateFormat;
  34 import java.text.DateFormatSymbols;
  35 import java.text.DecimalFormatSymbols;
  36 import java.text.NumberFormat;
  37 import java.text.spi.BreakIteratorProvider;
  38 import java.text.spi.CollatorProvider;
  39 import java.text.spi.DateFormatProvider;
  40 import java.text.spi.DateFormatSymbolsProvider;
  41 import java.text.spi.DecimalFormatSymbolsProvider;
  42 import java.text.spi.NumberFormatProvider;
  43 import java.util.Arrays;
  44 import java.util.Locale;
  45 import java.util.Map;

  46 import java.util.ServiceLoader;
  47 import java.util.concurrent.ConcurrentHashMap;
  48 import java.util.concurrent.ConcurrentMap;
  49 import java.util.spi.CalendarDataProvider;
  50 import java.util.spi.CalendarNameProvider;
  51 import java.util.spi.CurrencyNameProvider;
  52 import java.util.spi.LocaleNameProvider;
  53 import java.util.spi.LocaleServiceProvider;
  54 import java.util.spi.TimeZoneNameProvider;
  55 
  56 /**
  57  * LocaleProviderAdapter implementation for the installed SPI implementations.
  58  *
  59  * @author Naoto Sato
  60  * @author Masayoshi Okutsu
  61  */
  62 public class SPILocaleProviderAdapter extends AuxLocaleProviderAdapter {
  63 
  64     /**
  65      * Returns the type of this LocaleProviderAdapter
  66      */
  67     @Override
  68     public LocaleProviderAdapter.Type getAdapterType() {
  69         return LocaleProviderAdapter.Type.SPI;
  70     }
  71 
  72     @Override
  73     protected <P extends LocaleServiceProvider> P findInstalledProvider(final Class<P> c) {
  74         try {
  75             return AccessController.doPrivileged(new PrivilegedExceptionAction<P>() {
  76                 @Override
  77                 @SuppressWarnings(value={"unchecked", "deprecation"})
  78                 public P run() {
  79                     P delegate = null;
  80 
  81                     for (LocaleServiceProvider provider :
  82                              ServiceLoader.load(c, ClassLoader.getSystemClassLoader())) {
  83                         if (delegate == null) {
  84                             try {
  85                                 delegate =
  86                                     (P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() +
  87                                               "$" +
  88                                               c.getSimpleName() +
  89                                               "Delegate")
  90                                               .newInstance();
  91                             }  catch (ClassNotFoundException |
  92                                       InstantiationException |
  93                                       IllegalAccessException e) {
  94                                 LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString());
  95                                 return null;
  96                             }
  97                         }
  98 
  99                         ((Delegate)delegate).addImpl(provider);
 100                     }
 101                     return delegate;
 102                 }
 103             });
 104         }  catch (PrivilegedActionException e) {
 105             LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString());

 106         }
 107         return null;
 108     }
 109 
 110     /*
 111      * Delegate interface. All the implementations have to have the class name
 112      * following "<provider class name>Delegate" convention.
 113      */
 114     private interface Delegate<P extends LocaleServiceProvider> {
 115         default public void addImpl(P impl) {
 116             for (Locale l : impl.getAvailableLocales()) {
 117                 getDelegateMap().putIfAbsent(l, impl);
 118             }
 119         }
 120 
 121         /*
 122          * Obtain the real SPI implementation, using locale fallback
 123          */
 124         default public P getImpl(Locale locale) {
 125             for (Locale l : LocaleServiceProviderPool.getLookupLocales(locale.stripExtensions())) {
 126                 P ret = getDelegateMap().get(l);
 127                 if (ret != null) {
 128                     return ret;
 129                 }
 130             }
 131             return null;
 132         }
 133 
 134         public Map<Locale, P> getDelegateMap();
 135 
 136         default public Locale[] getAvailableLocalesDelegate() {
 137             return getDelegateMap().keySet().stream().toArray(Locale[]::new);
 138         }
 139 
 140         default public boolean isSupportedLocaleDelegate(Locale locale) {
 141             Map<Locale, P> map = getDelegateMap();
 142             Locale override = CalendarDataUtility.findRegionOverride(locale);
 143 
 144             // First, call the method with extensions (if any)
 145             P impl = map.get(override);
 146             if (impl != null) {
 147                 return impl.isSupportedLocale(override);
 148             } else {
 149                 // The default behavior
 150                 Locale overrideNoExt = override.stripExtensions();
 151                 impl = map.get(overrideNoExt);
 152                 if (impl != null) {
 153                     return Arrays.stream(impl.getAvailableLocales())
 154                                 .anyMatch(overrideNoExt::equals);
 155                 }
 156             }
 157 
 158             return false;
 159         }
 160     }


   1 /*
   2  * Copyright (c) 2012, 2020, 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


  26 package sun.util.locale.provider;
  27 
  28 import java.security.AccessController;
  29 import java.security.PrivilegedActionException;
  30 import java.security.PrivilegedExceptionAction;
  31 import java.text.BreakIterator;
  32 import java.text.Collator;
  33 import java.text.DateFormat;
  34 import java.text.DateFormatSymbols;
  35 import java.text.DecimalFormatSymbols;
  36 import java.text.NumberFormat;
  37 import java.text.spi.BreakIteratorProvider;
  38 import java.text.spi.CollatorProvider;
  39 import java.text.spi.DateFormatProvider;
  40 import java.text.spi.DateFormatSymbolsProvider;
  41 import java.text.spi.DecimalFormatSymbolsProvider;
  42 import java.text.spi.NumberFormatProvider;
  43 import java.util.Arrays;
  44 import java.util.Locale;
  45 import java.util.Map;
  46 import java.util.ServiceConfigurationError;
  47 import java.util.ServiceLoader;
  48 import java.util.concurrent.ConcurrentHashMap;

  49 import java.util.spi.CalendarDataProvider;
  50 import java.util.spi.CalendarNameProvider;
  51 import java.util.spi.CurrencyNameProvider;
  52 import java.util.spi.LocaleNameProvider;
  53 import java.util.spi.LocaleServiceProvider;
  54 import java.util.spi.TimeZoneNameProvider;
  55 
  56 /**
  57  * LocaleProviderAdapter implementation for the installed SPI implementations.
  58  *
  59  * @author Naoto Sato
  60  * @author Masayoshi Okutsu
  61  */
  62 public class SPILocaleProviderAdapter extends AuxLocaleProviderAdapter {
  63 
  64     /**
  65      * Returns the type of this LocaleProviderAdapter
  66      */
  67     @Override
  68     public LocaleProviderAdapter.Type getAdapterType() {
  69         return LocaleProviderAdapter.Type.SPI;
  70     }
  71 
  72     @Override
  73     protected <P extends LocaleServiceProvider> P findInstalledProvider(final Class<P> c) {
  74         try {
  75             return AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
  76                 @Override
  77                 @SuppressWarnings(value={"unchecked", "deprecation"})
  78                 public P run() {
  79                     P delegate = null;
  80 
  81                     for (LocaleServiceProvider provider :
  82                              ServiceLoader.load(c, ClassLoader.getSystemClassLoader())) {
  83                         if (delegate == null) {
  84                             try {
  85                                 delegate =
  86                                     (P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() +
  87                                               "$" +
  88                                               c.getSimpleName() +
  89                                               "Delegate")
  90                                               .newInstance();
  91                             }  catch (ClassNotFoundException |
  92                                       InstantiationException |
  93                                       IllegalAccessException e) {
  94                                 throw new ServiceConfigurationError(
  95                                     "SPI locale provider cannot be instantiated.", e);
  96                             }
  97                         }
  98 
  99                         ((Delegate)delegate).addImpl(provider);
 100                     }
 101                     return delegate;
 102                 }
 103             });
 104         }  catch (PrivilegedActionException e) {
 105             throw new ServiceConfigurationError(
 106                 "SPI locale provider cannot be instantiated.", e);
 107         }

 108     }
 109 
 110     /*
 111      * Delegate interface. All the implementations have to have the class name
 112      * following "<provider class name>Delegate" convention.
 113      */
 114     private interface Delegate<P extends LocaleServiceProvider> {
 115         default void addImpl(P impl) {
 116             for (Locale l : impl.getAvailableLocales()) {
 117                 getDelegateMap().putIfAbsent(l, impl);
 118             }
 119         }
 120 
 121         /*
 122          * Obtain the real SPI implementation, using locale fallback
 123          */
 124         default P getImpl(Locale locale) {
 125             for (Locale l : LocaleServiceProviderPool.getLookupLocales(locale.stripExtensions())) {
 126                 P ret = getDelegateMap().get(l);
 127                 if (ret != null) {
 128                     return ret;
 129                 }
 130             }
 131             return null;
 132         }
 133 
 134         Map<Locale, P> getDelegateMap();
 135 
 136         default Locale[] getAvailableLocalesDelegate() {
 137             return getDelegateMap().keySet().toArray(new Locale[0]);
 138         }
 139 
 140         default boolean isSupportedLocaleDelegate(Locale locale) {
 141             Map<Locale, P> map = getDelegateMap();
 142             Locale override = CalendarDataUtility.findRegionOverride(locale);
 143 
 144             // First, call the method with extensions (if any)
 145             P impl = map.get(override);
 146             if (impl != null) {
 147                 return impl.isSupportedLocale(override);
 148             } else {
 149                 // The default behavior
 150                 Locale overrideNoExt = override.stripExtensions();
 151                 impl = map.get(overrideNoExt);
 152                 if (impl != null) {
 153                     return Arrays.stream(impl.getAvailableLocales())
 154                                 .anyMatch(overrideNoExt::equals);
 155                 }
 156             }
 157 
 158             return false;
 159         }
 160     }


< prev index next >