package org.radargun.config;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
/**
* Location of @Property through delegated classes.
* Effectively a list of fields, where the value of one field is instance of following field's declaring class.
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class Path {
private final Field[] fields;
private boolean complete;
public Path(Field[] fields) {
if (fields.length == 0) throw new IllegalArgumentException();
this.fields = fields;
}
public Path(Field field) {
this(new Field[] {field});
}
public Object get(Object source) throws IllegalAccessException {
for (Field f : fields) {
f.setAccessible(true);
source = f.get(source);
}
return source;
}
public void set(Object source, Object value) throws IllegalAccessException {
for (int i = 0; i < fields.length - 1; ++i) {
Field f = fields[i];
f.setAccessible(true);
source = f.get(source);
}
Field f = fields[fields.length - 1];
f.setAccessible(true);
f.set(source, value);
}
public Path with(Field field) {
Field[] newFields = Arrays.copyOf(fields, fields.length + 1);
newFields[fields.length] = field;
return new Path(newFields);
}
public Property getTargetAnnotation() {
return fields[fields.length - 1].getAnnotation(Property.class);
}
public Type getTargetGenericType() {
return fields[fields.length - 1].getGenericType();
}
public Class<?> getTargetType() {
return fields[fields.length - 1].getType();
}
public boolean isTrivial() {
return fields.length == 1;
}
public void setComplete(boolean complete) {
this.complete = complete;
}
public boolean isComplete() {
return complete;
}
public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationClass) {
for (Field f : fields) {
if (f.isAnnotationPresent(annotationClass)) {
return true;
}
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < fields.length; ++i) {
if (i != 0) sb.append(" -> ");
sb.append(fields[i].getDeclaringClass().getSimpleName()).append('.').append(fields[i].getName());
}
return sb.toString();
}
}