PrinterState.java

package org.sterling.util;

import java.io.PrintStream;

public class PrinterState implements VisitorState {

    private final VisitorTracker tracker;
    private final PrintStream out;
    private int currentIndent;

    public PrinterState(PrintStream out) {
       this(out, 0);
    }

    public PrinterState(PrintStream out, int indent) {
        this.tracker = new VisitorTracker();
        this.out = out;
        this.currentIndent = indent;
    }

    public void begin(Object node) {
        println(formatNode(node));
        indent();
    }

    @Override
    public void beginVisit(Object node) {
        tracker.beginVisit(node);
    }

    public void end() {
        dedent();
    }

    @Override
    public void endVisit(Object node) {
        tracker.endVisit(node);
    }

    public void println(String value) {
        out.print(getIndent());
        out.println("+" + value);
    }

    private void dedent() {
        currentIndent--;
    }

    private String getIndent() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < currentIndent; i++) {
            builder.append("  ");
        }
        return builder.toString();
    }

    private void indent() {
        currentIndent++;
    }

    protected String formatNode(Object node) {
        return node.getClass().getSimpleName();
    }
}