net.thucydides.core.annotations.Fields Maven / Gradle / Ivy
package net.thucydides.core.annotations;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Find the annotated fields in a given class.
* Used as a utility class for the higher-level annotation processing.
* Typical use:
*
*
* for (Field field : Fields.of(someClass).allFields()) {
* ...
* }
*
*
*/
public class Fields {
private static final Logger LOGGER = LoggerFactory.getLogger(Fields.class);
private final Class clazz;
public enum FieldValue {
UNDEFINED
}
public static Fields of(final Class testClass) {
return new Fields(testClass);
}
private Fields(Class clazz) {
this.clazz = clazz;
}
public Set allFields() {
Set fields = new HashSet();
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
fields.addAll(Arrays.asList(clazz.getFields()));
if (clazz != Object.class) {
fields.addAll(Fields.of(clazz.getSuperclass()).allFields());
}
return fields;
}
public Set declaredFields() {
Set fields = new HashSet();
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
return fields;
}
public Set nonStaticFields() {
Set fields = allFields();
Set nonStaticFields = new HashSet();
for(Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())) {
nonStaticFields.add(field);
}
}
return nonStaticFields;
}
public Optional withName(String pages) {
for(Field field : allFields()) {
if (field.getName().equals(pages)){
return Optional.of(field);
}
}
return Optional.absent();
}
public Set fieldsAnnotatedBy(Class annotationClass) {
Set fields = allFields();
Set annotatedFields = new HashSet<>();
for(Field field : fields) {
if (field.getAnnotation(annotationClass) != null) {
annotatedFields.add(field);
}
}
return annotatedFields;
}
public static FieldValueBuilder of(Object object) {
return new FieldValueBuilder(object);
}
public static class FieldValueBuilder {
private final Object object;
public FieldValueBuilder(Object object) {
this.object = object;
}
public Map asMap() {
Map fieldValues = Maps.newHashMap();
for(Field field : Fields.of(object.getClass()).allFields()) {
try {
field.setAccessible(true);
if (isValid(field)) {
fieldValues.put(field.getName(), fieldValueFrom(field).or(FieldValue.UNDEFINED));
}
} catch (IllegalAccessException e) {
LOGGER.warn("Failed to inject the field " + field.getName(), e);
}
}
fieldValues.put("self",object);
fieldValues.put("this",object);
return ImmutableMap.copyOf(fieldValues);
}
private boolean isValid(Field field) {
return ((field != null) && (!field.getName().contains("CGLIB")));
}
private FieldValueProvider fieldValueFrom(Field field) {
return new FieldValueProvider(field, object);
}
private static class FieldValueProvider {
Field field;
Object object;
public FieldValueProvider(Field field, Object object) {
this.field = field;
this.object = object;
}
public Object or(FieldValue undefinedValue) throws IllegalAccessException {
return ((field == null) || (object == null)|| (field.get(object) == null)) ? undefinedValue : field.get(object);
}
}
}
public static boolean isAbstract(Field field) {
return Modifier.isAbstract(field.getType().getModifiers());
}
public static boolean isFinal(Field field) {
return Modifier.isFinal(field.getType().getModifiers());
}
public static boolean isStatic(Field field) {
return Modifier.isStatic(field.getType().getModifiers());
}
}