package com.netflix.governator.internal; import java.lang.reflect.Field; import java.lang.reflect.Method; import com.google.common.base.Supplier; /** * Utility class for class, field and method-based introspection. * * @author elandau */ public class TypeInspector { /** * visitor interface for introspection processing */ public interface TypeVisitor { boolean visit(Field field); boolean visit(Method method); boolean visit(Class<?> clazz); } public static <R, V extends Supplier<R>&TypeVisitor> R accept(Class<?> type, V visitor) { accept(type, (TypeVisitor)visitor); return visitor.get(); } public static void accept(Class<?> type, TypeVisitor visitor) { if (_accept(type, visitor)) { // check these only once at the top level for (Class<?> iface : type.getInterfaces()) { if (!_accept(iface, visitor)) break; } } } private static boolean _accept(Class<?> type, TypeVisitor visitor) { if (type == null) { return false; } boolean continueVisit = visitor.visit(type); if (continueVisit) { for (final Field field : type.getDeclaredFields()) { continueVisit = visitor.visit(field); if (!continueVisit) break; } if (continueVisit) { for (final Method method : type.getDeclaredMethods()) { continueVisit = visitor.visit(method); if (!continueVisit) break; } if (continueVisit) { continueVisit = _accept(type.getSuperclass(), visitor); } } } return continueVisit; } }