Last active
October 28, 2023 02:41
-
-
Save westc/d9e96f235afbbb9927cdb027ef25ed11 to your computer and use it in GitHub Desktop.
Apex class that interprets JSON values and allows for easy traversal and type casting.
This file contains hidden or 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
public class JSONValue { | |
private Object objValue; | |
public JSONValue(String serialized) { | |
this.objValue = JSON.deserializeUntyped(serialized); | |
} | |
private JSONValue(Object unserialized) { | |
this.objValue = unserialized; | |
} | |
public JSONValue get(Object[] keys) { | |
JSONValue level = this; | |
for (Object key : keys) { | |
level = level.get(key); | |
} | |
return level; | |
} | |
public JSONValue get(Object key) { | |
return new JSONValue(this.getAsObject(key)); | |
} | |
public Decimal getAsDecimal(Object key) { | |
Object objValue = getAsObject(key); | |
return objValue instanceof String | |
? Decimal.valueOf((String)objValue) | |
: Decimal.valueOf((Double)objValue); | |
} | |
public Boolean getAsBoolean(Object key) { | |
return (Boolean)getAsObject(key); | |
} | |
public Double getAsDouble(Object key) { | |
return (Double)getAsObject(key); | |
} | |
public Integer getAsInteger(Object key) { | |
return (Integer)getAsObject(key); | |
} | |
public String getAsString(Object key) { | |
return (String)getAsObject(key); | |
} | |
public Object getAsObject(Object keys) { | |
if (keys instanceof Object[]) { | |
Object level = this.objValue; | |
for (Object key : (Object[])keys) { | |
level = getAsObject(level, key); | |
} | |
return level; | |
} | |
return getAsObject(this.objValue, keys); | |
} | |
private static Object getAsObject(Object value, Object key) { | |
if (value instanceof Map<String,Object>) { | |
if (key instanceof String) { | |
Map<String,Object> mapValue = (Map<String,Object>)value; | |
String strKey = (String)key; | |
if (mapValue.containsKey(strKey)) { | |
return mapValue.get(strKey); | |
} | |
} | |
} | |
else if (value instanceof Object[]) { | |
if (key instanceof Integer) { | |
Object[] arrayValue = (Object[])value; | |
Integer intKey = (Integer)key; | |
Integer count = arrayValue.size(); | |
if (intKey < 0) intKey += count; | |
if (0 <= intKey && intKey <= count) { | |
return arrayValue.get(intKey); | |
} | |
} | |
} | |
else { | |
throw new TypeException('You can only use getter on an array or a map.'); | |
} | |
throw new TypeException('The specified key could not be found.'); | |
} | |
public Integer asInteger() { | |
return (Integer)this.objValue; | |
} | |
public String asString() { | |
return (String)this.objValue; | |
} | |
public Boolean asBoolean() { | |
return (Boolean)this.objValue; | |
} | |
public Double asDouble() { | |
return (Double)this.objValue; | |
} | |
public Object asObject() { | |
return this.objValue; | |
} | |
public Decimal asDecimal() { | |
return this.objValue instanceof String | |
? Decimal.valueOf((String)this.objValue) | |
: Decimal.valueOf((Double)this.objValue); | |
} | |
} |
This file contains hidden or 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
String strJSON = '{"people":[{"firstName": "John","lastName":"Smith","attributes":{"isHuman":true,"isWeak":false}}]}'; | |
JSONValue jv = new JSONValue(strJSON); | |
Assert.areEqual('John', jv.get('people').get(-1).get('firstName').asString()); | |
Assert.areEqual('Smith', jv.get(new Object[]{'people', 0, 'lastName'}).asString()); | |
Assert.areEqual(true, jv.get('people').get(0).get('attributes').getAsBoolean('isHuman')); | |
Assert.areEqual(false, jv.getAsBoolean(new Object[]{'people', -1, 'attributes', 'isWeak'})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment