00001
00005 package edu.mit.csail.sdg.squander.serializer.special;
00006
00007 import java.lang.reflect.Field;
00008 import java.util.LinkedList;
00009 import java.util.List;
00010
00011 import edu.mit.csail.sdg.squander.absstate.AbstractState;
00012 import edu.mit.csail.sdg.squander.absstate.FieldValue;
00013 import edu.mit.csail.sdg.squander.absstate.ObjAbsState;
00014 import edu.mit.csail.sdg.squander.absstate.ObjTuple;
00015 import edu.mit.csail.sdg.squander.absstate.ObjTupleSet;
00016 import edu.mit.csail.sdg.squander.spec.ClassSpec;
00017 import edu.mit.csail.sdg.squander.spec.JField;
00018 import edu.mit.csail.sdg.squander.spec.JavaScene;
00019 import edu.mit.csail.sdg.squander.utils.ReflectionUtils;
00020
00027 public class DefaultObjSer implements IObjSer {
00028
00029 private static final AbstractState abstractState = new AbstractState();
00030
00031 @Override
00032 public boolean accepts(Class<?> clz) {
00033 return true;
00034 }
00035
00036 @Override
00037 public Object newInstance(Class<?> cls) {
00038 return ReflectionUtils.createObjectDefaultConstructor(cls);
00039 }
00040
00041 @Override
00042 public List<FieldValue> absFunc(JavaScene javaScene, Object obj) {
00043 try {
00044 ClassSpec cls = javaScene.classSpecForObj(obj);
00045 assert cls != null : "can't find class spec for: " + obj.getClass().getName();
00046 List<FieldValue> result = new LinkedList<FieldValue>();
00047 for (JField jf : cls.usedFieldsAll()) {
00048 if (!jf.isSpec()) {
00049
00050 Field field = jf.getJavaField();
00051 field.setAccessible(true);
00052 Object value = field.get(obj);
00053 FieldValue fv = new FieldValue(jf, 2);
00054 fv.addTuple(new ObjTuple(obj, value));
00055 result.add(fv);
00056 } else {
00057
00058 ObjAbsState objState = abstractState.getObjState(obj);
00059 if (objState == null)
00060 continue;
00061 FieldValue fv = objState.getSpecField(jf.name());
00062 if (fv != null && fv.jfield().isPureAbstract())
00063 result.add(fv);
00064 }
00065
00066 }
00067 return result;
00068 } catch (Exception e) {
00069 throw new RuntimeException(e);
00070 }
00071 }
00072
00073 @Override
00074 public Object concrFunc(Object obj, FieldValue fldVal) {
00075 Field javaField = fldVal.jfield().getJavaField();
00076 ObjTupleSet value = fldVal.tupleSet();
00077 if (javaField != null) {
00078 assert value.arity() == 2 : "can't set non-unary value for Java field " + javaField + ": " + value;
00079 assert value.tuples().size() == 1 : "can't set non-tuple value for Java field " + javaField + ": " + value;
00080 ReflectionUtils.setFieldValue(obj, javaField, value.iterator().next().get(1));
00081 } else {
00082 ObjAbsState objState = abstractState.getOrAddObjState(obj);
00083 objState.add(fldVal);
00084 }
00085 return obj;
00086 }
00087
00088 }