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 }