view test/java/dyn/MethodHandlePrinter.java @ 43:67e51ee24c47

More (kills Zero!)
author Gary Benson <gbenson@redhat.com>
date Mon, 28 Mar 2011 15:03:25 +0100
parents 1abb32424461
children 0ca449acee7d
line wrap: on
line source

package test.java.dyn;

import java.dyn.MethodHandle;
import java.lang.reflect.Field;

public class MethodHandlePrinter {
    static void print(MethodHandle mh) {
        StringBuilder builder = new StringBuilder();
        formatObject(builder, mh, "");
        System.out.println(builder.toString());
    }

    private static void formatObject(StringBuilder builder,
                                     Object obj,
                                     String indent) {
        Class klass = obj.getClass();
        builder.append(indent);
        builder.append(klass.getName());
        builder.append(" {\n");
        Object vmtarget = formatFields(builder, obj, klass, indent + "  ");
        builder.append(indent);
        builder.append("}");
        if (vmtarget != null) {
            builder.append(", ");
            formatObject(builder, vmtarget, indent);
        }
    }

    private static Object formatFields(StringBuilder builder,
                                       Object obj,
                                       Class klass,
                                       String indent) {
        Object vmtarget = null;

        Class parent = klass.getSuperclass();
        if (parent != Object.class) {
            Object result = formatFields(builder, obj, parent, indent);
            if (result != null) {
                if (vmtarget != null)
                    throw new RuntimeException();
                vmtarget = result;
            }
            builder.append("\n");
        }
        
        builder.append(indent);
        builder.append(klass.getName());
        builder.append(":\n");

        for (Field field: klass.getDeclaredFields()) {
            String name = field.getName();
            Object value;
            try {
                if (!field.isAccessible())
                    field.setAccessible(true);
                value = field.get(obj);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (name.equals("vmtarget")) {
                if (vmtarget != null)
                    throw new RuntimeException();
                vmtarget = value;
            }

            Class type = field.getType();
            String typeName = type.getName();

            builder.append(indent);
            builder.append(typeName);
            builder.append(' ');
            builder.append(name);
            builder.append(" = ");
            builder.append(value);

            builder.append('\n');

        }
        return vmtarget;
    }
}