KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > definition > DescriptorUtil


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

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

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

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

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

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

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