1 16 17 package org.apache.axis.utils.bytecode; 18 19 import org.apache.axis.utils.Messages; 20 21 import java.io.ByteArrayInputStream ; 22 import java.io.ByteArrayOutputStream ; 23 import java.io.EOFException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.lang.reflect.Constructor ; 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.lang.reflect.Member ; 30 import java.lang.reflect.Method ; 31 import java.util.HashMap ; 32 import java.util.Map ; 33 34 48 public class ClassReader extends ByteArrayInputStream { 49 private static final int CONSTANT_Class = 7; 52 private static final int CONSTANT_Fieldref = 9; 53 private static final int CONSTANT_Methodref = 10; 54 private static final int CONSTANT_InterfaceMethodref = 11; 55 private static final int CONSTANT_String = 8; 56 private static final int CONSTANT_Integer = 3; 57 private static final int CONSTANT_Float = 4; 58 private static final int CONSTANT_Long = 5; 59 private static final int CONSTANT_Double = 6; 60 private static final int CONSTANT_NameAndType = 12; 61 private static final int CONSTANT_Utf8 = 1; 62 67 private int[] cpoolIndex; 68 private Object [] cpool; 69 70 private Map attrMethods; 71 72 80 protected static byte[] getBytes(Class c) throws IOException { 81 InputStream fin = c.getResourceAsStream('/' + c.getName().replace('.', '/') + ".class"); 82 if (fin == null) { 83 throw new IOException ( 84 Messages.getMessage("cantLoadByecode", c.getName())); 85 } 86 try { 87 ByteArrayOutputStream out = new ByteArrayOutputStream (); 88 byte[] buf = new byte[1024]; 89 int actual; 90 do { 91 actual = fin.read(buf); 92 if (actual > 0) { 93 out.write(buf, 0, actual); 94 } 95 } while (actual > 0); 96 return out.toByteArray(); 97 } finally { 98 fin.close(); 99 } 100 } 101 102 static String classDescriptorToName(String desc) { 103 return desc.replace('/', '.'); 104 } 105 106 protected static Map findAttributeReaders(Class c) { 107 HashMap map = new HashMap (); 108 Method [] methods = c.getMethods(); 109 110 for (int i = 0; i < methods.length; i++) { 111 String name = methods[i].getName(); 112 if (name.startsWith("read") && methods[i].getReturnType() == void.class) { 113 map.put(name.substring(4), methods[i]); 114 } 115 } 116 117 return map; 118 } 119 120 121 protected static String getSignature(Member method, Class [] paramTypes) { 122 124 StringBuffer b = new StringBuffer ((method instanceof Method ) ? method.getName() : "<init>"); 125 b.append('('); 126 127 for (int i = 0; i < paramTypes.length; i++) { 128 addDescriptor(b, paramTypes[i]); 129 } 130 131 b.append(')'); 132 if (method instanceof Method ) { 133 addDescriptor(b, ((Method ) method).getReturnType()); 134 } else if (method instanceof Constructor ) { 135 addDescriptor(b, void.class); 136 } 137 138 return b.toString(); 139 } 140 141 private static void addDescriptor(StringBuffer b, Class c) { 142 if (c.isPrimitive()) { 143 if (c == void.class) 144 b.append('V'); 145 else if (c == int.class) 146 b.append('I'); 147 else if (c == boolean.class) 148 b.append('Z'); 149 else if (c == byte.class) 150 b.append('B'); 151 else if (c == short.class) 152 b.append('S'); 153 else if (c == long.class) 154 b.append('J'); 155 else if (c == char.class) 156 b.append('C'); 157 else if (c == float.class) 158 b.append('F'); 159 else if (c == double.class) b.append('D'); 160 } else if (c.isArray()) { 161 b.append('['); 162 addDescriptor(b, c.getComponentType()); 163 } else { 164 b.append('L').append(c.getName().replace('.', '/')).append(';'); 165 } 166 } 167 168 169 172 protected final int readShort() { 173 return (read() << 8) | read(); 174 } 175 176 179 protected final int readInt() { 180 return (read() << 24) | (read() << 16) | (read() << 8) | read(); 181 } 182 183 186 protected void skipFully(int n) throws IOException { 187 while (n > 0) { 188 int c = (int) skip(n); 189 if (c <= 0) 190 throw new EOFException (Messages.getMessage("unexpectedEOF00")); 191 n -= c; 192 } 193 } 194 195 protected final Member resolveMethod(int index) throws IOException , ClassNotFoundException , NoSuchMethodException { 196 int oldPos = pos; 197 try { 198 Member m = (Member ) cpool[index]; 199 if (m == null) { 200 pos = cpoolIndex[index]; 201 Class owner = resolveClass(readShort()); 202 NameAndType nt = resolveNameAndType(readShort()); 203 String signature = nt.name + nt.type; 204 if (nt.name.equals("<init>")) { 205 Constructor [] ctors = owner.getConstructors(); 206 for (int i = 0; i < ctors.length; i++) { 207 String sig = getSignature(ctors[i], ctors[i].getParameterTypes()); 208 if (sig.equals(signature)) { 209 cpool[index] = m = ctors[i]; 210 return m; 211 } 212 } 213 } else { 214 Method [] methods = owner.getDeclaredMethods(); 215 for (int i = 0; i < methods.length; i++) { 216 String sig = getSignature(methods[i], methods[i].getParameterTypes()); 217 if (sig.equals(signature)) { 218 cpool[index] = m = methods[i]; 219 return m; 220 } 221 } 222 } 223 throw new NoSuchMethodException (signature); 224 } 225 return m; 226 } finally { 227 pos = oldPos; 228 } 229 230 } 231 232 protected final Field resolveField(int i) throws IOException , ClassNotFoundException , NoSuchFieldException { 233 int oldPos = pos; 234 try { 235 Field f = (Field ) cpool[i]; 236 if (f == null) { 237 pos = cpoolIndex[i]; 238 Class owner = resolveClass(readShort()); 239 NameAndType nt = resolveNameAndType(readShort()); 240 cpool[i] = f = owner.getDeclaredField(nt.name); 241 } 242 return f; 243 } finally { 244 pos = oldPos; 245 } 246 } 247 248 private static class NameAndType { 249 String name; 250 String type; 251 252 public NameAndType(String name, String type) { 253 this.name = name; 254 this.type = type; 255 } 256 } 257 258 protected final NameAndType resolveNameAndType(int i) throws IOException { 259 int oldPos = pos; 260 try { 261 NameAndType nt = (NameAndType) cpool[i]; 262 if (nt == null) { 263 pos = cpoolIndex[i]; 264 String name = resolveUtf8(readShort()); 265 String type = resolveUtf8(readShort()); 266 cpool[i] = nt = new NameAndType(name, type); 267 } 268 return nt; 269 } finally { 270 pos = oldPos; 271 } 272 } 273 274 275 protected final Class resolveClass(int i) throws IOException , ClassNotFoundException { 276 int oldPos = pos; 277 try { 278 Class c = (Class ) cpool[i]; 279 if (c == null) { 280 pos = cpoolIndex[i]; 281 String name = resolveUtf8(readShort()); 282 cpool[i] = c = Class.forName(classDescriptorToName(name)); 283 } 284 return c; 285 } finally { 286 pos = oldPos; 287 } 288 } 289 290 protected final String resolveUtf8(int i) throws IOException { 291 int oldPos = pos; 292 try { 293 String s = (String ) cpool[i]; 294 if (s == null) { 295 pos = cpoolIndex[i]; 296 int len = readShort(); 297 skipFully(len); 298 cpool[i] = s = new String (buf, pos - len, len, "utf-8"); 299 } 300 return s; 301 } finally { 302 pos = oldPos; 303 } 304 } 305 306 protected final void readCpool() throws IOException { 307 int count = readShort(); cpoolIndex = new int[count]; 309 cpool = new Object [count]; 310 for (int i = 1; i < count; i++) { 311 int c = read(); 312 cpoolIndex[i] = super.pos; 313 switch (c) { 315 case CONSTANT_Fieldref: 316 case CONSTANT_Methodref: 317 case CONSTANT_InterfaceMethodref: 318 case CONSTANT_NameAndType: 319 320 readShort(); 323 case CONSTANT_Class: 324 case CONSTANT_String: 325 326 readShort(); break; 328 329 case CONSTANT_Long: 330 case CONSTANT_Double: 331 332 readInt(); 334 i++; 337 339 case CONSTANT_Integer: 340 case CONSTANT_Float: 341 342 readInt(); break; 344 345 case CONSTANT_Utf8: 346 347 int len = readShort(); 348 skipFully(len); 349 break; 350 351 default: 352 throw new IllegalStateException ( 354 Messages.getMessage("unexpectedBytes00")); 355 } 356 } 357 } 358 359 protected final void skipAttributes() throws IOException { 360 int count = readShort(); 361 for (int i = 0; i < count; i++) { 362 readShort(); skipFully(readInt()); 364 } 365 } 366 367 372 protected final void readAttributes() throws IOException { 373 int count = readShort(); 374 for (int i = 0; i < count; i++) { 375 int nameIndex = readShort(); int attrLen = readInt(); 377 int curPos = pos; 378 379 String attrName = resolveUtf8(nameIndex); 380 381 Method m = (Method ) attrMethods.get(attrName); 382 383 if (m != null) { 384 try { 385 m.invoke(this, new Object []{}); 386 } catch (IllegalAccessException e) { 387 pos = curPos; 388 skipFully(attrLen); 389 } catch (InvocationTargetException e) { 390 try { 391 throw e.getTargetException(); 392 } catch (Error ex) { 393 throw ex; 394 } catch (RuntimeException ex) { 395 throw ex; 396 } catch (IOException ex) { 397 throw ex; 398 } catch (Throwable ex) { 399 pos = curPos; 400 skipFully(attrLen); 401 } 402 } 403 } else { 404 skipFully(attrLen); 406 } 407 } 408 } 409 410 414 public void readCode() throws IOException { 415 readShort(); readShort(); skipFully(readInt()); skipFully(8 * readShort()); 420 readAttributes(); 423 } 424 425 protected ClassReader(byte buf[], Map attrMethods) { 426 super(buf); 427 428 this.attrMethods = attrMethods; 429 } 430 } 431 432 | Popular Tags |