View Javadoc
1 package attrib4j.bcel; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.StringTokenizer; 6 7 import attrib4j.Log; 8 9 /*** 10 * The signature of a method that is available from the BCEL library uses 11 * descriptors as defined in Section 4.3 of the Java Virtual Machine 12 * specificaiton. Javadoc and Java do not use signatures in this same format. 13 * This class converts the Javadoc/Java signature format to that used by 14 * the JVM spec. 15 * To summarize the descriptors 16 * <code> 17 * A method descriptor represents the parameters that the method takes 18 * and the value that it returns: 19 * 20 * MethodDescriptor: 21 * ( ParameterDescriptor* ) ReturnDescriptor 22 * 23 * A parameter descriptor represents a parameter passed to a method: 24 * 25 * ParameterDescriptor: 26 * FieldType 27 * 28 * A return descriptor represents the type of the value returned from a method. 29 * It is a series of characters generated by the grammar: 30 * 31 * ReturnDescriptor: 32 * FieldType 33 * V 34 * 35 * The character V indicates that the method returns no value 36 * (its return type is void). 37 *</code> 38 * 39 *<code> 40 * A field descriptor represents the type of a class, instance, or local 41 * variable. It is a series of characters generated by the grammar: 42 * 43 * FieldDescriptor: 44 * FieldType 45 * 46 * ComponentType: 47 * FieldType 48 * 49 * FieldType: 50 * BaseType 51 * ObjectType 52 * ArrayType 53 * 54 * BaseType: 55 * B 56 * C 57 * D 58 * F 59 * I 60 * J 61 * S 62 * Z 63 * 64 * ObjectType: 65 * L <classname> ; 66 * 67 * ArrayType: 68 * [ ComponentType 69 * 70 * The characters of BaseType, the L and ; of ObjectType, and the [ of 71 * ArrayType are all ASCII characters. The <classname> represents a fully 72 * qualified class or interface name. For historical reasons it is encoded in 73 * internal form (4.2). The interpretation of the field types is as shown 74 * in Table 4.2. 75 * 76 * BaseType Character Type Interpretation 77 * ---------------------------------------------- 78 * B byte signed byte 79 * C char Unicode character 80 * D double double-precision floating-point value 81 * F float single-precision floating-point value 82 * I int integer 83 * J long long integer 84 * L<classname>; reference an instance of class <classname> 85 * S short signed short 86 * Z boolean true or false 87 * [ reference one array dimension 88 * 89 * 90 * 91 * @author <a href="mailto:mpollack@speakeasy.org">Mark Pollack</a> 92 */ 93 94 public class DescriptorUtil { 95 96 private static Map _paramTypeMap = new HashMap(); 97 private static Map _returnTypeMap = new HashMap(); 98 99 static { 100 _paramTypeMap.put("byte", "B"); 101 _paramTypeMap.put("char", "C"); 102 _paramTypeMap.put("double", "D"); 103 _paramTypeMap.put("float", "F"); 104 _paramTypeMap.put("int", "I"); 105 _paramTypeMap.put("long", "J"); 106 //todo: make generic...look for 'dots' of package. that algorithm 107 //doesn't handle packageless (default package) classes though.. 108 // _paramTypeMap.put("object reference","L<classname>") 109 _paramTypeMap.put("java.lang.Object", "Ljava/lang/Object;"); 110 _paramTypeMap.put("short", "S"); 111 _paramTypeMap.put("boolean", "Z"); 112 //todo 113 _paramTypeMap.put("array reference", "["); 114 115 _returnTypeMap.put("void", "V"); 116 117 } 118 119 /*** 120 * Converts from the Java/Javadoc method signature the JVM spec format. 121 * 122 * TODO This class is poorly implemented and the code base no 123 * longer depends on it. Think about removing it. 124 * 125 * @param javadocSig method signature as returned via Javadoc API. 126 * @param javadocReturnType return type as returned via Javadoc API. 127 * @return mtehod signature as defined in the JVM spec. 128 */ 129 public static String convert(String javadocSig, String javadocReturnType) { 130 //remove the leading and trailing parens 131 String javadocSigTrim = 132 javadocSig.substring(1, javadocSig.length() - 1); 133 StringTokenizer st = new StringTokenizer(javadocSigTrim, ","); 134 StringBuffer jvmBuff = new StringBuffer("("); 135 while (st.hasMoreTokens()) { 136 //remove the leading space character. 137 String sigElement = st.nextToken().trim(); 138 if (_paramTypeMap.containsKey(sigElement)) { 139 jvmBuff.append(_paramTypeMap.get(sigElement)); 140 } else { 141 Log.log( 142 "could not find javadoc parameter signature element " 143 + sigElement 144 + " in conversion map", 145 Log.ERROR, 146 "DescriptorUtil"); 147 } 148 149 } 150 jvmBuff.append(")"); 151 if (_returnTypeMap.containsKey(javadocReturnType)) { 152 jvmBuff.append(_returnTypeMap.get(javadocReturnType)); 153 } else { 154 Log.log( 155 "could not find javadoc return signature " 156 + javadocReturnType 157 + " in conversion map", 158 Log.ERROR, 159 "DescriptorUtil"); 160 } 161 return jvmBuff.toString(); 162 } 163 164 /*** 165 * Convert a method signature as definedin the JVM spec to that used 166 * in the Javadoc API. The BCEL library gives method signatures in 167 * the JVM format. 168 * 169 * @param bcelSignature The JVM format of a method signature. 170 * @return a <code>String[]</code> containing the method parameter as 171 * elements of the array. 172 */ 173 public static String[] convertToJavaFormat(String bcelSignature) { 174 int i = 0; 175 if (bcelSignature.charAt(i) != '(') { 176 Log.log( 177 "BCEL signature didn't start with (. Can't convert " 178 + bcelSignature 179 + "> to javadoc representation", 180 Log.ERROR, 181 "DescriptorUtil"); 182 return null; 183 } 184 185 int j = 0; 186 StringBuffer stringbuffer = new StringBuffer(); 187 for (i++; i < bcelSignature.length();) { 188 if (bcelSignature.charAt(i) == ')') { 189 i++; 190 break; //we are at the end of the signature. 191 } 192 if (i > 1) { 193 //put in spaces to later tokenize on. 194 stringbuffer.append(" "); 195 } 196 i = jvmFormatToJavaFormat(bcelSignature, i, stringbuffer); 197 //count number of elements parsed. 198 j++; 199 } 200 201 //convert to string array. 202 String convertedString = stringbuffer.toString(); 203 String as[] = new String[j]; 204 205 int k = 0; 206 StringTokenizer st = new StringTokenizer(convertedString); 207 while (st.hasMoreTokens()) { 208 as[k++] = st.nextToken(); 209 } 210 return as; 211 212 } 213 214 /*** 215 * The utility method that does the real work of parsing through 216 * the JVM formatted string and adding an converted method parameter 217 * description to the StringBuffer. 218 * 219 * @param s The JVM formatted string that is being parsed. 220 * @param i The offset into the string being parsed. 221 * @param stringbuffer The storage for building the converted method 222 * signature. 223 * @return new offset location for parsing. 224 */ 225 private static int jvmFormatToJavaFormat( 226 String jvmFormat, 227 int i, 228 StringBuffer stringbuffer) { 229 String s1 = ""; 230 //arrays. 231 for (; jvmFormat.charAt(i) == '['; i++) { 232 s1 = s1 + "[]"; 233 } 234 235 startover : switch (jvmFormat.charAt(i)) { 236 case 66 : // 'B' 237 stringbuffer.append("byte"); 238 break; 239 240 case 67 : // 'C' 241 stringbuffer.append("char"); 242 break; 243 244 case 68 : // 'D' 245 stringbuffer.append("double"); 246 break; 247 248 case 70 : // 'F' 249 stringbuffer.append("float"); 250 break; 251 252 case 73 : // 'I' 253 stringbuffer.append("int"); 254 break; 255 256 case 74 : // 'J' 257 stringbuffer.append("long"); 258 break; 259 260 case 83 : // 'S' 261 stringbuffer.append("short"); 262 break; 263 264 case 90 : // 'Z' 265 stringbuffer.append("boolean"); 266 break; 267 268 case 86 : // 'V' 269 stringbuffer.append("void"); 270 break; 271 272 case 76 : // 'L' 273 //special case for objects. 274 for (i++; i < jvmFormat.length(); i++) { 275 if (jvmFormat.charAt(i) == '/') { 276 //convert to period 277 stringbuffer.append('.'); 278 } else { 279 if (jvmFormat.charAt(i) == ';') { 280 //we reached the end 281 break startover; 282 } 283 //copy contents. 284 stringbuffer.append(jvmFormat.charAt(i)); 285 } 286 } 287 break; 288 289 default : 290 Log.log( 291 "Can't convert jvm fromat " 292 + jvmFormat 293 + " to javadoc representation", 294 Log.ERROR, 295 "DescriptorUtil"); 296 return jvmFormat.length(); 297 } 298 stringbuffer = stringbuffer.append(s1); 299 return ++i; 300 } 301 302 } // DescriptorUtil

This page was automatically generated by Maven