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 */ 36 public final class ObjectFactory { 37 38 // 39 // Constants 40 // 41 private static final String JAXP_INTERNAL = "com.sun.org.apache"; 42 private static final String STAX_INTERNAL = "com.sun.xml.internal"; 43 44 /** Set to true for debugging */ 45 private static final boolean DEBUG = isDebugEnabled(); 46 47 48 // 49 // Private static methods 50 // 51 52 /** Returns true if debug has been enabled. */ 53 private static boolean isDebugEnabled() { 54 try { 55 String val = SecuritySupport.getSystemProperty("xerces.debug"); 56 // Allow simply setting the prop to turn on debug 57 return (val != null && (!"false".equals(val))); 58 } 59 catch (SecurityException se) {} 60 return false; 61 } // isDebugEnabled() 62 63 /** Prints a message to standard error if debugging is enabled. */ 64 private static void debugPrintln(String msg) { 65 if (DEBUG) { 66 System.err.println("XERCES: " + msg); 67 } 68 } // debugPrintln(String) 69 70 /** 71 * Figure out which ClassLoader to use. For JDK 1.2 and later use 72 * the context ClassLoader. 73 */ 74 public static ClassLoader findClassLoader() 75 throws ConfigurationError 76 { 77 if (System.getSecurityManager()!=null) { 78 //this will ensure bootclassloader is used 79 return null; 80 } 81 // Figure out which ClassLoader to use for loading the provider 82 // class. If there is a Context ClassLoader then use it. 83 ClassLoader context = SecuritySupport.getContextClassLoader(); 84 ClassLoader system = SecuritySupport.getSystemClassLoader(); 85 86 ClassLoader chain = system; 87 while (true) { 88 if (context == chain) { 89 // Assert: we are on JDK 1.1 or we have no Context ClassLoader 90 // or any Context ClassLoader in chain of system classloader 91 // (including extension ClassLoader) so extend to widest 92 // ClassLoader (always look in system ClassLoader if Xerces 93 // is in boot/extension/system classpath and in current 94 // ClassLoader otherwise); normal classloaders delegate 95 // back to system ClassLoader first so this widening doesn't 96 // change the fact that context ClassLoader will be consulted 97 ClassLoader current = ObjectFactory.class.getClassLoader(); 98 99 chain = system; 100 while (true) { 101 if (current == chain) { 102 // Assert: Current ClassLoader in chain of 103 // boot/extension/system ClassLoaders 104 return system; 105 } 106 if (chain == null) { 107 break; 108 } 109 chain = SecuritySupport.getParentClassLoader(chain); 110 } 111 112 // Assert: Current ClassLoader not in chain of 113 // boot/extension/system ClassLoaders 114 return current; 115 } 116 117 if (chain == null) { 118 // boot ClassLoader reached 119 break; 120 } 121 122 // Check for any extension ClassLoaders in chain up to 123 // boot ClassLoader 124 chain = SecuritySupport.getParentClassLoader(chain); 125 } 126 127 // Assert: Context ClassLoader not in chain of 128 // boot/extension/system ClassLoaders 129 return context; 130 } // findClassLoader():ClassLoader 131 132 /** 133 * Create an instance of a class using the same classloader for the ObjectFactory by default 134 * or bootclassloader when Security Manager is in place 135 */ 136 public static Object newInstance(String className, boolean doFallback) 137 throws ConfigurationError 138 { 139 if (System.getSecurityManager()!=null) { 140 return newInstance(className, null, doFallback); 141 } else { 142 return newInstance(className, 143 findClassLoader (), doFallback); 144 } 145 } 146 147 /** 148 * Create an instance of a class using the specified ClassLoader 149 */ 150 public static Object newInstance(String className, ClassLoader cl, 151 boolean doFallback) 152 throws ConfigurationError 153 { 154 // assert(className != null); 155 try{ 156 Class providerClass = findProviderClass(className, cl, doFallback); 157 Object instance = providerClass.newInstance(); 158 if (DEBUG) debugPrintln("created new instance of " + providerClass + 159 " using ClassLoader: " + cl); 160 return instance; 161 } catch (ClassNotFoundException x) { 162 throw new ConfigurationError( 163 "Provider " + className + " not found", x); 164 } catch (Exception x) { 165 throw new ConfigurationError( 166 "Provider " + className + " could not be instantiated: " + x, 167 x); 168 } 169 } 170 171 /** 172 * Find a Class using the same classloader for the ObjectFactory by default 173 * or bootclassloader when Security Manager is in place 174 */ 175 public static Class findProviderClass(String className, boolean doFallback) 176 throws ClassNotFoundException, ConfigurationError 177 { 178 return findProviderClass (className, 179 findClassLoader (), doFallback); 180 } 181 /** 182 * Find a Class using the specified ClassLoader 183 */ 184 public static Class findProviderClass(String className, ClassLoader cl, 185 boolean doFallback) 186 throws ClassNotFoundException, ConfigurationError 187 { 188 //throw security exception if the calling thread is not allowed to access the package 189 //restrict the access to package as speicified in java.security policy 190 SecurityManager security = System.getSecurityManager(); 191 if (security != null) { 192 if (className.startsWith(JAXP_INTERNAL) || 193 className.startsWith(STAX_INTERNAL)) { 194 cl = null; 195 } else { 196 final int lastDot = className.lastIndexOf("."); 197 String packageName = className; 198 if (lastDot != -1) packageName = className.substring(0, lastDot); 199 security.checkPackageAccess(packageName); 200 } 201 } 202 Class providerClass; 203 if (cl == null) { 204 //use the bootstrap ClassLoader. 205 providerClass = Class.forName(className, false, ObjectFactory.class.getClassLoader()); 206 } else { 207 try { 208 providerClass = cl.loadClass(className); 209 } catch (ClassNotFoundException x) { 210 if (doFallback) { 211 // Fall back to current classloader 212 ClassLoader current = ObjectFactory.class.getClassLoader(); 213 if (current == null) { 214 providerClass = Class.forName(className); 215 } else if (cl != current) { 216 cl = current; 217 providerClass = cl.loadClass(className); 218 } else { 219 throw x; 220 } 221 } else { 222 throw x; 223 } 224 } 225 } 226 227 return providerClass; 228 } 229 230 } // class ObjectFactory