/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.analytics.blotter; import java.util.Iterator; import java.util.List; import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.util.ArgumentChecker; /** * Wraps a JSON object so it can be used to build a Joda bean. */ /* package */ class JsonBeanDataSource implements BeanDataSource { /** The underlying data. */ private final JSONObject _json; /* package */ JsonBeanDataSource(JSONObject json) { ArgumentChecker.notNull(json, "json"); _json = json; } /** * The JSON library has a NULL sentinel but doesn't document where it's used and where null is used. * @return true if value is null or equals JSONObject.NULL */ private static boolean isNull(Object value) { return value == null || value == JSONObject.NULL; } @Override public Object getValue(String propertyName) { return createValue(_json.opt(propertyName)); } @Override public List<Object> getCollectionValues(String propertyName) { JSONArray array = _json.optJSONArray(propertyName); return createCollection(array); } // TODO this won't cope with maps with beans as keys or values. need to fix @Override public Map<?, ?> getMapValues(String propertyName) { JSONObject jsonObject = _json.optJSONObject(propertyName); if (isNull(jsonObject)) { return null; } Map<String, Object> map = Maps.newHashMap(); for (Iterator<?> it = jsonObject.keys(); it.hasNext(); ) { String key = (String) it.next(); map.put(key, jsonObject.opt(key)); } return map; } private static Object createValue(Object object) { if (isNull(object)) { return null; } else if (object instanceof JSONObject) { return new JsonBeanDataSource((JSONObject) object); } else if (object instanceof JSONArray) { return createCollection((JSONArray) object); } else { return object; } } private static List<Object> createCollection(JSONArray array) { if (isNull(array)) { return null; } List<Object> items = Lists.newArrayList(); for (int i = 0; i < array.length(); i++) { Object item; try { item = array.get(i); } catch (JSONException e) { return null; } items.add(createValue(item)); } return items; } @Override public String getBeanTypeName() { // TODO should this be configurable? try { return _json.getString("type"); } catch (JSONException e) { throw new OpenGammaRuntimeException("Failed to read JSON", e); } } }