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/xpath/XPathFactoryFinder.java
32285 views
1
/*
2
* Copyright (c) 2004, 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.xpath;
27
28
import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl;
29
import java.io.File;
30
import java.net.URL;
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
38
/**
39
* Implementation of {@link XPathFactory#newInstance(String)}.
40
*
41
* @author <a href="[email protected]">Kohsuke Kawaguchi</a>
42
* @version $Revision: 1.7 $, $Date: 2010-11-01 04:36:14 $
43
* @since 1.5
44
*/
45
class XPathFactoryFinder {
46
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xpath.internal";
47
48
private static final SecuritySupport ss = new SecuritySupport() ;
49
/** debug support code. */
50
private static boolean debug = false;
51
static {
52
// Use try/catch block to support applets
53
try {
54
debug = ss.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 msg to print
74
*/
75
private static void debugPrintln(String msg) {
76
if (debug) {
77
System.err.println("JAXP: " + msg);
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 == ss.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 = ss.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 = ss.getSystemProperty( "java.home" );
178
String configFile = javah + File.separator +
179
"lib" + File.separator + "jaxp.properties";
180
181
// try to read from $java.home/lib/jaxp.properties
182
try {
183
if(firstTime){
184
synchronized(cacheProps){
185
if(firstTime){
186
File f=new File( configFile );
187
firstTime = false;
188
if(ss.doesFileExist(f)){
189
debugPrintln("Read properties file " + f);
190
cacheProps.load(ss.getFileInputStream(f));
191
}
192
}
193
}
194
}
195
final String factoryClassName = cacheProps.getProperty(propertyName);
196
debugPrintln("found " + factoryClassName + " in $java.home/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
private Class<?> createClass(String className) {
238
Class clazz;
239
// make sure we have access to restricted packages
240
boolean internal = false;
241
if (System.getSecurityManager() != null) {
242
if (className != null && className.startsWith(DEFAULT_PACKAGE)) {
243
internal = true;
244
}
245
}
246
247
// use approprite ClassLoader
248
try {
249
if (classLoader != null && !internal) {
250
clazz = Class.forName(className, false, classLoader);
251
} else {
252
clazz = Class.forName(className);
253
}
254
} catch (Throwable t) {
255
if(debug) {
256
t.printStackTrace();
257
}
258
return null;
259
}
260
261
return clazz;
262
}
263
264
/**
265
* <p>Creates an instance of the specified and returns it.</p>
266
*
267
* @param className
268
* fully qualified class name to be instantiated.
269
*
270
* @return null
271
* if it fails. Error messages will be printed by this method.
272
*/
273
XPathFactory createInstance(String className)
274
throws XPathFactoryConfigurationException
275
{
276
XPathFactory xPathFactory = null;
277
278
debugPrintln("createInstance(" + className + ")");
279
280
// get Class from className
281
Class<?> clazz = createClass(className);
282
if (clazz == null) {
283
debugPrintln("failed to getClass(" + className + ")");
284
return null;
285
}
286
debugPrintln("loaded " + className + " from " + which(clazz));
287
288
// instantiate Class as a XPathFactory
289
try {
290
xPathFactory = (XPathFactory) clazz.newInstance();
291
} catch (ClassCastException classCastException) {
292
debugPrintln("could not instantiate " + clazz.getName());
293
if (debug) {
294
classCastException.printStackTrace();
295
}
296
return null;
297
} catch (IllegalAccessException illegalAccessException) {
298
debugPrintln("could not instantiate " + clazz.getName());
299
if (debug) {
300
illegalAccessException.printStackTrace();
301
}
302
return null;
303
} catch (InstantiationException instantiationException) {
304
debugPrintln("could not instantiate " + clazz.getName());
305
if (debug) {
306
instantiationException.printStackTrace();
307
}
308
return null;
309
}
310
311
return xPathFactory;
312
}
313
314
// Call isObjectModelSupportedBy with initial context.
315
private boolean isObjectModelSupportedBy(final XPathFactory factory,
316
final String objectModel,
317
AccessControlContext acc) {
318
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
319
public Boolean run() {
320
return factory.isObjectModelSupported(objectModel);
321
}
322
}, acc);
323
}
324
325
/**
326
* Finds a service provider subclass of XPathFactory that supports the
327
* given object model using the ServiceLoader.
328
*
329
* @param objectModel URI of object model to support.
330
* @return An XPathFactory supporting the specified object model, or null
331
* if none is found.
332
* @throws XPathFactoryConfigurationException if a configuration error is found.
333
*/
334
private XPathFactory findServiceProvider(final String objectModel)
335
throws XPathFactoryConfigurationException {
336
337
assert objectModel != null;
338
// store current context.
339
final AccessControlContext acc = AccessController.getContext();
340
try {
341
return AccessController.doPrivileged(new PrivilegedAction<XPathFactory>() {
342
public XPathFactory run() {
343
final ServiceLoader<XPathFactory> loader =
344
ServiceLoader.load(SERVICE_CLASS);
345
for (XPathFactory factory : loader) {
346
// restore initial context to call
347
// factory.isObjectModelSupportedBy
348
if (isObjectModelSupportedBy(factory, objectModel, acc)) {
349
return factory;
350
}
351
}
352
return null; // no factory found.
353
}
354
});
355
} catch (ServiceConfigurationError error) {
356
throw new XPathFactoryConfigurationException(error);
357
}
358
}
359
360
private static final Class<XPathFactory> SERVICE_CLASS = XPathFactory.class;
361
362
private static String which( Class clazz ) {
363
return which( clazz.getName(), clazz.getClassLoader() );
364
}
365
366
/**
367
* <p>Search the specified classloader for the given classname.</p>
368
*
369
* @param classname the fully qualified name of the class to search for
370
* @param loader the classloader to search
371
*
372
* @return the source location of the resource, or null if it wasn't found
373
*/
374
private static String which(String classname, ClassLoader loader) {
375
376
String classnameAsResource = classname.replace('.', '/') + ".class";
377
378
if( loader==null ) loader = ClassLoader.getSystemClassLoader();
379
380
//URL it = loader.getResource(classnameAsResource);
381
URL it = ss.getResourceAsURL(loader, classnameAsResource);
382
if (it != null) {
383
return it.toString();
384
} else {
385
return null;
386
}
387
}
388
}
389
390