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/validation/SchemaFactoryFinder.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.validation;
27
28
import com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory;
29
import java.io.File;
30
import java.lang.reflect.Method;
31
import java.lang.reflect.Modifier;
32
import java.net.URL;
33
import java.security.AccessControlContext;
34
import java.security.AccessController;
35
import java.security.PrivilegedAction;
36
import java.util.Properties;
37
import java.util.ServiceConfigurationError;
38
import java.util.ServiceLoader;
39
40
/**
41
* Implementation of {@link SchemaFactory#newInstance(String)}.
42
*
43
* @author <a href="[email protected]">Kohsuke Kawaguchi</a>
44
* @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:13 $
45
* @since 1.5
46
*/
47
class SchemaFactoryFinder {
48
49
/** debug support code. */
50
private static boolean debug = false;
51
/**
52
*<p> Take care of restrictions imposed by java security model </p>
53
*/
54
private static final SecuritySupport ss = new SecuritySupport();
55
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal";
56
/**
57
* <p>Cache properties for performance.</p>
58
*/
59
private static final Properties cacheProps = new Properties();
60
61
/**
62
* <p>First time requires initialization overhead.</p>
63
*/
64
private static volatile boolean firstTime = true;
65
66
static {
67
// Use try/catch block to support applets
68
try {
69
debug = ss.getSystemProperty("jaxp.debug") != null;
70
} catch (Exception unused) {
71
debug = false;
72
}
73
}
74
75
/**
76
* <p>Conditional debug printing.</p>
77
*
78
* @param msg to print
79
*/
80
private static void debugPrintln(String msg) {
81
if (debug) {
82
System.err.println("JAXP: " + msg);
83
}
84
}
85
86
/**
87
* <p><code>ClassLoader</code> to use to find <code>SchemaFactory</code>.</p>
88
*/
89
private final ClassLoader classLoader;
90
91
/**
92
* <p>Constructor that specifies <code>ClassLoader</code> to use
93
* to find <code>SchemaFactory</code>.</p>
94
*
95
* @param loader
96
* to be used to load resource, {@link SchemaFactory}, and
97
* {@link SchemaFactoryLoader} implementations during
98
* the resolution process.
99
* If this parameter is null, the default system class loader
100
* will be used.
101
*/
102
public SchemaFactoryFinder(ClassLoader loader) {
103
this.classLoader = loader;
104
if( debug ) {
105
debugDisplayClassLoader();
106
}
107
}
108
109
private void debugDisplayClassLoader() {
110
try {
111
if( classLoader == ss.getContextClassLoader() ) {
112
debugPrintln("using thread context class loader ("+classLoader+") for search");
113
return;
114
}
115
} catch( Throwable unused ) {
116
// getContextClassLoader() undefined in JDK1.1
117
}
118
119
if( classLoader==ClassLoader.getSystemClassLoader() ) {
120
debugPrintln("using system class loader ("+classLoader+") for search");
121
return;
122
}
123
124
debugPrintln("using class loader ("+classLoader+") for search");
125
}
126
127
/**
128
* <p>Creates a new {@link SchemaFactory} object for the specified
129
* schema language.</p>
130
*
131
* @param schemaLanguage
132
* See {@link SchemaFactory Schema Language} table in <code>SchemaFactory</code>
133
* for the list of available schema languages.
134
*
135
* @return <code>null</code> if the callee fails to create one.
136
*
137
* @throws NullPointerException
138
* If the <code>schemaLanguage</code> parameter is null.
139
* @throws SchemaFactoryConfigurationError
140
* If a configuration error is encountered.
141
*/
142
public SchemaFactory newFactory(String schemaLanguage) {
143
if(schemaLanguage==null) {
144
throw new NullPointerException();
145
}
146
SchemaFactory f = _newFactory(schemaLanguage);
147
if (f != null) {
148
debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage);
149
} else {
150
debugPrintln("unable to find a factory for " + schemaLanguage);
151
}
152
return f;
153
}
154
155
/**
156
* <p>Lookup a <code>SchemaFactory</code> for the given <code>schemaLanguage</code>.</p>
157
*
158
* @param schemaLanguage Schema language to lookup <code>SchemaFactory</code> for.
159
*
160
* @return <code>SchemaFactory</code> for the given <code>schemaLanguage</code>.
161
*/
162
private SchemaFactory _newFactory(String schemaLanguage) {
163
SchemaFactory sf;
164
165
String propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage;
166
167
// system property look up
168
try {
169
debugPrintln("Looking up system property '"+propertyName+"'" );
170
String r = ss.getSystemProperty(propertyName);
171
if(r!=null) {
172
debugPrintln("The value is '"+r+"'");
173
sf = createInstance(r);
174
if(sf!=null) return sf;
175
} else
176
debugPrintln("The property is undefined.");
177
} catch( Throwable t ) {
178
if( debug ) {
179
debugPrintln("failed to look up system property '"+propertyName+"'" );
180
t.printStackTrace();
181
}
182
}
183
184
String javah = ss.getSystemProperty( "java.home" );
185
String configFile = javah + File.separator +
186
"lib" + File.separator + "jaxp.properties";
187
188
189
// try to read from $java.home/lib/jaxp.properties
190
try {
191
if(firstTime){
192
synchronized(cacheProps){
193
if(firstTime){
194
File f=new File( configFile );
195
firstTime = false;
196
if(ss.doesFileExist(f)){
197
debugPrintln("Read properties file " + f);
198
cacheProps.load(ss.getFileInputStream(f));
199
}
200
}
201
}
202
}
203
final String factoryClassName = cacheProps.getProperty(propertyName);
204
debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
205
206
if (factoryClassName != null) {
207
sf = createInstance(factoryClassName);
208
if(sf != null){
209
return sf;
210
}
211
}
212
} catch (Exception ex) {
213
if (debug) {
214
ex.printStackTrace();
215
}
216
}
217
218
// Try with ServiceLoader
219
final SchemaFactory factoryImpl = findServiceProvider(schemaLanguage);
220
221
// The following assertion should always be true.
222
// Uncomment it, recompile, and run with -ea in case of doubts:
223
// assert factoryImpl == null || factoryImpl.isSchemaLanguageSupported(schemaLanguage);
224
225
if (factoryImpl != null) {
226
return factoryImpl;
227
}
228
229
// platform default
230
if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) {
231
debugPrintln("attempting to use the platform default XML Schema validator");
232
return new XMLSchemaFactory();
233
}
234
235
debugPrintln("all things were tried, but none was found. bailing out.");
236
return null;
237
}
238
239
/** <p>Create class using appropriate ClassLoader.</p>
240
*
241
* @param className Name of class to create.
242
* @return Created class or <code>null</code>.
243
*/
244
private Class<?> createClass(String className) {
245
Class<?> clazz;
246
// make sure we have access to restricted packages
247
boolean internal = false;
248
if (System.getSecurityManager() != null) {
249
if (className != null && className.startsWith(DEFAULT_PACKAGE)) {
250
internal = true;
251
}
252
}
253
254
try {
255
if (classLoader != null && !internal) {
256
clazz = Class.forName(className, false, classLoader);
257
} else {
258
clazz = Class.forName(className);
259
}
260
} catch (Throwable t) {
261
if(debug) {
262
t.printStackTrace();
263
}
264
return null;
265
}
266
267
return clazz;
268
}
269
270
/**
271
* <p>Creates an instance of the specified and returns it.</p>
272
*
273
* @param className
274
* fully qualified class name to be instantiated.
275
*
276
* @return null
277
* if it fails. Error messages will be printed by this method.
278
*/
279
SchemaFactory createInstance(String className) {
280
SchemaFactory schemaFactory = null;
281
282
debugPrintln("createInstance(" + className + ")");
283
284
// get Class from className
285
Class<?> clazz = createClass(className);
286
if (clazz == null) {
287
debugPrintln("failed to getClass(" + className + ")");
288
return null;
289
}
290
debugPrintln("loaded " + className + " from " + which(clazz));
291
292
// instantiate Class as a SchemaFactory
293
try {
294
if (!SchemaFactory.class.isAssignableFrom(clazz)) {
295
throw new ClassCastException(clazz.getName()
296
+ " cannot be cast to " + SchemaFactory.class);
297
}
298
schemaFactory = (SchemaFactory) clazz.newInstance();
299
} catch (ClassCastException classCastException) {
300
debugPrintln("could not instantiate " + clazz.getName());
301
if (debug) {
302
classCastException.printStackTrace();
303
}
304
return null;
305
} catch (IllegalAccessException illegalAccessException) {
306
debugPrintln("could not instantiate " + clazz.getName());
307
if (debug) {
308
illegalAccessException.printStackTrace();
309
}
310
return null;
311
} catch (InstantiationException instantiationException) {
312
debugPrintln("could not instantiate " + clazz.getName());
313
if (debug) {
314
instantiationException.printStackTrace();
315
}
316
return null;
317
}
318
319
return schemaFactory;
320
}
321
322
// Call isSchemaLanguageSupported with initial context.
323
private boolean isSchemaLanguageSupportedBy(final SchemaFactory factory,
324
final String schemaLanguage,
325
AccessControlContext acc) {
326
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
327
public Boolean run() {
328
return factory.isSchemaLanguageSupported(schemaLanguage);
329
}
330
}, acc);
331
}
332
333
/**
334
* Finds a service provider subclass of SchemaFactory that supports the
335
* given schema language using the ServiceLoader.
336
*
337
* @param schemaLanguage The schema language for which we seek a factory.
338
* @return A SchemaFactory supporting the specified schema language, or null
339
* if none is found.
340
* @throws SchemaFactoryConfigurationError if a configuration error is found.
341
*/
342
private SchemaFactory findServiceProvider(final String schemaLanguage) {
343
assert schemaLanguage != null;
344
// store current context.
345
final AccessControlContext acc = AccessController.getContext();
346
try {
347
return AccessController.doPrivileged(new PrivilegedAction<SchemaFactory>() {
348
public SchemaFactory run() {
349
final ServiceLoader<SchemaFactory> loader =
350
ServiceLoader.load(SERVICE_CLASS);
351
for (SchemaFactory factory : loader) {
352
// restore initial context to call
353
// factory.isSchemaLanguageSupported
354
if (isSchemaLanguageSupportedBy(factory, schemaLanguage, acc)) {
355
return factory;
356
}
357
}
358
return null; // no factory found.
359
}
360
});
361
} catch (ServiceConfigurationError error) {
362
throw new SchemaFactoryConfigurationError(
363
"Provider for " + SERVICE_CLASS + " cannot be created", error);
364
}
365
}
366
367
private static final Class<SchemaFactory> SERVICE_CLASS = SchemaFactory.class;
368
369
370
private static String which( Class<?> clazz ) {
371
return which( clazz.getName(), clazz.getClassLoader() );
372
}
373
374
/**
375
* <p>Search the specified classloader for the given classname.</p>
376
*
377
* @param classname the fully qualified name of the class to search for
378
* @param loader the classloader to search
379
*
380
* @return the source location of the resource, or null if it wasn't found
381
*/
382
private static String which(String classname, ClassLoader loader) {
383
384
String classnameAsResource = classname.replace('.', '/') + ".class";
385
386
if( loader==null ) loader = ClassLoader.getSystemClassLoader();
387
388
//URL it = loader.getResource(classnameAsResource);
389
URL it = ss.getResourceAsURL(loader, classnameAsResource);
390
if (it != null) {
391
return it.toString();
392
} else {
393
return null;
394
}
395
}
396
}
397
398