Class ClassPrinter

java.lang.Object
org.glavo.classfile.components.ClassPrinter

public final class ClassPrinter extends Object
A printer of classfiles and its elements.

Any ClassModel, FieldModel, MethodModel, or CodeModel can be printed to a human-readable structured text in JSON, XML, or YAML format. Or it can be exported into a tree of traversable and printable nodes, more exactly into a tree of ClassPrinter.MapNode, ClassPrinter.ListNode, and ClassPrinter.LeafNode instances.

Level of details to print or to export is driven by ClassPrinter.Verbosity option.

The most frequent use case is to simply print a class:

ClassPrinter.toJson(classModel, ClassPrinter.Verbosity.TRACE_ALL, System.out::print);

ClassPrinter allows to traverse tree of simple printable nodes to hook custom printer:

void customPrint(ClassModel classModel) {
    print(ClassPrinter.toTree(classModel, ClassPrinter.Verbosity.TRACE_ALL));
}

void print(ClassPrinter.Node node) {
    switch (node) {
        case ClassPrinter.MapNode mn -> {
            // print map header
            mn.values().forEach(this::print);
        }
        case ClassPrinter.ListNode ln -> {
            // print list header
            ln.forEach(this::print);
        }
        case ClassPrinter.LeafNode n -> {
            // print leaf node
        }
    }
}

Another use case for ClassPrinter is to simplify writing of automated tests:

@Test
void printNodesInTest(ClassModel classModel) {
    var classNode = ClassPrinter.toTree(classModel, ClassPrinter.Verbosity.TRACE_ALL);
    assertContains(classNode, "method name", "myFooMethod");
    assertContains(classNode, "field name", "myBarField");
    assertContains(classNode, "inner class", "MyInnerFooClass");
}

void assertContains(ClassPrinter.Node node, ConstantDesc key, ConstantDesc value) {
    if (!node.walk().anyMatch(n -> n instanceof ClassPrinter.LeafNode ln
                           && ln.name().equals(key)
                           && ln.value().equals(value))) {
        node.toYaml(System.out::print);
        throw new AssertionError("expected %s: %s".formatted(key, value));
    }
}