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}