00001
00005 package edu.mit.csail.sdg.squander.serializer.special;
00006
00007 import java.util.HashMap;
00008 import java.util.LinkedList;
00009 import java.util.List;
00010 import java.util.Map;
00011
00012 import edu.mit.csail.sdg.squander.absstate.FieldValue;
00013 import edu.mit.csail.sdg.squander.absstate.ObjTuple;
00014 import edu.mit.csail.sdg.squander.absstate.ObjTupleSet;
00015 import edu.mit.csail.sdg.squander.spec.ClassSpec;
00016 import edu.mit.csail.sdg.squander.spec.JField;
00017 import edu.mit.csail.sdg.squander.spec.JavaScene;
00018
00024 public class MapSer implements IObjSer {
00025
00026 public static final String DATA = "elts";
00027 public static final String LENGTH = "length";
00028
00029 @Override
00030 public boolean accepts(Class<?> clz) {
00031 return Map.class.isAssignableFrom(clz);
00032 }
00033
00034 @SuppressWarnings("unchecked")
00035 @Override
00036 public Map newInstance(Class<?> cls) {
00037 return new HashMap();
00038 }
00039
00040 @SuppressWarnings("unchecked")
00041 @Override
00042 public List<FieldValue> absFunc(JavaScene javaScene, Object obj) {
00043 Map<Object, Object> map = (Map<Object, Object>) obj;
00044 ClassSpec cls = javaScene.classSpecForObj(obj);
00045 List<FieldValue> result = new LinkedList<FieldValue>();
00046
00047 JField dataFld = cls.findField(DATA);
00048 if (dataFld != null) {
00049 FieldValue fvElems = new FieldValue(dataFld, 3);
00050 for (Map.Entry e : map.entrySet()) {
00051 fvElems.addTuple(new ObjTuple(obj, e.getKey(), e.getValue()));
00052 }
00053 result.add(fvElems);
00054 }
00055
00056 JField lenField = cls.findField(LENGTH);
00057 if (lenField != null) {
00058 FieldValue fvLen = new FieldValue(lenField, 2);
00059 fvLen.addTuple(new ObjTuple(obj, map.size()));
00060 result.add(fvLen);
00061 }
00062
00063 return result;
00064 }
00065
00066 @Override
00067 public Object concrFunc(Object obj, FieldValue fieldValue) {
00068 String fldName = fieldValue.jfield().name();
00069 if (DATA.equals(fldName))
00070 return restoreElems(obj, fieldValue);
00071
00072
00073 else if (!fieldValue.jfield().isPureAbstract())
00074 return obj;
00075 else
00076 throw new RuntimeException("Unknown field name for Java Map: " + fldName);
00077 }
00078
00079 @SuppressWarnings("unchecked")
00080 private Object restoreElems(Object obj, FieldValue fieldValue) {
00081 ObjTupleSet value = fieldValue.tupleSet();
00082 assert value.arity() == 3;
00083 Map map = (Map) obj;
00084 map.clear();
00085 for (ObjTuple ot : value)
00086 map.put(ot.get(1), ot.get(2));
00087 return map;
00088 }
00089
00090
00091
00092
00093
00094 }