Skip to content
Permalink
Browse files

replaced html/text renderers delegation by inheritance

  • Loading branch information...
maciejmikosik committed Apr 17, 2017
1 parent 32aff87 commit 66eac970458e809f6b7c06329ee96fffa086e4bd
@@ -29,6 +29,7 @@ public static Logger logger(Writer writer, Renderer<String> renderer) {
public void log(Message message) {
try {
writer.write(renderer.render(message));
writer.write("\n");
writer.flush();
} catch (IOException e) {
throw new LogBuddyException(e);
@@ -2,97 +2,59 @@

import static java.lang.String.format;
import static java.util.stream.Collectors.joining;
import static org.logbuddy.LogBuddyException.check;
import static org.logbuddy.common.Strings.lines;
import static org.logbuddy.common.Strings.times;
import static org.logbuddy.common.Throwables.stackTrace;
import static org.logbuddy.renderer.gallery.Gallery.gallery;

import java.awt.image.RenderedImage;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import org.logbuddy.Message;
import org.logbuddy.Renderer;
import org.logbuddy.model.Completed.ReturnedObject;
import org.logbuddy.model.Completed.ReturnedVoid;
import org.logbuddy.model.Completed.Thrown;
import org.logbuddy.model.InvocationDepth;
import org.logbuddy.model.Invoked;

public class HtmlRenderer implements Renderer<String> {
private final Renderer<String> textRenderer;

public HtmlRenderer(Renderer<String> textRenderer) {
check(textRenderer != null);
this.textRenderer = textRenderer;
}
public class HtmlRenderer extends TextRenderer {
public HtmlRenderer() {}

public String render(Object model) {
if (model instanceof Message) {
return renderImpl((Message) model);
} else if (model instanceof Invoked) {
return renderImpl((Invoked) model);
} else if (model instanceof ReturnedObject) {
return renderImpl((ReturnedObject) model);
} else if (model instanceof ReturnedVoid) {
return renderImpl((ReturnedVoid) model);
} else if (model instanceof Thrown) {
return renderImpl((Thrown) model);
} else if (model instanceof Throwable) {
return renderImpl((Throwable) model);
} else if (model instanceof InvocationDepth) {
return renderImpl((InvocationDepth) model);
} else if (model instanceof List) {
return renderImpl("List", (List<?>) model);
} else if (model != null && model.getClass().isArray()) {
return renderImpl("", arrayToList(model));
} else if (model instanceof RenderedImage) {
return gallery()
.height(100)
.paint((RenderedImage) model);
} else {
return escape(textRenderer.render(model));
}
}

private String renderImpl(Message message) {
StringBuilder builder = new StringBuilder();
builder.append("<span style=\"display: block; white-space: nowrap; font-family: monospace;\">");
for (Object attribute : message.attributes()) {
builder.append(render(attribute)).append("&nbsp;&nbsp;");
return super.render(model);
}
builder.append(render(message.content()));
builder.append("</span>\n");
return builder.toString();
}

private String renderImpl(Invoked invoked) {
String renderedArguments = invoked.arguments.stream()
.map(argument -> render(argument))
.collect(joining(", "));
return format("%s.%s(%s)",
render(invoked.instance),
invoked.method.getName(),
renderedArguments);
}

private String renderImpl(ReturnedObject returned) {
return format("returned %s", render(returned.object));
protected String escape(String string) {
return string
.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace(" ", "&nbsp;")
.replace("\t", "&nbsp;&nbsp;")
.replace("\"", "&quot;");
}

private String renderImpl(ReturnedVoid returned) {
return "returned";
private String renderImpl(Message message) {
return format(""
+ "<span style=\"display: block; white-space: nowrap; font-family: monospace;\">"
+ "%s"
+ "</span>",
super.render(message));
}

private String renderImpl(Thrown thrown) {
return format("thrown %s", render(thrown.throwable));
return escape("thrown ") + render(thrown.throwable);
}

private String renderImpl(Throwable throwable) {
String stackTrace = lines(stackTrace(throwable)).stream()
.map(HtmlRenderer::escape)
.map(this::escape)
.map(line -> format("<code>%s</code><br/>", line))
.collect(joining());
String openStackTraceInNewTab = format(""
@@ -102,33 +64,4 @@ private String renderImpl(Throwable throwable) {
stackTrace);
return format("<a href=\"#\" onclick=\"%s\">%s</a>", openStackTraceInNewTab, throwable);
}

private String renderImpl(InvocationDepth depth) {
return times(2 * depth.value, "&nbsp;");
}

private String renderImpl(String prefix, List<?> list) {
return list.stream()
.map(element -> render(element))
.collect(joining(escape(", "), escape(prefix + "["), escape("]")));
}

private static String escape(String string) {
return string
.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace(" ", "&nbsp;")
.replace("\t", "&nbsp;&nbsp;")
.replace("\"", "&quot;");
}

private static List<Object> arrayToList(Object array) {
int length = Array.getLength(array);
List<Object> list = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
list.add(Array.get(array, i));
}
return list;
}
}
@@ -45,6 +45,8 @@ public TextRenderer() {
public String render(Object model) {
if (model == null) {
return "null";
} else if (model instanceof String) {
return escape((String) model);
} else if (model instanceof Message) {
return renderImpl((Message) model);
} else if (model instanceof Invoked) {
@@ -72,57 +74,62 @@ public String render(Object model) {
}
}

protected String escape(String string) {
return string;
}

private String renderImpl(Message message) {
StringBuilder builder = new StringBuilder();
for (Object attribute : message.attributes()) {
builder.append(render(attribute)).append("\t");
builder.append(render(attribute)).append(escape(" "));
}
builder.append(render(message.content()));
builder.append("\n");
return builder.toString();
}

private String renderImpl(Invoked invoked) {
String renderedArguments = invoked.arguments.stream()
.map(argument -> render(argument))
.collect(joining(", "));
return format("%s.%s(%s)",
render(invoked.instance),
invoked.method.getName(),
renderedArguments);
return ""
+ render(invoked.instance)
+ escape(".")
+ escape(invoked.method.getName())
+ escape("(")
+ invoked.arguments.stream()
.map(this::render)
.collect(joining(escape(", ")))
+ escape(")");
}

private String renderImpl(ReturnedObject returned) {
return format("returned %s", render(returned.object));
return escape("returned ") + render(returned.object);
}

private String renderImpl(ReturnedVoid returned) {
return "returned";
return escape("returned");
}

private String renderImpl(Thrown thrown) {
return format("thrown %s", stackTrace(thrown.throwable));
return escape("thrown ") + escape(stackTrace(thrown.throwable));
}

private String renderImpl(InvocationDepth depth) {
return times(depth.value, "\t");
return escape(times(2 * depth.value, " "));
}

private String renderImpl(String prefix, List<?> list) {
return list.stream()
.map(element -> render(element))
.collect(joining(", ", prefix + "[", "]"));
.map(this::render)
.collect(joining(escape(", "), escape(prefix + "["), escape("]")));
}

private String renderImpl(ZonedDateTime zonedDateTime) {
return dateTimeFormatter.format(zonedDateTime);
return escape(dateTimeFormatter.format(zonedDateTime));
}

private String renderImpl(Thread thread) {
return format("Thread(%s)", thread.getName());
return escape(format("Thread(%s)", thread.getName()));
}

private String renderImpl(Class type) {
return type.getName();
return escape(type.getName());
}
}
@@ -48,7 +48,7 @@ public void writes_line_to_writer() {
given(willReturn(rendered), renderer).render(message);
when(() -> logger.log(message));
thenReturned();
thenEqual(writer.toString(), rendered);
thenEqual(writer.toString(), rendered + "\n");
}

@Test

0 comments on commit 66eac97

Please sign in to comment.
You can’t perform that action at this time.