package com.hubspot.jinjava.lib.filter; import static com.hubspot.jinjava.util.Logging.ENGINE_LOG; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import com.hubspot.jinjava.doc.annotations.JinjavaDoc; import com.hubspot.jinjava.doc.annotations.JinjavaParam; import com.hubspot.jinjava.doc.annotations.JinjavaSnippet; import com.hubspot.jinjava.interpret.JinjavaInterpreter; import com.hubspot.jinjava.objects.date.PyishDate; @JinjavaDoc( value = "Pretty print a variable. Useful for debugging.", params = @JinjavaParam(value = "value", type = "object", desc = "Object to Pretty Print"), snippets = { @JinjavaSnippet( code = "{% set this_var =\"Variable that I want to debug\" %}\n" + "{{ this_var|pprint }}") }) public class PrettyPrintFilter implements Filter { @Override public String getName() { return "pprint"; } @Override public Object filter(Object var, JinjavaInterpreter interpreter, String... args) { if (var == null) { return "null"; } String varStr = null; if (var instanceof String || var instanceof Number || var instanceof PyishDate || var instanceof Iterable || var instanceof Map) { varStr = Objects.toString(var); } else { varStr = objPropsToString(var); } return StringEscapeUtils.escapeHtml4("{% raw %}(" + var.getClass().getSimpleName() + ": " + varStr + "){% endraw %}"); } private String objPropsToString(Object var) { List<String> props = new LinkedList<>(); try { BeanInfo beanInfo = Introspector.getBeanInfo(var.getClass()); for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) { try { if (pd.getPropertyType().equals(Class.class)) { continue; } Method readMethod = pd.getReadMethod(); if (readMethod != null && !readMethod.getDeclaringClass().equals(Object.class)) { props.add(pd.getName() + "=" + readMethod.invoke(var)); } } catch (Exception e) { ENGINE_LOG.error("Error reading bean value", e); } } } catch (IntrospectionException e) { ENGINE_LOG.error("Error inspecting bean", e); } return '{' + StringUtils.join(props, ", ") + '}'; } }