/* Copyright 2006 by Sean Luke Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package ec.util; import java.lang.reflect.*; import javax.swing.tree.*; import javax.swing.event.*; public class ReflectedObject implements TreeModel { Class type; // the class or TYPE of the object Object obj; // the object. Primitive objects are cast into their wrapper types String name; // the name of the instance variable holding the object. Top-level objects have a name of "->" Object uniq; // a unique identifier for this particular instance variable (used to make getIndexOfChild() possible, ick) static ReflectedObject unknown = new ReflectedObject(null) { public String toString() { return ""; } }; public ReflectedObject(Object o) { this(o,(o==null ? Object.class : o.getClass()),null,null); } protected ReflectedObject(Object o, Class t, String n, Object u) { obj = o; type = t; name = n; uniq = u; } public String toString() { String field = (name == null ? "" : name + ": "); try { if (obj == null) return field + "null"; else if (type.isArray()) return field + type.getName() + ", length=" + Array.getLength(obj); return field+type.getName()+" "+obj.toString(); } catch (Exception e) { e.printStackTrace(); return field + type.getName() + " "; } } public int getNumChildren() { return getNumFields() + getNumProperties(); } public ReflectedObject getChild(int index) { int f = getNumFields(); if (index < f) return getField(index); else return getProperty(index - f); } public ReflectedObject[] getChildren() { ReflectedObject[] fields = getFields(); ReflectedObject[] props = getProperties(); ReflectedObject o[] = new ReflectedObject[fields.length + props.length]; System.arraycopy(fields,0,o,0,fields.length); System.arraycopy(props,0,o,fields.length,props.length); return o; } public int getNumFields() { try { if (obj == null || type.isPrimitive()) return 0; else if (type.isArray()) { return Array.getLength(obj); } else { return type.getFields().length; } } catch (IllegalArgumentException e) { e.printStackTrace(); throw new RuntimeException("Unexpected Exception: " + e); } } public ReflectedObject getField(int index) { try { if (obj == null || type.isPrimitive() || index < 0) return null; else if (type.isArray()) { int len = Array.getLength(obj); if (index > len) return null; return new ReflectedObject(Array.get(obj,index), type.getComponentType(),""+index, ""+index); } else { Field[] f = type.getFields(); int len = f.length; if (index > len) return null; return new ReflectedObject(f[index].get(obj), (f[index].get(obj) == null || f[index].getType().isPrimitive() ? f[index].getType() : f[index].get(obj).getClass()), f[index].getName(), f[index]); } } catch (IllegalArgumentException e) { e.printStackTrace(); throw new RuntimeException("Unexpected Exception: " + e); } catch (IllegalAccessException e) { e.printStackTrace(); throw new RuntimeException("Unexpected Exception: " + e); } } public ReflectedObject[] getFields() { try { if (obj == null || type.isPrimitive()) return new ReflectedObject[0]; else if (type.isArray()) { int len = Array.getLength(obj); ReflectedObject[] ref = new ReflectedObject[len]; for(int x = 0; x < len; x++) ref[x] = new ReflectedObject(Array.get(obj,x), type.getComponentType(),""+x,""+x); return ref; } else { Field[] f = type.getFields(); int len = f.length; ReflectedObject[] ref = new ReflectedObject[len]; for(int x=0;x