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 }
|