Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxp/src/javax/xml/transform/FactoryFinder.java
32285 views
1
/*
2
* Copyright (c) 2003, 2017, 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 javax.xml.transform;
27
28
import java.io.File;
29
import java.lang.reflect.Method;
30
import java.lang.reflect.Modifier;
31
import java.security.AccessController;
32
import java.security.PrivilegedAction;
33
import java.util.Iterator;
34
import java.util.Properties;
35
import java.util.ServiceConfigurationError;
36
import java.util.ServiceLoader;
37
38
/**
39
* <p>Implements pluggable Datatypes.</p>
40
*
41
* <p>This class is duplicated for each JAXP subpackage so keep it in
42
* sync. It is package private for secure class loading.</p>
43
*
44
* @author [email protected]
45
* @author [email protected]
46
*/
47
class FactoryFinder {
48
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xalan.internal.";
49
50
/**
51
* Internal debug flag.
52
*/
53
private static boolean debug = false;
54
55
/**
56
* Cache for properties in java.home/lib/jaxp.properties
57
*/
58
private final static Properties cacheProps = new Properties();
59
60
/**
61
* Flag indicating if properties from java.home/lib/jaxp.properties
62
* have been cached.
63
*/
64
static volatile boolean firstTime = true;
65
66
/**
67
* Security support class use to check access control before
68
* getting certain system resources.
69
*/
70
private final static SecuritySupport ss = new SecuritySupport();
71
72
// Define system property "jaxp.debug" to get output
73
static {
74
// Use try/catch block to support applets, which throws
75
// SecurityException out of this code.
76
try {
77
String val = ss.getSystemProperty("jaxp.debug");
78
// Allow simply setting the prop to turn on debug
79
debug = val != null && !"false".equals(val);
80
}
81
catch (SecurityException se) {
82
debug = false;
83
}
84
}
85
86
private static void dPrint(String msg) {
87
if (debug) {
88
System.err.println("JAXP: " + msg);
89
}
90
}
91
92
/**
93
* Attempt to load a class using the class loader supplied. If that fails
94
* and fall back is enabled, the current (i.e. bootstrap) class loader is
95
* tried.
96
*
97
* If the class loader supplied is <code>null</code>, first try using the
98
* context class loader followed by the current (i.e. bootstrap) class
99
* loader.
100
*
101
* Use bootstrap classLoader if cl = null and useBSClsLoader is true
102
*/
103
static private Class<?> getProviderClass(String className, ClassLoader cl,
104
boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException
105
{
106
try {
107
if (cl == null) {
108
if (useBSClsLoader) {
109
return Class.forName(className, false, FactoryFinder.class.getClassLoader());
110
} else {
111
cl = ss.getContextClassLoader();
112
if (cl == null) {
113
throw new ClassNotFoundException();
114
}
115
else {
116
return Class.forName(className, false, cl);
117
}
118
}
119
}
120
else {
121
return Class.forName(className, false, cl);
122
}
123
}
124
catch (ClassNotFoundException e1) {
125
if (doFallback) {
126
// Use current class loader - should always be bootstrap CL
127
return Class.forName(className, false, FactoryFinder.class.getClassLoader());
128
}
129
else {
130
throw e1;
131
}
132
}
133
}
134
135
/**
136
* Create an instance of a class. Delegates to method
137
* <code>getProviderClass()</code> in order to load the class.
138
*
139
* @param type Base class / Service interface of the factory to
140
* instantiate.
141
*
142
* @param className Name of the concrete class corresponding to the
143
* service provider
144
*
145
* @param cl <code>ClassLoader</code> used to load the factory class. If <code>null</code>
146
* current <code>Thread</code>'s context classLoader is used to load the factory class.
147
*
148
* @param doFallback True if the current ClassLoader should be tried as
149
* a fallback if the class is not found using cl
150
*
151
*/
152
static <T> T newInstance(Class<T> type, String className, ClassLoader cl,
153
boolean doFallback)
154
throws TransformerFactoryConfigurationError
155
{
156
assert type != null;
157
158
boolean useBSClsLoader = false;
159
// make sure we have access to restricted packages
160
if (System.getSecurityManager() != null) {
161
if (className != null && className.startsWith(DEFAULT_PACKAGE)) {
162
cl = null;
163
useBSClsLoader = true;
164
}
165
}
166
167
try {
168
Class<?> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader);
169
if (!type.isAssignableFrom(providerClass)) {
170
throw new ClassCastException(className + " cannot be cast to " + type.getName());
171
}
172
Object instance = providerClass.newInstance();
173
174
if (debug) { // Extra check to avoid computing cl strings
175
dPrint("created new instance of " + providerClass +
176
" using ClassLoader: " + cl);
177
}
178
return type.cast(instance);
179
}
180
catch (ClassNotFoundException x) {
181
throw new TransformerFactoryConfigurationError(x,
182
"Provider " + className + " not found");
183
}
184
catch (Exception x) {
185
throw new TransformerFactoryConfigurationError(x,
186
"Provider " + className + " could not be instantiated: " + x);
187
}
188
}
189
190
/**
191
* Finds the implementation Class object in the specified order. Main
192
* entry point.
193
* @return Class object of factory, never null
194
*
195
* @param type Base class / Service interface of the
196
* factory to find.
197
*
198
* @param fallbackClassName Implementation class name, if nothing else
199
* is found. Use null to mean no fallback.
200
*
201
* Package private so this code can be shared.
202
*/
203
static <T> T find(Class<T> type, String fallbackClassName)
204
throws TransformerFactoryConfigurationError
205
{
206
assert type != null;
207
208
final String factoryId = type.getName();
209
210
dPrint("find factoryId =" + factoryId);
211
// Use the system property first
212
try {
213
String systemProp = ss.getSystemProperty(factoryId);
214
if (systemProp != null) {
215
dPrint("found system property, value=" + systemProp);
216
return newInstance(type, systemProp, null, true);
217
}
218
}
219
catch (SecurityException se) {
220
if (debug) se.printStackTrace();
221
}
222
223
// try to read from $java.home/lib/jaxp.properties
224
try {
225
if (firstTime) {
226
synchronized (cacheProps) {
227
if (firstTime) {
228
String configFile = ss.getSystemProperty("java.home") + File.separator +
229
"lib" + File.separator + "jaxp.properties";
230
File f = new File(configFile);
231
firstTime = false;
232
if (ss.doesFileExist(f)) {
233
dPrint("Read properties file "+f);
234
cacheProps.load(ss.getFileInputStream(f));
235
}
236
}
237
}
238
}
239
final String factoryClassName = cacheProps.getProperty(factoryId);
240
241
if (factoryClassName != null) {
242
dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName);
243
return newInstance(type, factoryClassName, null, true);
244
}
245
}
246
catch (Exception ex) {
247
if (debug) ex.printStackTrace();
248
}
249
250
// Try Jar Service Provider Mechanism
251
T provider = findServiceProvider(type);
252
if (provider != null) {
253
return provider;
254
}
255
if (fallbackClassName == null) {
256
throw new TransformerFactoryConfigurationError(null,
257
"Provider for " + factoryId + " cannot be found");
258
}
259
260
dPrint("loaded from fallback value: " + fallbackClassName);
261
return newInstance(type, fallbackClassName, null, true);
262
}
263
264
/*
265
* Try to find provider using the ServiceLoader.
266
*
267
* @param type Base class / Service interface of the factory to find.
268
*
269
* @return instance of provider class if found or null
270
*/
271
private static <T> T findServiceProvider(final Class<T> type)
272
throws TransformerFactoryConfigurationError
273
{
274
try {
275
return AccessController.doPrivileged(new PrivilegedAction<T>() {
276
public T run() {
277
final ServiceLoader<T> serviceLoader = ServiceLoader.load(type);
278
final Iterator<T> iterator = serviceLoader.iterator();
279
if (iterator.hasNext()) {
280
return iterator.next();
281
} else {
282
return null;
283
}
284
}
285
});
286
} catch(ServiceConfigurationError e) {
287
// It is not possible to wrap an error directly in
288
// FactoryConfigurationError - so we need to wrap the
289
// ServiceConfigurationError in a RuntimeException.
290
// The alternative would be to modify the logic in
291
// FactoryConfigurationError to allow setting a
292
// Throwable as the cause, but that could cause
293
// compatibility issues down the road.
294
final RuntimeException x = new RuntimeException(
295
"Provider for " + type + " cannot be created", e);
296
final TransformerFactoryConfigurationError error =
297
new TransformerFactoryConfigurationError(x, x.getMessage());
298
throw error;
299
}
300
}
301
}
302
303