src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java

Print this page
rev 6057 : imported patch 8001205.8001562


   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 sun.util.locale.provider;
  27 
  28 import java.util.ArrayList;

  29 import java.util.Collections;
  30 import java.util.HashSet;
  31 import java.util.IllformedLocaleException;
  32 import java.util.List;
  33 import java.util.Locale;
  34 import java.util.Locale.Builder;
  35 import java.util.ResourceBundle.Control;
  36 import java.util.Set;
  37 import java.util.concurrent.ConcurrentHashMap;
  38 import java.util.concurrent.ConcurrentMap;
  39 import java.util.spi.LocaleServiceProvider;
  40 import sun.util.logging.PlatformLogger;
  41 
  42 /**
  43  * An instance of this class holds a set of the third party implementations of a particular
  44  * locale sensitive service, such as {@link java.util.spi.LocaleNameProvider}.
  45  *
  46  * @author Naoto Sato
  47  * @author Masayoshi Okutsu
  48  */


 160         PlatformLogger logger = PlatformLogger.getLogger(caller.getCanonicalName());
 161         logger.config(message);
 162     }
 163 
 164     /**
 165      * Lazy loaded set of available locales.
 166      * Loading all locales is a very long operation.
 167      */
 168     private static class AllAvailableLocales {
 169         /**
 170          * Available locales for all locale sensitive services.
 171          * This also contains JRE's available locales
 172          */
 173         static final Locale[] allAvailableLocales;
 174 
 175         static {
 176             Set<Locale> all = new HashSet<>();
 177             for (Class<? extends LocaleServiceProvider> c : spiClasses) {
 178                 LocaleServiceProviderPool pool =
 179                     LocaleServiceProviderPool.getPool(c);
 180                 all.addAll(pool.getAvailableLocaleList());
 181             }
 182 
 183             allAvailableLocales = all.toArray(new Locale[0]);
 184         }
 185 
 186         // No instantiation
 187         private AllAvailableLocales() {
 188         }
 189     }
 190 
 191     /**
 192      * Returns an array of available locales for all the provider classes.
 193      * This array is a merged array of all the locales that are provided by each
 194      * provider, including the JRE.
 195      *
 196      * @return an array of the available locales for all provider classes
 197      */
 198     public static Locale[] getAllAvailableLocales() {
 199         return AllAvailableLocales.allAvailableLocales.clone();
 200     }
 201 
 202     /**
 203      * Returns an array of available locales.  This array is a
 204      * merged array of all the locales that are provided by each
 205      * provider, including the JRE.
 206      *
 207      * @return an array of the available locales
 208      */
 209     public Locale[] getAvailableLocales() {
 210         Set<Locale> locList = getAvailableLocaleList();



 211         Locale[] tmp = new Locale[locList.size()];
 212         locList.toArray(tmp);
 213         return tmp;
 214     }
 215 
 216     private synchronized Set<Locale> getAvailableLocaleList() {







 217         if (availableLocales == null) {
 218             availableLocales = new HashSet<>();
 219             for (LocaleServiceProvider lsp : providers.values()) {
 220                 Locale[] locales = lsp.getAvailableLocales();
 221                 for (Locale locale: locales) {
 222                     availableLocales.add(getLookupLocale(locale));
 223                 }
 224             }
 225 
 226             // Remove Locale.ROOT for the compatibility.
 227             availableLocales.remove(Locale.ROOT);
 228         }
 229 
 230         return availableLocales;
 231     }
 232 
 233     /**
 234      * Returns whether any provider for this locale sensitive
 235      * service is available or not, excluding JRE's one.
 236      *
 237      * @return true if any provider (other than JRE) is available
 238      */
 239     boolean hasProviders() {
 240         return providers.size() != 1 ||
 241                providers.get(LocaleProviderAdapter.Type.JRE) == null;
 242     }
 243 
 244     /**
 245      * Returns the provider's localized object for the specified
 246      * locale.
 247      *


 278     @SuppressWarnings("unchecked")
 279     private <P extends LocaleServiceProvider, S> S getLocalizedObjectImpl(LocalizedObjectGetter<P, S> getter,
 280                                      Locale locale,
 281                                      boolean isObjectProvider,
 282                                      String key,
 283                                      Object... params) {
 284         if (locale == null) {
 285             throw new NullPointerException();
 286         }
 287 
 288         // Check whether JRE is the sole locale data provider or not,
 289         // and directly call it if it is.
 290         if (!hasProviders()) {
 291             return getter.getObject(
 292                 (P)providers.get(LocaleProviderAdapter.Type.JRE),
 293                 locale, key, params);
 294         }
 295 
 296         List<Locale> lookupLocales = getLookupLocales(locale);
 297 
 298         Set<Locale> available = getAvailableLocaleList();
 299         for (Locale current : lookupLocales) {
 300             if (available.contains(current)) {
 301                 S providersObj;
 302 
 303                 for (LocaleProviderAdapter.Type type: findProviders(current)) {
 304                     LocaleServiceProvider lsp = providers.get(type);
 305                     providersObj = getter.getObject((P)lsp, locale, key, params);
 306                     if (providersObj != null) {
 307                         return providersObj;
 308                     } else if (isObjectProvider) {
 309                         config(LocaleServiceProviderPool.class,
 310                             "A locale sensitive service provider returned null for a localized objects,  which should not happen.  provider: "
 311                                 + lsp + " locale: " + locale);
 312                     }
 313                 }
 314             }
 315         }
 316 
 317         // not found.
 318         return null;




   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 sun.util.locale.provider;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.Collections;
  31 import java.util.HashSet;
  32 import java.util.IllformedLocaleException;
  33 import java.util.List;
  34 import java.util.Locale;
  35 import java.util.Locale.Builder;
  36 import java.util.ResourceBundle.Control;
  37 import java.util.Set;
  38 import java.util.concurrent.ConcurrentHashMap;
  39 import java.util.concurrent.ConcurrentMap;
  40 import java.util.spi.LocaleServiceProvider;
  41 import sun.util.logging.PlatformLogger;
  42 
  43 /**
  44  * An instance of this class holds a set of the third party implementations of a particular
  45  * locale sensitive service, such as {@link java.util.spi.LocaleNameProvider}.
  46  *
  47  * @author Naoto Sato
  48  * @author Masayoshi Okutsu
  49  */


 161         PlatformLogger logger = PlatformLogger.getLogger(caller.getCanonicalName());
 162         logger.config(message);
 163     }
 164 
 165     /**
 166      * Lazy loaded set of available locales.
 167      * Loading all locales is a very long operation.
 168      */
 169     private static class AllAvailableLocales {
 170         /**
 171          * Available locales for all locale sensitive services.
 172          * This also contains JRE's available locales
 173          */
 174         static final Locale[] allAvailableLocales;
 175 
 176         static {
 177             Set<Locale> all = new HashSet<>();
 178             for (Class<? extends LocaleServiceProvider> c : spiClasses) {
 179                 LocaleServiceProviderPool pool =
 180                     LocaleServiceProviderPool.getPool(c);
 181                 all.addAll(pool.getAvailableLocaleSet());
 182             }
 183 
 184             allAvailableLocales = all.toArray(new Locale[0]);
 185         }
 186 
 187         // No instantiation
 188         private AllAvailableLocales() {
 189         }
 190     }
 191 
 192     /**
 193      * Returns an array of available locales for all the provider classes.
 194      * This array is a merged array of all the locales that are provided by each
 195      * provider, including the JRE.
 196      *
 197      * @return an array of the available locales for all provider classes
 198      */
 199     public static Locale[] getAllAvailableLocales() {
 200         return AllAvailableLocales.allAvailableLocales.clone();
 201     }
 202 
 203     /**
 204      * Returns an array of available locales.  This array is a
 205      * merged array of all the locales that are provided by each
 206      * provider, including the JRE's FormatData locales.
 207      *
 208      * @return an array of the available locales
 209      */
 210     public Locale[] getAvailableLocales() {
 211         Set<Locale> locList = new HashSet<>();
 212         locList.addAll(getAvailableLocaleSet());
 213         // Make sure it all contains JRE's FormatData locales for compatibility.
 214         locList.addAll(Arrays.asList(LocaleProviderAdapter.forJRE().getAvailableLocales()));
 215         Locale[] tmp = new Locale[locList.size()];
 216         locList.toArray(tmp);
 217         return tmp;
 218     }
 219 
 220     /**
 221      * Returns the union of locale sets that are available from
 222      * each service provider. This method does NOT return the
 223      * defensive copy.
 224      *
 225      * @return a set of available locales
 226      */
 227     private synchronized Set<Locale> getAvailableLocaleSet() {
 228         if (availableLocales == null) {
 229             availableLocales = new HashSet<>();
 230             for (LocaleServiceProvider lsp : providers.values()) {
 231                 Locale[] locales = lsp.getAvailableLocales();
 232                 for (Locale locale: locales) {
 233                     availableLocales.add(getLookupLocale(locale));
 234                 }
 235             }



 236         }
 237 
 238         return availableLocales;
 239     }
 240 
 241     /**
 242      * Returns whether any provider for this locale sensitive
 243      * service is available or not, excluding JRE's one.
 244      *
 245      * @return true if any provider (other than JRE) is available
 246      */
 247     boolean hasProviders() {
 248         return providers.size() != 1 ||
 249                providers.get(LocaleProviderAdapter.Type.JRE) == null;
 250     }
 251 
 252     /**
 253      * Returns the provider's localized object for the specified
 254      * locale.
 255      *


 286     @SuppressWarnings("unchecked")
 287     private <P extends LocaleServiceProvider, S> S getLocalizedObjectImpl(LocalizedObjectGetter<P, S> getter,
 288                                      Locale locale,
 289                                      boolean isObjectProvider,
 290                                      String key,
 291                                      Object... params) {
 292         if (locale == null) {
 293             throw new NullPointerException();
 294         }
 295 
 296         // Check whether JRE is the sole locale data provider or not,
 297         // and directly call it if it is.
 298         if (!hasProviders()) {
 299             return getter.getObject(
 300                 (P)providers.get(LocaleProviderAdapter.Type.JRE),
 301                 locale, key, params);
 302         }
 303 
 304         List<Locale> lookupLocales = getLookupLocales(locale);
 305 
 306         Set<Locale> available = getAvailableLocaleSet();
 307         for (Locale current : lookupLocales) {
 308             if (available.contains(current)) {
 309                 S providersObj;
 310 
 311                 for (LocaleProviderAdapter.Type type: findProviders(current)) {
 312                     LocaleServiceProvider lsp = providers.get(type);
 313                     providersObj = getter.getObject((P)lsp, locale, key, params);
 314                     if (providersObj != null) {
 315                         return providersObj;
 316                     } else if (isObjectProvider) {
 317                         config(LocaleServiceProviderPool.class,
 318                             "A locale sensitive service provider returned null for a localized objects,  which should not happen.  provider: "
 319                                 + lsp + " locale: " + locale);
 320                     }
 321                 }
 322             }
 323         }
 324 
 325         // not found.
 326         return null;