1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 24package com.sun.org.apache.xml.internal.security.transforms; 25 26import java.io.IOException; 27import java.io.InputStream; 28import java.net.URL; 29import java.util.ArrayList; 30import java.util.Enumeration; 31import java.util.List; 32 33/** 34 * This class is extremely useful for loading resources and classes in a fault 35 * tolerant manner that works across different applications servers. Do not 36 * touch this unless you're a grizzled classloading guru veteran who is going to 37 * verify any change on 6 different application servers. 38 */ 39// NOTE! This is a duplicate of utils.ClassLoaderUtils with public 40// modifiers changed to package-private. Make sure to integrate any future 41// changes to utils.ClassLoaderUtils to this file. 42final class ClassLoaderUtils { 43 44 /** {@link org.apache.commons.logging} logging facility */ 45 private static final java.util.logging.Logger log = 46 java.util.logging.Logger.getLogger(ClassLoaderUtils.class.getName()); 47 48 private ClassLoaderUtils() { 49 } 50 51 /** 52 * Load a given resource. <p/> This method will try to load the resource 53 * using the following methods (in order): 54 * <ul> 55 * <li>From Thread.currentThread().getContextClassLoader() 56 * <li>From ClassLoaderUtil.class.getClassLoader() 57 * <li>callingClass.getClassLoader() 58 * </ul> 59 * 60 * @param resourceName The name of the resource to load 61 * @param callingClass The Class object of the calling object 62 */ 63 static URL getResource(String resourceName, Class<?> callingClass) { 64 URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName); 65 if (url == null && resourceName.startsWith("/")) { 66 //certain classloaders need it without the leading / 67 url = 68 Thread.currentThread().getContextClassLoader().getResource( 69 resourceName.substring(1) 70 ); 71 } 72 73 ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader(); 74 if (cluClassloader == null) { 75 cluClassloader = ClassLoader.getSystemClassLoader(); 76 } 77 if (url == null) { 78 url = cluClassloader.getResource(resourceName); 79 } 80 if (url == null && resourceName.startsWith("/")) { 81 //certain classloaders need it without the leading / 82 url = cluClassloader.getResource(resourceName.substring(1)); 83 } 84 85 if (url == null) { 86 ClassLoader cl = callingClass.getClassLoader(); 87 88 if (cl != null) { 89 url = cl.getResource(resourceName); 90 } 91 } 92 93 if (url == null) { 94 url = callingClass.getResource(resourceName); 95 } 96 97 if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) { 98 return getResource('/' + resourceName, callingClass); 99 } 100 101 return url; 102 } 103 104 /** 105 * Load a given resources. <p/> This method will try to load the resources 106 * using the following methods (in order): 107 * <ul> 108 * <li>From Thread.currentThread().getContextClassLoader() 109 * <li>From ClassLoaderUtil.class.getClassLoader() 110 * <li>callingClass.getClassLoader() 111 * </ul> 112 * 113 * @param resourceName The name of the resource to load 114 * @param callingClass The Class object of the calling object 115 */ 116 static List<URL> getResources(String resourceName, Class<?> callingClass) { 117 List<URL> ret = new ArrayList<URL>(); 118 Enumeration<URL> urls = new Enumeration<URL>() { 119 public boolean hasMoreElements() { 120 return false; 121 } 122 public URL nextElement() { 123 return null; 124 } 125 126 }; 127 try { 128 urls = Thread.currentThread().getContextClassLoader().getResources(resourceName); 129 } catch (IOException e) { 130 if (log.isLoggable(java.util.logging.Level.FINE)) { 131 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 132 } 133 //ignore 134 } 135 if (!urls.hasMoreElements() && resourceName.startsWith("/")) { 136 //certain classloaders need it without the leading / 137 try { 138 urls = 139 Thread.currentThread().getContextClassLoader().getResources( 140 resourceName.substring(1) 141 ); 142 } catch (IOException e) { 143 if (log.isLoggable(java.util.logging.Level.FINE)) { 144 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 145 } 146 // ignore 147 } 148 } 149 150 ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader(); 151 if (cluClassloader == null) { 152 cluClassloader = ClassLoader.getSystemClassLoader(); 153 } 154 if (!urls.hasMoreElements()) { 155 try { 156 urls = cluClassloader.getResources(resourceName); 157 } catch (IOException e) { 158 if (log.isLoggable(java.util.logging.Level.FINE)) { 159 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 160 } 161 // ignore 162 } 163 } 164 if (!urls.hasMoreElements() && resourceName.startsWith("/")) { 165 //certain classloaders need it without the leading / 166 try { 167 urls = cluClassloader.getResources(resourceName.substring(1)); 168 } catch (IOException e) { 169 if (log.isLoggable(java.util.logging.Level.FINE)) { 170 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 171 } 172 // ignore 173 } 174 } 175 176 if (!urls.hasMoreElements()) { 177 ClassLoader cl = callingClass.getClassLoader(); 178 179 if (cl != null) { 180 try { 181 urls = cl.getResources(resourceName); 182 } catch (IOException e) { 183 if (log.isLoggable(java.util.logging.Level.FINE)) { 184 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 185 } 186 // ignore 187 } 188 } 189 } 190 191 if (!urls.hasMoreElements()) { 192 URL url = callingClass.getResource(resourceName); 193 if (url != null) { 194 ret.add(url); 195 } 196 } 197 while (urls.hasMoreElements()) { 198 ret.add(urls.nextElement()); 199 } 200 201 202 if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != '/')) { 203 return getResources('/' + resourceName, callingClass); 204 } 205 return ret; 206 } 207 208 209 /** 210 * This is a convenience method to load a resource as a stream. <p/> The 211 * algorithm used to find the resource is given in getResource() 212 * 213 * @param resourceName The name of the resource to load 214 * @param callingClass The Class object of the calling object 215 */ 216 static InputStream getResourceAsStream(String resourceName, Class<?> callingClass) { 217 URL url = getResource(resourceName, callingClass); 218 219 try { 220 return (url != null) ? url.openStream() : null; 221 } catch (IOException e) { 222 if (log.isLoggable(java.util.logging.Level.FINE)) { 223 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 224 } 225 return null; 226 } 227 } 228 229 /** 230 * Load a class with a given name. <p/> It will try to load the class in the 231 * following order: 232 * <ul> 233 * <li>From Thread.currentThread().getContextClassLoader() 234 * <li>Using the basic Class.forName() 235 * <li>From ClassLoaderUtil.class.getClassLoader() 236 * <li>From the callingClass.getClassLoader() 237 * </ul> 238 * 239 * @param className The name of the class to load 240 * @param callingClass The Class object of the calling object 241 * @throws ClassNotFoundException If the class cannot be found anywhere. 242 */ 243 static Class<?> loadClass(String className, Class<?> callingClass) 244 throws ClassNotFoundException { 245 try { 246 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 247 248 if (cl != null) { 249 return cl.loadClass(className); 250 } 251 } catch (ClassNotFoundException e) { 252 if (log.isLoggable(java.util.logging.Level.FINE)) { 253 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 254 } 255 //ignore 256 } 257 return loadClass2(className, callingClass); 258 } 259 260 private static Class<?> loadClass2(String className, Class<?> callingClass) 261 throws ClassNotFoundException { 262 try { 263 return Class.forName(className); 264 } catch (ClassNotFoundException ex) { 265 try { 266 if (ClassLoaderUtils.class.getClassLoader() != null) { 267 return ClassLoaderUtils.class.getClassLoader().loadClass(className); 268 } 269 } catch (ClassNotFoundException exc) { 270 if (callingClass != null && callingClass.getClassLoader() != null) { 271 return callingClass.getClassLoader().loadClass(className); 272 } 273 } 274 if (log.isLoggable(java.util.logging.Level.FINE)) { 275 log.log(java.util.logging.Level.FINE, ex.getMessage(), ex); 276 } 277 throw ex; 278 } 279 } 280} 281