package vebugger; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.reflections.Reflections; public final class VisualDebuggerAid { private static Map<Class<?>, VebuggerTemplate> templates = new HashMap<>(); static { Reflections reflections = new Reflections("vebugger.templates"); Set<Class<? extends VebuggerTemplate>> templateClasses = reflections.getSubTypesOf(VebuggerTemplate.class); for (Class<? extends VebuggerTemplate> templateClass : templateClasses) { try { VebuggerTemplate template = templateClass.newInstance(); templates.put(template.getType(), template); } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } } public static final String toString(Object obj) { return toString(obj, true); } public static final String toString(Object obj, boolean includeHtmlWrapper) { if (obj != null) { VebuggerTemplate template = findMatchingTemplate(obj.getClass()); if (template != null) { StringBuilder sb = new StringBuilder(); if (includeHtmlWrapper) { sb.append("<html><body>"); } template.render(sb, obj); if (includeHtmlWrapper) { sb.append("</body></html>"); } return sb.toString(); } } return String.valueOf(obj); } private static final VebuggerTemplate findMatchingTemplate(Class<?> clazz) { VebuggerTemplate template = findMatchingClassTemplate(clazz); if (template == null) { template = findMatchingInterfaceTemplate(clazz); } if (template == null && clazz.isArray()) { template = findMatchingClassTemplate(Object[].class); } return template; } private static final VebuggerTemplate findMatchingClassTemplate(Class<?> clazz) { if (!clazz.equals(Object.class)) { VebuggerTemplate template; if ((template = templates.get(clazz)) != null) { return template; } return findMatchingClassTemplate(clazz.getSuperclass()); } return null; } private static VebuggerTemplate findMatchingInterfaceTemplate(Class<?> clazz) { if (!clazz.equals(Object.class)) { VebuggerTemplate template; for (Class<?> interfaze : clazz.getInterfaces()) { if ((template = templates.get(interfaze)) != null) { return template; } } return findMatchingInterfaceTemplate(clazz.getSuperclass()); } return null; } }