Created
August 6, 2014 09:14
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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