< prev index next >

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

Print this page
rev 59397 : imported patch 8245241
   1 /*
   2  * Copyright (c) 2012, 2016, 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 sun.util.locale.provider;
  27 

  28 import java.text.spi.BreakIteratorProvider;
  29 import java.text.spi.CollatorProvider;
  30 import java.text.spi.DateFormatProvider;
  31 import java.text.spi.DateFormatSymbolsProvider;
  32 import java.text.spi.DecimalFormatSymbolsProvider;
  33 import java.text.spi.NumberFormatProvider;
  34 import java.util.ArrayList;
  35 import java.util.Collections;
  36 import java.util.List;
  37 import java.util.Locale;
  38 import java.util.Map;
  39 import java.util.ResourceBundle;

  40 import java.util.Set;
  41 import java.util.concurrent.ConcurrentHashMap;
  42 import java.util.concurrent.ConcurrentMap;
  43 import java.util.spi.CalendarDataProvider;
  44 import java.util.spi.CalendarNameProvider;
  45 import java.util.spi.CurrencyNameProvider;
  46 import java.util.spi.LocaleNameProvider;
  47 import java.util.spi.LocaleServiceProvider;
  48 import java.util.spi.TimeZoneNameProvider;
  49 import sun.security.action.GetPropertyAction;
  50 import sun.text.spi.JavaTimeDateTimePatternProvider;
  51 import sun.util.spi.CalendarProvider;
  52 


  53 /**
  54  * The LocaleProviderAdapter abstract class.
  55  *
  56  * @author Naoto Sato
  57  * @author Masayoshi Okutsu
  58  */
  59 public abstract class LocaleProviderAdapter {
  60     /**
  61      * Adapter type.
  62      */
  63     public static enum Type {
  64         JRE("sun.util.locale.provider.JRELocaleProviderAdapter", "sun.util.resources", "sun.text.resources"),
  65         CLDR("sun.util.cldr.CLDRLocaleProviderAdapter", "sun.util.resources.cldr", "sun.text.resources.cldr"),
  66         SPI("sun.util.locale.provider.SPILocaleProviderAdapter"),
  67         HOST("sun.util.locale.provider.HostLocaleProviderAdapter"),
  68         FALLBACK("sun.util.locale.provider.FallbackLocaleProviderAdapter", "sun.util.resources", "sun.text.resources");
  69 
  70         private final String CLASSNAME;
  71         private final String UTIL_RESOURCES_PACKAGE;
  72         private final String TEXT_RESOURCES_PACKAGE;
  73 
  74         private Type(String className) {
  75             this(className, null, null);
  76         }
  77 
  78         private Type(String className, String util, String text) {
  79             CLASSNAME = className;
  80             UTIL_RESOURCES_PACKAGE = util;
  81             TEXT_RESOURCES_PACKAGE = text;
  82         }
  83 
  84         public String getAdapterClassName() {
  85             return CLASSNAME;
  86         }
  87 
  88         public String getUtilResourcesPackage() {
  89             return UTIL_RESOURCES_PACKAGE;
  90         }
  91 
  92         public String getTextResourcesPackage() {
  93             return TEXT_RESOURCES_PACKAGE;
  94         }
  95     }
  96 
  97     /**
  98      * LocaleProviderAdapter preference list.
  99      */
 100     private static final List<Type> adapterPreference;
 101 
 102     /**
 103      * LocaleProviderAdapter instances
 104      */
 105     private static final Map<Type, LocaleProviderAdapter> adapterInstances = new ConcurrentHashMap<>();
 106 
 107     /**
 108      * Default fallback adapter type, which should return something meaningful in any case.
 109      * This is either CLDR or FALLBACK.
 110      */
 111     static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter;
 112 
 113     /**
 114      * Adapter lookup cache.
 115      */
 116     private static ConcurrentMap<Class<? extends LocaleServiceProvider>, ConcurrentMap<Locale, LocaleProviderAdapter>>
 117         adapterCache = new ConcurrentHashMap<>();
 118 
 119     static {
 120         String order = GetPropertyAction.privilegedGetProperty("java.locale.providers");
 121         List<Type> typeList = new ArrayList<>();

 122 
 123         // Check user specified adapter preference
 124         if (order != null && !order.isEmpty()) {
 125             String[] types = order.split(",");
 126             for (String type : types) {
 127                 type = type.trim().toUpperCase(Locale.ROOT);
 128                 if (type.equals("COMPAT")) {
 129                     type = "JRE";
 130                 }
 131                 try {
 132                     Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
 133                     if (!typeList.contains(aType)) {
 134                         typeList.add(aType);
 135                     }
 136                 } catch (IllegalArgumentException | UnsupportedOperationException e) {
 137                     // could be caused by the user specifying wrong
 138                     // provider name or format in the system property
 139                     LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
 140                 }
 141             }
 142         }
 143 
 144         defaultLocaleProviderAdapter = Type.CLDR;
 145         if (!typeList.isEmpty()) {
 146             // bona fide preference exists
 147             if (!(typeList.contains(Type.CLDR) || (typeList.contains(Type.JRE)))) {
 148                 // Append FALLBACK as the last resort when no ResourceBundleBasedAdapter is available.
 149                 typeList.add(Type.FALLBACK);
 150                 defaultLocaleProviderAdapter = Type.FALLBACK;
 151             }
 152         } else {
 153             // Default preference list.
 154             typeList.add(Type.CLDR);
 155             typeList.add(Type.JRE);
 156         }
 157         adapterPreference = Collections.unmodifiableList(typeList);









 158     }
 159 
 160     /**
 161      * Returns the singleton instance for each adapter type
 162      */
 163     public static LocaleProviderAdapter forType(Type type) {
 164         switch (type) {
 165         case JRE:
 166         case CLDR:
 167         case SPI:
 168         case HOST:
 169         case FALLBACK:
 170             LocaleProviderAdapter adapter = null;
 171             LocaleProviderAdapter cached = adapterInstances.get(type);
 172             if (cached == null) {
 173                 try {
 174                     // lazily load adapters here
 175                     @SuppressWarnings("deprecation")
 176                     Object tmp = Class.forName(type.getAdapterClassName()).newInstance();
 177                     adapter = (LocaleProviderAdapter)tmp;
 178                     cached = adapterInstances.putIfAbsent(type, adapter);
 179                     if (cached != null) {
 180                         adapter = cached;
 181                     }
 182                 } catch (ClassNotFoundException |


 183                          IllegalAccessException |
 184                          InstantiationException |
 185                          UnsupportedOperationException e) {
 186                     LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
 187                     adapterInstances.putIfAbsent(type, NONEXISTENT_ADAPTER);
 188                     if (defaultLocaleProviderAdapter == type) {
 189                         defaultLocaleProviderAdapter = Type.FALLBACK;
 190                     }
 191                 }
 192             } else if (cached != NONEXISTENT_ADAPTER) {
 193                 adapter = cached;
 194             }
 195             return adapter;
 196         default:
 197             throw new InternalError("unknown locale data adapter type");
 198         }
 199     }
 200 
 201     public static LocaleProviderAdapter forJRE() {
 202         return forType(Type.JRE);
 203     }
 204 
 205     public static LocaleProviderAdapter getResourceBundleBased() {
 206         for (Type type : getAdapterPreference()) {
 207             if (type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK) {
 208                 LocaleProviderAdapter adapter = forType(type);
 209                 if (adapter != null) {
 210                     return adapter;
 211                 }
 212             }
 213         }
 214         // Shouldn't happen.


 423 
 424     /**
 425      * Returns a CalendarProvider for this LocaleProviderAdapter, or null if no
 426      * CalendarProvider is available.
 427      *
 428      * @return a CalendarProvider
 429      */
 430     public abstract CalendarProvider getCalendarProvider();
 431 
 432     /**
 433      * Returns a JavaTimeDateTimePatternProvider for this LocaleProviderAdapter,
 434      * or null if no JavaTimeDateTimePatternProvider is available.
 435      *
 436      * @return a JavaTimeDateTimePatternProvider
 437      */
 438     public abstract JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider();
 439 
 440     public abstract LocaleResources getLocaleResources(Locale locale);
 441 
 442     public abstract Locale[] getAvailableLocales();
 443 
 444     private static final LocaleProviderAdapter NONEXISTENT_ADAPTER = new NonExistentAdapter();
 445     private static final class NonExistentAdapter extends FallbackLocaleProviderAdapter {
 446         @Override
 447         public LocaleProviderAdapter.Type getAdapterType() {
 448             return null;
 449         }
 450 
 451         private NonExistentAdapter() {};
 452     }
 453 }
   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
  23  * questions.
  24  */
  25 
  26 package sun.util.locale.provider;
  27 
  28 import java.lang.reflect.InvocationTargetException;
  29 import java.text.spi.BreakIteratorProvider;
  30 import java.text.spi.CollatorProvider;
  31 import java.text.spi.DateFormatProvider;
  32 import java.text.spi.DateFormatSymbolsProvider;
  33 import java.text.spi.DecimalFormatSymbolsProvider;
  34 import java.text.spi.NumberFormatProvider;
  35 import java.util.ArrayList;
  36 import java.util.Collections;
  37 import java.util.List;
  38 import java.util.Locale;
  39 import java.util.Map;
  40 import java.util.ResourceBundle;
  41 import java.util.ServiceConfigurationError;
  42 import java.util.Set;
  43 import java.util.concurrent.ConcurrentHashMap;
  44 import java.util.concurrent.ConcurrentMap;
  45 import java.util.spi.CalendarDataProvider;
  46 import java.util.spi.CalendarNameProvider;
  47 import java.util.spi.CurrencyNameProvider;
  48 import java.util.spi.LocaleNameProvider;
  49 import java.util.spi.LocaleServiceProvider;
  50 import java.util.spi.TimeZoneNameProvider;
  51 import sun.security.action.GetPropertyAction;
  52 import sun.text.spi.JavaTimeDateTimePatternProvider;
  53 import sun.util.spi.CalendarProvider;
  54 
  55 import static java.lang.System.*;
  56 
  57 /**
  58  * The LocaleProviderAdapter abstract class.
  59  *
  60  * @author Naoto Sato
  61  * @author Masayoshi Okutsu
  62  */
  63 public abstract class LocaleProviderAdapter {
  64     /**
  65      * Adapter type.
  66      */
  67     public enum Type {
  68         JRE("sun.util.locale.provider.JRELocaleProviderAdapter", "sun.util.resources", "sun.text.resources"),
  69         CLDR("sun.util.cldr.CLDRLocaleProviderAdapter", "sun.util.resources.cldr", "sun.text.resources.cldr"),
  70         SPI("sun.util.locale.provider.SPILocaleProviderAdapter"),
  71         HOST("sun.util.locale.provider.HostLocaleProviderAdapter"),
  72         FALLBACK("sun.util.locale.provider.FallbackLocaleProviderAdapter", "sun.util.resources", "sun.text.resources");
  73 
  74         private final String CLASSNAME;
  75         private final String UTIL_RESOURCES_PACKAGE;
  76         private final String TEXT_RESOURCES_PACKAGE;
  77 
  78         Type(String className) {
  79             this(className, null, null);
  80         }
  81 
  82         Type(String className, String util, String text) {
  83             CLASSNAME = className;
  84             UTIL_RESOURCES_PACKAGE = util;
  85             TEXT_RESOURCES_PACKAGE = text;
  86         }
  87 
  88         public String getAdapterClassName() {
  89             return CLASSNAME;
  90         }
  91 
  92         public String getUtilResourcesPackage() {
  93             return UTIL_RESOURCES_PACKAGE;
  94         }
  95 
  96         public String getTextResourcesPackage() {
  97             return TEXT_RESOURCES_PACKAGE;
  98         }
  99     }
 100 
 101     /**
 102      * LocaleProviderAdapter preference list.
 103      */
 104     private static final List<Type> adapterPreference;
 105 
 106     /**
 107      * LocaleProviderAdapter instances
 108      */
 109     private static final Map<Type, LocaleProviderAdapter> adapterInstances = new ConcurrentHashMap<>();
 110 
 111     /**
 112      * Default fallback adapter type, which should return something meaningful in any case.
 113      * This is either CLDR or FALLBACK.
 114      */
 115     static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter;
 116 
 117     /**
 118      * Adapter lookup cache.
 119      */
 120     private static final ConcurrentMap<Class<? extends LocaleServiceProvider>, ConcurrentMap<Locale, LocaleProviderAdapter>>
 121         adapterCache = new ConcurrentHashMap<>();
 122 
 123     static {
 124         String order = GetPropertyAction.privilegedGetProperty("java.locale.providers");
 125         ArrayList<Type> typeList = new ArrayList<>();
 126         String invalidTypeMessage = null;
 127 
 128         // Check user specified adapter preference
 129         if (order != null && !order.isEmpty()) {
 130             String[] types = order.split(",");
 131             for (String type : types) {
 132                 type = type.trim().toUpperCase(Locale.ROOT);
 133                 if (type.equals("COMPAT")) {
 134                     type = "JRE";
 135                 }
 136                 try {
 137                     Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
 138                     if (!typeList.contains(aType)) {
 139                         typeList.add(aType);
 140                     }
 141                 } catch (IllegalArgumentException e) {
 142                     // construct a log message.
 143                     invalidTypeMessage = "Invalid locale provider adapter \"" + type + "\" ignored.";

 144                 }
 145             }
 146         }
 147 
 148         defaultLocaleProviderAdapter = Type.CLDR;
 149         if (!typeList.isEmpty()) {
 150             // bona fide preference exists
 151             if (!(typeList.contains(Type.CLDR) || typeList.contains(Type.JRE))) {
 152                 // Append FALLBACK as the last resort when no ResourceBundleBasedAdapter is available.
 153                 typeList.add(Type.FALLBACK);
 154                 defaultLocaleProviderAdapter = Type.FALLBACK;
 155             }
 156         } else {
 157             // Default preference list.
 158             typeList.add(Type.CLDR);
 159             typeList.add(Type.JRE);
 160         }
 161         adapterPreference = Collections.unmodifiableList(typeList);
 162 
 163         // Emit logs, if any, after 'adapterPreference' is initialized which is needed
 164         // for logging.
 165         if (invalidTypeMessage != null) {
 166             // could be caused by the user specifying wrong
 167             // provider name or format in the system property
 168             getLogger(LocaleProviderAdapter.class.getCanonicalName())
 169                 .log(Logger.Level.INFO, invalidTypeMessage);
 170         }
 171     }
 172 
 173     /**
 174      * Returns the singleton instance for each adapter type
 175      */
 176     public static LocaleProviderAdapter forType(Type type) {
 177         switch (type) {
 178         case JRE:
 179         case CLDR:
 180         case SPI:
 181         case HOST:
 182         case FALLBACK:
 183             LocaleProviderAdapter adapter = adapterInstances.get(type);
 184             if (adapter == null) {

 185                 try {
 186                     // lazily load adapters here
 187                     adapter = (LocaleProviderAdapter)Class.forName(type.getAdapterClassName())
 188                             .getDeclaredConstructor().newInstance();
 189                     LocaleProviderAdapter cached = adapterInstances.putIfAbsent(type, adapter);

 190                     if (cached != null) {
 191                         adapter = cached;
 192                     }
 193                 } catch (NoSuchMethodException |
 194                          InvocationTargetException |
 195                          ClassNotFoundException |
 196                          IllegalAccessException |
 197                          InstantiationException |
 198                          UnsupportedOperationException e) {
 199                     throw new ServiceConfigurationError("Locale provider adapter \"" +
 200                             type + "\"cannot be instantiated.", e);


 201                 }
 202             }



 203             return adapter;
 204         default:
 205             throw new InternalError("unknown locale data adapter type");
 206         }
 207     }
 208 
 209     public static LocaleProviderAdapter forJRE() {
 210         return forType(Type.JRE);
 211     }
 212 
 213     public static LocaleProviderAdapter getResourceBundleBased() {
 214         for (Type type : getAdapterPreference()) {
 215             if (type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK) {
 216                 LocaleProviderAdapter adapter = forType(type);
 217                 if (adapter != null) {
 218                     return adapter;
 219                 }
 220             }
 221         }
 222         // Shouldn't happen.


 431 
 432     /**
 433      * Returns a CalendarProvider for this LocaleProviderAdapter, or null if no
 434      * CalendarProvider is available.
 435      *
 436      * @return a CalendarProvider
 437      */
 438     public abstract CalendarProvider getCalendarProvider();
 439 
 440     /**
 441      * Returns a JavaTimeDateTimePatternProvider for this LocaleProviderAdapter,
 442      * or null if no JavaTimeDateTimePatternProvider is available.
 443      *
 444      * @return a JavaTimeDateTimePatternProvider
 445      */
 446     public abstract JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider();
 447 
 448     public abstract LocaleResources getLocaleResources(Locale locale);
 449 
 450     public abstract Locale[] getAvailableLocales();










 451 }
< prev index next >