if (!(jsonNCube.get("axes") instanceof JsonObject))
{
throw new IllegalArgumentException("Must specify a list of axes for the ncube, under the key 'axes' as [{axis 1}, {axis 2}, ... {axis n}].");
}
JsonObject axes = (JsonObject) jsonNCube.get("axes");
Object[] items = axes.getArray();
if (ArrayUtilities.isEmpty(items))
{
throw new IllegalArgumentException("Must be at least one axis defined in the JSON format.");
}
// Read axes
for (Object item : items)
{
Map jsonAxis = (Map) item;
String name = getString(jsonAxis, "name");
AxisType type = AxisType.valueOf(getString(jsonAxis, "type"));
boolean hasDefault = getBoolean(jsonAxis, "hasDefault");
AxisValueType valueType = AxisValueType.valueOf(getString(jsonAxis, "valueType"));
final int preferredOrder = getLong(jsonAxis, "preferredOrder").intValue();
final Boolean multiMatch = getBoolean(jsonAxis, "multiMatch");
Axis axis = new Axis(name, type, valueType, hasDefault, preferredOrder, multiMatch);
ncube.addAxis(axis);
axis.metaProps = new CaseInsensitiveMap();
axis.metaProps.putAll(jsonAxis);
axis.metaProps.remove("name");
axis.metaProps.remove("type");
axis.metaProps.remove("hasDefault");
axis.metaProps.remove("valueType");
axis.metaProps.remove("preferredOrder");
axis.metaProps.remove("multiMatch");
axis.metaProps.remove("columns");
if (axis.metaProps.size() < 1)
{
axis.metaProps = null;
}
if (!(jsonAxis.get("columns") instanceof JsonObject))
{
throw new IllegalArgumentException("'columns' must be specified, axis '" + name + "', NCube '" + cubeName + "'");
}
JsonObject colMap = (JsonObject) jsonAxis.get("columns");
if (!colMap.isArray())
{
throw new IllegalArgumentException("'columns' must be an array, axis '" + name + "', NCube '" + cubeName + "'");
}
// Read columns
Object[] cols = colMap.getArray();
for (Object col : cols)
{
Map jsonColumn = (Map) col;
Object value = jsonColumn.get("value");
String url = (String)jsonColumn.get("url");
String colType = (String) jsonColumn.get("type");
Object id = jsonColumn.get("id");
if (value == null)
{
if (id == null)
{
throw new IllegalArgumentException("Missing 'value' field on column or it is null, axis '" + name + "', NCube '" + cubeName + "'");
}
else
{ // Allows you to skip setting both id and value to the same value.
value = id;
}
}
boolean cache = true;
if (jsonColumn.containsKey("cache"))
{
if (jsonColumn.get("cache") instanceof Boolean)
{
cache = (Boolean) jsonColumn.get("cache");
}
else if (jsonColumn.get("cache") instanceof String)
{ // Allow setting it as a String too
cache = "true".equalsIgnoreCase((String)jsonColumn.get("cache"));
}
else
{
throw new IllegalArgumentException("'cache' parameter must be set to 'true' or 'false', or not used (defaults to 'true')");
}
}
Column colAdded;
if (type == AxisType.DISCRETE || type == AxisType.NEAREST)
{
colAdded = ncube.addColumn(axis.getName(), (Comparable) parseJsonValue(value, null, colType, false));
}
else if (type == AxisType.RANGE)
{
Object[] rangeItems = ((JsonObject)value).getArray();
if (rangeItems.length != 2)
{
throw new IllegalArgumentException("Range must have exactly two items, axis '" + name +"', NCube '" + cubeName + "'");
}
Comparable low = (Comparable) parseJsonValue(rangeItems[0], null, colType, false);
Comparable high = (Comparable) parseJsonValue(rangeItems[1], null, colType, false);
colAdded = ncube.addColumn(axis.getName(), new Range(low, high));
}
else if (type == AxisType.SET)
{
Object[] rangeItems = ((JsonObject)value).getArray();
RangeSet rangeSet = new RangeSet();
for (Object pt : rangeItems)
{
if (pt instanceof Object[])
{
Object[] rangeValues = (Object[]) pt;
Comparable low = (Comparable) parseJsonValue(rangeValues[0], null, colType, false);
Comparable high = (Comparable) parseJsonValue(rangeValues[1], null, colType, false);
Range range = new Range(low, high);
rangeSet.add(range);
}
else
{
rangeSet.add((Comparable)parseJsonValue(pt, null, colType, false));
}
}
colAdded = ncube.addColumn(axis.getName(), rangeSet);
}
else if (type == AxisType.RULE)
{
Object cmd = parseJsonValue(value, url, colType, cache);
if (!(cmd instanceof CommandCell))
{
throw new IllegalArgumentException("Column values on a RULE axis must be of type CommandCell, axis '" + name + "', NCube '" + cubeName + "'");
}
colAdded = ncube.addColumn(axis.getName(), (CommandCell)cmd);
}
else
{
throw new IllegalArgumentException("Unsupported Axis Type '" + type + "' for simple JSON input, axis '" + name + "', NCube '" + cubeName + "'");
}
if (id != null)
{
long sysId = colAdded.getId();
userIdToUniqueId.put(id, sysId);
}
colAdded.metaProps = new CaseInsensitiveMap();
colAdded.metaProps.putAll(jsonColumn);
colAdded.metaProps.remove("id");
colAdded.metaProps.remove("value");
colAdded.metaProps.remove("type");
colAdded.metaProps.remove("url");
colAdded.metaProps.remove("cache");
if (colAdded.metaProps.size() < 1)
{
colAdded.metaProps = null;
}
}
}
// Read cells
if (!(jsonNCube.get("cells") instanceof JsonObject))
{
throw new IllegalArgumentException("Must specify the 'cells' portion. It can be empty but must be specified, NCube '" + cubeName + "'");
}
JsonObject cellMap = (JsonObject) jsonNCube.get("cells");
if (!cellMap.isArray())
{
throw new IllegalArgumentException("'cells' must be an []. It can be empty but must be specified, NCube '" + cubeName + "'");
}
Object[] cells = cellMap.getArray();
for (Object cell : cells)
{
JsonObject cMap = (JsonObject) cell;
Object ids = cMap.get("id");
String type = (String) cMap.get("type");
String url = (String) cMap.get("url");
boolean cache = false;
if (cMap.containsKey("cache"))
{
if (cMap.get("cache") instanceof Boolean)
{
cache = (Boolean) cMap.get("cache");
}
else
{
throw new IllegalArgumentException("'cache' parameter must be set to 'true' or 'false', or not used (defaults to 'true')");
}
}
Object v = parseJsonValue(cMap.get("value"), url, type, cache);
if (ids instanceof JsonObject)
{ // If specified as ID array, build coordinate that way
Set<Long> colIds = new HashSet<Long>();
for (Object id : ((JsonObject)ids).getArray())
{
if (!userIdToUniqueId.containsKey(id))
{
throw new IllegalArgumentException("ID specified in cell does not match an ID in the columns, id: " + id);
}
colIds.add(userIdToUniqueId.get(id));
}
ncube.setCellById(v, colIds);
}
else
{ // specified as key-values along each axis
if (!(cMap.get("key") instanceof JsonObject))
{
throw new IllegalArgumentException("'key' must be a JSON object {}, NCube '" + cubeName + "'");
}
JsonObject<String, Object> keys = (JsonObject<String, Object>) cMap.get("key");
for (Map.Entry<String, Object> entry : keys.entrySet())
{
keys.put(entry.getKey(), parseJsonValue(entry.getValue(), null, null, false));
}
ncube.setCell(v, keys);