1 28 29 package org.jibx.binding.classes; 30 31 import java.util.HashMap ; 32 33 import org.apache.bcel.Constants; 34 import org.apache.bcel.classfile.ExceptionTable; 35 import org.apache.bcel.classfile.FieldOrMethod; 36 import org.apache.bcel.classfile.Method; 37 import org.apache.bcel.classfile.Utility; 38 import org.apache.bcel.generic.ArrayType; 39 import org.apache.bcel.generic.ObjectType; 40 import org.apache.bcel.generic.Type; 41 import org.jibx.runtime.JiBXException; 42 43 50 51 public class ClassItem 52 { 53 54 private static final String [] EMPTY_STRING_ARRAY = new String [0]; 55 56 57 private static HashMap s_primitiveMap = new HashMap (); 58 59 60 private static HashMap s_typeMap = new HashMap (); 61 62 63 private static HashMap s_signatureParamsMap = new HashMap (); 64 65 66 private static HashMap s_signatureTypeMap = new HashMap (); 67 68 static { 69 s_primitiveMap.put("boolean", new String [] { "Z", "I" }); 70 s_primitiveMap.put("byte", new String [] { "B", "S", "I" }); 71 s_primitiveMap.put("char", new String [] { "C", "I" }); 72 s_primitiveMap.put("double", new String [] { "D" }); 73 s_primitiveMap.put("float", new String [] { "F" }); 74 s_primitiveMap.put("int", new String [] { "I" }); 75 s_primitiveMap.put("long", new String [] { "J" }); 76 s_primitiveMap.put("short", new String [] { "S", "I" }); 77 s_primitiveMap.put("void", new String [] { "V" }); 78 s_typeMap.put("boolean", Type.BOOLEAN); 79 s_typeMap.put("byte", Type.BYTE); 80 s_typeMap.put("char", Type.CHAR); 81 s_typeMap.put("double", Type.DOUBLE); 82 s_typeMap.put("float", Type.FLOAT); 83 s_typeMap.put("int", Type.INT); 84 s_typeMap.put("long", Type.LONG); 85 s_typeMap.put("short", Type.SHORT); 86 s_typeMap.put("void", Type.VOID); 87 } 88 89 90 private ClassFile m_classFile; 91 92 93 private String m_name; 94 95 96 private String m_signature; 97 98 99 private String m_typeName; 100 101 102 private String [] m_argTypes; 103 104 105 private FieldOrMethod m_item; 106 107 115 116 public ClassItem(String name, ClassFile cf, FieldOrMethod item) { 117 m_classFile = cf; 118 m_name = name; 119 m_item = item; 120 m_signature = item.getSignature(); 121 if (item instanceof Method) { 122 m_typeName = getTypeFromSignature(m_signature); 123 m_argTypes = getParametersFromSignature(m_signature); 124 } else { 125 m_typeName = Utility.signatureToString(m_signature, false); 126 } 127 } 128 129 134 135 public ClassFile getClassFile() { 136 return m_classFile; 137 } 138 139 144 145 public String getName() { 146 return m_name; 147 } 148 149 154 155 public String getTypeName() { 156 return m_typeName; 157 } 158 159 164 165 public int getArgumentCount() { 166 if (m_item instanceof Method) { 167 return m_argTypes.length; 168 } else { 169 return 0; 170 } 171 } 172 173 179 180 public String getArgumentType(int index) { 181 if (m_item instanceof Method) { 182 return m_argTypes[index]; 183 } else { 184 return null; 185 } 186 } 187 188 193 194 public String [] getArgumentTypes() { 195 if (m_item instanceof Method) { 196 return m_argTypes; 197 } else { 198 return null; 199 } 200 } 201 202 207 208 public int getAccessFlags() { 209 return m_item.getAccessFlags(); 210 } 211 212 217 218 public void setAccessFlags(int flags) { 219 m_item.setAccessFlags(flags); 220 m_classFile.setModified(); 221 } 222 223 231 232 public void makeAccessible(ClassFile src) throws JiBXException { 233 234 int access = getAccessFlags(); 236 if ((access & Constants.ACC_PUBLIC) == 0) { 237 238 ClassFile dest = getClassFile(); 240 if (dest.getPackage().equals(src.getPackage())) { 241 if ((access & Constants.ACC_PRIVATE) != 0) { 242 access = access - Constants.ACC_PRIVATE; 243 } 244 } else { 245 246 ClassFile ancestor = src; 248 while ((ancestor = ancestor.getSuperFile()) != null) { 249 if (ancestor == dest) { 250 break; 251 } 252 } 253 254 if (ancestor == null) { 256 int clear = Constants.ACC_PRIVATE | 257 Constants.ACC_PROTECTED; 258 access = (access & ~clear) | Constants.ACC_PUBLIC; 259 } else if ((access & Constants.ACC_PROTECTED) == 0) { 260 access = (access & ~Constants.ACC_PRIVATE) | 261 Constants.ACC_PROTECTED; 262 } 263 } 264 265 if (access != getAccessFlags()) { 267 if (dest.isModifiable()) { 268 setAccessFlags(access); 269 } else { 270 throw new JiBXException 271 ("Unable to change access permissions for " + 272 getName() + " in class " + src.getName()); 273 } 274 } 275 } 276 } 277 278 283 284 public boolean isStatic() { 285 return (getAccessFlags() & Constants.ACC_STATIC) != 0; 286 } 287 288 293 294 public String getSignature() { 295 return m_signature; 296 } 297 298 303 304 public boolean isMethod() { 305 return m_item == null || m_item instanceof Method; 306 } 307 308 314 315 public boolean isInitializer() { 316 return m_item != null && m_item.getName().equals("<init>"); 317 } 318 319 325 326 public String [] getExceptions() { 327 if (m_item instanceof Method) { 328 ExceptionTable etab = ((Method)m_item).getExceptionTable(); 329 if (etab != null) { 330 return etab.getExceptionNames(); 331 } else { 332 return EMPTY_STRING_ARRAY; 333 } 334 } 335 return null; 336 } 337 338 343 344 public static boolean isPrimitive(String type) { 345 return s_primitiveMap.get(type) != null; 346 } 347 348 353 354 public static String getPrimitiveSignature(String type) { 355 return ((String [])s_primitiveMap.get(type))[0]; 356 } 357 358 364 365 public static String [] getParametersFromSignature(String sig) { 366 String [] types = (String [])s_signatureParamsMap.get(sig); 367 if (types == null) { 368 types = Utility.methodSignatureArgumentTypes(sig, false); 369 s_signatureParamsMap.put(sig, types); 370 } 371 return types; 372 } 373 374 380 381 public static String getTypeFromSignature(String sig) { 382 String type = (String )s_signatureTypeMap.get(sig); 383 if (type == null) { 384 type = Utility.methodSignatureReturnType(sig, false); 385 s_signatureTypeMap.put(sig, type); 386 } 387 return type; 388 } 389 390 396 397 public static Type typeFromName(String name) { 398 399 Type type = (Type)s_typeMap.get(name); 401 if (type == null) { 402 403 int dimen = 0; 405 String base = name; 406 while (base.endsWith("[]")) { 407 dimen++; 408 base = base.substring(0, base.length()-2); 409 } 410 411 if (dimen > 0) { 413 type = (Type)s_typeMap.get(base); 414 } 415 416 if (type == null) { 418 type = new ObjectType(base); 419 s_typeMap.put(base, type); 420 } 421 422 if (dimen > 0) { 424 type = new ArrayType(type, dimen); 425 s_typeMap.put(name, type); 426 } 427 } 428 return type; 429 } 430 431 441 442 public static ClassItem findVirtualMethod(String name, String [] sigs) 443 throws JiBXException { 444 445 int split = name.lastIndexOf('.'); 447 String cname = name.substring(0, split); 448 String mname = name.substring(split+1); 449 ClassFile cf = ClassCache.getClassFile(cname); 450 451 for (int i = 0; i < sigs.length; i++) { 453 ClassItem method = cf.getMethod(mname, sigs[i]); 454 if (method != null) { 455 return method; 456 } 457 } 458 return null; 459 } 460 461 471 472 public static ClassItem findStaticMethod(String name, String [] sigs) 473 throws JiBXException { 474 475 int split = name.lastIndexOf('.'); 477 String cname = name.substring(0, split); 478 String mname = name.substring(split+1); 479 ClassFile cf = ClassCache.getClassFile(cname); 480 481 for (int i = 0; i < sigs.length; i++) { 483 ClassItem method = cf.getStaticMethod(mname, sigs[i]); 484 if (method != null) { 485 return method; 486 } 487 } 488 return null; 489 } 490 491 500 501 public static String [] getSignatureVariants(String name) 502 throws JiBXException { 503 Object obj = s_primitiveMap.get(name); 504 if (obj == null) { 505 ClassFile cf = ClassCache.getClassFile(name); 506 return cf.getInstanceSigs(); 507 } else { 508 return (String [])obj; 509 } 510 } 511 512 522 523 public static boolean isAssignable(String from, String to) 524 throws JiBXException { 525 526 if (from.equals(to)) { 528 return true; 529 } else { 530 531 Object fobj = s_primitiveMap.get(from); 533 Object tobj = s_primitiveMap.get(to); 534 if (fobj == null && tobj == null) { 535 536 ClassFile cf = ClassCache.getClassFile(from); 538 String [] sigs = cf.getInstanceSigs(); 539 String match = Utility.getSignature(to); 540 for (int i = 0; i < sigs.length; i++) { 541 if (match.equals(sigs[i])) { 542 return true; 543 } 544 } 545 return false; 546 547 } else if (fobj != null && tobj != null) { 548 549 String [] fsigs = (String [])fobj; 551 String [] tsigs = (String [])tobj; 552 if (tsigs.length == 1) { 553 for (int i = 0; i < fsigs.length; i++) { 554 if (fsigs[i] == tsigs[0]) { 555 return true; 556 } 557 } 558 } 559 return false; 560 561 } else { 562 563 return false; 565 566 } 567 } 568 } 569 } | Popular Tags |