package org.etk.reflect.api.visit;
import org.etk.reflect.api.ClassTypeInfo;
import org.etk.reflect.api.ParameterizedTypeInfo;
import org.etk.reflect.api.TypeInfo;
import org.etk.reflect.api.VisitorStrategy;
public abstract class HierarchyVisitorStrategy<V extends HierarchyVisitor<V>> implements VisitorStrategy<V, HierarchyVisitorStrategy<V>> {
public final void visit(TypeInfo type, V visitor) {
if (type instanceof ClassTypeInfo) {
ClassTypeInfo classType = (ClassTypeInfo)type;
if (accept(classType)) {
if (visitor.enter(classType)) {
TypeInfo superType = classType.getSuperType();
if (superType != null) {
visit(superType, visitor);
}
for (TypeInfo implementedInterface : classType.getInterfaces()) {
visit(implementedInterface, visitor);
}
visitor.leave(classType);
}
leave(classType);
}
} else if (type instanceof ParameterizedTypeInfo) {
visit(((ParameterizedTypeInfo)type).getRawType(), visitor);
} else {
}
}
/**
* Controls wether or not a type will be visited. The method implementation returns true and can be overriden.
*
* @param type the type to accept or refuse
* @return true if the type should be visited
*/
protected boolean accept(ClassTypeInfo type) {
return true;
}
/**
* Signals that a type has been visited. This method will only be called for types which have been accepted
* by the {@link #accept(org.reflext.api.ClassTypeInfo)} method. The default implementation has an empty body.
*
* @param type the visited type
*/
protected void leave(ClassTypeInfo type) {
}
}