1 8 package com.tc.backport175.proxy; 9 10 import com.tc.backport175.bytecode.AnnotationElement; 11 import com.tc.backport175.bytecode.AnnotationReader; 12 13 import com.tc.asm.Type; 14 15 import java.lang.reflect.InvocationHandler ; 16 import java.lang.reflect.Method ; 17 import java.lang.reflect.Array ; 18 import java.lang.reflect.Field ; 19 import java.io.Serializable ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.ArrayList ; 23 24 30 public class JavaDocAnnotationInvocationHander implements InvocationHandler , Serializable { 31 static final long serialVersionUID = 1584167345753299421L; 32 33 private static final String TO_STRING_METHOD_NAME = "toString"; 34 private static final String ANNOTATION_TYPE_METHOD_NAME = "annotationType"; 35 36 private final Class m_annotationInterface; 37 private final AnnotationElement.Annotation m_annotation; 38 private final String m_annotationName; 39 40 44 private final ClassLoader m_annotatedClassClassLoader; 45 46 private ClassLoader getAnnotatedClassClassLoader() { 47 return m_annotatedClassClassLoader; 48 } 49 50 57 public JavaDocAnnotationInvocationHander( 58 final Class annotationInterface, 59 final AnnotationElement.Annotation annotation, 60 final ClassLoader annotatedClassClassLoader) { 61 m_annotationInterface = annotationInterface; 62 m_annotation = annotation; 63 m_annotationName = annotationInterface.getName().replace('/', '.'); 64 m_annotatedClassClassLoader = annotatedClassClassLoader!=null?annotatedClassClassLoader:ClassLoader.getSystemClassLoader(); 65 } 66 67 76 public Object invoke(final Object proxy, final Method method, final Object [] args) throws Throwable { 77 final String methodName = method.getName(); 78 if (methodName.equals(ANNOTATION_TYPE_METHOD_NAME)) { 79 return m_annotationInterface; 80 } else if (methodName.equals(TO_STRING_METHOD_NAME)) { 81 return invokeToString(); 82 } else { 83 return invokeAnnotationValue(method); 84 } 85 } 86 87 93 private Object invokeAnnotationValue(final Method method) { 94 Object returnValue = null; 95 for (Iterator it = m_annotation.getElements().iterator(); it.hasNext();) { 96 AnnotationElement.NamedValue namedValue = (AnnotationElement.NamedValue)it.next(); 97 if (namedValue.getName().equals(method.getName())) { 98 returnValue = resolveValue(namedValue, method.getReturnType()); 99 break; 100 } 101 } 102 return returnValue; 103 } 104 105 110 private Object invokeToString() { 111 StringBuffer sb = new StringBuffer (); 112 sb.append('@'); 113 sb.append(m_annotationName); 114 sb.append('('); 115 sb.append(m_annotation.toString()); 116 sb.append(')'); 117 return sb.toString(); 118 } 119 120 127 private Object resolveValue(final AnnotationElement.NamedValue namedValue, final Class valueType) { 128 if (namedValue.isResolved()) { 129 return namedValue.getResolvedValue(); 130 } 131 AnnotationElement.Type type = namedValue.getType(); 132 final Object value; 133 if (type.equals(AnnotationElement.Type.ANNOTATION)) { 134 AnnotationElement.Annotation annotation = (AnnotationElement.Annotation)namedValue.getValue(); 135 value = ProxyFactory.newAnnotationProxy(annotation, getAnnotatedClassClassLoader()); 136 137 } else if (type.equals(AnnotationElement.Type.ARRAY)) { 138 value = resolveArray(namedValue, valueType); 139 140 } else if (type.equals(AnnotationElement.Type.ENUM)) { 141 value = resolveEnum(namedValue); 142 143 } else if (type.equals(AnnotationElement.Type.TYPE)) { 144 value = resolveType(namedValue); 145 146 } else { 147 value = namedValue.getValue(); 148 } 149 namedValue.setResolvedValue(value); 150 return value; 151 } 152 153 159 private Object resolveType(final AnnotationElement.NamedValue namedValue) { 160 final Object value = namedValue.getValue(); 161 if (value instanceof Type) { 162 final Type type = (Type)value; 164 final Class resolvedType; 165 try { 166 if (type.getClassName().endsWith("[]")) { 167 int dimensions = type.getDimensions(); 169 Type elementType = type.getElementType(); 170 Class componentType = resolveType(elementType); 171 resolvedType = Array.newInstance(componentType, new int[dimensions]).getClass(); 172 } else { 173 resolvedType = resolveType(type); 174 } 175 } catch (ClassNotFoundException cnfe) { 176 throw new ResolveAnnotationException( 177 "class [" + type.getClassName() + "] defined in annotation can not be found in class loader [" + 178 m_annotatedClassClassLoader + "]", cnfe 179 ); 180 } 181 return resolvedType; 182 } else { 183 return value; 185 } 186 } 187 188 195 private Class resolveType(final Type type) throws ClassNotFoundException { 196 Class resolvedType; 197 if (Type.LONG_TYPE.equals(type)) { 198 resolvedType = long.class; 199 } else if (Type.INT_TYPE.equals(type)) { 200 resolvedType = int.class; 201 } else if (Type.SHORT_TYPE.equals(type)) { 202 resolvedType = short.class; 203 } else if (Type.DOUBLE_TYPE.equals(type)) { 204 resolvedType = double.class; 205 } else if (Type.FLOAT_TYPE.equals(type)) { 206 resolvedType = float.class; 207 } else if (Type.BOOLEAN_TYPE.equals(type)) { 208 resolvedType = boolean.class; 209 } else if (Type.BYTE_TYPE.equals(type)) { 210 resolvedType = byte.class; 211 } else if (Type.CHAR_TYPE.equals(type)) { 212 resolvedType = char.class; 213 } else { 214 resolvedType = Class.forName(type.getClassName(), false, getAnnotatedClassClassLoader()); 215 } 216 return resolvedType; 217 } 218 219 225 private Object resolveEnum(final AnnotationElement.NamedValue namedValue) { 226 AnnotationElement.Enum enumElement = (AnnotationElement.Enum)namedValue.getValue(); 227 String className = AnnotationReader.toJavaName(enumElement.getDesc()); 228 String value = enumElement.getValue(); 229 230 try { 231 Class clazz = Class.forName(className, false, getAnnotatedClassClassLoader()); 232 Field field = clazz.getDeclaredField(value); 233 try { 234 return field.get(null); 235 } catch (IllegalAccessException e) { 236 throw new ResolveAnnotationException( 237 "can not access static reference field due to: " + e.toString(), e 238 ); 239 } 240 } catch (Exception e) { 241 throw new ResolveAnnotationException( 242 "could not retrieve static reference to field (enum) [" + className + "." + 243 namedValue.getName() + "] due to: " + e.toString(), e 244 ); 245 } 246 } 247 248 255 private Object resolveArray(final AnnotationElement.NamedValue namedValue, final Class valueType) { 256 if (!valueType.isArray()) { 257 throw new IllegalArgumentException ( 258 "annotation interface method [" + namedValue.getName() + "] in interface [" + m_annotationName + 259 "] needs to return an ARRAY type" 260 ); 261 } 262 AnnotationElement.Array array = (AnnotationElement.Array)namedValue.getValue(); 263 Class componentType = valueType.getComponentType(); 264 265 List arrayElements = array.getElements(); 266 List elementList = new ArrayList (); 267 for (Iterator it2 = arrayElements.iterator(); it2.hasNext();) { 268 AnnotationElement.NamedValue arrayValue = (AnnotationElement.NamedValue)it2.next(); 269 270 elementList.add(resolveValue(arrayValue, componentType)); 272 } 273 274 if (componentType.isPrimitive()) { 275 if (componentType.equals(int.class)) { 276 int[] arrayInstance = (int[])Array.newInstance(componentType, arrayElements.size()); 277 int i = 0; 278 for (Iterator it = elementList.iterator(); it.hasNext();) { 279 Integer primitive = (Integer )it.next(); 280 arrayInstance[i++] = primitive.intValue(); 281 } 282 return arrayInstance; 283 } else if (componentType.equals(long.class)) { 284 long[] arrayInstance = (long[])Array.newInstance(componentType, arrayElements.size()); 285 int i = 0; 286 for (Iterator it = elementList.iterator(); it.hasNext();) { 287 Long primitive = (Long )it.next(); 288 arrayInstance[i++] = primitive.longValue(); 289 } 290 return arrayInstance; 291 } else if (componentType.equals(short.class)) { 292 short[] arrayInstance = (short[])Array.newInstance(componentType, arrayElements.size()); 293 int i = 0; 294 for (Iterator it = elementList.iterator(); it.hasNext();) { 295 Short primitive = (Short )it.next(); 296 arrayInstance[i++] = primitive.shortValue(); 297 } 298 return arrayInstance; 299 } else if (componentType.equals(float.class)) { 300 float[] arrayInstance = (float[])Array.newInstance(componentType, arrayElements.size()); 301 int i = 0; 302 for (Iterator it = elementList.iterator(); it.hasNext();) { 303 Float primitive = (Float )it.next(); 304 arrayInstance[i++] = primitive.floatValue(); 305 } 306 return arrayInstance; 307 } else if (componentType.equals(double.class)) { 308 double[] arrayInstance = (double[])Array.newInstance(componentType, arrayElements.size()); 309 int i = 0; 310 for (Iterator it = elementList.iterator(); it.hasNext();) { 311 Double primitive = (Double )it.next(); 312 arrayInstance[i++] = primitive.doubleValue(); 313 } 314 return arrayInstance; 315 } else if (componentType.equals(char.class)) { 316 char[] arrayInstance = (char[])Array.newInstance(componentType, arrayElements.size()); 317 int i = 0; 318 for (Iterator it = elementList.iterator(); it.hasNext();) { 319 Character primitive = (Character )it.next(); 320 arrayInstance[i++] = primitive.charValue(); 321 } 322 return arrayInstance; 323 } else if (componentType.equals(boolean.class)) { 324 boolean[] arrayInstance = (boolean[])Array.newInstance(componentType, arrayElements.size()); 325 int i = 0; 326 for (Iterator it = elementList.iterator(); it.hasNext();) { 327 Boolean primitive = (Boolean )it.next(); 328 arrayInstance[i++] = primitive.booleanValue(); 329 } 330 return arrayInstance; 331 } else if (componentType.equals(byte.class)) { 332 byte[] arrayInstance = (byte[])Array.newInstance(componentType, arrayElements.size()); 333 int i = 0; 334 for (Iterator it = elementList.iterator(); it.hasNext();) { 335 Byte primitive = (Byte )it.next(); 336 arrayInstance[i++] = primitive.byteValue(); 337 } 338 return arrayInstance; 339 } 340 } else { 341 Object [] arrayInstance = (Object [])Array.newInstance(componentType, arrayElements.size()); 342 int i = 0; 343 for (Iterator it = elementList.iterator(); it.hasNext();) { 344 Object element = it.next(); 345 arrayInstance[i++] = element; 346 } 347 return arrayInstance; 348 } 349 return null; 350 } 351 352 } 353 354 | Popular Tags |