private IAnnotationModel processAnnotation(CtAnnotation<? extends Annotation> annotation) { String simpleName = annotation.getActualAnnotation().annotationType().getSimpleName(); AnnotationModel annotationModel = new AnnotationModel(); annotationModel.setName(simpleName); Map<String, Object> elementValues = annotation.getElementValues(); for (Map.Entry<String, Object> entry : elementValues.entrySet()) { String key = entry.getKey(); if (key == null) { continue; } Object value = entry.getValue(); ArrayList<CtAnnotation<?>> annotationList = toCtAnnotationList(value); if (annotationList != null) { int size = annotationList.size(); IAnnotationModel[] annotationModels = new IAnnotationModel[size]; for (int i = 0; i < size; i++) { CtAnnotation<?> subAnnotation = annotationList.get(i); IAnnotationModel subAnnotationModel = processAnnotation(subAnnotation); annotationModels[i] = subAnnotationModel; } annotationModel.addValue(key, annotationModels); } else if (value instanceof String[]) { annotationModel.addValue(key, value); } else { if (value instanceof CtNewArray<?>) { List<?> elements = ((CtNewArray<?>) value).getElements(); int size = elements.size(); Object[] arr = new Object[size]; for (int i = 0; i < size; i++) { Object elem = elements.get(i); if (elem instanceof CtCodeElement) { PartialEvaluator eval = factory.Eval().createPartialEvaluator(); arr[i] = eval.evaluate(null, (CtCodeElement) elem); } else { arr[i] = elem; } } value = arr; } if (value instanceof CtCodeElement) { PartialEvaluator eval = factory.Eval().createPartialEvaluator(); value = eval.evaluate(null, (CtCodeElement) value); } if (value instanceof CtLiteral<?>) { value = ((CtLiteral<?>) value).getValue().toString(); } else if (value instanceof CtFieldReference<?>) { Member member = ((CtFieldReference<?>) value).getActualField(); // if field references a static final String, use string's value if (member instanceof Field) { Field field = (Field) member; int mod = field.getModifiers(); if (Modifier.isStatic(mod) && Modifier.isFinal(mod)) { field.setAccessible(true); try { value = field.get(null).toString(); } catch (Throwable t) { value = member.getName(); // NOOP tolerate any exception/error, and fall back to using name of field below } } // fall back to using name of field reference else { value = member.getName(); } } } else if (value.getClass().isArray()) { int length = Array.getLength(value); String[] arr = new String[length]; for (int i = 0; i < length; i++) { Object elem = Array.get(value, i); String sVal = elem.toString(); if (elem instanceof CtLiteral<?>) { sVal = ((CtLiteral<?>) elem).getValue().toString(); } else if (elem instanceof CtFieldReference<?>) { sVal = ((CtFieldReference<?>) elem).getActualField().getName(); } arr[i] = sVal; } value = arr; } else { value = value.toString(); } if (value == null) { value = "null"; } annotationModel.addValue(key, value); } } return annotationModel; }