package com.lexicalscope.fluentreflection;
import static java.util.Collections.unmodifiableList;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.inject.TypeLiteral;
final class ReflectedFieldsImpl<T> implements ReflectedFields<T> {
private final ReflectedTypeFactory reflectedTypeFactory;
private final ReflectedSuperclassesAndInterfaces<T> allTypes;
private final TypeLiteral<T> typeLiteral;
private List<FluentField> declaredFields;
private List<FluentField> reflectedFields;
ReflectedFieldsImpl(
final ReflectedTypeFactory reflectedTypeFactory,
final TypeLiteral<T> typeLiteral,
final ReflectedSuperclassesAndInterfaces<T> allTypes) {
this.reflectedTypeFactory = reflectedTypeFactory;
this.typeLiteral = typeLiteral;
this.allTypes = allTypes;
}
@Override public List<FluentField> fields() {
if (reflectedFields == null) {
final List<FluentField> result = new ArrayList<FluentField>();
result.addAll(declaredFields());
for (final FluentClass<?> klassToReflect : allTypes.superclassesAndInterfaces()) {
result.addAll(klassToReflect.declaredFields());
}
Collections.reverse(result);
reflectedFields = unmodifiableList(result);
}
return reflectedFields;
}
private List<FluentField> getDeclaredFieldsOfClass(final TypeLiteral<?> typeLiteralToReflect) {
final List<FluentField> result = new ArrayList<FluentField>();
final Field[] declaredFields = typeLiteralToReflect.getRawType().getDeclaredFields();
for (final Field method : declaredFields) {
result.add(reflectedTypeFactory.field(typeLiteralToReflect, method));
}
return result;
}
@Override public List<FluentField> declaredFields() {
if (declaredFields == null) {
declaredFields = unmodifiableList(getDeclaredFieldsOfClass(typeLiteral));
}
return declaredFields;
}
}