1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.utils; 22 23 /** 24 * This class is duplicated for each JAXP subpackage so keep it in sync. 25 * It is package private and therefore is not exposed as part of the JAXP 26 * API. 27 * <p> 28 * This code is designed to implement the JAXP 1.1 spec pluggability 29 * feature and is designed to run on JDK version 1.1 and 30 * later, and to compile on JDK 1.2 and onward. 31 * The code also runs both as part of an unbundled jar file and 32 * when bundled as part of the JDK. 33 * <p> 34 * 35 * @version $Id: ObjectFactory.java,v 1.6 2010/04/23 01:44:34 joehw Exp $ 36 */ 37 public final class ObjectFactory { 38 39 // 40 // Constants 41 // 42 private static final String JAXP_INTERNAL = "com.sun.org.apache"; 43 private static final String STAX_INTERNAL = "com.sun.xml.internal"; 44 45 /** Set to true for debugging */ 46 private static final boolean DEBUG = isDebugEnabled(); 47 48 49 // 50 // Private static methods 51 // 52 53 /** Returns true if debug has been enabled. */ 54 private static boolean isDebugEnabled() { 55 try { 56 String val = SecuritySupport.getSystemProperty("xerces.debug"); 57 // Allow simply setting the prop to turn on debug 58 return (val != null && (!"false".equals(val))); 59 } 60 catch (SecurityException se) {} 61 return false; 62 } // isDebugEnabled() 63 64 /** Prints a message to standard error if debugging is enabled. */ 65 private static void debugPrintln(String msg) { 66 if (DEBUG) { 67 System.err.println("XERCES: " + msg); 68 } 69 } // debugPrintln(String) 70 71 /** 72 * Figure out which ClassLoader to use. For JDK 1.2 and later use 73 * the context ClassLoader. 74 */ 75 public static ClassLoader findClassLoader() 76 throws ConfigurationError 77 { 78 if (System.getSecurityManager()!=null) { 79 //this will ensure bootclassloader is used 80 return null; 81 } 82 // Figure out which ClassLoader to use for loading the provider 83 // class. If there is a Context ClassLoader then use it. 84 ClassLoader context = SecuritySupport.getContextClassLoader(); 85 ClassLoader system = SecuritySupport.getSystemClassLoader(); 86 87 ClassLoader chain = system; 88 while (true) { 89 if (context == chain) { 90 // Assert: we are on JDK 1.1 or we have no Context ClassLoader 91 // or any Context ClassLoader in chain of system classloader 92 // (including extension ClassLoader) so extend to widest 93 // ClassLoader (always look in system ClassLoader if Xerces 94 // is in boot/extension/system classpath and in current 95 // ClassLoader otherwise); normal classloaders delegate 96 // back to system ClassLoader first so this widening doesn't 97 // change the fact that context ClassLoader will be consulted 98 ClassLoader current = ObjectFactory.class.getClassLoader(); 99 100 chain = system; 101 while (true) { 102 if (current == chain) { 103 // Assert: Current ClassLoader in chain of 104 // boot/extension/system ClassLoaders 105 return system; 106 } 107 if (chain == null) { 108 break; 109 } 110 chain = SecuritySupport.getParentClassLoader(chain); 111 } 112 113 // Assert: Current ClassLoader not in chain of 114 // boot/extension/system ClassLoaders 115 return current; 116 } 117 118 if (chain == null) { 119 // boot ClassLoader reached 120 break; 121 } 122 123 // Check for any extension ClassLoaders in chain up to 124 // boot ClassLoader 125 chain = SecuritySupport.getParentClassLoader(chain); 126 } 127 128 // Assert: Context ClassLoader not in chain of 129 // boot/extension/system ClassLoaders 130 return context; 131 } // findClassLoader():ClassLoader 132 133 /** 134 * Create an instance of a class using the same classloader for the ObjectFactory by default 135 * or bootclassloader when Security Manager is in place 136 */ 137 public static Object newInstance(String className, boolean doFallback) 138 throws ConfigurationError 139 { 140 if (System.getSecurityManager()!=null) { 141 return newInstance(className, null, doFallback); 142 } else { 143 return newInstance(className, 144 findClassLoader (), doFallback); 145 } 146 } 147 148 /** 149 * Create an instance of a class using the specified ClassLoader 150 */ 151 public static Object newInstance(String className, ClassLoader cl, 152 boolean doFallback) 153 throws ConfigurationError 154 { 155 // assert(className != null); 156 try{ 157 Class providerClass = findProviderClass(className, cl, doFallback); 158 Object instance = providerClass.newInstance(); 159 if (DEBUG) debugPrintln("created new instance of " + providerClass + 160 " using ClassLoader: " + cl); 161 return instance; 162 } catch (ClassNotFoundException x) { 163 throw new ConfigurationError( 164 "Provider " + className + " not found", x); 165 } catch (Exception x) { 166 throw new ConfigurationError( 167 "Provider " + className + " could not be instantiated: " + x, 168 x); 169 } 170 } 171 172 /** 173 * Find a Class using the same classloader for the ObjectFactory by default 174 * or bootclassloader when Security Manager is in place 175 */ 176 public static Class findProviderClass(String className, boolean doFallback) 177 throws ClassNotFoundException, ConfigurationError 178 { 179 return findProviderClass (className, 180 findClassLoader (), doFallback); 181 } 182 /** 183 * Find a Class using the specified ClassLoader 184 */ 185 public static Class findProviderClass(String className, ClassLoader cl, 186 boolean doFallback) 187 throws ClassNotFoundException, ConfigurationError 188 { 189 //throw security exception if the calling thread is not allowed to access the package 190 //restrict the access to package as speicified in java.security policy 191 SecurityManager security = System.getSecurityManager(); 192 if (security != null) { 193 if (className.startsWith(JAXP_INTERNAL) || 194 className.startsWith(STAX_INTERNAL)) { 195 cl = null; 196 } else { 197 final int lastDot = className.lastIndexOf("."); 198 String packageName = className; 199 if (lastDot != -1) packageName = className.substring(0, lastDot); 200 security.checkPackageAccess(packageName); 201 } 202 } 203 Class providerClass; 204 if (cl == null) { 205 //use the bootstrap ClassLoader. 206 providerClass = Class.forName(className, false, ObjectFactory.class.getClassLoader()); 207 } else { 208 try { 209 providerClass = cl.loadClass(className); 210 } catch (ClassNotFoundException x) { 211 if (doFallback) { 212 // Fall back to current classloader 213 ClassLoader current = ObjectFactory.class.getClassLoader(); 214 if (current == null) { 215 providerClass = Class.forName(className); 216 } else if (cl != current) { 217 cl = current; 218 providerClass = cl.loadClass(className); 219 } else { 220 throw x; 221 } 222 } else { 223 throw x; 224 } 225 } 226 } 227 228 return providerClass; 229 } 230 231 } // class ObjectFactory