package org.easysoa.discovery.code;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import com.thoughtworks.qdox.model.AbstractBaseJavaEntity;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.annotation.AnnotationValue;
public class ParsingUtils {
public static boolean hasAnnotation(AbstractBaseJavaEntity entity, String fullyQualifiedAnnotationName) {
return getAnnotation(entity, fullyQualifiedAnnotationName) != null;
}
public static com.thoughtworks.qdox.model.Annotation getAnnotation(AbstractBaseJavaEntity entity, String fullyQualifiedAnnotationName) {
for (com.thoughtworks.qdox.model.Annotation annotation : entity.getAnnotations()) {
if (fullyQualifiedAnnotationName.equals(annotation.getType().getFullyQualifiedName())) {
return annotation;
}
}
return null;
}
/**
* Supports String, arrays (of String else toString()), else toString(), strips quotes
* @param method
* @param annotation
* @param property
* @return
*/
@SuppressWarnings("unchecked")
public static String getAnnotationPropertyString(AbstractBaseJavaEntity method, String annotation, String property) {
if (ParsingUtils.hasAnnotation(method, annotation)) {
com.thoughtworks.qdox.model.Annotation webResultAnn = ParsingUtils.getAnnotation(method, annotation);
AnnotationValue annValue = webResultAnn.getProperty(property);
if (annValue != null) {
Object parameterValue = annValue.getParameterValue();
if (parameterValue == null) {
return null;
}
if (parameterValue instanceof String) {
return evaluateAnnotationStringValue(method.getParentClass(), (String) parameterValue);
}
if (parameterValue instanceof List<?>) {
StringBuffer sbuf = new StringBuffer();
for (Object s : (List<Object>) parameterValue) {
if (s instanceof String) {
s = evaluateAnnotationStringValue(method.getParentClass(), (String) s);
}
sbuf.append(", ");
sbuf.append(s);
}
if (sbuf.length() != 0) {
sbuf.delete(0, 2);
}
return sbuf.toString();
}
// default :
String stringValue = annValue.toString();
if (stringValue != null) {
// removing parsed but useless double quotes :
return evaluateAnnotationStringValue(method.getParentClass(), stringValue);
}
}
}
return null;
}
/**
* Supports "..." and (package.)Type.field constants
* @param typeResolver
* @param s
* @return
*/
public static String evaluateAnnotationStringValue(JavaClass typeResolver, String stringValue) {
// removing parsed but useless double quotes :
if (stringValue.charAt(0) == '"' && stringValue.charAt(stringValue.length() - 1) == '"') {
stringValue = stringValue.substring(1, stringValue.length() - 1);
} else {
// assuming it's in the form of (package.)Type.field :
int lastIndexOfDot = stringValue.lastIndexOf('.');
String typeName = stringValue.substring(0, lastIndexOfDot);
String typeClassName = typeResolver.resolveType(typeName);
if (typeClassName != null) {
try {
Class<?> typeClass = typeResolver.getClass().getClassLoader().loadClass(typeClassName);
String staticFieldName = stringValue.substring(lastIndexOfDot + 1);
Field staticField = typeClass.getField(staticFieldName);
staticField.setAccessible(true); // in case of private constant in same class
Object staticFieldValue = staticField.get(null);
return (staticFieldValue == null) ? null : String.valueOf(staticFieldValue);
} catch (Exception e) {
//log.warning("Unsupported annotation evaluation for " + stringValue + " in " + typeResolver);
}
}
// TODO better : also imported fields...
}
// TODO better : other primitive types
return stringValue;
}
public static boolean hasAnnotation(AnnotatedElement annotable, String fullyQualifiedAnnotationName) {
return getAnnotation(annotable, fullyQualifiedAnnotationName) != null;
}
public static Annotation getAnnotation(AnnotatedElement annotable, String fullyQualifiedAnnotationName) {
for (java.lang.annotation.Annotation annotation : annotable.getAnnotations()) {
if (fullyQualifiedAnnotationName.equals(annotation.annotationType().getName())) {
return annotation;
}
}
return null;
}
public static String getAnnotationPropertyString(AnnotatedElement annotable, String fullyQualifiedAnnotationName, String property) {
if (ParsingUtils.hasAnnotation(annotable, fullyQualifiedAnnotationName)) {
Annotation ann = ParsingUtils.getAnnotation(annotable, fullyQualifiedAnnotationName);
try {
// annotation value introspection : see http://blog.dahanne.net/2012/05/07/dynamically-proxying-annotations-to-avoid-inducing-api-dependency/
Method annMemberMethod = ann.getClass().getDeclaredMethod(property);
Object annValue = annMemberMethod.invoke(ann, new Object[0]);
if (annValue != null) {
if (annValue instanceof String[]) {
StringBuffer sbuf = new StringBuffer();
for (String s : (String[]) annValue) { //TODO or List<?> ? still test this
sbuf.append(", ");
sbuf.append(String.valueOf(s));
}
if (sbuf.length() != 0) {
sbuf.delete(0, 2);
}
return sbuf.toString();
}
return annValue.toString(); // TODO better : also String[] values...
}
} catch (Exception e) {
throw new RuntimeException("Reflection error in getAnnotationPropertyString("
+ annotable + ", " + fullyQualifiedAnnotationName + ", " + property + ")", e);
}
}
return null;
}
public static boolean isTestClass(JavaClass c) {
return c.getSource().getURL().getPath().contains("src/test/");
}
}