package com.adidas.dam.marvin.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import com.adidas.dam.marvin.domain.Filterable;
import com.adidas.dam.marvin.domain.ODataType;
import com.adidas.dam.marvin.domain.Orderable;
import com.adidas.dam.marvin.domain.Selectable;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Helper analyzing entity classes in regards to set annotations returning
* information in regards to filterability, selectability or used OData datatype.
*
* @author Daniel Eichten <daniel.eichten@adidas-group.com>
*/
public final class AnnotationHelper {
/**
* Private empty default constructor to prevent instantiation of this class
*/
private AnnotationHelper() {
super();
}
/**
* Takes passed class, looks for a private field which is identified by the passed field
* name and afterwards checks if {@link Filterable} annotation is set.
*
* @param clazz Entity class to be analyzed
* @param fieldName Name of field going to be checked.
* @return true if field is present in give class and has {@link Filterable} annotation,
* false otherwise
*/
public static boolean hasFilterableAnnotation(final Class<?> clazz, final String fieldName) {
return fieldHasAnnotation(findField(clazz, fieldName), Filterable.class);
}
/**
* Takes passed class, looks for a private field which is identified by the passed field
* name and afterwards checks if {@link Orderable} annotation is set.
*
* @param clazz Entity class to be analyzed
* @param fieldName Name of field going to be checked.
* @return true if field is present in give class and has {@link Orderable} annotation,
* false otherwise
*/
public static boolean hasOrderableAnnotation(final Class<?> clazz, final String fieldName) {
return fieldHasAnnotation(findField(clazz, fieldName), Orderable.class);
}
/**
* Takes passed class, looks for a private field which is identified by the passed field
* name and afterwards checks if {@link Selectable} annotation is set.
*
* @param clazz Entity class to be analyzed
* @param fieldName Name of field going to be checked.
* @return true if field is present in give class and has {@link Selectable} annotation,
* false otherwise
*/
public static boolean hasSelectableAnnotation(final Class<?> clazz, final String fieldName) {
return fieldHasAnnotation(findField(clazz, fieldName), Selectable.class);
}
/**
* Takes passed class, looks for a private field which is identified by the passed field
* name and afterwards checks if {@link ODataType} annotation is set. If found it will
* return the given data type. Otherwise it will return "string".
*
* @param clazz Entity class to be analyzed
* @param fieldName Name of field going to be checked.
* @return data type to be used if field is present in given class and has {@link ODataType}
* annotation, "string" in all other cases
*/
public static String getODataType(final Class<?> clazz, final String fieldName) {
final Field field = findField(clazz, fieldName);
if (field != null) {
final ODataType oDataType = field.getAnnotation(ODataType.class);
if (oDataType != null) {
return oDataType.value();
}
}
return "string";
}
/**
* Checks if a field has the desired annotation set.
*
* @param field name of field to be checked.
* @param annotationClass Class of annotation to be checked.
* @return true if given field has desired annotation, false otherwise
*/
private static boolean fieldHasAnnotation(final Field field,
final Class<? extends Annotation> annotationClass) {
return ((field != null) && (field.getAnnotation(annotationClass) != null));
}
/**
* Takes the given clazz, tries to find the named field and returns it. If
* field is not found it will try to look into the parent class until the whole
* class tree is traversed.
*
* @param clazz class to be analyzed
* @param fieldName name of the field to be looked for
* @return Field on success, otherwise null
*/
private static Field findField(final Class<?> clazz, final String fieldName) {
if (clazz != null) {
Class<?> myClass = clazz;
do {
for (Field field : myClass.getDeclaredFields()) {
final JsonProperty prop = field.getAnnotation(JsonProperty.class);
if ((prop != null) && prop.value().equals(fieldName)) {
return field;
}
}
myClass = myClass.getSuperclass();
} while (myClass != null);
}
return null;
}
}