KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > definition > DescriptorUtil


1 package org.codehaus.aspectwerkz.definition;
2
3 import java.util.HashMap JavaDoc;
4 import java.util.Map JavaDoc;
5 import java.util.StringTokenizer JavaDoc;
6
7 /**
8  * The signature of a method that is available from the BCEL library uses descriptors as defined in Section 4.3 of the
9  * Java Virtual Machine specificaiton. Javadoc and Java do not use signatures in this same format. This class converts
10  * the Javadoc/Java signature format to that used by the JVM spec. To summarize the descriptors <code> A method
11  * descriptor represents the parameters that the method takes and the value that it returns:
12  * <p/>
13  * MethodDescriptor: ( ParameterDescriptor* ) ReturnDescriptor
14  * <p/>
15  * A parameter descriptor represents a parameter passed to a method:
16  * <p/>
17  * ParameterDescriptor: FieldType
18  * <p/>
19  * A return descriptor represents the type of the value returned from a method. It is a series of characters generated
20  * by the grammar:
21  * <p/>
22  * ReturnDescriptor: FieldType V
23  * <p/>
24  * The character V indicates that the method returns no value (its return type is void). </code>
25  * <p/>
26  * <code> A field descriptor represents the type of a class, instance, or local variable. It is a series of characters
27  * generated by the grammar:
28  * <p/>
29  * FieldDescriptor: FieldType
30  * <p/>
31  * ComponentType: FieldType
32  * <p/>
33  * FieldType: BaseType ObjectType ArrayType
34  * <p/>
35  * BaseType: B C D F I J S Z
36  * <p/>
37  * ObjectType: L <classname> ;
38  * <p/>
39  * ArrayType: [ ComponentType
40  * <p/>
41  * The characters of BaseType, the L and ; of ObjectType, and the [ of ArrayType are all ASCII characters. The
42  * <classname> represents a fully qualified class or interface name. For historical reasons it is encoded in internal
43  * form (4.2). The interpretation of the field types is as shown in Table 4.2.
44  * <p/>
45  * BaseType Character Type Interpretation ---------------------------------------------- B byte
46  * signed byte C char Unicode character D double double-precision
47  * floating-point value F float single-precision floating-point value I int
48  * integer J long long integer L<classname>; reference an instance of class <classname> S
49  * short signed short Z boolean true or false [ reference one array dimension
50  *
51  * @author <a HREF="mailto:mpollack@speakeasy.org">Mark Pollack</a>
52  */

