package info.guardianproject.odkparser.utils; import info.guardianproject.odkparser.Constants; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.List; import org.witness.informacam.json.JSONArray; import org.witness.informacam.json.JSONException; import org.witness.informacam.json.JSONObject; import org.witness.informacam.json.JSONTokener; import android.util.Log; public class Model extends JSONObject { public final static String LOG = Constants.Logger.PARSER; Field[] fields; @SuppressWarnings("rawtypes") public Object getObjectByParameter(List root, String key, Object value) { for(Object o : root) { try { Field f = o.getClass().getDeclaredField(key); Object v = f.get(o); if(v.equals(value)) { return o; } } catch (NoSuchFieldException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } catch (IllegalArgumentException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } catch (IllegalAccessException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } } return null; } public void inflate(byte[] jsonStringBytes) { try { inflate((JSONObject) new JSONTokener(new String(jsonStringBytes)).nextValue()); } catch (JSONException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public void inflate(JSONObject values) { //Log.d(LOG, "attempting to inflate object with values:\n" + values.toString()); fields = this.getClass().getFields(); for(Field f : fields) { try { f.setAccessible(true); if(values.has(f.getName())) { boolean isModel = false; if(f.getType().getSuperclass() == Model.class) { isModel = true; } if(f.getType() == List.class) { List subValue = new ArrayList(); Class clz = (Class<?>) ((ParameterizedType) f.getGenericType()).getActualTypeArguments()[0]; //Log.d(LOG, "UGH: " + clz.getName()); Object test = clz.newInstance(); if(test instanceof Model) { isModel = true; } if(isModel) { JSONArray ja = values.getJSONArray(f.getName()); for(int i=0; i<ja.length(); i++) { Object value = clz.newInstance(); ((Model) value).inflate(ja.getJSONObject(i)); subValue.add(value); } } else { for(Object v : (List<?>) values.get(f.getName())) { subValue.add(v); } } f.set(this, subValue); } else if(f.getType() == byte[].class) { f.set(this, values.getString(f.getName()).getBytes()); } else if(isModel) { Class clz = (Class<?>) f.getType(); Model val = (Model) clz.newInstance(); //Log.d(LOG, "the thing should read:\n" + values.getJSONObject(f.getName()).toString()); val.inflate(values.getJSONObject(f.getName())); f.set(this, val); } else { f.set(this, values.get(f.getName())); } } } catch (IllegalArgumentException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } catch (JSONException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } catch (IllegalAccessException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } catch (InstantiationException e) { Log.e(LOG, e.toString()); e.printStackTrace(); } } //Log.d(LOG, "finished inflating object, which is now\n" + this.asJson().toString()); } public JSONObject asJson() { fields = this.getClass().getFields(); JSONObject json = new JSONObject(); for(Field f : fields) { f.setAccessible(true); if(f.getName().contains("this$")) { continue; } if(f.getName().equals("NULL") || f.getName().equals("LOG")) { continue; } try { Object value = f.get(this); //Log.d(LOG, "HEY THIS TYPE " + f.getType().getSuperclass()); boolean isModel = false; if(f.getType().getSuperclass() == Model.class) { isModel = true; } if(f.getType() == List.class) { JSONArray subValue = new JSONArray(); for(Object v : (List<?>) value) { // Log.d(LOG, v.getClass().getName()); if(v instanceof Model) { subValue.put(((Model) v).asJson()); } else { subValue.put(v); } } json.put(f.getName(), subValue); } else if(f.getType() == byte[].class) { json.put(f.getName(), new String((byte[]) value)); } else if(isModel) { json.put(f.getName(), ((Model) value).asJson()); } else { json.put(f.getName(), value); } } catch (IllegalArgumentException e) { Log.d(LOG, e.toString()); e.printStackTrace(); } catch (IllegalAccessException e) { Log.d(LOG, e.toString()); e.printStackTrace(); } catch (JSONException e) { Log.d(LOG, e.toString()); e.printStackTrace(); } catch (NullPointerException e) { } } return json; } }