/Users/lyon/j4p/src/javassist/runtime/Desc.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15
16 package javassist.runtime;
17
18 /**
19 * A support class for implementing <code>$sig</code> and
20 * <code>$type</code>.
21 * This support class is required at runtime
22 * only if <code>$sig</code> or <code>$type</code> is used.
23 */
24 public class Desc {
25
26 /**
27 * Specifies how a <code>java.lang.Class</code> object is loaded.
28 *
29 * <p>If true, it is loaded by:
30 * <ul><pre>Thread.currentThread().getContextClassLoader().loadClass()</pre></ul>
31 * <p>If false, it is loaded by <code>Class.forName()</code>.
32 * The default value is false.
33 */
34 public static boolean useContextClassLoader = false;
35
36 private static Class getClassObject(String name)
37 throws ClassNotFoundException {
38 if (useContextClassLoader)
39 return Thread.currentThread().getContextClassLoader()
40 .loadClass(name);
41 else
42 return Class.forName(name);
43 }
44
45 /**
46 * Interprets the given class name.
47 * It is used for implementing <code>$class</code>.
48 */
49 public static Class getClazz(String name) {
50 try {
51 return getClassObject(name);
52 } catch (ClassNotFoundException e) {
53 throw new RuntimeException("$class: internal error");
54 }
55 }
56
57 /**
58 * Interprets the given type descriptor representing a method
59 * signature. It is used for implementing <code>$sig</code>.
60 */
61 public static Class[] getParams(String desc) {
62 if (desc.charAt(0) != '(')
63 throw new RuntimeException("$sig: internal error");
64
65 return getType(desc, desc.length(), 1, 0);
66 }
67
68 /**
69 * Interprets the given type descriptor.
70 * It is used for implementing <code>$type</code>.
71 */
72 public static Class getType(String desc) {
73 Class[] result = getType(desc, desc.length(), 0, 0);
74 if (result == null || result.length != 1)
75 throw new RuntimeException("$type: internal error");
76
77 return result[0];
78 }
79
80 private static Class[] getType(String desc, int descLen,
81 int start, int num) {
82 Class clazz;
83 if (start >= descLen)
84 return new Class[num];
85
86 char c = desc.charAt(start);
87 switch (c) {
88 case 'Z':
89 clazz = Boolean.TYPE;
90 break;
91 case 'C':
92 clazz = Character.TYPE;
93 break;
94 case 'B':
95 clazz = Byte.TYPE;
96 break;
97 case 'S':
98 clazz = Short.TYPE;
99 break;
100 case 'I':
101 clazz = Integer.TYPE;
102 break;
103 case 'J':
104 clazz = Long.TYPE;
105 break;
106 case 'F':
107 clazz = Float.TYPE;
108 break;
109 case 'D':
110 clazz = Double.TYPE;
111 break;
112 case 'V':
113 clazz = Void.TYPE;
114 break;
115 case 'L':
116 case '[':
117 return getClassType(desc, descLen, start, num);
118 default :
119 return new Class[num];
120 }
121
122 Class[] result = getType(desc, descLen, start + 1, num + 1);
123 result[num] = clazz;
124 return result;
125 }
126
127 private static Class[] getClassType(String desc, int descLen,
128 int start, int num) {
129 int end = start;
130 while (desc.charAt(end) == '[')
131 ++end;
132
133 if (desc.charAt(end) == 'L') {
134 end = desc.indexOf(';', end);
135 if (end < 0)
136 throw new IndexOutOfBoundsException("bad descriptor");
137 }
138
139 String cname;
140 if (desc.charAt(start) == 'L')
141 cname = desc.substring(start + 1, end);
142 else
143 cname = desc.substring(start, end + 1);
144
145 Class[] result = getType(desc, descLen, end + 1, num + 1);
146 try {
147 result[num] = getClassObject(cname.replace('/', '.'));
148 } catch (ClassNotFoundException e) {
149 // "new RuntimeException(e)" is not available in JDK 1.3.
150 throw new RuntimeException(e.getMessage());
151 }
152
153 return result;
154 }
155 }
156