1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2004 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 * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.utils; 25 26 /** 27 * This class is duplicated for each JAXP subpackage so keep it in sync. 28 * It is package private and therefore is not exposed as part of the JAXP 29 * API. 30 * <p> 31 * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code> 32 * class and modified to be used as a general utility for creating objects 33 * dynamically. 34 * 35 * @version $Id: ObjectFactory.java,v 1.11 2010-11-01 04:34:25 joehw Exp $ 36 */ 37 public 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 = false; 47 48 49 /** Prints a message to standard error if debugging is enabled. */ 50 private static void debugPrintln(String msg) { 51 if (DEBUG) { 52 System.err.println("JAXP: " + msg); 53 } 54 } // debugPrintln(String) 55 56 /** 57 * Figure out which ClassLoader to use. For JDK 1.2 and later use 58 * the context ClassLoader. 59 */ 60 public static ClassLoader findClassLoader() 61 { 62 if (System.getSecurityManager()!=null) { 63 //this will ensure bootclassloader is used 64 return null; 65 } 66 67 // Figure out which ClassLoader to use for loading the provider 68 // class. If there is a Context ClassLoader then use it. 69 ClassLoader context = SecuritySupport.getContextClassLoader(); 70 ClassLoader system = SecuritySupport.getSystemClassLoader(); 71 72 ClassLoader chain = system; 73 while (true) { 74 if (context == chain) { 75 // Assert: we are on JDK 1.1 or we have no Context ClassLoader 76 // or any Context ClassLoader in chain of system classloader 77 // (including extension ClassLoader) so extend to widest 78 // ClassLoader (always look in system ClassLoader if Xalan 79 // is in boot/extension/system classpath and in current 80 // ClassLoader otherwise); normal classloaders delegate 81 // back to system ClassLoader first so this widening doesn't 82 // change the fact that context ClassLoader will be consulted 83 ClassLoader current = ObjectFactory.class.getClassLoader(); 84 85 chain = system; 86 while (true) { 87 if (current == chain) { 88 // Assert: Current ClassLoader in chain of 89 // boot/extension/system ClassLoaders 90 return system; 91 } 92 if (chain == null) { 93 break; 94 } 95 chain = SecuritySupport.getParentClassLoader(chain); 96 } 97 98 // Assert: Current ClassLoader not in chain of 99 // boot/extension/system ClassLoaders 100 return current; 101 } 102 103 if (chain == null) { 104 // boot ClassLoader reached 105 break; 106 } 107 108 // Check for any extension ClassLoaders in chain up to 109 // boot ClassLoader 110 chain = SecuritySupport.getParentClassLoader(chain); 111 } 112 113 // Assert: Context ClassLoader not in chain of 114 // boot/extension/system ClassLoaders 115 return context; 116 } // findClassLoader():ClassLoader 117 118 /** 119 * Create an instance of a class using the same class loader for the ObjectFactory by default 120 * or boot class loader when Security Manager is in place 121 */ 122 public static Object newInstance(String className, boolean doFallback) 123 throws ConfigurationError 124 { 125 if (System.getSecurityManager()!=null) { 126 return newInstance(className, null, doFallback); 127 } else { 128 return newInstance(className, 129 findClassLoader (), doFallback); 130 } 131 } 132 133 /** 134 * Create an instance of a class using the specified ClassLoader 135 */ 136 static Object newInstance(String className, ClassLoader cl, 137 boolean doFallback) 138 throws ConfigurationError 139 { 140 // assert(className != null); 141 try{ 142 Class providerClass = findProviderClass(className, cl, doFallback); 143 Object instance = providerClass.newInstance(); 144 if (DEBUG) debugPrintln("created new instance of " + providerClass + 145 " using ClassLoader: " + cl); 146 return instance; 147 } catch (ClassNotFoundException x) { 148 throw new ConfigurationError( 149 "Provider " + className + " not found", x); 150 } catch (Exception x) { 151 throw new ConfigurationError( 152 "Provider " + className + " could not be instantiated: " + x, 153 x); 154 } 155 } 156 157 /** 158 * Find a Class using the same class loader for the ObjectFactory by default 159 * or boot class loader when Security Manager is in place 160 */ 161 public static Class<?> findProviderClass(String className, boolean doFallback) 162 throws ClassNotFoundException, ConfigurationError 163 { 164 return findProviderClass (className, 165 findClassLoader (), doFallback); 166 } 167 168 /** 169 * Find a Class using the specified ClassLoader 170 */ 171 private static Class<?> findProviderClass(String className, ClassLoader cl, 172 boolean doFallback) 173 throws ClassNotFoundException, ConfigurationError 174 { 175 //throw security exception if the calling thread is not allowed to access the 176 //class. Restrict the access to the package classes as specified in java.security policy. 177 SecurityManager security = System.getSecurityManager(); 178 try{ 179 if (security != null){ 180 if (className.startsWith(JAXP_INTERNAL) || 181 className.startsWith(STAX_INTERNAL)) { 182 cl = null; 183 } else { 184 final int lastDot = className.lastIndexOf("."); 185 String packageName = className; 186 if (lastDot != -1) packageName = className.substring(0, lastDot); 187 security.checkPackageAccess(packageName); 188 } 189 } 190 }catch(SecurityException e){ 191 throw e; 192 } 193 194 Class<?> providerClass; 195 if (cl == null) { 196 providerClass = Class.forName(className, false, ObjectFactory.class.getClassLoader()); 197 } else { 198 try { 199 providerClass = cl.loadClass(className); 200 } catch (ClassNotFoundException x) { 201 if (doFallback) { 202 // Fall back to current classloader 203 ClassLoader current = ObjectFactory.class.getClassLoader(); 204 if (current == null) { 205 providerClass = Class.forName(className); 206 } else if (cl != current) { 207 cl = current; 208 providerClass = cl.loadClass(className); 209 } else { 210 throw x; 211 } 212 } else { 213 throw x; 214 } 215 } 216 } 217 218 return providerClass; 219 } 220 221 } // class ObjectFactory