Package net.cakenet.jsaton.script.debug

Source Code of net.cakenet.jsaton.script.debug.JavaExtractor

package net.cakenet.jsaton.script.debug;

import net.cakenet.jsaton.script.debug.collections.AbstractDebugArrayProvider;
import net.cakenet.jsaton.script.debug.collections.DebugArrayElement;
import net.cakenet.jsaton.script.debug.collections.DebugArrayObject;
import net.cakenet.jsaton.script.debug.collections.DebugArrayProvider;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

public class JavaExtractor implements VariableExtractor<Object> {
    private static Map<Object, DebugObject> created = new HashMap<>();
    public static JavaExtractor instance = new JavaExtractor();

    public DebugObject extractFrom(Object o) {
        return new OnDemandDebugObject(new JavaDebugObjectProvider(o));
    }

    private DebugObject provide(final Object o) {
        if (o == null)
            return new SimpleDebugObject();
        if (o instanceof DebugObject)
            return (DebugObject) o;
        try {
            Class c = o.getClass();
            if(c.isArray()) {
                final int len = Array.getLength(o);
                return new DebugArrayObject(new DebugArrayProvider() {
                    private BitSet map = new BitSet(len);
                    private DebugArrayElement[] provided = new DebugArrayElement[len];

                    public int size() {
                        return len;
                    }

                    public DebugArrayElement get(int index) {
                        if(map.get(index))
                            return provided[index];
                        DebugObject v = extractFrom(Array.get(o, index));
                        DebugArrayElement created = new DebugArrayElement(index, v);
                        provided[index] = created;
                        map.set(index);
                        return created;
                    }

                    public int indexOf(Object child) {
                        for(int i = 0; i < provided.length; i++) {
                            Object p = map.get(i)? provided[i]: get(i);
                            if(p == child || (p != null && p.equals(child)))
                                return i;
                        }
                        return -1;
                    }
                });
            }

            if(Collection.class.isAssignableFrom(c)) {
                final Collection col = (Collection) o;
                final int len = col.size();
                final Iterator it = col.iterator();
                return new DebugArrayObject(new AbstractDebugArrayProvider() {
                    protected DebugArrayElement next() {
                        return new DebugArrayElement(this.index, extractFrom(it.next()));
                    }

                    public int size() {
                        return len;
                    }
                });
            }

            // array, iterable or map...
            if (c.isArray() || Iterable.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c) || c.isPrimitive())
                return new SimpleDebugObject(null, c.getCanonicalName(), o);

            DebugObject base = null;
            DebugObject root = null;
            for (Class cur = c; cur != null; cur = cur.getSuperclass()) {
                List<DebugObject> variables = new LinkedList<>();
                SimpleDebugObject obj = new SimpleDebugObject(null, c.getCanonicalName(), o);
                Field[] fields = c.getDeclaredFields();
                for (Field f : fields) {
                    if((f.getModifiers() & Modifier.STATIC) != 0)
                        continue; // Skip static fields...
                    boolean origAccessible = f.isAccessible();
                    if (!origAccessible)
                        f.setAccessible(true);

                    String name = f.getName();
                    Object o1 = f.get(o);
                    Class type = f.getType();
                    DebugObject val = extractFrom(o1);
                    val.type = type.getCanonicalName();
                    val.name = name;
                    variables.add(val);

                    if (!origAccessible)
                        f.setAccessible(false);
                }

                if (!variables.isEmpty())
                    obj.variables = variables;
                // next...
                if (base == null) {
                    base = obj;
                    root = base;
                } else {
                    base.parent = obj;
                    base = obj;
                }

            }
            return root;
        } catch (Exception e) {
            e.printStackTrace();
            return extractFrom(o);
        }
    }

    class JavaDebugObjectProvider implements DebugObjectProvider {
        private Object source;

        public JavaDebugObjectProvider(Object source) {
            this.source = source;
        }

        public DebugObject provide() {
            return JavaExtractor.this.provide(source);
        }
    }
}
TOP

Related Classes of net.cakenet.jsaton.script.debug.JavaExtractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.