    001/*
    002@license.text@
    003 */
    004package com.hammurapi.common;
    005
    006import java.util.HashSet;
    007import java.util.LinkedList;
    008import java.util.Set;
    009
    010/**
    011 * Visits class hierarchy in the order: class, implemented
    012 * interfaces, superclass, superclass implemented interfaces, ...
    013 * java.lang.Object is always visited last.
    014 * @author Pavel Vlasov
    015 * @revision $Revision$
    016 */
    017public class ClassHierarchyVisitable implements Visitable<Class<?>> {
    018        private Class<?> clazz;
    019
    020        public ClassHierarchyVisitable(Class<?> clazz) {
    021                this.clazz=clazz;
    022        }
    023
    024        public boolean accept(Visitor<Class<?>> visitor) {
    025                LinkedList<Class<?>> queue=new LinkedList<Class<?>>();
    026                queue.add(clazz);
    027                Set<Class<?>> visited=new HashSet<Class<?>>();
    028                visited.add(Object.class);
    029
    030                while (!queue.isEmpty()) {
    031                        Class<?> currentClazz = queue.removeFirst();
    032                        if (visitor.visit(currentClazz)) {
    033                                Class<?>[] interfaces = currentClazz.getInterfaces();
    034                                for (int i=0; i<interfaces.length; i++) {
    035                                        if (visited.add(interfaces[i])) {
    036                                                queue.add(interfaces[i]);
    037                                        }
    038                                }
    039
    040                                Class<?> superclass = currentClazz.getSuperclass();
    041                                if (superclass!=null && visited.add(superclass)) {
    042                                        queue.add(superclass);
    043                                }
    044                        } else {
    045                                return false;
    046                        }
    047                }
    048
    049                return visitor.visit(Object.class);
    050        }
    051
    052}