Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java
40948 views
1
/*
2
* Copyright (c) 2004, 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.xpath;
27
28
import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl;
29
import java.io.File;
30
import java.lang.reflect.InvocationTargetException;
31
import java.security.AccessControlContext;
32
import java.security.AccessController;
33
import java.security.PrivilegedAction;
34
import java.util.Properties;
35
import java.util.ServiceConfigurationError;
36
import java.util.ServiceLoader;
37
import java.util.function.Supplier;
38
import jdk.xml.internal.SecuritySupport;
39
40
/**
41
* Implementation of {@link XPathFactory#newInstance(String)}.
42
*
43
* @author Kohsuke Kawaguchi
44
* @since 1.5
45
*/
46
class XPathFactoryFinder {
47
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xpath.internal";
48
49
/** debug support code. */
50
private static boolean debug = false;
51
static {
52
// Use try/catch block to support applets
53
try {
54
debug = SecuritySupport.getSystemProperty("jaxp.debug") != null;
55
} catch (Exception unused) {
56
debug = false;
57
}
58
}
59
60
/**
61
* <p>Cache properties for performance.</p>
62
*/
63
private static final Properties cacheProps = new Properties();
64
65
/**
66
* <p>First time requires initialization overhead.</p>
67
*/
68
private volatile static boolean firstTime = true;
69
70
/**
71
* <p>Conditional debug printing.</p>
72
*
73
* @param msgGen Supplier function that returns debug message
74
*/
75
private static void debugPrintln(Supplier<String> msgGen) {
76
if (debug) {
77
System.err.println("JAXP: " + msgGen.get());
78
}
79
}
80
81
/**
82
* <p><code>ClassLoader</code> to use to find <code>XPathFactory</code>.</p>
83
*/
84
private final ClassLoader classLoader;
85
86
/**
87
* <p>Constructor that specifies <code>ClassLoader</code> to use
88
* to find <code>XPathFactory</code>.</p>
89
*
90
* @param loader
91
* to be used to load resource and {@link XPathFactory}
92
* implementations during the resolution process.
93
* If this parameter is null, the default system class loader
94
* will be used.
95
*/
96
public XPathFactoryFinder(ClassLoader loader) {
97
this.classLoader = loader;
98
if( debug ) {
99
debugDisplayClassLoader();
100
}
101
}
102
103
private void debugDisplayClassLoader() {
104
try {
105
if( classLoader == SecuritySupport.getContextClassLoader() ) {
106
debugPrintln(() -> "using thread context class loader ("+classLoader+") for search");
107
return;
108
}
109
} catch( Throwable unused ) {
110
// getContextClassLoader() undefined in JDK1.1
111
}
112
113
if( classLoader==ClassLoader.getSystemClassLoader() ) {
114
debugPrintln(() -> "using system class loader ("+classLoader+") for search");
115
return;
116
}
117
118
debugPrintln(() -> "using class loader ("+classLoader+") for search");
119
}
120
121
/**
122
* <p>Creates a new {@link XPathFactory} object for the specified
123
* object model.</p>
124
*
125
* @param uri
126
* Identifies the underlying object model.
127
*
128
* @return <code>null</code> if the callee fails to create one.
129
*
130
* @throws NullPointerException
131
* If the parameter is null.
132
*/
133
public XPathFactory newFactory(String uri) throws XPathFactoryConfigurationException {
134
if (uri == null) {
135
throw new NullPointerException();
136
}
137
XPathFactory f = _newFactory(uri);
138
if (f != null) {
139
debugPrintln(()->"factory '" + f.getClass().getName() + "' was found for " + uri);
140
} else {
141
debugPrintln(()->"unable to find a factory for " + uri);
142
}
143
return f;
144
}
145
146
/**
147
* <p>Lookup a {@link XPathFactory} for the given object model.</p>
148
*
149
* @param uri identifies the object model.
150
*
151
* @return {@link XPathFactory} for the given object model.
152
*/
153
private XPathFactory _newFactory(String uri) throws XPathFactoryConfigurationException {
154
XPathFactory xpathFactory = null;
155
156
String propertyName = SERVICE_CLASS.getName() + ":" + uri;
157
158
// system property look up
159
try {
160
debugPrintln(()->"Looking up system property '"+propertyName+"'" );
161
String r = SecuritySupport.getSystemProperty(propertyName);
162
if(r!=null) {
163
debugPrintln(()->"The value is '"+r+"'");
164
xpathFactory = createInstance(r);
165
if (xpathFactory != null) {
166
return xpathFactory;
167
}
168
} else
169
debugPrintln(()->"The property is undefined.");
170
} catch( Throwable t ) {
171
if( debug ) {
172
debugPrintln(()->"failed to look up system property '"+propertyName+"'" );
173
t.printStackTrace();
174
}
175
}
176
177
String javah = SecuritySupport.getSystemProperty( "java.home" );
178
String configFile = javah + File.separator +
179
"conf" + File.separator + "jaxp.properties";
180
181
// try to read from $java.home/conf/jaxp.properties
182
try {
183
if(firstTime){
184
synchronized(cacheProps){
185
if(firstTime){
186
File f=new File( configFile );
187
firstTime = false;
188
if(SecuritySupport.doesFileExist(f)){
189
debugPrintln(()->"Read properties file " + f);
190
cacheProps.load(SecuritySupport.getFileInputStream(f));
191
}
192
}
193
}
194
}
195
final String factoryClassName = cacheProps.getProperty(propertyName);
196
debugPrintln(()->"found " + factoryClassName + " in $java.home/conf/jaxp.properties");
197
198
if (factoryClassName != null) {
199
xpathFactory = createInstance(factoryClassName);
200
if(xpathFactory != null){
201
return xpathFactory;
202
}
203
}
204
} catch (Exception ex) {
205
if (debug) {
206
ex.printStackTrace();
207
}
208
}
209
210
// Try with ServiceLoader
211
assert xpathFactory == null;
212
xpathFactory = findServiceProvider(uri);
213
214
// The following assertion should always be true.
215
// Uncomment it, recompile, and run with -ea in case of doubts:
216
// assert xpathFactory == null || xpathFactory.isObjectModelSupported(uri);
217
218
if (xpathFactory != null) {
219
return xpathFactory;
220
}
221
222
// platform default
223
if(uri.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) {
224
debugPrintln(()->"attempting to use the platform default W3C DOM XPath lib");
225
return new XPathFactoryImpl();
226
}
227
228
debugPrintln(()->"all things were tried, but none was found. bailing out.");
229
return null;
230
}
231
232
/** <p>Create class using appropriate ClassLoader.</p>
233
*
234
* @param className Name of class to create.
235
* @return Created class or <code>null</code>.
236
*/
237
@SuppressWarnings("removal")
238
private Class<?> createClass(String className) {
239
Class<?> clazz;
240
// make sure we have access to restricted packages
241
boolean internal = false;
242
if (System.getSecurityManager() != null) {
243
if (className != null && className.startsWith(DEFAULT_PACKAGE)) {
244
internal = true;
245
}
246
}
247
248
// use approprite ClassLoader
249
try {
250
if (classLoader != null && !internal) {
251
clazz = Class.forName(className, false, classLoader);
252
} else {
253
clazz = Class.forName(className);
254
}
255
} catch (Throwable t) {
256
if(debug) {
257
t.printStackTrace();
258
}
259
return null;
260
}
261
262
return clazz;
263
}
264
265
/**
266
* <p>Creates an instance of the specified and returns it.</p>
267
*
268
* @param className
269
* fully qualified class name to be instantiated.
270
*
271
* @return null
272
* if it fails. Error messages will be printed by this method.
273
*/
274
XPathFactory createInstance(String className)
275
throws XPathFactoryConfigurationException
276
{
277
XPathFactory xPathFactory = null;
278
279
debugPrintln(()->"createInstance(" + className + ")");
280
281
// get Class from className
282
Class<?> clazz = createClass(className);
283
if (clazz == null) {
284
debugPrintln(()->"failed to getClass(" + className + ")");
285
return null;
286
}
287
debugPrintln(()->"loaded " + className + " from " + which(clazz));
288
289
// instantiate Class as a XPathFactory
290
try {
291
xPathFactory = (XPathFactory) clazz.getConstructor().newInstance();
292
} catch (ClassCastException | IllegalAccessException | IllegalArgumentException |
293
InstantiationException | InvocationTargetException | NoSuchMethodException |
294
SecurityException ex) {
295
debugPrintln(()->"could not instantiate " + clazz.getName());
296
if (debug) {
297
ex.printStackTrace();
298
}
299
return null;
300
}
301
302
return xPathFactory;
303
}
304
305
// Call isObjectModelSupportedBy with initial context.
306
@SuppressWarnings("removal")
307
private boolean isObjectModelSupportedBy(final XPathFactory factory,
308
final String objectModel,
309
AccessControlContext acc) {
310
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
311
public Boolean run() {
312
return factory.isObjectModelSupported(objectModel);
313
}
314
}, acc);
315
}
316
317
/**
318
* Finds a service provider subclass of XPathFactory that supports the
319
* given object model using the ServiceLoader.
320
*
321
* @param objectModel URI of object model to support.
322
* @return An XPathFactory supporting the specified object model, or null
323
* if none is found.
324
* @throws XPathFactoryConfigurationException if a configuration error is found.
325
*/
326
@SuppressWarnings("removal")
327
private XPathFactory findServiceProvider(final String objectModel)
328
throws XPathFactoryConfigurationException {
329
330
assert objectModel != null;
331
// store current context.
332
final AccessControlContext acc = AccessController.getContext();
333
try {
334
return AccessController.doPrivileged(new PrivilegedAction<XPathFactory>() {
335
public XPathFactory run() {
336
final ServiceLoader<XPathFactory> loader =
337
ServiceLoader.load(SERVICE_CLASS);
338
for (XPathFactory factory : loader) {
339
// restore initial context to call
340
// factory.isObjectModelSupportedBy
341
if (isObjectModelSupportedBy(factory, objectModel, acc)) {
342
return factory;
343
}
344
}
345
return null; // no factory found.
346
}
347
});
348
} catch (ServiceConfigurationError error) {
349
throw new XPathFactoryConfigurationException(error);
350
}
351
}
352
353
private static final Class<XPathFactory> SERVICE_CLASS = XPathFactory.class;
354
355
// Used for debugging purposes
356
private static String which( Class<?> clazz ) {
357
return SecuritySupport.getClassSource(clazz);
358
}
359
360
}
361
362