19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id$ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.utils; 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.InputStream; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException; 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.File; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.FileInputStream; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Properties; 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.BufferedReader; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.InputStreamReader; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class is duplicated for each JAXP subpackage so keep it in sync. 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It is package private and therefore is not exposed as part of the JAXP 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * API. 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This code is designed to implement the JAXP 1.1 spec pluggability 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * feature and is designed to run on JDK version 1.1 and 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * later, and to compile on JDK 1.2 and onward. 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The code also runs both as part of an unbundled jar file and 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * when bundled as part of the JDK. 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p> 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code> 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * class and modified to be used as a general utility for creating objects 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * dynamically. 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @version $Id: $ 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonclass ObjectFactory { 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Constants 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // name of default properties file to look for in JDK's jre/lib directory 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static final String DEFAULT_PROPERTIES_FILENAME = 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "xalan.properties"; 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static final String SERVICES_PATH = "META-INF/services/"; 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Set to true for debugging */ 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static final boolean DEBUG = false; 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** cache the contents of the xalan.properties file. 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Until an attempt has been made to read this file, this will 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * be null; if the file does not exist or we encounter some other error 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * during the read, this will be empty. 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static Properties fXalanProperties = null; 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /*** 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Cache the time stamp of the xalan.properties file so 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * that we know if it's been modified and can invalidate 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the cache when necessary. 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static long fLastModified = -1; 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Public static methods 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Finds the implementation Class object in the specified order. The 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified order is the following: 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <ol> 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>query the system property using <code>System.getProperty</code> 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>META-INF/services/<i>factoryId</i></code> file 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>use fallback classname 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </ol> 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return instance of factory, never null 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param factoryId Name of the factory to find, same as 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a property name 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param fallbackClassName Implementation class name, if nothing else 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is found. Use null to mean no fallback. 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @exception ObjectFactory.ConfigurationError 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Object createObject(String factoryId, String fallbackClassName) 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError { 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return createObject(factoryId, null, fallbackClassName); 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // createObject(String,String):Object 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Finds the implementation Class object in the specified order. The 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified order is the following: 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <ol> 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>query the system property using <code>System.getProperty</code> 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>META-INF/services/<i>factoryId</i></code> file 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>use fallback classname 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </ol> 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return instance of factory, never null 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param factoryId Name of the factory to find, same as 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a property name 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param propertiesFilename The filename in the $java.home/lib directory 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the properties file. If none specified, 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ${java.home}/lib/xalan.properties will be used. 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param fallbackClassName Implementation class name, if nothing else 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is found. Use null to mean no fallback. 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @exception ObjectFactory.ConfigurationError 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Object createObject(String factoryId, 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String propertiesFilename, 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fallbackClassName) 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Class factoryClass = lookUpFactoryClass(factoryId, 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson propertiesFilename, 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fallbackClassName); 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (factoryClass == null) { 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider for " + factoryId + " cannot be found", null); 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try{ 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object instance = factoryClass.newInstance(); 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("created new instance of factory " + factoryId); 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return instance; 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (Exception x) { 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider for factory " + factoryId 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + " could not be instantiated: " + x, x); 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // createObject(String,String,String):Object 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Finds the implementation Class object in the specified order. The 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified order is the following: 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <ol> 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>query the system property using <code>System.getProperty</code> 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>META-INF/services/<i>factoryId</i></code> file 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>use fallback classname 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </ol> 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Class object of factory, never null 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param factoryId Name of the factory to find, same as 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a property name 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param propertiesFilename The filename in the $java.home/lib directory 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the properties file. If none specified, 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ${java.home}/lib/xalan.properties will be used. 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param fallbackClassName Implementation class name, if nothing else 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is found. Use null to mean no fallback. 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @exception ObjectFactory.ConfigurationError 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Class lookUpFactoryClass(String factoryId) 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return lookUpFactoryClass(factoryId, null, null); 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // lookUpFactoryClass(String):Class 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Finds the implementation Class object in the specified order. The 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specified order is the following: 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <ol> 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>query the system property using <code>System.getProperty</code> 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>META-INF/services/<i>factoryId</i></code> file 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>use fallback classname 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </ol> 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Class object that provides factory service, never null 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param factoryId Name of the factory to find, same as 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a property name 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param propertiesFilename The filename in the $java.home/lib directory 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the properties file. If none specified, 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ${java.home}/lib/xalan.properties will be used. 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param fallbackClassName Implementation class name, if nothing else 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is found. Use null to mean no fallback. 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @exception ObjectFactory.ConfigurationError 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Class lookUpFactoryClass(String factoryId, 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String propertiesFilename, 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fallbackClassName) 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String factoryClassName = lookUpFactoryClassName(factoryId, 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson propertiesFilename, 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fallbackClassName); 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader cl = findClassLoader(); 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (factoryClassName == null) { 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson factoryClassName = fallbackClassName; 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assert(className != null); 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try{ 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Class providerClass = findProviderClass(factoryClassName, 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson cl, 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson true); 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("created new instance of " + providerClass + 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson " using ClassLoader: " + cl); 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return providerClass; 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (ClassNotFoundException x) { 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider " + factoryClassName + " not found", x); 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (Exception x) { 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider "+factoryClassName+" could not be instantiated: "+x, 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson x); 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // lookUpFactoryClass(String,String,String):Class 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Finds the name of the required implementation class in the specified 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * order. The specified order is the following: 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <ol> 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>query the system property using <code>System.getProperty</code> 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>read <code>META-INF/services/<i>factoryId</i></code> file 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <li>use fallback classname 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </ol> 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return name of class that provides factory service, never null 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param factoryId Name of the factory to find, same as 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a property name 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param propertiesFilename The filename in the $java.home/lib directory 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the properties file. If none specified, 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ${java.home}/lib/xalan.properties will be used. 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param fallbackClassName Implementation class name, if nothing else 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is found. Use null to mean no fallback. 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @exception ObjectFactory.ConfigurationError 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static String lookUpFactoryClassName(String factoryId, 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String propertiesFilename, 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fallbackClassName) 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson SecuritySupport ss = SecuritySupport.getInstance(); 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Use the system property first 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String systemProp = ss.getSystemProperty(factoryId); 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (systemProp != null) { 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("found system property, value=" + systemProp); 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return systemProp; 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (SecurityException se) { 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Ignore and continue w/ next location 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Try to read from propertiesFilename, or 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // $java.home/lib/xalan.properties 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String factoryClassName = null; 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // no properties file name specified; use 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // $JAVA_HOME/lib/xalan.properties: 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (propertiesFilename == null) { 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson File propertiesFile = null; 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean propertiesFileExists = false; 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String javah = ss.getSystemProperty("java.home"); 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson propertiesFilename = javah + File.separator + 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson propertiesFile = new File(propertiesFilename); 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson propertiesFileExists = ss.getFileExists(propertiesFile); 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (SecurityException e) { 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // try again... 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fLastModified = -1; 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXalanProperties = null; 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson synchronized (ObjectFactory.class) { 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean loadProperties = false; 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FileInputStream fis = null; 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // file existed last time 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fLastModified >= 0) { 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(propertiesFileExists && 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson loadProperties = true; 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // file has stopped existing... 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(!propertiesFileExists) { 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fLastModified = -1; 3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXalanProperties = null; 3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // else, file wasn't modified! 3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // file has started to exist: 3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(propertiesFileExists) { 3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson loadProperties = true; 3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fLastModified = ss.getLastModified(propertiesFile); 3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // else, nothing's changed 3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(loadProperties) { 3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // must never have attempted to read xalan.properties 3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // before (or it's outdeated) 3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXalanProperties = new Properties(); 3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fis = ss.getFileInputStream(propertiesFile); 3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXalanProperties.load(fis); 3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (Exception x) { 3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXalanProperties = null; 3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fLastModified = -1; 3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assert(x instanceof FileNotFoundException 3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // || x instanceof SecurityException) 3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // In both cases, ignore and continue w/ next location 3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson finally { 3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // try to close the input stream if one was opened. 3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (fis != null) { 3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fis.close(); 3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Ignore the exception. 3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch (IOException exc) {} 3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fXalanProperties != null) { 3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson factoryClassName = fXalanProperties.getProperty(factoryId); 3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson FileInputStream fis = null; 3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fis = ss.getFileInputStream(new File(propertiesFilename)); 3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Properties props = new Properties(); 3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson props.load(fis); 3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson factoryClassName = props.getProperty(factoryId); 3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (Exception x) { 3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assert(x instanceof FileNotFoundException 3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // || x instanceof SecurityException) 3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // In both cases, ignore and continue w/ next location 3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson finally { 3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // try to close the input stream if one was opened. 3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (fis != null) { 3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fis.close(); 3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Ignore the exception. 3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch (IOException exc) {} 3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (factoryClassName != null) { 3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("found in " + propertiesFilename + ", value=" 3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + factoryClassName); 3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return factoryClassName; 3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Try Jar Service Provider Mechanism 3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return findJarServiceProviderName(factoryId); 3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // lookUpFactoryClass(String,String):String 3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Private static methods 3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Prints a message to standard error if debugging is enabled. */ 3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static void debugPrintln(String msg) { 3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (DEBUG) { 3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.err.println("JAXP: " + msg); 3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // debugPrintln(String) 3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Figure out which ClassLoader to use. For JDK 1.2 and later use 3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the context ClassLoader. 3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static ClassLoader findClassLoader() 3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError 3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson SecuritySupport ss = SecuritySupport.getInstance(); 3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Figure out which ClassLoader to use for loading the provider 3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // class. If there is a Context ClassLoader then use it. 4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader context = ss.getContextClassLoader(); 4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader system = ss.getSystemClassLoader(); 4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader chain = system; 4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (true) { 4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (context == chain) { 4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assert: we are on JDK 1.1 or we have no Context ClassLoader 4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // or any Context ClassLoader in chain of system classloader 4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (including extension ClassLoader) so extend to widest 4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ClassLoader (always look in system ClassLoader if Xalan 4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // is in boot/extension/system classpath and in current 4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ClassLoader otherwise); normal classloaders delegate 4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // back to system ClassLoader first so this widening doesn't 4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // change the fact that context ClassLoader will be consulted 4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader current = ObjectFactory.class.getClassLoader(); 4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chain = system; 4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (true) { 4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (current == chain) { 4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assert: Current ClassLoader in chain of 4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // boot/extension/system ClassLoaders 4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return system; 4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (chain == null) { 4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chain = ss.getParentClassLoader(chain); 4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assert: Current ClassLoader not in chain of 4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // boot/extension/system ClassLoaders 4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return current; 4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (chain == null) { 4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // boot ClassLoader reached 4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson break; 4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Check for any extension ClassLoaders in chain up to 4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // boot ClassLoader 4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson chain = ss.getParentClassLoader(chain); 4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson }; 4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Assert: Context ClassLoader not in chain of 4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // boot/extension/system ClassLoaders 4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return context; 4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // findClassLoader():ClassLoader 4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Create an instance of a class using the specified ClassLoader 4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Object newInstance(String className, ClassLoader cl, 4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean doFallback) 4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ConfigurationError 4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // assert(className != null); 4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try{ 4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Class providerClass = findProviderClass(className, cl, doFallback); 4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object instance = providerClass.newInstance(); 4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("created new instance of " + providerClass + 4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson " using ClassLoader: " + cl); 4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return instance; 4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (ClassNotFoundException x) { 4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider " + className + " not found", x); 4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (Exception x) { 4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new ConfigurationError( 4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "Provider " + className + " could not be instantiated: " + x, 4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson x); 4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Find a Class using the specified ClassLoader 4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static Class findProviderClass(String className, ClassLoader cl, 4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean doFallback) 4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws ClassNotFoundException, ConfigurationError 4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //throw security exception if the calling thread is not allowed to access the 4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //class. Restrict the access to the package classes as specified in java.security policy. 4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson SecurityManager security = System.getSecurityManager(); 4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try{ 4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (security != null){ 4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson final int lastDot = className.lastIndexOf("."); 4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String packageName = className; 4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (lastDot != -1) packageName = className.substring(0, lastDot); 4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson security.checkPackageAccess(packageName); 4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson }catch(SecurityException e){ 4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw e; 4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Class providerClass; 4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (cl == null) { 4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XXX Use the bootstrap ClassLoader. There is no way to 4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // load a class using the bootstrap ClassLoader that works 4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // in both JDK 1.1 and Java 2. However, this should still 4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // work b/c the following should be true: 5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (cl == null) iff current ClassLoader == null 5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Thus Class.forName(String) will use the current 5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ClassLoader which will be the bootstrap ClassLoader. 5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson providerClass = Class.forName(className); 5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson providerClass = cl.loadClass(className); 5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (ClassNotFoundException x) { 5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (doFallback) { 5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Fall back to current classloader 5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader current = ObjectFactory.class.getClassLoader(); 5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (current == null) { 5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson providerClass = Class.forName(className); 5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else if (cl != current) { 5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson cl = current; 5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson providerClass = cl.loadClass(className); 5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw x; 5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw x; 5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return providerClass; 5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Find the name of service provider using Jar Service Provider Mechanism 5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return instance of provider class if found or null 5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static String findJarServiceProviderName(String factoryId) 5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson SecuritySupport ss = SecuritySupport.getInstance(); 5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String serviceId = SERVICES_PATH + factoryId; 5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson InputStream is = null; 5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // First try the Context ClassLoader 5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader cl = findClassLoader(); 5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson is = ss.getResourceAsStream(cl, serviceId); 5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If no provider found then try the current ClassLoader 5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (is == null) { 5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ClassLoader current = ObjectFactory.class.getClassLoader(); 5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (cl != current) { 5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson cl = current; 5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson is = ss.getResourceAsStream(cl, serviceId); 5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (is == null) { 5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No provider found 5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("found jar resource=" + serviceId + 5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson " using ClassLoader: " + cl); 5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Read the service provider name in UTF-8 as specified in 5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the jar spec. Unfortunately this fails in Microsoft 5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // VJ++, which does not implement the UTF-8 5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // encoding. Theoretically, we should simply let it fail in 5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // that case, since the JVM is obviously broken if it 5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // doesn't support such a basic standard. But since there 5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // are still some users attempting to use VJ++ for 5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // development, we have dropped in a fallback which makes a 5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // second attempt using the platform's default encoding. In 5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // VJ++ this is apparently ASCII, which is a subset of 5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // UTF-8... and since the strings we'll be reading here are 5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // also primarily limited to the 7-bit ASCII range (at 5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // least, in English versions), this should work well 5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // enough to keep us on the air until we're ready to 5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // officially decommit from VJ++. [Edited comment from 5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // jkesselm] 5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson BufferedReader rd; 5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); 5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (java.io.UnsupportedEncodingException e) { 5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson rd = new BufferedReader(new InputStreamReader(is)); 5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String factoryClassName = null; 5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XXX Does not handle all possible input as specified by the 5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Jar Service Provider specification 5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson factoryClassName = rd.readLine(); 5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (IOException x) { 5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No provider found 5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson finally { 5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // try to close the reader. 5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson rd.close(); 5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Ignore the exception. 6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch (IOException exc) {} 6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (factoryClassName != null && 6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ! "".equals(factoryClassName)) { 6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson debugPrintln("found in resource, value=" 6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson + factoryClassName); 6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Note: here we do not want to fall back to the current 6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ClassLoader because we want to avoid the case where the 6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // resource file was found using one ClassLoader and the 6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // provider class was instantiated using a different one. 6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return factoryClassName; 6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // No provider found 6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return null; 6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Classes 6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * A configuration error. 6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static class ConfigurationError 6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson extends Error { 6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final long serialVersionUID = 2036619216663421552L; 6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Data 6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Exception. */ 6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private Exception exception; 6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Constructors 6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Construct a new instance with the specified detail string and 6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * exception. 6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ConfigurationError(String msg, Exception x) { 6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson super(msg); 6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.exception = x; 6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // <init>(String,Exception) 6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Public methods 6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Returns the exception associated to this error. */ 6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Exception getException() { 6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return exception; 6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // getException():Exception 6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // class ConfigurationError 6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} // class ObjectFactory 662