package com.lexicalscope.fluentreflection; import static java.util.Collections.unmodifiableList; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import com.google.inject.TypeLiteral; final class ReflectedMethodsImpl<T> implements ReflectedMethods<T> { private final ReflectedTypeFactory reflectedTypeFactory; private final ReflectedSuperclassesAndInterfaces<T> allTypes; private final TypeLiteral<T> typeLiteral; private List<FluentMethod> declaredMethods; private List<FluentMethod> reflectedMethods; ReflectedMethodsImpl( final ReflectedTypeFactory reflectedTypeFactory, final TypeLiteral<T> typeLiteral, final ReflectedSuperclassesAndInterfaces<T> allTypes) { this.reflectedTypeFactory = reflectedTypeFactory; this.typeLiteral = typeLiteral; this.allTypes = allTypes; } @Override public List<FluentMethod> methods() { if (reflectedMethods == null) { final List<FluentMethod> result = new ArrayList<FluentMethod>(); for (final FluentClass<?> klassToReflect : allTypes.superclassesAndInterfaces()) { result.addAll(klassToReflect.declaredMethods()); } result.addAll(declaredMethods()); reflectedMethods = unmodifiableList(result); } return reflectedMethods; } @Override public List<FluentMethod> declaredMethods() { if (declaredMethods == null) { declaredMethods = unmodifiableList(getDeclaredMethodsOfClass(typeLiteral)); } return declaredMethods; } private List<FluentMethod> getDeclaredMethodsOfClass(final TypeLiteral<?> typeLiteralToReflect) { final List<FluentMethod> result = new ArrayList<FluentMethod>(); final Method[] declaredMethods = typeLiteralToReflect.getRawType().getDeclaredMethods(); for (final Method method : declaredMethods) { result.add(reflectedTypeFactory.method(typeLiteralToReflect, method)); } return result; } }