author | duke |
Wed, 05 Jul 2017 20:05:43 +0200 | |
changeset 27256 | 61c8e362c4a1 |
parent 25868 | 686eef1e7a79 |
child 27574 | 2e8afdf5c6fb |
permissions | -rw-r--r-- |
12005 | 1 |
/* |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
2 |
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. |
12005 | 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 java.io.File; |
|
29 |
import java.lang.reflect.Method; |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
30 |
import java.lang.reflect.Modifier; |
12005 | 31 |
import java.net.URL; |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
32 |
import java.security.AccessControlContext; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
33 |
import java.security.AccessController; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
34 |
import java.security.PrivilegedAction; |
12005 | 35 |
import java.util.Properties; |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
36 |
import java.util.ServiceConfigurationError; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
37 |
import java.util.ServiceLoader; |
12005 | 38 |
|
39 |
/** |
|
40 |
* Implementation of {@link XPathFactory#newInstance(String)}. |
|
41 |
* |
|
42 |
* @author <a href="Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> |
|
43 |
* @since 1.5 |
|
44 |
*/ |
|
45 |
class XPathFactoryFinder { |
|
16953 | 46 |
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xpath.internal"; |
12005 | 47 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
48 |
private static final SecuritySupport ss = new SecuritySupport() ; |
12005 | 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; |
|
15545 | 55 |
} catch (Exception unused) { |
12005 | 56 |
debug = false; |
57 |
} |
|
58 |
} |
|
59 |
||
60 |
/** |
|
61 |
* <p>Cache properties for performance.</p> |
|
62 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
63 |
private static final Properties cacheProps = new Properties(); |
12005 | 64 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
65 |
/** |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
66 |
* <p>First time requires initialization overhead.</p> |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
67 |
*/ |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
68 |
private volatile static boolean firstTime = true; |
12005 | 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 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
91 |
* to be used to load resource and {@link XPathFactory} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
92 |
* implementations during the resolution process. |
12005 | 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 |
} |
|
15545 | 109 |
} catch( Throwable unused ) { |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
110 |
// getContextClassLoader() undefined in JDK1.1 |
12005 | 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 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
123 |
* object model.</p> |
12005 | 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 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
133 |
public XPathFactory newFactory(String uri) throws XPathFactoryConfigurationException { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
134 |
if (uri == null) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
135 |
throw new NullPointerException(); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
136 |
} |
12005 | 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 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
153 |
private XPathFactory _newFactory(String uri) throws XPathFactoryConfigurationException { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
154 |
XPathFactory xpathFactory = null; |
12005 | 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+"'"); |
|
12458 | 164 |
xpathFactory = createInstance(r, true); |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
165 |
if (xpathFactory != null) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
166 |
return xpathFactory; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
167 |
} |
12005 | 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 |
} |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
195 |
final String factoryClassName = cacheProps.getProperty(propertyName); |
12005 | 196 |
debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); |
197 |
||
198 |
if (factoryClassName != null) { |
|
12458 | 199 |
xpathFactory = createInstance(factoryClassName, true); |
12005 | 200 |
if(xpathFactory != null){ |
201 |
return xpathFactory; |
|
202 |
} |
|
203 |
} |
|
204 |
} catch (Exception ex) { |
|
205 |
if (debug) { |
|
206 |
ex.printStackTrace(); |
|
207 |
} |
|
208 |
} |
|
209 |
||
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
210 |
// Try with ServiceLoader |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
211 |
assert xpathFactory == null; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
212 |
xpathFactory = findServiceProvider(uri); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
213 |
|
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
214 |
// The following assertion should always be true. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
215 |
// Uncomment it, recompile, and run with -ea in case of doubts: |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
216 |
// assert xpathFactory == null || xpathFactory.isObjectModelSupported(uri); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
217 |
|
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
218 |
if (xpathFactory != null) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
219 |
return xpathFactory; |
12005 | 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"); |
|
12458 | 225 |
return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", true); |
12005 | 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 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
237 |
private Class<?> createClass(String className) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
238 |
Class clazz; |
16953 | 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 |
} |
|
12005 | 246 |
|
16953 | 247 |
// use approprite ClassLoader |
248 |
try { |
|
249 |
if (classLoader != null && !internal) { |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
250 |
clazz = Class.forName(className, false, classLoader); |
16953 | 251 |
} else { |
252 |
clazz = Class.forName(className); |
|
12005 | 253 |
} |
16953 | 254 |
} catch (Throwable t) { |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
255 |
if(debug) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
256 |
t.printStackTrace(); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
257 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
258 |
return null; |
16953 | 259 |
} |
12005 | 260 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
261 |
return clazz; |
12005 | 262 |
} |
263 |
||
264 |
/** |
|
265 |
* <p>Creates an instance of the specified and returns it.</p> |
|
266 |
* |
|
267 |
* @param className |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
268 |
* fully qualified class name to be instantiated. |
12005 | 269 |
* |
270 |
* @return null |
|
271 |
* if it fails. Error messages will be printed by this method. |
|
272 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
273 |
XPathFactory createInstance( String className ) |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
274 |
throws XPathFactoryConfigurationException |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
275 |
{ |
12458 | 276 |
return createInstance( className, false ); |
277 |
} |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
278 |
|
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
279 |
XPathFactory createInstance( String className, boolean useServicesMechanism ) |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
280 |
throws XPathFactoryConfigurationException |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
281 |
{ |
12005 | 282 |
XPathFactory xPathFactory = null; |
283 |
||
284 |
debugPrintln("createInstance(" + className + ")"); |
|
285 |
||
286 |
// get Class from className |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
287 |
Class<?> clazz = createClass(className); |
12005 | 288 |
if (clazz == null) { |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
289 |
debugPrintln("failed to getClass(" + className + ")"); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
290 |
return null; |
12005 | 291 |
} |
292 |
debugPrintln("loaded " + className + " from " + which(clazz)); |
|
293 |
||
294 |
// instantiate Class as a XPathFactory |
|
295 |
try { |
|
12458 | 296 |
if (!useServicesMechanism) { |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
297 |
xPathFactory = newInstanceNoServiceLoader(clazz); |
12458 | 298 |
} |
299 |
if (xPathFactory == null) { |
|
12005 | 300 |
xPathFactory = (XPathFactory) clazz.newInstance(); |
12458 | 301 |
} |
12005 | 302 |
} catch (ClassCastException classCastException) { |
303 |
debugPrintln("could not instantiate " + clazz.getName()); |
|
304 |
if (debug) { |
|
305 |
classCastException.printStackTrace(); |
|
306 |
} |
|
307 |
return null; |
|
308 |
} catch (IllegalAccessException illegalAccessException) { |
|
309 |
debugPrintln("could not instantiate " + clazz.getName()); |
|
310 |
if (debug) { |
|
311 |
illegalAccessException.printStackTrace(); |
|
312 |
} |
|
313 |
return null; |
|
314 |
} catch (InstantiationException instantiationException) { |
|
315 |
debugPrintln("could not instantiate " + clazz.getName()); |
|
316 |
if (debug) { |
|
317 |
instantiationException.printStackTrace(); |
|
318 |
} |
|
319 |
return null; |
|
320 |
} |
|
321 |
||
322 |
return xPathFactory; |
|
323 |
} |
|
12458 | 324 |
/** |
325 |
* Try to construct using newXPathFactoryNoServiceLoader |
|
326 |
* method if available. |
|
327 |
*/ |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
328 |
private static XPathFactory newInstanceNoServiceLoader( |
12458 | 329 |
Class<?> providerClass |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
330 |
) throws XPathFactoryConfigurationException { |
12458 | 331 |
// Retain maximum compatibility if no security manager. |
332 |
if (System.getSecurityManager() == null) { |
|
333 |
return null; |
|
334 |
} |
|
335 |
try { |
|
336 |
Method creationMethod = |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
337 |
providerClass.getDeclaredMethod( |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
338 |
"newXPathFactoryNoServiceLoader" |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
339 |
); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
340 |
final int modifiers = creationMethod.getModifiers(); |
12005 | 341 |
|
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
342 |
// Do not call "newXPathFactoryNoServiceLoader" if it's |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
343 |
// not public static. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
344 |
if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
345 |
return null; |
12005 | 346 |
} |
347 |
||
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
348 |
// Only calls "newXPathFactoryNoServiceLoader" if it's |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
349 |
// declared to return an instance of XPathFactory. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
350 |
final Class<?> returnType = creationMethod.getReturnType(); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
351 |
if (SERVICE_CLASS.isAssignableFrom(returnType)) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
352 |
return SERVICE_CLASS.cast(creationMethod.invoke(null, (Object[])null)); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
353 |
} else { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
354 |
// Should not happen since |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
355 |
// XPathFactoryImpl.newXPathFactoryNoServiceLoader is |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
356 |
// declared to return XPathFactory. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
357 |
throw new ClassCastException(returnType |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
358 |
+ " cannot be cast to " + SERVICE_CLASS); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
359 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
360 |
} catch (ClassCastException e) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
361 |
throw new XPathFactoryConfigurationException(e); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
362 |
} catch (NoSuchMethodException exc) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
363 |
return null; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
364 |
} catch (Exception exc) { |
12005 | 365 |
return null; |
366 |
} |
|
367 |
} |
|
368 |
||
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
369 |
// Call isObjectModelSupportedBy with initial context. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
370 |
private boolean isObjectModelSupportedBy(final XPathFactory factory, |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
371 |
final String objectModel, |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
372 |
AccessControlContext acc) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
373 |
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
374 |
public Boolean run() { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
375 |
return factory.isObjectModelSupported(objectModel); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
376 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
377 |
}, acc); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
378 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
379 |
|
12005 | 380 |
/** |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
381 |
* Finds a service provider subclass of XPathFactory that supports the |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
382 |
* given object model using the ServiceLoader. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
383 |
* |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
384 |
* @param objectModel URI of object model to support. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
385 |
* @return An XPathFactory supporting the specified object model, or null |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
386 |
* if none is found. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
387 |
* @throws XPathFactoryConfigurationException if a configuration error is found. |
12005 | 388 |
*/ |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
389 |
private XPathFactory findServiceProvider(final String objectModel) |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
390 |
throws XPathFactoryConfigurationException { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
391 |
|
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
392 |
assert objectModel != null; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
393 |
// store current context. |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
394 |
final AccessControlContext acc = AccessController.getContext(); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
395 |
try { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
396 |
return AccessController.doPrivileged(new PrivilegedAction<XPathFactory>() { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
397 |
public XPathFactory run() { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
398 |
final ServiceLoader<XPathFactory> loader = |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
399 |
ServiceLoader.load(SERVICE_CLASS); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
400 |
for (XPathFactory factory : loader) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
401 |
// restore initial context to call |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
402 |
// factory.isObjectModelSupportedBy |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
403 |
if (isObjectModelSupportedBy(factory, objectModel, acc)) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
404 |
return factory; |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
405 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
406 |
} |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
407 |
return null; // no factory found. |
12005 | 408 |
} |
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
409 |
}); |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
410 |
} catch (ServiceConfigurationError error) { |
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
411 |
throw new XPathFactoryConfigurationException(error); |
12005 | 412 |
} |
413 |
} |
|
414 |
||
17264
3aff554ad461
8005954: JAXP Plugability Layer should use java.util.ServiceLoader
dfuchs
parents:
16953
diff
changeset
|
415 |
private static final Class<XPathFactory> SERVICE_CLASS = XPathFactory.class; |
12005 | 416 |
|
417 |
private static String which( Class clazz ) { |
|
418 |
return which( clazz.getName(), clazz.getClassLoader() ); |
|
419 |
} |
|
420 |
||
421 |
/** |
|
422 |
* <p>Search the specified classloader for the given classname.</p> |
|
423 |
* |
|
424 |
* @param classname the fully qualified name of the class to search for |
|
425 |
* @param loader the classloader to search |
|
426 |
* |
|
427 |
* @return the source location of the resource, or null if it wasn't found |
|
428 |
*/ |
|
429 |
private static String which(String classname, ClassLoader loader) { |
|
430 |
||
431 |
String classnameAsResource = classname.replace('.', '/') + ".class"; |
|
432 |
||
433 |
if( loader==null ) loader = ClassLoader.getSystemClassLoader(); |
|
434 |
||
435 |
//URL it = loader.getResource(classnameAsResource); |
|
436 |
URL it = ss.getResourceAsURL(loader, classnameAsResource); |
|
437 |
if (it != null) { |
|
438 |
return it.toString(); |
|
439 |
} else { |
|
440 |
return null; |
|
441 |
} |
|
442 |
} |
|
443 |
} |