--- /dev/null
+package com.vaadin.tests.util;\r
+\r
+import java.lang.reflect.Modifier;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import com.vaadin.tests.VaadinClasses;\r
+\r
+public class GraphVizClassHierarchyCreator {\r
+\r
+ public static void main(String[] args) {\r
+ String gv = getGraphVizHierarchy((List) VaadinClasses.getComponents(),\r
+ "com.vaadin");\r
+ System.out.println(gv);\r
+ }\r
+\r
+ private static String getGraphVizHierarchy(List<Class> classes,\r
+ String packageToInclude) {\r
+ boolean includeInterfaces = false;\r
+\r
+ StringBuilder header = new StringBuilder();\r
+ header.append("digraph finite_state_machine {\n"\r
+ + " rankdir=BT;\n" + " dpi=\"150\";\n"\r
+ + " ratio=\"0.25\";\n");\r
+\r
+ StringBuilder sb = new StringBuilder();\r
+\r
+ Set<Class> classesAndParents = new HashSet<Class>();\r
+ for (Class<?> cls : classes) {\r
+ addClassAndParents(classesAndParents, cls, packageToInclude);\r
+ }\r
+\r
+ Set<Class> interfaces = new HashSet<Class>();\r
+ for (Object cls : classesAndParents.toArray()) {\r
+ for (Class<?> c : ((Class) cls).getInterfaces()) {\r
+ addClassAndParentInterfaces(classesAndParents, c,\r
+ packageToInclude);\r
+ }\r
+ }\r
+\r
+ for (Class<?> c : classesAndParents) {\r
+ appendClass(sb, c, c.getSuperclass(), packageToInclude,\r
+ includeInterfaces);\r
+ for (Class ci : c.getInterfaces()) {\r
+ appendClass(sb, c, ci, packageToInclude, includeInterfaces);\r
+ }\r
+ }\r
+\r
+ header.append(" node [shape = ellipse, style=\"dotted\"] ");\r
+ for (Class c : classesAndParents) {\r
+ if (!c.isInterface() && Modifier.isAbstract(c.getModifiers())) {\r
+ header.append(c.getSimpleName() + " ");\r
+ }\r
+ }\r
+ if (includeInterfaces) {\r
+ System.out.print(" node [shape = ellipse, style=\"solid\"] ");\r
+ for (Class c : classesAndParents) {\r
+ if (c.isInterface()) {\r
+ header.append(c.getSimpleName() + " ");\r
+ }\r
+ }\r
+ header.append(";\n");\r
+ }\r
+ header.append(";\n");\r
+ header.append(" node [shape = rectangle, style=\"solid\"];\n");\r
+ return header.toString() + sb.toString() + "}";\r
+ }\r
+\r
+ private static void addClassAndParents(Set<Class> classesAndParents,\r
+ Class<?> cls, String packageToInclude) {\r
+\r
+ if (cls == null) {\r
+ return;\r
+ }\r
+\r
+ if (classesAndParents.contains(cls)) {\r
+ return;\r
+ }\r
+\r
+ if (!cls.getPackage().getName().startsWith(packageToInclude)) {\r
+ return;\r
+ }\r
+\r
+ classesAndParents.add(cls);\r
+ addClassAndParents(classesAndParents, cls.getSuperclass(),\r
+ packageToInclude);\r
+\r
+ }\r
+\r
+ private static void addClassAndParentInterfaces(\r
+ Set<Class> classesAndParents, Class<?> cls, String packageToInclude) {\r
+\r
+ if (cls == null) {\r
+ return;\r
+ }\r
+\r
+ if (classesAndParents.contains(cls)) {\r
+ return;\r
+ }\r
+\r
+ if (!cls.getPackage().getName().startsWith(packageToInclude)) {\r
+ return;\r
+ }\r
+\r
+ classesAndParents.add(cls);\r
+ for (Class iClass : cls.getInterfaces()) {\r
+ addClassAndParentInterfaces(classesAndParents, iClass,\r
+ packageToInclude);\r
+ }\r
+\r
+ }\r
+\r
+ private static void appendClass(StringBuilder sb, Class<?> c,\r
+ Class<?> superClass, String packageToInclude,\r
+ boolean includeInterfaces) {\r
+ if (superClass == null) {\r
+ return;\r
+ }\r
+ if (!c.getPackage().getName().startsWith(packageToInclude)) {\r
+ return;\r
+ }\r
+ if (!superClass.getPackage().getName().startsWith(packageToInclude)) {\r
+ return;\r
+ }\r
+ if (!includeInterfaces && (c.isInterface() || superClass.isInterface())) {\r
+ return;\r
+ }\r
+\r
+ sb.append(c.getSimpleName()).append(" -> ")\r
+ .append(superClass.getSimpleName()).append("\n");\r
+\r
+ }\r
+\r
+ private static void addInterfaces(Set<Class> interfaces, Class<?> cls) {\r
+ if (interfaces.contains(cls)) {\r
+ return;\r
+ }\r
+\r
+ if (cls.isInterface()) {\r
+ interfaces.add(cls);\r
+ }\r
+\r
+ for (Class c : cls.getInterfaces()) {\r
+ addInterfaces(interfaces, c);\r
+ }\r
+ }\r
+\r
+}\r