1 55 56 package org.jboss.axis.utils.bytecode; 57 58 import org.jboss.axis.utils.Messages; 59 60 import java.io.ByteArrayInputStream ; 61 import java.io.ByteArrayOutputStream ; 62 import java.io.EOFException ; 63 import java.io.IOException ; 64 import java.io.InputStream ; 65 import java.lang.reflect.Constructor ; 66 import java.lang.reflect.Field ; 67 import java.lang.reflect.InvocationTargetException ; 68 import java.lang.reflect.Member ; 69 import java.lang.reflect.Method ; 70 import java.util.HashMap ; 71 import java.util.Map ; 72 73 87 public class ClassReader extends ByteArrayInputStream 88 { 89 private static final int CONSTANT_Class = 7; 92 private static final int CONSTANT_Fieldref = 9; 93 private static final int CONSTANT_Methodref = 10; 94 private static final int CONSTANT_InterfaceMethodref = 11; 95 private static final int CONSTANT_String = 8; 96 private static final int CONSTANT_Integer = 3; 97 private static final int CONSTANT_Float = 4; 98 private static final int CONSTANT_Long = 5; 99 private static final int CONSTANT_Double = 6; 100 private static final int CONSTANT_NameAndType = 12; 101 private static final int CONSTANT_Utf8 = 1; 102 107 private int[] cpoolIndex; 108 private Object [] cpool; 109 110 private Map attrMethods; 111 112 121 protected static byte[] getBytes(Class c) throws IOException 122 { 123 InputStream fin = c.getResourceAsStream('/' + c.getName().replace('.', '/') + ".class"); 124 if (fin == null) 125 { 126 throw new IOException (Messages.getMessage("cantLoadByecode", c.getName())); 127 } 128 try 129 { 130 ByteArrayOutputStream out = new ByteArrayOutputStream (); 131 byte[] buf = new byte[1024]; 132 int actual; 133 do 134 { 135 actual = fin.read(buf); 136 if (actual > 0) 137 { 138 out.write(buf, 0, actual); 139 } 140 } 141 while (actual > 0); 142 return out.toByteArray(); 143 } 144 finally 145 { 146 fin.close(); 147 } 148 } 149 150 static String classDescriptorToName(String desc) 151 { 152 return desc.replace('/', '.'); 153 } 154 155 protected static Map findAttributeReaders(Class c) 156 { 157 HashMap map = new HashMap (); 158 Method [] methods = c.getMethods(); 159 160 for (int i = 0; i < methods.length; i++) 161 { 162 String name = methods[i].getName(); 163 if (name.startsWith("read") && methods[i].getReturnType() == void.class) 164 { 165 map.put(name.substring(4), methods[i]); 166 } 167 } 168 169 return map; 170 } 171 172 173 protected static String getSignature(Member method, Class [] paramTypes) 174 { 175 177 StringBuffer b = new StringBuffer ((method instanceof Method ) ? method.getName() : "<init>"); 178 b.append('('); 179 180 for (int i = 0; i < paramTypes.length; i++) 181 { 182 addDescriptor(b, paramTypes[i]); 183 } 184 185 b.append(')'); 186 if (method instanceof Method ) 187 { 188 addDescriptor(b, ((Method )method).getReturnType()); 189 } 190 else if (method instanceof Constructor ) 191 { 192 addDescriptor(b, void.class); 193 } 194 195 return b.toString(); 196 } 197 198 private static void addDescriptor(StringBuffer b, Class c) 199 { 200 if (c.isPrimitive()) 201 { 202 if (c == void.class) 203 b.append('V'); 204 else if (c == int.class) 205 b.append('I'); 206 else if (c == boolean.class) 207 b.append('Z'); 208 else if (c == byte.class) 209 b.append('B'); 210 else if (c == short.class) 211 b.append('S'); 212 else if (c == long.class) 213 b.append('J'); 214 else if (c == char.class) 215 b.append('C'); 216 else if (c == float.class) 217 b.append('F'); 218 else if (c == double.class) b.append('D'); 219 } 220 else if (c.isArray()) 221 { 222 b.append('['); 223 addDescriptor(b, c.getComponentType()); 224 } 225 else 226 { 227 b.append('L').append(c.getName().replace('.', '/')).append(';'); 228 } 229 } 230 231 232 235 protected final int readShort() 236 { 237 return (read() << 8) | read(); 238 } 239 240 243 protected final int readInt() 244 { 245 return (read() << 24) | (read() << 16) | (read() << 8) | read(); 246 } 247 248 251 protected void skipFully(int n) throws IOException 252 { 253 while (n > 0) 254 { 255 int c = (int)skip(n); 256 if (c <= 0) 257 throw new EOFException (Messages.getMessage("unexpectedEOF00")); 258 n -= c; 259 } 260 } 261 262 protected final Member resolveMethod(int index) throws IOException , ClassNotFoundException , NoSuchMethodException 263 { 264 int oldPos = pos; 265 try 266 { 267 Member m = (Member )cpool[index]; 268 if (m == null) 269 { 270 pos = cpoolIndex[index]; 271 Class owner = resolveClass(readShort()); 272 NameAndType nt = resolveNameAndType(readShort()); 273 String signature = nt.name + nt.type; 274 if (nt.name.equals("<init>")) 275 { 276 Constructor [] ctors = owner.getConstructors(); 277 for (int i = 0; i < ctors.length; i++) 278 { 279 String sig = getSignature(ctors[i], ctors[i].getParameterTypes()); 280 if (sig.equals(signature)) 281 { 282 cpool[index] = m = ctors[i]; 283 return m; 284 } 285 } 286 } 287 else 288 { 289 Method [] methods = owner.getDeclaredMethods(); 290 for (int i = 0; i < methods.length; i++) 291 { 292 String sig = getSignature(methods[i], methods[i].getParameterTypes()); 293 if (sig.equals(signature)) 294 { 295 cpool[index] = m = methods[i]; 296 return m; 297 } 298 } 299 } 300 throw new NoSuchMethodException (signature); 301 } 302 return m; 303 } 304 finally 305 { 306 pos = oldPos; 307 } 308 309 } 310 311 protected final Field resolveField(int i) throws IOException , ClassNotFoundException , NoSuchFieldException 312 { 313 int oldPos = pos; 314 try 315 { 316 Field f = (Field )cpool[i]; 317 if (f == null) 318 { 319 pos = cpoolIndex[i]; 320 Class owner = resolveClass(readShort()); 321 NameAndType nt = resolveNameAndType(readShort()); 322 cpool[i] = f = owner.getDeclaredField(nt.name); 323 } 324 return f; 325 } 326 finally 327 { 328 pos = oldPos; 329 } 330 } 331 332 private static class NameAndType 333 { 334 String name; 335 String type; 336 337 public NameAndType(String name, String type) 338 { 339 this.name = name; 340 this.type = type; 341 } 342 } 343 344 protected final NameAndType resolveNameAndType(int i) throws IOException 345 { 346 int oldPos = pos; 347 try 348 { 349 NameAndType nt = (NameAndType)cpool[i]; 350 if (nt == null) 351 { 352 pos = cpoolIndex[i]; 353 String name = resolveUtf8(readShort()); 354 String type = resolveUtf8(readShort()); 355 cpool[i] = nt = new NameAndType(name, type); 356 } 357 return nt; 358 } 359 finally 360 { 361 pos = oldPos; 362 } 363 } 364 365 366 protected final Class resolveClass(int i) throws IOException , ClassNotFoundException 367 { 368 int oldPos = pos; 369 try 370 { 371 Class c = (Class )cpool[i]; 372 if (c == null) 373 { 374 pos = cpoolIndex[i]; 375 String name = resolveUtf8(readShort()); 376 cpool[i] = c = Class.forName(classDescriptorToName(name)); 377 } 378 return c; 379 } 380 finally 381 { 382 pos = oldPos; 383 } 384 } 385 386 protected final String resolveUtf8(int i) throws IOException 387 { 388 int oldPos = pos; 389 try 390 { 391 String s = (String )cpool[i]; 392 if (s == null) 393 { 394 pos = cpoolIndex[i]; 395 int len = readShort(); 396 skipFully(len); 397 cpool[i] = s = new String (buf, pos - len, len, "utf-8"); 398 } 399 return s; 400 } 401 finally 402 { 403 pos = oldPos; 404 } 405 } 406 407 protected final void readCpool() throws IOException 408 { 409 int count = readShort(); cpoolIndex = new int[count]; 411 cpool = new Object [count]; 412 for (int i = 1; i < count; i++) 413 { 414 int c = read(); 415 cpoolIndex[i] = super.pos; 416 switch (c) { 418 case CONSTANT_Fieldref: 419 case CONSTANT_Methodref: 420 case CONSTANT_InterfaceMethodref: 421 case CONSTANT_NameAndType: 422 423 readShort(); 426 case CONSTANT_Class: 427 case CONSTANT_String: 428 429 readShort(); break; 431 432 case CONSTANT_Long: 433 case CONSTANT_Double: 434 435 readInt(); 437 i++; 440 442 case CONSTANT_Integer: 443 case CONSTANT_Float: 444 445 readInt(); break; 447 448 case CONSTANT_Utf8: 449 450 int len = readShort(); 451 skipFully(len); 452 break; 453 454 default: 455 throw new IllegalStateException (Messages.getMessage("unexpectedBytes00")); 457 } 458 } 459 } 460 461 protected final void skipAttributes() throws IOException 462 { 463 int count = readShort(); 464 for (int i = 0; i < count; i++) 465 { 466 readShort(); skipFully(readInt()); 468 } 469 } 470 471 476 protected final void readAttributes() throws IOException 477 { 478 int count = readShort(); 479 for (int i = 0; i < count; i++) 480 { 481 int nameIndex = readShort(); int attrLen = readInt(); 483 int curPos = pos; 484 485 String attrName = resolveUtf8(nameIndex); 486 487 Method m = (Method )attrMethods.get(attrName); 488 489 if (m != null) 490 { 491 try 492 { 493 m.invoke(this, new Object []{}); 494 } 495 catch (IllegalAccessException e) 496 { 497 pos = curPos; 498 skipFully(attrLen); 499 } 500 catch (InvocationTargetException e) 501 { 502 try 503 { 504 throw e.getTargetException(); 505 } 506 catch (Error ex) 507 { 508 throw ex; 509 } 510 catch (RuntimeException ex) 511 { 512 throw ex; 513 } 514 catch (IOException ex) 515 { 516 throw ex; 517 } 518 catch (Throwable ex) 519 { 520 pos = curPos; 521 skipFully(attrLen); 522 } 523 } 524 } 525 else 526 { 527 skipFully(attrLen); 529 } 530 } 531 } 532 533 538 public void readCode() throws IOException 539 { 540 readShort(); readShort(); skipFully(readInt()); skipFully(8 * readShort()); 545 readAttributes(); 548 } 549 550 protected ClassReader(byte buf[], Map attrMethods) 551 { 552 super(buf); 553 554 this.attrMethods = attrMethods; 555 } 556 } 557 558 | Popular Tags |