53 public class DescriptorUtil {
54     private static Map JavaDoc _paramTypeMap = new HashMap JavaDoc();
55
56     private static Map JavaDoc _returnTypeMap = new HashMap JavaDoc();
57
58     static {
59         _paramTypeMap.put("byte", "B");
60         _paramTypeMap.put("char", "C");
61         _paramTypeMap.put("double", "D");
62         _paramTypeMap.put("float", "F");
63         _paramTypeMap.put("int", "I");
64         _paramTypeMap.put("long", "J");
65
66         //todo: make generic...look for 'dots' of package. that algorithm doesn't handle
67
// packageless (default package)
68
// classes though..
69
_paramTypeMap.put("java.lang.Object", "Ljava/lang/Object;");
70         _paramTypeMap.put("short", "S");
71         _paramTypeMap.put("boolean", "Z");
72
73         //todo
74
_paramTypeMap.put("array reference", "[");
75         _returnTypeMap.put("void", "V");
76     }
77
78     /**
79      * Converts from the Java/Javadoc method signature the JVM spec format.
80      *
81      * @param javadocSig method signature as returned via Javadoc API.
82      * @param javadocReturnType return type as returned via Javadoc API.
83      * @return mtehod signature as defined in the JVM spec.
84      */

85     public static String JavaDoc convert(String JavaDoc javadocSig, String JavaDoc javadocReturnType) {
86         //remove the leading and trailing parens
87
String JavaDoc javadocSigTrim = javadocSig.substring(1, javadocSig.length() - 1);
88         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(javadocSigTrim, ",");
89         StringBuffer JavaDoc jvmBuff = new StringBuffer JavaDoc("(");
90         while (st.hasMoreTokens()) {
91             //remove the leading space character.
92
String JavaDoc sigElement = st.nextToken().trim();
93             if (_paramTypeMap.containsKey(sigElement)) {
94                 jvmBuff.append(_paramTypeMap.get(sigElement));
95             }
96         }
97         jvmBuff.append(")");
98         if (_returnTypeMap.containsKey(javadocReturnType)) {
99             jvmBuff.append(_returnTypeMap.get(javadocReturnType));
100         }
101         return jvmBuff.toString();
102     }
103
104     /**
105      * Convert a JVM signature as defined in the JVM spec to that used in the Java.
106      *
107      * @param jvmSignature The JVM format signature.
108      * @return a <code>String[]</code> containing the method parameter as elements of the array.
109      */

110     public static String JavaDoc[] getParameters(final String JavaDoc jvmSignature) {
111         int i = 0;
112         if (jvmSignature.charAt(i) != '(') {
113             return null;
114         }
115         int j = 0;
116         StringBuffer JavaDoc stringbuffer = new StringBuffer JavaDoc();
117         for (i++; i < jvmSignature.length();) {
118             if (jvmSignature.charAt(i) == ')') {
119                 i++;
120                 break; //we are at the end of the signature.
121
}
122             if (i > 1) {
123                 //put in spaces to later tokenize on.
124
stringbuffer.append(" ");
125             }
126             i = jvmFormatToJavaFormat(jvmSignature, i, stringbuffer);
127
128             //count number of elements parsed.
129
j++;
130         }
131
132         //convert to string array.
133
String JavaDoc convertedString = stringbuffer.toString();
134         String JavaDoc[] as = new String JavaDoc[j];
135         int k = 0;
136         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(convertedString);
137         while (st.hasMoreTokens()) {
138             as[k++] = st.nextToken();
139         }
140         return as;
141     }
142
143     /**
144      * The utility method that does the real work of parsing through the JVM formatted string and adding an converted
145      * method parameter description to the StringBuffer.
146      *
147      * @param jvmFormat The JVM formatted string that is being parsed.
148      * @param i The offset into the string being parsed.
149      * @param stringbuffer The storage for building the converted method signature.
150      * @return new offset location for parsing.
151      * @TODO this an extremely ugly method (the int an stringbuffer params must be removed)
152      */

153     private static int jvmFormatToJavaFormat(final String JavaDoc jvmFormat, int i, StringBuffer JavaDoc stringbuffer) {
154         String JavaDoc s1 = "";
155
156         //arrays.
157
for (; jvmFormat.charAt(i) == '['; i++) {
158             s1 = s1 + "[]";
159         }
160         startover: switch (jvmFormat.charAt(i)) {
161             case 66: // 'B'
162
stringbuffer.append("byte");
163                 break;
164             case 67: // 'C'
165
stringbuffer.append("char");
166                 break;
167             case 68: // 'D'
168
stringbuffer.append("double");
169                 break;
170             case 70: // 'F'
171
stringbuffer.append("float");
172                 break;
173             case 73: // 'I'
174
stringbuffer.append("int");
175                 break;
176             case 74: // 'J'
177
stringbuffer.append("long");
178                 break;
179             case 83: // 'S'
180
stringbuffer.append("short");
181                 break;
182             case 90: // 'Z'
183
stringbuffer.append("boolean");
184                 break;
185             case 86: // 'V'
186
stringbuffer.append("void");
187                 break;
188             case 76: // 'L'
189

190                 //special case for objects.
191
for (i++; i < jvmFormat.length(); i++) {
192                     if (jvmFormat.charAt(i) == '/') {
193                         //convert to period
194
stringbuffer.append('.');
195                     } else {
196                         if (jvmFormat.charAt(i) == ';') {
197                             //we reached the end
198
break startover;
199                         }
200
201                         //copy contents.
202
stringbuffer.append(jvmFormat.charAt(i));
203                     }
204                 }
205                 break;
206             default:
207                 return jvmFormat.length();
208         }
209         stringbuffer = stringbuffer.append(s1);
210         return ++i;
211     }
212 }
Popular Tags