checkpoint
[sbp.git] / src / edu / berkeley / sbp / util / Reflection.java
index cf683f0..fd43a45 100644 (file)
@@ -4,8 +4,8 @@ import java.lang.reflect.*;
 
 /** Random reflection-related utilities */
 public final class Reflection {
-
-    private static Object rebuild(Object o, Class c) {
+    
+    public static Object rebuild(Object o, Class c) {
         //System.out.println("rebuild " + o + " (a " + (o==null?null:o.getClass().getName()) + ") " + c);
         if (o==null || c.isAssignableFrom(o.getClass())) return o;
         if ((c == Character.class || c == Character.TYPE) && o instanceof String && ((String)o).length()==1) return new Character(((String)o).charAt(0));
@@ -23,10 +23,16 @@ public final class Reflection {
             }
             if (c == String.class) {
                 boolean ok = true;
-                for(int i=0; i<a.length; i++) if (a[i]==null || !(a[i] instanceof Character)) ok = false;
+                for(int i=0; i<a.length; i++)
+                    if (a[i]==null || (!(a[i] instanceof Character) && !(a[i] instanceof String)))
+                        ok = false;
                 if (ok) {
                     StringBuffer s = new StringBuffer();
-                    for(int i=0; i<a.length; i++) s.append((((Character)a[i])).charValue());
+                    for(int i=0; i<a.length; i++)
+                        s.append(a[i] instanceof Character
+                                 ? (((Character)a[i]).charValue())+""
+                                 : (String)a[i]
+                                 );
                     return s.toString();
                 }
             }
@@ -34,6 +40,7 @@ public final class Reflection {
             Object[] ret = (Object[])Array.newInstance(c.getComponentType(), 1);
             ret[0] = o;
             return ret;
+        } else if (c==int.class && o instanceof Number) { return o;
         } else {
             throw new Error("unable to cast " + o + " from " + o.getClass().getName() + " to " + c.getName());
         }
@@ -44,10 +51,43 @@ public final class Reflection {
         return (Object[])Array.newInstance(c, i);
     }
 
+    public static String indent(String s, int indent) {
+        if (s.indexOf('\n')==-1) return s;
+        StringBuffer ret = new StringBuffer();
+        for(int i=0; i<s.length(); i++) {
+            char c = s.charAt(i);
+            ret.append(c);
+            if (c=='\n')
+                for(int j=0; j<indent; j++)
+                    ret.append(' ');
+        }
+        return ret.toString();
+    }
+
+    public static String show(Object o) {
+        if (o==null) return "null";
+        if (! (o instanceof Object[])) return o.toString() + " : " + o.getClass().getName();
+        Object[] arr = (Object[])o;
+        StringBuffer ret = new StringBuffer();
+        ret.append(o.getClass().getComponentType().getName());
+        ret.append("[]:\n");
+        for(int i=0; i<arr.length; i++)
+            ret.append(indent(show(arr[i]), 4) + "\n");
+        return ret.toString();
+    }
+
+    public static Object lub(Object argo) {
+        if (argo instanceof Object[]) return lub((Object[])argo);
+        return argo;
+    }
     public static Object[] lub(Object[] argo) {
         if (argo==null) return null;
         Class c = null;
-        for(Object o : argo) if (o != null) c = Reflection.lub(c, o.getClass());
+        for(int i=0; i<argo.length; i++) {
+            if (argo[i]==null) continue;
+            argo[i] = lub(argo[i]);
+            c = Reflection.lub(c, argo[i].getClass());
+        }
         if (c==null) c = Object.class;
         Object[] ret = Reflection.newArray(c, argo.length);
         System.arraycopy(argo, 0, ret, 0, argo.length);
@@ -60,9 +100,15 @@ public final class Reflection {
         if (a==b) return a;
         if (a.isAssignableFrom(b)) return a;
         if (b.isAssignableFrom(a)) return b;
+        if (a.isArray() && b.isArray())
+            return arrayClass(lub(a.getComponentType(), b.getComponentType()));
         return lub(b, a.getSuperclass());
     }
 
+    public static Class arrayClass(Class c) {
+        return Reflection.newArray(c, 0).getClass();
+    }
+
     /** a version of <tt>Class.forName</tt> that returns <tt>null</tt> instead of throwing an exception */
     public static Class forNameOrNull(String s) {
         try {
@@ -72,6 +118,7 @@ public final class Reflection {
         }
     }
 
+    public static Object fuzzyInvoke(Object o, Member m) { return fuzzyInvoke(o, m, new Object[0]); }
     /** invoke method/constructor m on object o with arguments args, and perform reasonable coercions as needed */
     public static Object fuzzyInvoke(Object o, Member m, Object[] args) {
         try {
@@ -119,4 +166,35 @@ public final class Reflection {
         return o+"";
     }
 
+    public static boolean isConcrete(Class c) {
+        if ((c.getModifiers() & Modifier.ABSTRACT) != 0) return false;
+        if ((c.getModifiers() & Modifier.INTERFACE) != 0) return false;
+        return true;
+    }
+    public static boolean isStatic(Field f) {
+        if ((f.getModifiers() & Modifier.STATIC) != 0) return true;
+        return false;
+    }
+
+    public static Field getField(Class c, String s) {
+        try {
+            for(Field f : c.getDeclaredFields())
+                if (f.getName().equals(s))
+                    return f;
+        } catch (Exception e) { }
+        if (c.getSuperclass()==null || c.getSuperclass()==c) return null;
+        return getField(c.getSuperclass(), s);
+    }
+    public static Field getField(Class c, int i) {
+        try {
+            for(Field f : c.getDeclaredFields()) {
+                if (isStatic(f)) continue;
+                return f;
+            }
+            if (c.getSuperclass()==null || c.getSuperclass()==c) return null;
+            return getField(c.getSuperclass(), i);
+        } catch (Exception e) { }
+        return null;
+    }
+
 }