1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.jxpath.util; 18 19 import java.util.HashMap; 20 import java.util.Map; 21 22 /** 23 * Port of class loading methods from <code>org.apache.commons.lang.ClassUtils</code> from 24 * the Apache Commons Lang Component. Some adjustments made to remove dependency on 25 * <code>org.apache.commons.lang.StringUtils</code>. Also modified to fall back on the 26 * current class loader when an attempt to load a class with the context class loader 27 * results in a <code>java.lang.ClassNotFoundException</code>. 28 * 29 * @see org.apache.commons.lang.ClassUtils 30 * 31 * @author Stephen Colebourne 32 * @author Gary Gregory 33 * @author Norm Deane 34 * @author Alban Peignier 35 * @author Tomasz Blachowicz 36 * @author John Trimble 37 */ 38 public class ClassLoaderUtil { 39 /** 40 * Maps a primitive class name to its corresponding abbreviation used in array class names. 41 */ 42 private static Map abbreviationMap = new HashMap(); 43 44 /** 45 * Add primitive type abbreviation to maps of abbreviations. 46 * 47 * @param primitive Canonical name of primitive type 48 * @param abbreviation Corresponding abbreviation of primitive type 49 */ 50 private static void addAbbreviation(String primitive, String abbreviation) { 51 abbreviationMap.put(primitive, abbreviation); 52 } 53 54 /** 55 * Feed abbreviation maps 56 */ 57 static { 58 addAbbreviation("int", "I"); 59 addAbbreviation("boolean", "Z"); 60 addAbbreviation("float", "F"); 61 addAbbreviation("long", "J"); 62 addAbbreviation("short", "S"); 63 addAbbreviation("byte", "B"); 64 addAbbreviation("double", "D"); 65 addAbbreviation("char", "C"); 66 } 67 68 // Class loading 69 // ---------------------------------------------------------------------- 70 /** 71 * Returns the class represented by <code>className</code> using the 72 * <code>classLoader</code>. This implementation supports names like 73 * "<code>java.lang.String[]</code>" as well as "<code>[Ljava.lang.String;</code>". 74 * 75 * @param classLoader the class loader to use to load the class 76 * @param className the class name 77 * @param initialize whether the class must be initialized 78 * @return the class represented by <code>className</code> using the <code>classLoader</code> 79 * @throws ClassNotFoundException if the class is not found 80 */ 81 public static Class getClass(ClassLoader classLoader, String className, boolean initialize) 82 throws ClassNotFoundException { 83 Class clazz; 84 if (abbreviationMap.containsKey(className)) { 85 String clsName = "[" + abbreviationMap.get(className); 86 clazz = Class.forName(clsName, initialize, classLoader).getComponentType(); 87 } 88 else { 89 clazz = Class.forName(toCanonicalName(className), initialize, classLoader); 90 } 91 return clazz; 92 } 93 94 /** 95 * Returns the (initialized) class represented by <code>className</code> 96 * using the <code>classLoader</code>. This implementation supports names 97 * like "<code>java.lang.String[]</code>" as well as 98 * "<code>[Ljava.lang.String;</code>". 99 * 100 * @param classLoader the class loader to use to load the class 101 * @param className the class name 102 * @return the class represented by <code>className</code> using the <code>classLoader</code> 103 * @throws ClassNotFoundException if the class is not found 104 */ 105 public static Class getClass(ClassLoader classLoader, String className) throws ClassNotFoundException { 106 return getClass(classLoader, className, true); 107 } 108 109 /** 110 * Returns the (initialized) class represented by <code>className</code> 111 * using the current thread's context class loader. This implementation 112 * supports names like "<code>java.lang.String[]</code>" as well as 113 * "<code>[Ljava.lang.String;</code>". 114 * 115 * @param className the class name 116 * @return the class represented by <code>className</code> using the current thread's context class loader 117 * @throws ClassNotFoundException if the class is not found 118 */ 119 public static Class getClass(String className) throws ClassNotFoundException { 120 return getClass(className, true); 121 } 122 123 /** 124 * Returns the class represented by <code>className</code> using the 125 * current thread's context class loader. This implementation supports 126 * names like "<code>java.lang.String[]</code>" as well as 127 * "<code>[Ljava.lang.String;</code>". 128 * 129 * @param className the class name 130 * @param initialize whether the class must be initialized 131 * @return the class represented by <code>className</code> using the current thread's context class loader 132 * @throws ClassNotFoundException if the class is not found 133 */ 134 public static Class getClass(String className, boolean initialize) throws ClassNotFoundException { 135 ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); 136 ClassLoader currentCL = ClassLoaderUtil.class.getClassLoader(); 137 if (contextCL != null) { 138 try { 139 return getClass(contextCL, className, initialize); 140 } 141 catch (ClassNotFoundException e) {//NOPMD 142 // ignore this exception and try the current class loader. 143 } 144 } 145 return getClass(currentCL, className, initialize); 146 } 147 148 /** 149 * Converts a class name to a JLS style class name. 150 * 151 * @param className the class name 152 * @return the converted name 153 */ 154 private static String toCanonicalName(String className) { 155 if (className == null) { 156 throw new RuntimeException("Argument className was null."); 157 } 158 else if (className.endsWith("[]")) { 159 StringBuffer classNameBuffer = new StringBuffer(); 160 while (className.endsWith("[]")) { 161 className = className.substring(0, className.length() - 2); 162 classNameBuffer.append("["); 163 } 164 String abbreviation = (String) abbreviationMap.get(className); 165 if (abbreviation != null) { 166 classNameBuffer.append(abbreviation); 167 } 168 else { 169 classNameBuffer.append("L").append(className).append(";"); 170 } 171 className = classNameBuffer.toString(); 172 } 173 return className; 174 } 175 }