/* * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.xml.parsers; import java.io.File; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Properties; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; /** *
Implements pluggable Parsers.
* *This class is duplicated for each JAXP subpackage so keep it in * sync. It is package private for secure class loading.
* * @author Santiago.PericasGeertsen@sun.com * @author Huizhe.Wang@oracle.com */ class FactoryFinder { /** * Internal debug flag. */ private static boolean debug = false; /** * Cache for properties in java.home/lib/jaxp.properties */ private static final Properties cacheProps = new Properties(); /** * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ static volatile boolean firstTime = true; /** * Security support class use to check access control before * getting certain system resources. */ private static final SecuritySupport ss = new SecuritySupport(); // Define system property "jaxp.debug" to get output static { // Use try/catch block to support applets, which throws // SecurityException out of this code. try { String val = ss.getSystemProperty("jaxp.debug"); // Allow simply setting the prop to turn on debug debug = val != null && !"false".equals(val); } catch (SecurityException se) { debug = false; } } private static void dPrint(String msg) { if (debug) { System.err.println("JAXP: " + msg); } } /** * Attempt to load a class using the class loader supplied. If that fails * and fall back is enabled, the current (i.e. bootstrap) class loader is * tried. * * If the class loader supplied isnull
, first try using the
* context class loader followed by the current (i.e. bootstrap) class
* loader.
*
* Use bootstrap classLoader if cl = null and useBSClsLoader is true
*/
static private Class> getProviderClass(String className, ClassLoader cl,
boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException
{
try {
if (cl == null) {
if (useBSClsLoader) {
return Class.forName(className, true, FactoryFinder.class.getClassLoader());
} else {
cl = ss.getContextClassLoader();
if (cl == null) {
throw new ClassNotFoundException();
}
else {
return Class.forName(className, true, cl);
}
}
}
else {
return Class.forName(className, true, cl);
}
}
catch (ClassNotFoundException e1) {
if (doFallback) {
// Use current class loader - should always be bootstrap CL
return Class.forName(className, true, FactoryFinder.class.getClassLoader());
}
else {
throw e1;
}
}
}
/**
* Create an instance of a class. Delegates to method
* getProviderClass()
in order to load the class.
*
* @param className Name of the concrete class corresponding to the
* service provider
*
* @param cl ClassLoader
used to load the factory class. If null
* current Thread
's context classLoader is used to load the factory class.
*
* @param doFallback True if the current ClassLoader should be tried as
* a fallback if the class is not found using cl
*/
static Object newInstance(String className, ClassLoader cl, boolean doFallback)
throws FactoryConfigurationError
{
return newInstance(className, cl, doFallback, false);
}
/**
* Create an instance of a class. Delegates to method
* getProviderClass()
in order to load the class.
*
* @param className Name of the concrete class corresponding to the
* service provider
*
* @param cl ClassLoader
used to load the factory class. If null
* current Thread
's context classLoader is used to load the factory class.
*
* @param doFallback True if the current ClassLoader should be tried as
* a fallback if the class is not found using cl
*
* @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter
* is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader.
*/
static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader)
throws FactoryConfigurationError
{
try {
Class> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader);
Object instance = providerClass.newInstance();
if (debug) { // Extra check to avoid computing cl strings
dPrint("created new instance of " + providerClass +
" using ClassLoader: " + cl);
}
return instance;
}
catch (ClassNotFoundException x) {
throw new FactoryConfigurationError(x,
"Provider " + className + " not found");
}
catch (Exception x) {
throw new FactoryConfigurationError(x,
"Provider " + className + " could not be instantiated: " + x);
}
}
/**
* Finds the implementation Class object in the specified order. Main
* entry point.
* @return Class object of factory, never null
*
* @param type Base class / Service interface of the
* factory to find.
* @param fallbackClassName Implementation class name, if nothing else
* is found. Use null to mean no fallback.
*
* Package private so this code can be shared.
*/
static