00001
00005 package edu.mit.csail.sdg.squander.serializer.special;
00006
00007 import java.lang.reflect.Array;
00008 import java.util.LinkedList;
00009 import java.util.List;
00010
00011 import edu.mit.csail.sdg.squander.absstate.FieldValue;
00012 import edu.mit.csail.sdg.squander.absstate.ObjTuple;
00013 import edu.mit.csail.sdg.squander.absstate.ObjTupleSet;
00014 import edu.mit.csail.sdg.squander.spec.ClassSpec;
00015 import edu.mit.csail.sdg.squander.spec.JavaScene;
00016 import edu.mit.csail.sdg.squander.utils.ReflectionUtils;
00017
00023 public class ArraySer implements IObjSer {
00024
00025 public static final String ELEMS = "elems";
00026 public static final String LENGTH = "length";
00027
00028 @Override
00029 public boolean accepts(Class<?> clz) {
00030 return clz.isArray();
00031 }
00032
00033 @Override
00034 public Object newInstance(Class<?> cls) {
00035 return ReflectionUtils.createNewArray(cls.getComponentType(), 0);
00036 }
00037
00038 @Override
00039 public List<FieldValue> absFunc(JavaScene javaScene, Object obj) {
00040 ClassSpec cls = javaScene.classSpecForObj(obj);
00041 List<FieldValue> result = new LinkedList<FieldValue>();
00042 FieldValue fvElems = new FieldValue(cls.findField(ELEMS), 3);
00043 int len = Array.getLength(obj);
00044 for (int i = 0; i < len; i++) {
00045 fvElems.addTuple(new ObjTuple(obj, i, Array.get(obj, i)));
00046 }
00047 result.add(fvElems);
00048
00049 FieldValue fvLen = new FieldValue(cls.findField(LENGTH), 2);
00050 fvLen.addTuple(new ObjTuple(obj, len));
00051 result.add(fvLen);
00052
00053 return result;
00054 }
00055
00056 @Override
00057 public Object concrFunc(Object obj, FieldValue fieldValue) {
00058 String fldName = fieldValue.jfield().name();
00059 assert obj.getClass().isArray();
00060 if (ELEMS.equals(fldName))
00061 return restoreElems(obj, fieldValue);
00062 else if (LENGTH.equals(fldName))
00063 return restoreLength(obj, fieldValue);
00064 else
00065 throw new RuntimeException("Unknown field name for Java array: " + fldName);
00066 }
00067
00068 private Object restoreElems(Object obj, FieldValue fieldValue) {
00069 ObjTupleSet value = fieldValue.tupleSet();
00070 assert value.arity() == 3;
00071 Object arr = obj;
00072 int len = value.tuples().size();
00073 if (Array.getLength(obj) != len)
00074 arr = Array.newInstance(obj.getClass().getComponentType(), len);
00075 for (ObjTuple ot : value.tuples()) {
00076 int idx = (Integer) ot.get(1);
00077 Object elem = ot.get(2);
00078 Array.set(arr, idx, elem);
00079 }
00080 return arr;
00081 }
00082
00083 private Object restoreLength(Object obj, FieldValue fldVal) {
00084 return obj;
00085 }
00086
00087 }