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 }