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