View Javadoc

1   // ObjectTraverser.java, created Mon Feb  5 23:23:20 2001 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Runtime;
5   
6   import java.util.Iterator;
7   import java.io.PrintStream;
8   import java.lang.reflect.Field;
9   import java.lang.reflect.Modifier;
10  import joeq.Class.jq_Class;
11  import joeq.Class.jq_InstanceField;
12  import joeq.Class.jq_StaticField;
13  import joeq.ClassLib.ClassLibInterface;
14  import joeq.Main.jq;
15  import joeq.UTF.Utf8;
16  import jwutil.util.Assert;
17  
18  /***
19   * ObjectTraverser
20   *
21   * @author  John Whaley <jwhaley@alum.mit.edu>
22   * @version $Id: ObjectTraverser.java 2475 2006-12-24 09:44:50Z joewhaley $
23   */
24  public abstract class ObjectTraverser {
25  
26      public abstract void initialize();
27      public abstract Object mapStaticField(jq_StaticField f);
28      public abstract Object mapInstanceField(Object o, jq_InstanceField f);
29      public abstract Object mapValue(Object o);
30      
31      public static /*final*/ boolean TRACE = false;
32      public static final PrintStream out = System.out;
33      
34      public static final java.lang.Object NO_OBJECT = new java.lang.Object();
35      
36      public Object getStaticFieldValue(jq_StaticField f) {
37          if (jq.IsBootstrapping) {
38              java.lang.Object result = this.mapStaticField(f);
39              if (result != NO_OBJECT) return this.mapValue(result);
40          }
41          // get the value via real reflection.
42          if (TRACE) out.println("Getting value of static field "+f+" via reflection");
43          Field f2 = (Field) f.getJavaLangReflectMemberObject();
44          if (f2 == null) {
45              Class c = Reflection.getJDKType(f.getDeclaringClass());
46              String fieldName = f.getName().toString();
47              f2 = lookupField(c, fieldName);
48              if (f2 == null) {
49                  out.println("Cannot find static field "+f);
50                  return null;
51              }
52          }
53          return getStaticFieldValue_reflection(f2);
54      }
55  
56      public static Field lookupField(Class c, String fieldName) {
57          Field f2 = Reflection.getJDKField(c, fieldName);
58          if (f2 == null) {
59              jq_Class klass = (jq_Class)Reflection.getJQType(c);
60              for (Iterator i = ClassLibInterface.DEFAULT.getImplementationClassDescs(klass.getDesc()); i.hasNext(); ) {
61                  Utf8 u = (Utf8)i.next();
62                  if (TRACE) out.println("Checking mirror class "+u);
63                  String s = u.toString();
64                  Assert._assert(s.charAt(0) == 'L');
65                  try {
66                      c = Class.forName(s.substring(1, s.length()-1).replace('/', '.'));
67                      f2 = Reflection.getJDKField(c, fieldName);
68                      if (f2 != null) break;
69                  } catch (ClassNotFoundException x) {
70                      if (TRACE) out.println("Mirror class "+s+" doesn't exist");
71                  }
72              }
73          }
74          return f2;
75      }
76  
77      public Object getStaticFieldValue_reflection(Field f2) {
78          f2.setAccessible(true);
79          Assert._assert((f2.getModifiers() & Modifier.STATIC) != 0);
80          try {
81              Object o = f2.get(null);
82              if (jq.IsBootstrapping) o = this.mapValue(o);
83              return o;
84          } catch (IllegalAccessException x) {
85              Assert.UNREACHABLE();
86              return null;
87          }
88      }
89      
90      public Object getInstanceFieldValue(Object base, jq_InstanceField f) {
91          if (jq.IsBootstrapping) {
92              java.lang.Object result = this.mapInstanceField(base, f);
93              if (result != NO_OBJECT) return this.mapValue(result);
94          }
95          // get the value via real reflection.
96          if (TRACE) out.println("Getting value of instance field "+f+" via reflection");
97          Field f2 = (Field) f.getJavaLangReflectMemberObject();
98          if (f2 == null) {
99              Class c = Reflection.getJDKType(f.getDeclaringClass());
100             String fieldName = f.getName().toString();
101             f2 = lookupField(c, fieldName);
102             if (f2 == null) {
103                 out.println("Cannot find instance field "+f);
104                 return null;
105             }
106         }
107         return getInstanceFieldValue_reflection(base, f2);
108     }
109     public Object getInstanceFieldValue_reflection(Object base, Field f2) {
110         f2.setAccessible(true);
111         Assert._assert((f2.getModifiers() & Modifier.STATIC) == 0);
112         try {
113             Object o = f2.get(base);
114             if (jq.IsBootstrapping) o = this.mapValue(o);
115             return o;
116         } catch (IllegalAccessException x) {
117             Assert.UNREACHABLE();
118             return null;
119         } catch (IllegalArgumentException x) {
120             System.err.println("Cannot access "+f2+" in object of type "+base.getClass());
121             throw x;
122         }
123     }
124     
125     public void putStaticFieldValue(jq_StaticField f, Object o) {
126         Field f2 = (Field) f.getJavaLangReflectMemberObject();
127         if (f2 == null) {
128             Class c = Reflection.getJDKType(f.getDeclaringClass());
129             String fieldName = f.getName().toString();
130             f2 = lookupField(c, fieldName);
131         }
132         putStaticFieldValue_reflection(f2, o);
133     }
134     public void putStaticFieldValue_reflection(Field f2, Object o) {
135         if (TRACE) out.println("Setting value of static field "+f2+" via reflection");
136         f2.setAccessible(true);
137         Assert._assert((f2.getModifiers() & Modifier.STATIC) != 0);
138         try {
139             f2.set(null, o);
140         } catch (IllegalAccessException x) {
141             Assert.UNREACHABLE();
142         }
143     }
144     
145     public void putInstanceFieldValue(Object base, jq_InstanceField f, Object o) {
146         Field f2 = (Field) f.getJavaLangReflectMemberObject();
147         if (f2 == null) {
148             Class c = Reflection.getJDKType(f.getDeclaringClass());
149             String fieldName = f.getName().toString();
150             f2 = lookupField(c, fieldName);
151         }
152         putInstanceFieldValue_reflection(base, f2, o);
153     }
154     public void putInstanceFieldValue_reflection(Object base, Field f2, Object o) {
155         if (TRACE) out.println("Setting value of static field "+f2+" via reflection");
156         f2.setAccessible(true);
157         Assert._assert((f2.getModifiers() & Modifier.STATIC) == 0);
158         try {
159             f2.set(base, o);
160         } catch (IllegalAccessException x) {
161             Assert.UNREACHABLE();
162         }
163     }
164 }