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