Skip to content

Instantly share code, notes, and snippets.

@rockswang
Created August 6, 2014 09:14
Show Gist options
  • Save rockswang/d9df68aa54fdc0cd410e to your computer and use it in GitHub Desktop.
Save rockswang/d9df68aa54fdc0cd410e to your computer and use it in GitHub Desktop.
A JSONObject/JSONArray wrapper, simplifies JSON usage in android & java (json.org api)
package com.roxstudio.utils;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
public class Json implements Iterable<Json>, Externalizable {
private static final long serialVersionUID = 1L;
public static enum JsonType {
NULL,
BOOL,
NUMBER,
STRING,
OBJECT,
ARRAY,
}
public JsonType type;
private Object obj;
/**
* used by externalization
*/
public Json() {
}
public Json(Object obj) {
if (obj == null || JSONObject.NULL.equals(obj)) {
this.type = JsonType.NULL;
this.obj = null;
} if (obj instanceof JSONArray) {
this.type = JsonType.ARRAY;
this.obj = obj;
} else if (obj instanceof Boolean) {
this.type = JsonType.BOOL;
this.obj = obj;
} else if (obj instanceof Number) {
this.type = JsonType.NUMBER;
this.obj = obj;
} else if (obj instanceof String) {
this.type = JsonType.STRING;
this.obj = obj;
} else if (obj instanceof JSONObject) {
this.type = JsonType.OBJECT;
this.obj = obj;
} else {
throw new IllegalArgumentException(obj.getClass().toString());
}
}
public int length() {
assertType(JsonType.ARRAY);
return ((JSONArray) obj).length();
}
public final boolean asBool() {
Boolean v;
return (v = asBool(null)) == null ? false : v.booleanValue();
}
public final Boolean asBool(Boolean fallback) {
switch (type) {
case BOOL:
return ((Boolean) obj);
case NUMBER:
return ((Number) obj).intValue() != 0;
case STRING:
return "true".equalsIgnoreCase((String) obj) ? true : "false".equalsIgnoreCase((String) obj) ? false : fallback;
default:
return fallback;
}
}
public final int asInt() {
Integer v;
return (v = asInt(null)) == null ? 0 : v.intValue();
}
public final Integer asInt(Integer fallback) {
switch (type) {
case BOOL:
return ((Boolean) obj).booleanValue() ? 1 : 0;
case NUMBER:
return ((Number) obj).intValue();
case STRING:
try {
return Integer.valueOf((String) obj);
} catch (Exception ex) {}
default:
return fallback;
}
}
public final long asLong() {
Long v;
return (v = asLong(null)) == null ? 0L : v.longValue();
}
public final Long asLong(Long fallback) {
switch (type) {
case BOOL:
return ((Boolean) obj).booleanValue() ? 1L : 0L;
case NUMBER:
return ((Number) obj).longValue();
case STRING:
try {
return Long.valueOf((String) obj);
} catch (Exception ex) {}
default:
return fallback;
}
}
public final float asFloat() {
Float v;
return (v = asFloat(null)) == null ? 0F : v.floatValue();
}
public final Float asFloat(Float fallback) {
switch (type) {
case BOOL:
return ((Boolean) obj).booleanValue() ? 1F : 0F;
case NUMBER:
return ((Number) obj).floatValue();
case STRING:
try {
return Float.valueOf((String) obj);
} catch (Exception ex) {}
default:
return fallback;
}
}
public final double asDouble() {
Double v;
return (v = asDouble(null)) == null ? 0F : v.doubleValue();
}
public final Double asDouble(Double fallback) {
switch (type) {
case BOOL:
return ((Boolean) obj).booleanValue() ? 1.0 : 0.0;
case NUMBER:
return ((Number) obj).doubleValue();
case STRING:
try {
return Double.valueOf((String) obj);
} catch (Exception ex) {}
default:
return fallback;
}
}
public final String asStr() {
return asStr(null);
}
public final String asStr(String fallback) {
switch (type) {
case BOOL:
case NUMBER:
case STRING:
return obj.toString();
default:
return fallback;
}
}
public final JSONObject asObject() {
assertType(JsonType.OBJECT);
return (JSONObject) obj;
}
public final JSONArray asArray() {
assertType(JsonType.ARRAY);
return (JSONArray) obj;
}
public final String getStr(String name) {
return getStr(name, null);
}
public final String getStr(String name, String fallback) {
Json json = get(name, null);
return json != null ? json.asStr(fallback) : fallback;
}
public final boolean getBool(String name) {
return getBool(name, false);
}
public final Boolean getBool(String name, Boolean fallback) {
Json json = get(name, null);
return json != null ? json.asBool(fallback) : fallback;
}
public final int getInt(String name) {
return getInt(name, 0);
}
public final Integer getInt(String name, Integer fallback) {
Json json = get(name, null);
return json != null ? json.asInt(fallback) : fallback;
}
public final long getLong(String name) {
return getLong(name, 0L);
}
public final Long getLong(String name, Long fallback) {
Json json = get(name, null);
return json != null ? json.asLong(fallback) : fallback;
}
public final float getFloat(String name) {
return getFloat(name, 0F);
}
public final Float getFloat(String name, Float fallback) {
Json json = get(name, null);
return json != null ? json.asFloat(fallback) : fallback;
}
public final double getDouble(String name) {
return getDouble(name, 0.0);
}
public final Double getDouble(String name, Double fallback) {
Json json = get(name, null);
return json != null ? json.asDouble(fallback) : fallback;
}
public final Json getObject(String name) {
return getObject(name, null);
}
public final Json getObject(String name, JSONObject fallback) {
Json json = get(name, null);
return json != null && json.type == JsonType.OBJECT ? json : fallback != null ? new Json(fallback) : null;
}
public final Json getArray(String name) {
return getArray(name, null);
}
public final Json getArray(String name, JSONArray fallback) {
Json json = get(name, null);
return json != null && json.type == JsonType.ARRAY ? json : fallback != null ? new Json(fallback) : null;
}
public final Json get(String name, Json fallback) {
assertType(JsonType.OBJECT);
Object o;
return !((JSONObject) obj).isNull(name) && (o = ((JSONObject) obj).opt(name)) != null ? new Json(o) : fallback;
}
public final String getStrAt(int index) {
return getStrAt(index, null);
}
public final String getStrAt(int index, String fallback) {
Json json = getAt(index, null);
return json != null ? json.asStr(fallback) : fallback;
}
public final boolean getBoolAt(int index) {
return getBoolAt(index, false);
}
public final Boolean getBoolAt(int index, Boolean fallback) {
Json json = getAt(index, null);
return json != null ? json.asBool(fallback) : fallback;
}
public final int getIntAt(int index) {
return getIntAt(index, 0);
}
public final Integer getIntAt(int index, Integer fallback) {
Json json = getAt(index, null);
return json != null ? json.asInt(fallback) : fallback;
}
public final long getLongAt(int index) {
return getLongAt(index, 0L);
}
public final Long getLongAt(int index, Long fallback) {
Json json = getAt(index, null);
return json != null ? json.asLong(fallback) : fallback;
}
public final float getFloatAt(int index) {
return getFloatAt(index, 0F);
}
public final Float getFloatAt(int index, Float fallback) {
Json json = getAt(index, null);
return json != null ? json.asFloat(fallback) : fallback;
}
public final double getDoubleAt(int index) {
return getDoubleAt(index, 0.0);
}
public final Double getDoubleAt(int index, Double fallback) {
Json json = getAt(index, null);
return json != null ? json.asDouble(fallback) : fallback;
}
public final Json getObjectAt(int index) {
return getObjectAt(index, null);
}
public final Json getObjectAt(int index, JSONObject fallback) {
Json json = getAt(index, null);
return json != null && json.type == JsonType.OBJECT ? json : fallback != null ? new Json(fallback) : null;
}
public final Json getArrayAt(int index) {
return getArrayAt(index, null);
}
public final Json getArrayAt(int index, JSONArray fallback) {
Json json = getAt(index, null);
return json != null && json.type == JsonType.ARRAY ? json : fallback != null ? new Json(fallback) : null;
}
public final Json getAt(int index, Json fallback) {
assertType(JsonType.ARRAY);
Object o;
return !((JSONArray) obj).isNull(index) && (o = ((JSONArray) obj).opt(index)) != null ? new Json(o) : fallback;
}
public final void put(String name, Object value) {
assertType(JsonType.OBJECT);
if (!Util.empty(name)) {
try {
((JSONObject) obj).putOpt(name, value);
} catch (Exception ex) {
throw new IllegalArgumentException("" + value);
}
}
}
public final void putAt(int index, Object value) {
assertType(JsonType.ARRAY);
if (index < 0) index = ((JSONArray) obj).length() + index;
try {
((JSONArray) obj).put(index, value);
} catch (Exception ex) {
throw new IllegalArgumentException("index " + index + ", value " + value);
}
}
public final void add(Object value) {
assertType(JsonType.ARRAY);
try {
((JSONArray) obj).put(value);
} catch (Exception ex) {
throw new IllegalArgumentException("" + value);
}
}
@SuppressWarnings("unchecked")
public final <T> T[] toArray(Class<T> clazz, T[] array) {
assertType(JsonType.ARRAY);
int len = ((JSONArray) obj).length();
Object arr = array == null || array.length < len ? Array.newInstance(clazz, len) : array;
if (clazz == String.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getStrAt(i)));
} else if (clazz == Integer.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getIntAt(i, 0)));
} else if (clazz == Long.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getLongAt(i, 0L)));
} else if (clazz == Float.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getFloatAt(i, 0F)));
} else if (clazz == Double.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getDoubleAt(i, 0.0)));
} else if (clazz == Boolean.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getBoolAt(i, false)));
} else if (clazz == JSONObject.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getObjectAt(i)));
} else if (clazz == JSONArray.class) {
for (int i = len; --i >= 0; Array.set(arr, i, this.getArrayAt(i)));
}
return (T[]) arr;
}
public final Iterable<String> keys() {
assertType(JsonType.OBJECT);
return new Iterable<String>() {
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
Iterator<Json> names = new Json(((JSONObject) Json.this.obj).names()).iterator();
@Override
public boolean hasNext() {
return names.hasNext();
}
@Override
public String next() {
return names.next().asStr();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
@Override
public final Iterator<Json> iterator() {
assertType(JsonType.ARRAY);
return new Iterator<Json>() {
int index = 0;
@Override
public boolean hasNext() {
return index < Json.this.length();
}
@Override
public Json next() {
return Json.this.getAt(index++, null);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public final String toString() {
return "type=" + type + ",obj=" + obj;
}
private final boolean assertType(JsonType type) {
if (this.type == type) return true;
throw new IllegalAccessError("Type '" + this.type + "', expect '" + type + "'");
}
public static final Json parse(String s) {
if (s.trim().startsWith("[")) {
try {
return new Json(new JSONArray(s));
} catch (Exception ex) {
throw new IllegalArgumentException("JSONArray: " + s);
}
} else {
try {
return new Json(new JSONObject(s));
} catch (Exception ex) {
throw new IllegalArgumentException("JSONObject: " + s);
}
}
}
public static final Json createObject(Object[] pairs) {
JSONObject obj = new JSONObject();
for (int i = 0, n = pairs.length; i < n; i += 2) {
String key = (String) pairs[i];
try {
obj.putOpt(key, pairs[i + 1]);
} catch (Exception ex) {
throw new IllegalArgumentException("unexpected type at index " + (i + 1));
}
}
return new Json(obj);
}
public static final Json createArray(int[] array) {
JSONArray arr = new JSONArray();
for (int i = 0, n = array.length; i < n; arr.put(array[i++]));
return new Json(arr);
}
public static final <T> Json createArray(T[] array) {
JSONArray arr = new JSONArray();
for (int i = 0, n = array.length; i < n; arr.put(array[i++]));
return new Json(arr);
}
public static final JSONArray asJSONArray(Iterable<Json> list) {
JSONArray array = new JSONArray();
for (Json json: list) {
array.put(json.obj);
}
return array;
}
public static final List<Json> asList(JSONArray array) {
ArrayList<Json> list = new ArrayList<Json>();
for (int i = 0, n = array.length(); i < n; i++) {
list.add(new Json(array.opt(i)));
}
return list;
}
@Override
public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
this.type = JsonType.valueOf(input.readUTF());
String s = input.readUTF();
switch (type) {
case NULL: obj = null; break;
case BOOL: obj = Boolean.valueOf(s); break;
case NUMBER: obj = Double.valueOf(s); break;
case STRING: obj = s; break;
case OBJECT: try { obj = new JSONObject(s); } catch (Exception e) {}; break;
case ARRAY: try { obj = new JSONArray(s); } catch (Exception e) {}; break;
}
}
@Override
public void writeExternal(ObjectOutput output) throws IOException {
output.writeUTF(type.toString());
output.writeUTF(obj.toString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment