1 22 package org.jboss.reflect.plugins.javassist; 23 24 import java.lang.reflect.Array ; 25 import java.lang.reflect.Modifier ; 26 import java.util.Collection ; 27 import java.util.Map ; 28 29 import javassist.CtClass; 30 import javassist.CtConstructor; 31 import javassist.CtField; 32 import javassist.CtMethod; 33 import javassist.NotFoundException; 34 35 import org.jboss.reflect.plugins.ValueConvertor; 36 import org.jboss.reflect.spi.AnnotationValue; 37 import org.jboss.reflect.spi.ClassInfo; 38 import org.jboss.reflect.spi.ConstructorInfo; 39 import org.jboss.reflect.spi.FieldInfo; 40 import org.jboss.reflect.spi.InterfaceInfo; 41 import org.jboss.reflect.spi.MethodInfo; 42 import org.jboss.reflect.spi.TypeInfo; 43 import org.jboss.util.collection.CollectionsFactory; 44 import org.jboss.util.JBossStringBuilder; 45 46 52 public class JavassistTypeInfo extends JavassistInheritableAnnotationHolder implements ClassInfo, InterfaceInfo 53 { 54 55 private JavassistTypeInfoFactoryImpl factory; 56 57 58 private Class <? extends Object > clazz; 59 60 61 private Map <SignatureKey, JavassistConstructorInfo> constructors = CollectionsFactory.createLazyMap(); 62 63 64 private ConstructorInfo[] constructorArray; 65 66 67 private Map <String , JavassistFieldInfo> fields = CollectionsFactory.createLazyMap(); 68 69 70 private FieldInfo[] fieldArray; 71 72 73 private Map <SignatureKey, JavassistMethodInfo> methods = CollectionsFactory.createLazyMap(); 74 75 76 private MethodInfo[] methodArray; 77 78 85 JavassistTypeInfo(JavassistTypeInfoFactoryImpl factory, CtClass ctClass, Class <? extends Object > clazz) 86 { 87 super(ctClass, factory); 88 this.factory = factory; 89 this.clazz = clazz; 90 } 91 92 public String getName() 93 { 94 return ctClass.getName(); 95 } 96 97 public boolean isInterface() 98 { 99 return ctClass.isInterface(); 100 } 101 102 public int getModifiers() 103 { 104 return ctClass.getModifiers(); 105 } 106 107 public boolean isPublic() 108 { 109 return Modifier.isPublic(getModifiers()); 110 } 111 112 public boolean isStatic() 113 { 114 return Modifier.isStatic(getModifiers()); 115 } 116 117 public Class <? extends Object > getType() 118 { 119 return clazz; 120 } 121 122 public ClassInfo getSuperclass() 123 { 124 try 125 { 126 CtClass superclass = ctClass.getSuperclass(); 127 if (superclass == null) 128 return null; 129 return (ClassInfo) factory.getTypeInfo(superclass); 130 } 131 catch (NotFoundException e) 132 { 133 throw JavassistTypeInfoFactoryImpl.raiseClassNotFound(clazz.getSuperclass().getName(), e); 134 } 135 } 136 137 public InterfaceInfo[] getInterfaces() 138 { 139 try 140 { 141 CtClass[] interfaces = ctClass.getInterfaces(); 142 if (interfaces == null || interfaces.length == 0) 143 return null; 144 InterfaceInfo[] result = new InterfaceInfo[interfaces.length]; 145 for (int i = 0; i < result.length; ++i) 146 result[i] = (InterfaceInfo) factory.getTypeInfo(interfaces[i]); 147 return result; 148 } 149 catch (NotFoundException e) 150 { 151 throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for interfaces of " + getName(), e); 152 } 153 } 154 155 public ConstructorInfo[] getDeclaredConstructors() 156 { 157 if (constructorArray == null) 158 { 159 CtConstructor[] declaredConstructors = ctClass.getDeclaredConstructors(); 160 if (declaredConstructors == null || declaredConstructors.length == 0) 161 constructorArray = new ConstructorInfo[0]; 162 else 163 { 164 synchronized (constructors) 165 { 166 for (int i = 0; i < declaredConstructors.length; ++i) 167 generateConstructorInfo(declaredConstructors[i]); 168 Collection <JavassistConstructorInfo> constructorCollection = constructors.values(); 169 constructorArray = constructorCollection.toArray(new ConstructorInfo[constructorCollection.size()]); 170 } 171 } 172 } 173 return constructorArray; 174 } 175 176 public FieldInfo getDeclaredField(String name) 177 { 178 synchronized (fields) 179 { 180 FieldInfo field = fields.get(name); 181 if (field != null) 182 return field; 183 } 184 if (fieldArray != null) 185 return null; 186 try 187 { 188 CtField field = ctClass.getDeclaredField(name); 189 if (field == null) 190 return null; 191 return generateFieldInfo(field); 192 } 193 catch (NotFoundException e) 194 { 195 return null; 196 } 197 } 198 199 public FieldInfo[] getDeclaredFields() 200 { 201 if (fieldArray == null) 202 { 203 CtField[] declaredFields = ctClass.getDeclaredFields(); 204 if (declaredFields == null || declaredFields.length == 0) 205 fieldArray = new FieldInfo[0]; 206 else 207 { 208 synchronized (fields) 209 { 210 for (int i = 0; i < declaredFields.length; ++i) 211 generateFieldInfo(declaredFields[i]); 212 Collection <JavassistFieldInfo> fieldCollection = fields.values(); 213 fieldArray = fieldCollection.toArray(new FieldInfo[fieldCollection.size()]); 214 } 215 } 216 } 217 return fieldArray; 218 } 219 220 public MethodInfo getDeclaredMethod(String name, TypeInfo[] parameters) 221 { 222 SignatureKey key = new SignatureKey(name, parameters); 223 synchronized (methods) 224 { 225 MethodInfo method = methods.get(key); 226 if (method != null) 227 return method; 228 } 229 if (methodArray != null) 230 return null; 231 return generateMethodInfo(key); 232 } 233 234 public MethodInfo[] getDeclaredMethods() 235 { 236 if (methodArray == null) 237 { 238 CtMethod[] declaredMethods = ctClass.getDeclaredMethods(); 239 if (declaredMethods == null || declaredMethods.length == 0) 240 methodArray = new MethodInfo[0]; 241 else 242 { 243 synchronized (methods) 244 { 245 for (int i = 0; i < declaredMethods.length; ++i) 246 generateMethodInfo(declaredMethods[i]); 247 Collection <JavassistMethodInfo> methodCollection = methods.values(); 248 methodArray = methodCollection.toArray(new MethodInfo[methodCollection.size()]); 249 } 250 } 251 } 252 return methodArray; 253 } 254 255 public boolean isArray() 256 { 257 return getType().isArray(); 258 } 259 260 268 public static Class getArrayClass(Class clazz, int depth) 269 { 270 return Array.newInstance(clazz, depth).getClass(); 271 } 272 273 public TypeInfo getArrayType(int depth) 274 { 275 Class arrayClass = getArrayClass(getType(), depth); 276 return factory.getTypeInfo(arrayClass); 277 } 278 279 public Object [] newArrayInstance(int size) throws Throwable 280 { 281 Class clazz = getType(); 282 if (clazz.isArray() == false) 283 throw new ClassCastException (clazz + " is not an array."); 284 return (Object []) Array.newInstance(clazz.getComponentType(), size); 285 } 286 287 public Object convertValue(Object value) throws Throwable 288 { 289 return ValueConvertor.convertValue(getType(), value); 290 } 291 292 protected int getHashCode() 293 { 294 return getName().hashCode(); 295 } 296 297 public boolean equals(Object obj) 298 { 299 if (obj == this) 300 return true; 301 if (obj == null || obj instanceof TypeInfo == false) 302 return false; 303 304 TypeInfo other = (TypeInfo) obj; 305 return getName().equals(other.getName()); 306 } 307 308 public void toShortString(JBossStringBuilder buffer) 309 { 310 buffer.append(getName()); 311 } 312 313 protected void toString(JBossStringBuilder buffer) 314 { 315 buffer.append("name=").append(getName()); 316 super.toString(buffer); 317 } 318 319 324 protected JavassistTypeInfoFactoryImpl getFactory() 325 { 326 return factory; 327 } 328 329 335 protected ConstructorInfo generateConstructorInfo(CtConstructor constructor) 336 { 337 try 338 { 339 CtClass[] parameterTypes = constructor.getParameterTypes(); 340 String [] params = new String [parameterTypes.length]; 341 for (int i = 0; i < params.length; ++i) 342 params[i] = parameterTypes[i].getName(); 343 SignatureKey key = new SignatureKey(null, params); 344 JavassistConstructorInfo info = new JavassistConstructorInfo(factory, this, constructor); 345 synchronized (constructors) 346 { 347 constructors.put(key, info); 348 } 349 return info; 350 } 351 catch (NotFoundException e) 352 { 353 throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for constructor of " + getName(), e); 354 } 355 } 356 357 363 protected FieldInfo generateFieldInfo(CtField field) 364 { 365 JavassistFieldInfo info = new JavassistFieldInfo(factory, this, field); 366 synchronized (fields) 367 { 368 fields.put(field.getName(), info); 369 } 370 return info; 371 } 372 373 379 protected MethodInfo generateMethodInfo(SignatureKey key) 380 { 381 CtClass[] params = getParameterTypes(key); 382 try 383 { 384 CtMethod ctMethod = ctClass.getDeclaredMethod(key.name, params); 385 return generateMethodInfo(key, ctMethod); 386 } 387 catch (NotFoundException e) 388 { 389 throw JavassistTypeInfoFactoryImpl.raiseMethodNotFound("for method " + key.name, e); 390 } 391 } 392 393 399 protected MethodInfo generateMethodInfo(CtMethod method) 400 { 401 try 402 { 403 CtClass[] parameterTypes = method.getParameterTypes(); 404 String [] params = new String [parameterTypes.length]; 405 for (int i = 0; i < params.length; ++i) 406 params[i] = parameterTypes[i].getName(); 407 SignatureKey key = new SignatureKey(method.getName(), params); 408 return generateMethodInfo(key, method); 409 } 410 catch (NotFoundException e) 411 { 412 throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for method " + method.getName(), e); 413 } 414 } 415 416 423 protected MethodInfo generateMethodInfo(SignatureKey key, CtMethod method) 424 { 425 JavassistMethodInfo info = new JavassistMethodInfo(factory, this, key, method); 426 synchronized (methods) 427 { 428 methods.put(key, info); 429 } 430 return info; 431 } 432 433 439 protected CtClass[] getParameterTypes(SignatureKey key) 440 { 441 if (key.params == null) 442 return null; 443 444 CtClass[] result = new CtClass[key.params.length]; 445 for (int i = 0; i < key.params.length; ++i) 446 result[i] = factory.getCtClass(key.params[i]); 447 448 return result; 449 } 450 451 protected Object getAnnotatedTarget() 452 { 453 return ctClass; 454 } 455 456 public AnnotationValue[] getAnnotations() 457 { 458 return getAnnotations(ctClass); 459 } 460 461 @Override 462 public JavassistInheritableAnnotationHolder getSuperHolder() 463 { 464 try 465 { 466 CtClass zuper = ctClass.getSuperclass(); 467 if (zuper == null) 468 { 469 return null; 470 } 471 return (JavassistTypeInfo)factory.getTypeInfo(zuper); 472 } 473 catch (NotFoundException e) 474 { 475 throw new RuntimeException (e); 476 } 477 } 478 479 } 480 | Popular Tags |