+ * type of the annotation
*
- * type of the annotation
- *
- * @param m
- * method to check
- * @param annotationClass
- * annotation to look for
+ * @param m method to check
+ * @param annotationClass annotation to look for
* @return Depth of the annotation or -1 if the annotation is not on the method.
*/
private static int getAnnotationDepth(final Method m, final Class extends Annotation> annotationClass) {
@@ -1703,285 +704,6 @@ public class JSONObject {
}
}
- /**
- * Put a key/boolean pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A boolean which is the value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, boolean value) throws JSONException {
- return this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
- }
-
- public JSONObject put(String key, byte value) throws JSONException {
- return this.put(key, Byte.valueOf(value));
- }
-
- /**
- * Put a key/value pair in the JSONObject, where the value will be a
- * JSONArray which is produced from a Collection.
- *
- * @param key
- * A key string.
- * @param value
- * A Collection value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, Collection> value) throws JSONException {
- return this.put(key, new JSONArray(value));
- }
-
- /**
- * Put a key/double pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A double which is the value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, double value) throws JSONException {
- return this.put(key, Double.valueOf(value));
- }
-
- /**
- * Put a key/float pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A float which is the value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, float value) throws JSONException {
- return this.put(key, Float.valueOf(value));
- }
-
- /**
- * Put a key/int pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * An int which is the value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, int value) throws JSONException {
- return this.put(key, Integer.valueOf(value));
- }
-
- /**
- * Put a key/long pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A long which is the value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, long value) throws JSONException {
- return this.put(key, Long.valueOf(value));
- }
-
- /**
- * Put a key/value pair in the JSONObject, where the value will be a
- * JSONObject which is produced from a Map.
- *
- * @param key
- * A key string.
- * @param value
- * A Map value.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, Map, ?> value) throws JSONException {
- return this.put(key, new JSONObject(value));
- }
-
- /**
- * Put a key/value pair in the JSONObject. If the value is null
, then the
- * key will be removed from the JSONObject if it is present.
- *
- * @param key
- * A key string.
- * @param value
- * An object which is the value. It should be of one of these
- * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
- * String, or the JSONObject.NULL object.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number.
- * @throws NullPointerException
- * If the key is null
.
- */
- public JSONObject put(String key, Object value) throws JSONException {
- if (key == null) {
- throw new NullPointerException("Null key.");
- }
- if (value != null) {
- testValidity(value);
- this.map.put(key, value);
- } else {
- this.remove(key);
- }
- return this;
- }
-
- public JSONObject put(String key, byte[] bytes) throws JSONException {
- return this.put(key, (Object) bytes);
- }
-
- public JSONObject put(String key, UUID uuid) throws JSONException {
- return this.put(key, uuid.toString());
- }
-
- /**
- * Put a key/value pair in the JSONObject, but only if the key and the value
- * are both non-null, and only if there is not already a member with that
- * name.
- *
- * @param key
- * key to insert into
- * @param value
- * value to insert
- * @return this.
- * @throws JSONException
- * if the key is a duplicate
- */
- public JSONObject putOnce(String key, Object value) throws JSONException {
- if (key != null && value != null) {
- if (this.opt(key) != null) {
- throw new JSONException("Duplicate key \"" + key + "\"");
- }
- return this.put(key, value);
- }
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject, but only if the key and the value
- * are both non-null.
- *
- * @param key
- * A key string.
- * @param value
- * An object which is the value. It should be of one of these
- * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
- * String, or the JSONObject.NULL object.
- * @return this.
- * @throws JSONException
- * If the value is a non-finite number.
- */
- public JSONObject putOpt(String key, Object value) throws JSONException {
- if (key != null && value != null) {
- return this.put(key, value);
- }
- return this;
- }
-
- /**
- * Creates a JSONPointer using an initialization string and tries to
- * match it to an item within this JSONObject. For example, given a
- * JSONObject initialized with this document:
- *
entry : this.entrySet()) {
- String name = entry.getKey();
- Object valueThis = entry.getValue();
- Object valueOther = ((JSONObject)other).get(name);
- if(valueThis == valueOther) {
- continue;
- }
- if(valueThis == null) {
- return false;
- }
- if (valueThis instanceof JSONObject) {
- if (!((JSONObject)valueThis).similar(valueOther)) {
- return false;
- }
- } else if (valueThis instanceof JSONArray) {
- if (!((JSONArray)valueThis).similar(valueOther)) {
- return false;
- }
- } else if (!valueThis.equals(valueOther)) {
- return false;
- }
- }
- return true;
- } catch (Throwable exception) {
- return false;
- }
- }
-
/**
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
- *
+ *
* @param val value to test
* @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
*/
@@ -2130,16 +795,16 @@ public class JSONObject {
return val.indexOf('.') > -1 || val.indexOf('e') > -1
|| val.indexOf('E') > -1 || "-0".equals(val);
}
-
+
/**
- * Converts a string to a number using the narrowest possible type. Possible
+ * Converts a string to a number using the narrowest possible type. Possible
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
- *
+ *
* @param val value to convert
* @return Number representation of the value.
* @throws NumberFormatException thrown if the value is not a valid number. A public
- * caller should catch this and wrap it in a {@link JSONException} if applicable.
+ * caller should catch this and wrap it in a {@link JSONException} if applicable.
*/
protected static Number stringToNumber(final String val) throws NumberFormatException {
char initial = val.charAt(0);
@@ -2148,7 +813,7 @@ public class JSONObject {
if (isDecimalNotation(val)) {
// quick dirty way to see if we need a BigDecimal instead of a Double
// this only handles some cases of overflow or underflow
- if (val.length()>14) {
+ if (val.length() > 14) {
return new BigDecimal(val);
}
final Double d = Double.valueOf(val);
@@ -2164,7 +829,7 @@ public class JSONObject {
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
-
+
// string version
// The compare string length method reduces GC,
// but leads to smaller integers being placed in larger wrappers even though not
@@ -2177,33 +842,31 @@ public class JSONObject {
// return Long.valueOf(val);
//}
//return new BigInteger(val);
-
+
// BigInteger version: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
// long lived. Which is the better tradeoff? This is closer to what's
// in stringToValue.
BigInteger bi = new BigInteger(val);
- if(bi.bitLength()<=31){
+ if (bi.bitLength() <= 31) {
return Integer.valueOf(bi.intValue());
}
- if(bi.bitLength()<=63){
+ if (bi.bitLength() <= 63) {
return Long.valueOf(bi.longValue());
}
return bi;
}
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
/**
* Try to convert a string into a number, boolean, or null. If the string
* can't be converted, return the string.
*
- * @param string
- * A String. can not be null.
+ * @param string A String. can not be null.
* @return A simple JSON value.
- * @throws NullPointerException
- * Thrown if the string is null.
+ * @throws NullPointerException Thrown if the string is null.
*/
// Changes to this method must be copied to the corresponding method in
// the XML class to keep full support for Android
@@ -2257,10 +920,8 @@ public class JSONObject {
/**
* Throw an exception if the object is a NaN or infinite number.
*
- * @param o
- * The object to test.
- * @throws JSONException
- * If o is a non-finite number.
+ * @param o The object to test.
+ * @throws JSONException If o is a non-finite number.
*/
public static void testValidity(Object o) throws JSONException {
if (o != null) {
@@ -2278,83 +939,6 @@ public class JSONObject {
}
}
- /**
- * Produce a JSONArray containing the values of the members of this
- * JSONObject.
- *
- * @param names
- * A JSONArray containing a list of key strings. This determines
- * the sequence of the values in the result.
- * @return A JSONArray of values.
- * @throws JSONException
- * If any of the values are non-finite numbers.
- */
- public JSONArray toJSONArray(JSONArray names) throws JSONException {
- if (names == null || names.isEmpty()) {
- return null;
- }
- JSONArray ja = new JSONArray();
- for (int i = 0; i < names.length(); i += 1) {
- ja.put(this.opt(names.getString(i)));
- }
- return ja;
- }
-
- /**
- * Make a JSON text of this JSONObject. For compactness, no whitespace is
- * added. If this would not result in a syntactically correct JSON text,
- * then null will be returned instead.
- *
- * Warning: This method assumes that the data structure is acyclical.
- *
- *
- * @return a printable, displayable, portable, transmittable representation
- * of the object, beginning with {
(left
- * brace) and ending with }
(right
- * brace).
- */
- @Override
- public String toString() {
- try {
- return this.toString(0);
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * Make a pretty-printed JSON text of this JSONObject.
- *
- *
If indentFactor > 0
and the {@link JSONObject}
- * has only one key, then the object will be output on a single line:
- *
{@code {"key": 1}}
- *
- * If an object has 2 or more keys, then it will be output across
- * multiple lines: {
- * "key1": 1,
- * "key2": "value 2",
- * "key3": 3
- * }
- *
- * Warning: This method assumes that the data structure is acyclical.
- *
- *
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @return a printable, displayable, portable, transmittable representation
- * of the object, beginning with {
(left
- * brace) and ending with }
(right
- * brace).
- * @throws JSONException
- * If the object contains an invalid number.
- */
- public String toString(int indentFactor) throws JSONException {
- StringWriter w = new StringWriter();
- synchronized (w.getBuffer()) {
- return this.write(w, indentFactor, 0).toString();
- }
- }
-
/**
* Make a JSON text of an Object value. If the object has an
* value.toJSONString() method, then that method will be used to produce the
@@ -2370,20 +954,18 @@ public class JSONObject {
*
* Warning: This method assumes that the data structure is acyclical.
*
- * @param value
- * The value to be serialized.
+ * @param value The value to be serialized.
* @return a printable, displayable, transmittable representation of the
- * object, beginning with {
(left
- * brace) and ending with }
(right
- * brace).
- * @throws JSONException
- * If the value is or contains an invalid number.
+ * object, beginning with {
(left
+ * brace) and ending with }
(right
+ * brace).
+ * @throws JSONException If the value is or contains an invalid number.
*/
public static String valueToString(Object value) throws JSONException {
- // moves the implementation to JSONWriter as:
- // 1. It makes more sense to be part of the writer class
- // 2. For Android support this method is not available. By implementing it in the Writer
- // Android users can use the writer with the built in Android JSONObject implementation.
+ // moves the implementation to JSONWriter as:
+ // 1. It makes more sense to be part of the writer class
+ // 2. For Android support this method is not available. By implementing it in the Writer
+ // Android users can use the writer with the built in Android JSONObject implementation.
return JSONWriter.valueToString(value);
}
@@ -2395,8 +977,7 @@ public class JSONObject {
* one of the java packages, turn it into a string. And if it doesn't, try
* to wrap it in a JSONObject. If the wrapping fails, then null is returned.
*
- * @param object
- * The object to wrap
+ * @param object The object to wrap
* @return The wrapped value
*/
public static Object wrap(Object object) {
@@ -2440,22 +1021,8 @@ public class JSONObject {
}
}
- /**
- * Write the contents of the JSONObject as JSON text to a writer. For
- * compactness, no whitespace is added.
- *
- * Warning: This method assumes that the data structure is acyclical.
- *
- *
- * @return The writer.
- * @throws JSONException
- */
- public Writer write(Writer writer) throws JSONException {
- return this.write(writer, 0, 0);
- }
-
static final Writer writeValue(Writer writer, Object value,
- int indentFactor, int indent) throws JSONException, IOException {
+ int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) {
writer.write("null");
} else if (value instanceof JSONString) {
@@ -2469,7 +1036,7 @@ public class JSONObject {
} else if (value instanceof Number) {
// not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
final String numberAsString = numberToString((Number) value);
- if(NUMBER_PATTERN.matcher(numberAsString).matches()) {
+ if (NUMBER_PATTERN.matcher(numberAsString).matches()) {
writer.write(numberAsString);
} else {
// The Number value is not a valid JSON number.
@@ -2479,7 +1046,7 @@ public class JSONObject {
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof Enum>) {
- writer.write(quote(((Enum>)value).name()));
+ writer.write(quote(((Enum>) value).name()));
} else if (value instanceof JSONObject) {
((JSONObject) value).write(writer, indentFactor, indent);
} else if (value instanceof JSONArray) {
@@ -2505,12 +1072,1227 @@ public class JSONObject {
}
/**
- * Write the contents of the JSONObject as JSON text to a writer.
- *
+ * Create a new JSONException in a common format for incorrect conversions.
+ *
+ * @param key name of the key
+ * @param valueType the type of value being coerced to
+ * @param cause optional cause of the coercion failure
+ * @return JSONException that can be thrown.
+ */
+ private static JSONException wrongValueFormatException(
+ String key,
+ String valueType,
+ Throwable cause) {
+ return new JSONException(
+ "JSONObject[" + quote(key) + "] is not a " + valueType + "."
+ , cause);
+ }
+
+ /**
+ * Create a new JSONException in a common format for incorrect conversions.
+ *
+ * @param key name of the key
+ * @param valueType the type of value being coerced to
+ * @param cause optional cause of the coercion failure
+ * @return JSONException that can be thrown.
+ */
+ private static JSONException wrongValueFormatException(
+ String key,
+ String valueType,
+ Object value,
+ Throwable cause) {
+ return new JSONException(
+ "JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")."
+ , cause);
+ }
+
+ /**
+ * Accumulate values under a key. It is similar to the put method except
+ * that if there is already an object stored under the key then a JSONArray
+ * is stored under the key to hold all of the accumulated values. If there
+ * is already a JSONArray, then the new value is appended to it. In
+ * contrast, the put method replaces the previous value.
+ *
+ * If only one value is accumulated that is not a JSONArray, then the result
+ * will be the same as using put. But if multiple values are accumulated,
+ * then the result will be like append.
+ *
+ * @param key A key string.
+ * @param value An object to be accumulated under the key.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject accumulate(String key, Object value) throws JSONException {
+ testValidity(value);
+ Object object = this.opt(key);
+ if (object == null) {
+ this.put(key,
+ value instanceof JSONArray ? new JSONArray().put(value)
+ : value);
+ } else if (object instanceof JSONArray) {
+ ((JSONArray) object).put(value);
+ } else {
+ this.put(key, new JSONArray().put(object).put(value));
+ }
+ return this;
+ }
+
+ /**
+ * Append values to the array under a key. If the key does not exist in the
+ * JSONObject, then the key is put in the JSONObject with its value being a
+ * JSONArray containing the value parameter. If the key was already
+ * associated with a JSONArray, then the value parameter is appended to it.
+ *
+ * @param key A key string.
+ * @param value An object to be accumulated under the key.
+ * @return this.
+ * @throws JSONException If the value is non-finite number or if the current value associated with
+ * the key is not a JSONArray.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject append(String key, Object value) throws JSONException {
+ testValidity(value);
+ Object object = this.opt(key);
+ if (object == null) {
+ this.put(key, new JSONArray().put(value));
+ } else if (object instanceof JSONArray) {
+ this.put(key, ((JSONArray) object).put(value));
+ } else {
+ throw wrongValueFormatException(key, "JSONArray", null, null);
+ }
+ return this;
+ }
+
+ /**
+ * Get the value object associated with a key.
+ *
+ * @param key A key string.
+ * @return The object associated with the key.
+ * @throws JSONException if the key is not found.
+ */
+ public Object get(String key) throws JSONException {
+ if (key == null) {
+ throw new JSONException("Null key.");
+ }
+ Object object = this.opt(key);
+ if (object == null) {
+ throw new JSONException("JSONObject[" + quote(key) + "] not found.");
+ }
+ return object;
+ }
+
+ /**
+ * Get the enum value associated with a key.
+ *
+ * @param Enum Type
+ * @param clazz The type of enum to retrieve.
+ * @param key A key string.
+ * @return The enum value associated with the key
+ * @throws JSONException if the key is not found or if the value cannot be converted
+ * to an enum.
+ */
+ public > E getEnum(Class clazz, String key) throws JSONException {
+ E val = optEnum(clazz, key);
+ if (val == null) {
+ // JSONException should really take a throwable argument.
+ // If it did, I would re-implement this with the Enum.valueOf
+ // method and place any thrown exception in the JSONException
+ throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), null);
+ }
+ return val;
+ }
+
+ /**
+ * Get the boolean value associated with a key.
+ *
+ * @param key A key string.
+ * @return The truth.
+ * @throws JSONException if the value is not a Boolean or the String "true" or
+ * "false".
+ */
+ public boolean getBoolean(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object.equals(Boolean.FALSE)
+ || (object instanceof String && ((String) object)
+ .equalsIgnoreCase("false"))) {
+ return false;
+ } else if (object.equals(Boolean.TRUE)
+ || (object instanceof String && ((String) object)
+ .equalsIgnoreCase("true"))) {
+ return true;
+ }
+ throw wrongValueFormatException(key, "Boolean", null);
+ }
+
+ /**
+ * Get the BigInteger value associated with a key.
+ *
+ * @param key A key string.
+ * @return The numeric value.
+ * @throws JSONException if the key is not found or if the value cannot
+ * be converted to BigInteger.
+ */
+ public BigInteger getBigInteger(String key) throws JSONException {
+ Object object = this.get(key);
+ BigInteger ret = objectToBigInteger(object, null);
+ if (ret != null) {
+ return ret;
+ }
+ throw wrongValueFormatException(key, "BigInteger", object, null);
+ }
+
+ /**
+ * Get the BigDecimal value associated with a key. If the value is float or
+ * double, the the {@link BigDecimal#BigDecimal(double)} constructor will
+ * be used. See notes on the constructor for conversion issues that may
+ * arise.
+ *
+ * @param key A key string.
+ * @return The numeric value.
+ * @throws JSONException if the key is not found or if the value
+ * cannot be converted to BigDecimal.
+ */
+ public BigDecimal getBigDecimal(String key) throws JSONException {
+ Object object = this.get(key);
+ BigDecimal ret = objectToBigDecimal(object, null);
+ if (ret != null) {
+ return ret;
+ }
+ throw wrongValueFormatException(key, "BigDecimal", object, null);
+ }
+
+ /**
+ * Get the double value associated with a key.
+ *
+ * @param key A key string.
+ * @return The numeric value.
+ * @throws JSONException if the key is not found or if the value is not a Number
+ * object and cannot be converted to a number.
+ */
+ public double getDouble(String key) throws JSONException {
+ final Object object = this.get(key);
+ if (object instanceof Number) {
+ return ((Number) object).doubleValue();
+ }
+ try {
+ return Double.parseDouble(object.toString());
+ } catch (Exception e) {
+ throw wrongValueFormatException(key, "double", e);
+ }
+ }
+
+ /**
+ * Get the float value associated with a key.
+ *
+ * @param key A key string.
+ * @return The numeric value.
+ * @throws JSONException if the key is not found or if the value is not a Number
+ * object and cannot be converted to a number.
+ */
+ public float getFloat(String key) throws JSONException {
+ final Object object = this.get(key);
+ if (object instanceof Number) {
+ return ((Number) object).floatValue();
+ }
+ try {
+ return Float.parseFloat(object.toString());
+ } catch (Exception e) {
+ throw wrongValueFormatException(key, "float", e);
+ }
+ }
+
+ /**
+ * Get the Number value associated with a key.
+ *
+ * @param key A key string.
+ * @return The numeric value.
+ * @throws JSONException if the key is not found or if the value is not a Number
+ * object and cannot be converted to a number.
+ */
+ public Number getNumber(String key) throws JSONException {
+ Object object = this.get(key);
+ try {
+ if (object instanceof Number) {
+ return (Number) object;
+ }
+ return stringToNumber(object.toString());
+ } catch (Exception e) {
+ throw wrongValueFormatException(key, "number", e);
+ }
+ }
+
+ /**
+ * Get the int value associated with a key.
+ *
+ * @param key A key string.
+ * @return The integer value.
+ * @throws JSONException if the key is not found or if the value cannot be converted
+ * to an integer.
+ */
+ public int getInt(String key) throws JSONException {
+ final Object object = this.get(key);
+ if (object instanceof Number) {
+ return ((Number) object).intValue();
+ }
+ try {
+ return Integer.parseInt(object.toString());
+ } catch (Exception e) {
+ throw wrongValueFormatException(key, "int", e);
+ }
+ }
+
+ /**
+ * Get the JSONArray value associated with a key.
+ *
+ * @param key A key string.
+ * @return A JSONArray which is the value.
+ * @throws JSONException if the key is not found or if the value is not a JSONArray.
+ */
+ public JSONArray getJSONArray(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof JSONArray) {
+ return (JSONArray) object;
+ }
+ throw wrongValueFormatException(key, "JSONArray", null);
+ }
+
+ /**
+ * Get the JSONObject value associated with a key.
+ *
+ * @param key A key string.
+ * @return A JSONObject which is the value.
+ * @throws JSONException if the key is not found or if the value is not a JSONObject.
+ */
+ public JSONObject getJSONObject(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
+ }
+ throw wrongValueFormatException(key, "JSONObject", null);
+ }
+
+ /**
+ * Get the long value associated with a key.
+ *
+ * @param key A key string.
+ * @return The long value.
+ * @throws JSONException if the key is not found or if the value cannot be converted
+ * to a long.
+ */
+ public long getLong(String key) throws JSONException {
+ final Object object = this.get(key);
+ if (object instanceof Number) {
+ return ((Number) object).longValue();
+ }
+ try {
+ return Long.parseLong(object.toString());
+ } catch (Exception e) {
+ throw wrongValueFormatException(key, "long", e);
+ }
+ }
+
+ public UUID getUUID(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof UUID) {
+ return (UUID) object;
+ } else if (object instanceof String) {
+ return UUID.fromString(String.valueOf(object));
+ }
+ throw wrongValueFormatException(key, "UUID", null);
+ }
+
+ /**
+ * Get the string associated with a key.
+ *
+ * @param key A key string.
+ * @return A string which is the value.
+ * @throws JSONException if there is no string value for the key.
+ */
+ public String getString(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof String) {
+ return (String) object;
+ }
+ throw wrongValueFormatException(key, "string", null);
+ }
+
+ public byte getByte(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof Byte) {
+ return (byte) object;
+ }
+ throw wrongValueFormatException(key, "byte", null);
+ }
+
+ public byte[] getByteArray(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof JSONArray) {
+ JSONArray jsonArray = (JSONArray) object;
+ byte[] array = new byte[jsonArray.length()];
+ for (int k = 0; k < jsonArray.length(); k++) {
+ array[k] = Byte.valueOf(String.valueOf(jsonArray.get(k)));
+ }
+ return array;
+ }
+ if (object instanceof byte[]) {
+ return (byte[]) object;
+ }
+ throw wrongValueFormatException(key, "byteArray", null);
+ }
+
+ /**
+ * Determine if the JSONObject contains a specific key.
+ *
+ * @param key A key string.
+ * @return true if the key exists in the JSONObject.
+ */
+ public boolean has(String key) {
+ return this.map.containsKey(key);
+ }
+
+ /**
+ * Increment a property of a JSONObject. If there is no such property,
+ * create one with a value of 1 (Integer). If there is such a property, and if it is
+ * an Integer, Long, Double, Float, BigInteger, or BigDecimal then add one to it.
+ * No overflow bounds checking is performed, so callers should initialize the key
+ * prior to this call with an appropriate type that can handle the maximum expected
+ * value.
+ *
+ * @param key A key string.
+ * @return this.
+ * @throws JSONException If there is already a property with this name that is not an
+ * Integer, Long, Double, or Float.
+ */
+ public JSONObject increment(String key) throws JSONException {
+ Object value = this.opt(key);
+ if (value == null) {
+ this.put(key, 1);
+ } else if (value instanceof Integer) {
+ this.put(key, ((Integer) value).intValue() + 1);
+ } else if (value instanceof Long) {
+ this.put(key, ((Long) value).longValue() + 1L);
+ } else if (value instanceof BigInteger) {
+ this.put(key, ((BigInteger) value).add(BigInteger.ONE));
+ } else if (value instanceof Float) {
+ this.put(key, ((Float) value).floatValue() + 1.0f);
+ } else if (value instanceof Double) {
+ this.put(key, ((Double) value).doubleValue() + 1.0d);
+ } else if (value instanceof BigDecimal) {
+ this.put(key, ((BigDecimal) value).add(BigDecimal.ONE));
+ } else {
+ throw new JSONException("Unable to increment [" + quote(key) + "].");
+ }
+ return this;
+ }
+
+ /**
+ * Determine if the value associated with the key is null
or if there is no
+ * value.
+ *
+ * @param key A key string.
+ * @return true if there is no value associated with the key or if the value
+ * is the JSONObject.NULL object.
+ */
+ public boolean isNull(String key) {
+ return JSONObject.NULL.equals(this.opt(key));
+ }
+
+ /**
+ * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also
+ * modify the JSONObject. Use with caution.
+ *
+ * @return An iterator of the keys.
+ * @see Set#iterator()
+ */
+ public Iterator keys() {
+ return this.keySet().iterator();
+ }
+
+ /**
+ * Get a set of keys of the JSONObject. Modifying this key Set will also modify the
+ * JSONObject. Use with caution.
+ *
+ * @return A keySet.
+ * @see Map#keySet()
+ */
+ public Set keySet() {
+ return this.map.keySet();
+ }
+
+ /**
+ * Get a set of entries of the JSONObject. These are raw values and may not
+ * match what is returned by the JSONObject get* and opt* functions. Modifying
+ * the returned EntrySet or the Entry objects contained therein will modify the
+ * backing JSONObject. This does not return a clone or a read-only view.
+ *
+ * Use with caution.
+ *
+ * @return An Entry Set
+ * @see Map#entrySet()
+ */
+ protected Set> entrySet() {
+ return this.map.entrySet();
+ }
+
+ /**
+ * Get the number of keys stored in the JSONObject.
+ *
+ * @return The number of keys in the JSONObject.
+ */
+ public int length() {
+ return this.map.size();
+ }
+
+ /**
+ * Check if JSONObject is empty.
+ *
+ * @return true if JSONObject is empty, otherwise false.
+ */
+ public boolean isEmpty() {
+ return this.map.isEmpty();
+ }
+
+ /**
+ * Produce a JSONArray containing the names of the elements of this
+ * JSONObject.
+ *
+ * @return A JSONArray containing the key strings, or null if the JSONObject
+ * is empty.
+ */
+ public JSONArray names() {
+ if (this.map.isEmpty()) {
+ return null;
+ }
+ return new JSONArray(this.map.keySet());
+ }
+
+ /**
+ * Get an optional value associated with a key.
+ *
+ * @param key A key string.
+ * @return An object which is the value, or null if there is no value.
+ */
+ public Object opt(String key) {
+ return key == null ? null : this.map.get(key);
+ }
+
+ /**
+ * Get the enum value associated with a key.
+ *
+ * @param Enum Type
+ * @param clazz The type of enum to retrieve.
+ * @param key A key string.
+ * @return The enum value associated with the key or null if not found
+ */
+ public > E optEnum(Class clazz, String key) {
+ return this.optEnum(clazz, key, null);
+ }
+
+ /**
+ * Get the enum value associated with a key.
+ *
+ * @param Enum Type
+ * @param clazz The type of enum to retrieve.
+ * @param key A key string.
+ * @param defaultValue The default in case the value is not found
+ * @return The enum value associated with the key or defaultValue
+ * if the value is not found or cannot be assigned to clazz
+ */
+ public > E optEnum(Class clazz, String key, E defaultValue) {
+ try {
+ Object val = this.opt(key);
+ if (NULL.equals(val)) {
+ return defaultValue;
+ }
+ if (clazz.isAssignableFrom(val.getClass())) {
+ // we just checked it!
+ @SuppressWarnings("unchecked")
+ E myE = (E) val;
+ return myE;
+ }
+ return Enum.valueOf(clazz, val.toString());
+ } catch (IllegalArgumentException e) {
+ return defaultValue;
+ } catch (NullPointerException e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Get an optional boolean associated with a key. It returns false if there
+ * is no such key, or if the value is not Boolean.TRUE or the String "true".
+ *
+ * @param key A key string.
+ * @return The truth.
+ */
+ public boolean optBoolean(String key) {
+ return this.optBoolean(key, false);
+ }
+
+ /**
+ * Get an optional boolean associated with a key. It returns the
+ * defaultValue if there is no such key, or if it is not a Boolean or the
+ * String "true" or "false" (case insensitive).
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return The truth.
+ */
+ public boolean optBoolean(String key, boolean defaultValue) {
+ Object val = this.opt(key);
+ if (NULL.equals(val)) {
+ return defaultValue;
+ }
+ if (val instanceof Boolean) {
+ return ((Boolean) val).booleanValue();
+ }
+ try {
+ // we'll use the get anyway because it does string conversion.
+ return this.getBoolean(key);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Get an optional BigDecimal associated with a key, or the defaultValue if
+ * there is no such key or if its value is not a number. If the value is a
+ * string, an attempt will be made to evaluate it as a number. If the value
+ * is float or double, then the {@link BigDecimal#BigDecimal(double)}
+ * constructor will be used. See notes on the constructor for conversion
+ * issues that may arise.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
+ Object val = this.opt(key);
+ return objectToBigDecimal(val, defaultValue);
+ }
+
+ /**
+ * Get an optional BigInteger associated with a key, or the defaultValue if
+ * there is no such key or if its value is not a number. If the value is a
+ * string, an attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public BigInteger optBigInteger(String key, BigInteger defaultValue) {
+ Object val = this.opt(key);
+ return objectToBigInteger(val, defaultValue);
+ }
+
+ /**
+ * Get an optional double associated with a key, or NaN if there is no such
+ * key or if its value is not a number. If the value is a string, an attempt
+ * will be made to evaluate it as a number.
+ *
+ * @param key A string which is the key.
+ * @return An object which is the value.
+ */
+ public double optDouble(String key) {
+ return this.optDouble(key, Double.NaN);
+ }
+
+ /**
+ * Get an optional double associated with a key, or the defaultValue if
+ * there is no such key or if its value is not a number. If the value is a
+ * string, an attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public double optDouble(String key, double defaultValue) {
+ Number val = this.optNumber(key);
+ if (val == null) {
+ return defaultValue;
+ }
+ final double doubleValue = val.doubleValue();
+ // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
+ // return defaultValue;
+ // }
+ return doubleValue;
+ }
+
+ /**
+ * Get the optional double value associated with an index. NaN is returned
+ * if there is no value for the index, or if the value is not a number and
+ * cannot be converted to a number.
+ *
+ * @param key A key string.
+ * @return The value.
+ */
+ public float optFloat(String key) {
+ return this.optFloat(key, Float.NaN);
+ }
+
+ /**
+ * Get the optional double value associated with an index. The defaultValue
+ * is returned if there is no value for the index, or if the value is not a
+ * number and cannot be converted to a number.
+ *
+ * @param key A key string.
+ * @param defaultValue The default value.
+ * @return The value.
+ */
+ public float optFloat(String key, float defaultValue) {
+ Number val = this.optNumber(key);
+ if (val == null) {
+ return defaultValue;
+ }
+ final float floatValue = val.floatValue();
+ // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) {
+ // return defaultValue;
+ // }
+ return floatValue;
+ }
+
+ /**
+ * Get an optional int value associated with a key, or zero if there is no
+ * such key or if the value is not a number. If the value is a string, an
+ * attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @return An object which is the value.
+ */
+ public int optInt(String key) {
+ return this.optInt(key, 0);
+ }
+
+ /**
+ * Get an optional int value associated with a key, or the default if there
+ * is no such key or if the value is not a number. If the value is a string,
+ * an attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public int optInt(String key, int defaultValue) {
+ final Number val = this.optNumber(key, null);
+ if (val == null) {
+ return defaultValue;
+ }
+ return val.intValue();
+ }
+
+ /**
+ * Get an optional JSONArray associated with a key. It returns null if there
+ * is no such key, or if its value is not a JSONArray.
+ *
+ * @param key A key string.
+ * @return A JSONArray which is the value.
+ */
+ public JSONArray optJSONArray(String key) {
+ Object o = this.opt(key);
+ return o instanceof JSONArray ? (JSONArray) o : null;
+ }
+
+ /**
+ * Get an optional JSONObject associated with a key. It returns null if
+ * there is no such key, or if its value is not a JSONObject.
+ *
+ * @param key A key string.
+ * @return A JSONObject which is the value.
+ */
+ public JSONObject optJSONObject(String key) {
+ Object object = this.opt(key);
+ return object instanceof JSONObject ? (JSONObject) object : null;
+ }
+
+ /**
+ * Get an optional long value associated with a key, or zero if there is no
+ * such key or if the value is not a number. If the value is a string, an
+ * attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @return An object which is the value.
+ */
+ public long optLong(String key) {
+ return this.optLong(key, 0);
+ }
+
+ /**
+ * Get an optional long value associated with a key, or the default if there
+ * is no such key or if the value is not a number. If the value is a string,
+ * an attempt will be made to evaluate it as a number.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public long optLong(String key, long defaultValue) {
+ final Number val = this.optNumber(key, null);
+ if (val == null) {
+ return defaultValue;
+ }
+
+ return val.longValue();
+ }
+
+ /**
+ * Get an optional {@link Number} value associated with a key, or null
+ * if there is no such key or if the value is not a number. If the value is a string,
+ * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
+ * would be used in cases where type coercion of the number value is unwanted.
+ *
+ * @param key A key string.
+ * @return An object which is the value.
+ */
+ public Number optNumber(String key) {
+ return this.optNumber(key, null);
+ }
+
+ /**
+ * Get an optional {@link Number} value associated with a key, or the default if there
+ * is no such key or if the value is not a number. If the value is a string,
+ * an attempt will be made to evaluate it as a number. This method
+ * would be used in cases where type coercion of the number value is unwanted.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
+ */
+ public Number optNumber(String key, Number defaultValue) {
+ Object val = this.opt(key);
+ if (NULL.equals(val)) {
+ return defaultValue;
+ }
+ if (val instanceof Number) {
+ return (Number) val;
+ }
+
+ try {
+ return stringToNumber(val.toString());
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Get an optional string associated with a key. It returns an empty string
+ * if there is no such key. If the value is not a string and is not null,
+ * then it is converted to a string.
+ *
+ * @param key A key string.
+ * @return A string which is the value.
+ */
+ public String optString(String key) {
+ return this.optString(key, "");
+ }
+
+ /**
+ * Get an optional string associated with a key. It returns the defaultValue
+ * if there is no such key.
+ *
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return A string which is the value.
+ */
+ public String optString(String key, String defaultValue) {
+ Object object = this.opt(key);
+ return NULL.equals(object) ? defaultValue : object.toString();
+ }
+
+ /**
+ * Populates the internal map of the JSONObject with the bean properties. The
+ * bean can not be recursive.
+ *
+ * @param bean the bean
+ * @see JSONObject#JSONObject(Object)
+ */
+ private void populateMap(Object bean) {
+ Class> klass = bean.getClass();
+
+ // If klass is a System class then set includeSuperClass to false.
+
+ boolean includeSuperClass = klass.getClassLoader() != null;
+
+ Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods();
+ for (final Method method : methods) {
+ final int modifiers = method.getModifiers();
+ if (Modifier.isPublic(modifiers)
+ && !Modifier.isStatic(modifiers)
+ && method.getParameterTypes().length == 0
+ && !method.isBridge()
+ && method.getReturnType() != Void.TYPE
+ && isValidMethodName(method.getName())) {
+ final String key = getKeyNameFromMethod(method);
+ if (key != null && !key.isEmpty()) {
+ try {
+ final Object result = method.invoke(bean);
+ if (result != null) {
+ this.map.put(key, wrap(result));
+ // we don't use the result anywhere outside of wrap
+ // if it's a resource we should be sure to close it
+ // after calling toString
+ if (result instanceof Closeable) {
+ try {
+ ((Closeable) result).close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ } catch (IllegalAccessException ignore) {
+ } catch (IllegalArgumentException ignore) {
+ } catch (InvocationTargetException ignore) {
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Put a key/boolean pair in the JSONObject.
+ *
+ * @param key A key string.
+ * @param value A boolean which is the value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, boolean value) throws JSONException {
+ return this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ public JSONObject put(String key, byte value) throws JSONException {
+ return this.put(key, Byte.valueOf(value));
+ }
+
+ /**
+ * Put a key/value pair in the JSONObject, where the value will be a
+ * JSONArray which is produced from a Collection.
+ *
+ * @param key A key string.
+ * @param value A Collection value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, Collection> value) throws JSONException {
+ return this.put(key, new JSONArray(value));
+ }
+
+ /**
+ * Put a key/double pair in the JSONObject.
+ *
+ * @param key A key string.
+ * @param value A double which is the value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, double value) throws JSONException {
+ return this.put(key, Double.valueOf(value));
+ }
+
+ /**
+ * Put a key/float pair in the JSONObject.
+ *
+ * @param key A key string.
+ * @param value A float which is the value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, float value) throws JSONException {
+ return this.put(key, Float.valueOf(value));
+ }
+
+ /**
+ * Put a key/int pair in the JSONObject.
+ *
+ * @param key A key string.
+ * @param value An int which is the value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, int value) throws JSONException {
+ return this.put(key, Integer.valueOf(value));
+ }
+
+ /**
+ * Put a key/long pair in the JSONObject.
+ *
+ * @param key A key string.
+ * @param value A long which is the value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, long value) throws JSONException {
+ return this.put(key, Long.valueOf(value));
+ }
+
+ /**
+ * Put a key/value pair in the JSONObject, where the value will be a
+ * JSONObject which is produced from a Map.
+ *
+ * @param key A key string.
+ * @param value A Map value.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, Map, ?> value) throws JSONException {
+ return this.put(key, new JSONObject(value));
+ }
+
+ /**
+ * Put a key/value pair in the JSONObject. If the value is null
, then the
+ * key will be removed from the JSONObject if it is present.
+ *
+ * @param key A key string.
+ * @param value An object which is the value. It should be of one of these
+ * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
+ * String, or the JSONObject.NULL object.
+ * @return this.
+ * @throws JSONException If the value is non-finite number.
+ * @throws NullPointerException If the key is null
.
+ */
+ public JSONObject put(String key, Object value) throws JSONException {
+ if (key == null) {
+ throw new NullPointerException("Null key.");
+ }
+ if (value != null) {
+ testValidity(value);
+ this.map.put(key, value);
+ } else {
+ this.remove(key);
+ }
+ return this;
+ }
+
+ public JSONObject put(String key, byte[] bytes) throws JSONException {
+ return this.put(key, (Object) bytes);
+ }
+
+ public JSONObject put(String key, UUID uuid) throws JSONException {
+ return this.put(key, uuid.toString());
+ }
+
+ /**
+ * Put a key/value pair in the JSONObject, but only if the key and the value
+ * are both non-null, and only if there is not already a member with that
+ * name.
+ *
+ * @param key key to insert into
+ * @param value value to insert
+ * @return this.
+ * @throws JSONException if the key is a duplicate
+ */
+ public JSONObject putOnce(String key, Object value) throws JSONException {
+ if (key != null && value != null) {
+ if (this.opt(key) != null) {
+ throw new JSONException("Duplicate key \"" + key + "\"");
+ }
+ return this.put(key, value);
+ }
+ return this;
+ }
+
+ /**
+ * Put a key/value pair in the JSONObject, but only if the key and the value
+ * are both non-null.
+ *
+ * @param key A key string.
+ * @param value An object which is the value. It should be of one of these
+ * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
+ * String, or the JSONObject.NULL object.
+ * @return this.
+ * @throws JSONException If the value is a non-finite number.
+ */
+ public JSONObject putOpt(String key, Object value) throws JSONException {
+ if (key != null && value != null) {
+ return this.put(key, value);
+ }
+ return this;
+ }
+
+ /**
+ * Creates a JSONPointer using an initialization string and tries to
+ * match it to an item within this JSONObject. For example, given a
+ * JSONObject initialized with this document:
+ *
+ * {
+ * "a":{"b":"c"}
+ * }
+ *
+ * and this JSONPointer string:
+ *
+ * "/a/b"
+ *
+ * Then this method will return the String "c".
+ * A JSONPointerException may be thrown from code called by this method.
+ *
+ * @param jsonPointer string that can be used to create a JSONPointer
+ * @return the item matched by the JSONPointer, otherwise null
+ */
+ public Object query(String jsonPointer) {
+ return query(new JSONPointer(jsonPointer));
+ }
+
+ /**
+ * Uses a user initialized JSONPointer and tries to
+ * match it to an item within this JSONObject. For example, given a
+ * JSONObject initialized with this document:
+ *
+ * {
+ * "a":{"b":"c"}
+ * }
+ *
+ * and this JSONPointer:
+ *
+ * "/a/b"
+ *
+ * Then this method will return the String "c".
+ * A JSONPointerException may be thrown from code called by this method.
+ *
+ * @param jsonPointer string that can be used to create a JSONPointer
+ * @return the item matched by the JSONPointer, otherwise null
+ */
+ public Object query(JSONPointer jsonPointer) {
+ return jsonPointer.queryFrom(this);
+ }
+
+ /**
+ * Queries and returns a value from this object using {@code jsonPointer}, or
+ * returns null if the query fails due to a missing key.
+ *
+ * @param jsonPointer the string representation of the JSON pointer
+ * @return the queried value or {@code null}
+ * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
+ */
+ public Object optQuery(String jsonPointer) {
+ return optQuery(new JSONPointer(jsonPointer));
+ }
+
+ /**
+ * Queries and returns a value from this object using {@code jsonPointer}, or
+ * returns null if the query fails due to a missing key.
+ *
+ * @param jsonPointer The JSON pointer
+ * @return the queried value or {@code null}
+ * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
+ */
+ public Object optQuery(JSONPointer jsonPointer) {
+ try {
+ return jsonPointer.queryFrom(this);
+ } catch (JSONPointerException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Remove a name and its value, if present.
+ *
+ * @param key The name to be removed.
+ * @return The value that was associated with the name, or null if there was
+ * no value.
+ */
+ public Object remove(String key) {
+ return this.map.remove(key);
+ }
+
+ /**
+ * Determine if two JSONObjects are similar.
+ * They must contain the same set of names which must be associated with
+ * similar values.
+ *
+ * @param other The other JSONObject
+ * @return true if they are equal
+ */
+ public boolean similar(Object other) {
+ try {
+ if (!(other instanceof JSONObject)) {
+ return false;
+ }
+ if (!this.keySet().equals(((JSONObject) other).keySet())) {
+ return false;
+ }
+ for (final Entry entry : this.entrySet()) {
+ String name = entry.getKey();
+ Object valueThis = entry.getValue();
+ Object valueOther = ((JSONObject) other).get(name);
+ if (valueThis == valueOther) {
+ continue;
+ }
+ if (valueThis == null) {
+ return false;
+ }
+ if (valueThis instanceof JSONObject) {
+ if (!((JSONObject) valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (valueThis instanceof JSONArray) {
+ if (!((JSONArray) valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (!valueThis.equals(valueOther)) {
+ return false;
+ }
+ }
+ return true;
+ } catch (Throwable exception) {
+ return false;
+ }
+ }
+
+ /**
+ * Produce a JSONArray containing the values of the members of this
+ * JSONObject.
+ *
+ * @param names A JSONArray containing a list of key strings. This determines
+ * the sequence of the values in the result.
+ * @return A JSONArray of values.
+ * @throws JSONException If any of the values are non-finite numbers.
+ */
+ public JSONArray toJSONArray(JSONArray names) throws JSONException {
+ if (names == null || names.isEmpty()) {
+ return null;
+ }
+ JSONArray ja = new JSONArray();
+ for (int i = 0; i < names.length(); i += 1) {
+ ja.put(this.opt(names.getString(i)));
+ }
+ return ja;
+ }
+
+ /**
+ * Make a JSON text of this JSONObject. For compactness, no whitespace is
+ * added. If this would not result in a syntactically correct JSON text,
+ * then null will be returned instead.
+ *
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ *
+ * @return a printable, displayable, portable, transmittable representation
+ * of the object, beginning with {
(left
+ * brace) and ending with }
(right
+ * brace).
+ */
+ @Override
+ public String toString() {
+ try {
+ return this.toString(0);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Make a pretty-printed JSON text of this JSONObject.
+ *
*
If indentFactor > 0
and the {@link JSONObject}
* has only one key, then the object will be output on a single line:
*
{@code {"key": 1}}
- *
+ *
* If an object has 2 or more keys, then it will be output across
* multiple lines: {
* "key1": 1,
@@ -2521,12 +2303,54 @@ public class JSONObject {
* Warning: This method assumes that the data structure is acyclical.
*
*
- * @param writer
- * Writes the serialized JSON
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @param indent
- * The indentation of the top level.
+ * @param indentFactor The number of spaces to add to each level of indentation.
+ * @return a printable, displayable, portable, transmittable representation
+ * of the object, beginning with {
(left
+ * brace) and ending with }
(right
+ * brace).
+ * @throws JSONException If the object contains an invalid number.
+ */
+ public String toString(int indentFactor) throws JSONException {
+ StringWriter w = new StringWriter();
+ synchronized (w.getBuffer()) {
+ return this.write(w, indentFactor, 0).toString();
+ }
+ }
+
+ /**
+ * Write the contents of the JSONObject as JSON text to a writer. For
+ * compactness, no whitespace is added.
+ *
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ *
+ * @return The writer.
+ * @throws JSONException
+ */
+ public Writer write(Writer writer) throws JSONException {
+ return this.write(writer, 0, 0);
+ }
+
+ /**
+ * Write the contents of the JSONObject as JSON text to a writer.
+ *
+ *
If indentFactor > 0
and the {@link JSONObject}
+ * has only one key, then the object will be output on a single line:
+ *
{@code {"key": 1}}
+ *
+ * If an object has 2 or more keys, then it will be output across
+ * multiple lines: {
+ * "key1": 1,
+ * "key2": "value 2",
+ * "key3": 3
+ * }
+ *
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ *
+ * @param writer Writes the serialized JSON
+ * @param indentFactor The number of spaces to add to each level of indentation.
+ * @param indent The indentation of the top level.
* @return The writer.
* @throws JSONException
*/
@@ -2538,21 +2362,21 @@ public class JSONObject {
writer.write('{');
if (length == 1) {
- final Entry entry = this.entrySet().iterator().next();
+ final Entry entry = this.entrySet().iterator().next();
final String key = entry.getKey();
writer.write(quote(key));
writer.write(':');
if (indentFactor > 0) {
writer.write(' ');
}
- try{
+ try {
writeValue(writer, entry.getValue(), indentFactor, indent);
} catch (Exception e) {
throw new JSONException("Unable to write JSONObject value for key: " + key, e);
}
} else if (length != 0) {
final int newIndent = indent + indentFactor;
- for (final Entry entry : this.entrySet()) {
+ for (final Entry entry : this.entrySet()) {
if (needsComma) {
writer.write(',');
}
@@ -2611,37 +2435,55 @@ public class JSONObject {
}
return results;
}
-
+
/**
- * Create a new JSONException in a common format for incorrect conversions.
- * @param key name of the key
- * @param valueType the type of value being coerced to
- * @param cause optional cause of the coercion failure
- * @return JSONException that can be thrown.
+ * JSONObject.NULL is equivalent to the value that JavaScript calls null,
+ * whilst Java's null is equivalent to the value that JavaScript calls
+ * undefined.
*/
- private static JSONException wrongValueFormatException(
- String key,
- String valueType,
- Throwable cause) {
- return new JSONException(
- "JSONObject[" + quote(key) + "] is not a " + valueType + "."
- , cause);
- }
-
- /**
- * Create a new JSONException in a common format for incorrect conversions.
- * @param key name of the key
- * @param valueType the type of value being coerced to
- * @param cause optional cause of the coercion failure
- * @return JSONException that can be thrown.
- */
- private static JSONException wrongValueFormatException(
- String key,
- String valueType,
- Object value,
- Throwable cause) {
- return new JSONException(
- "JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")."
- , cause);
+ private static final class Null {
+
+ /**
+ * There is only intended to be a single instance of the NULL object,
+ * so the clone method returns itself.
+ *
+ * @return NULL.
+ */
+ @Override
+ protected final Object clone() {
+ return this;
+ }
+
+ /**
+ * A Null object is equal to the null value and to itself.
+ *
+ * @param object An object to test for nullness.
+ * @return true if the object parameter is the JSONObject.NULL object or
+ * null.
+ */
+ @Override
+ public boolean equals(Object object) {
+ return object == null || object == this;
+ }
+
+ /**
+ * A Null object is equal to the null value and to itself.
+ *
+ * @return always returns 0.
+ */
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ /**
+ * Get the "null" string value.
+ *
+ * @return The string "null".
+ */
+ @Override
+ public String toString() {
+ return "null";
+ }
}
}
diff --git a/src/main/java/json/JSONPointer.java b/src/main/java/json/JSONPointer.java
index bef1ee0..28a8a31 100644
--- a/src/main/java/json/JSONPointer.java
+++ b/src/main/java/json/JSONPointer.java
@@ -36,18 +36,18 @@ SOFTWARE.
/**
* A JSON Pointer is a simple query language defined for JSON documents by
* RFC 6901.
- *
+ *
* In a nutshell, JSONPointer allows the user to navigate into a JSON document
* using strings, and retrieve targeted objects, like a simple form of XPATH.
* Path segments are separated by the '/' char, which signifies the root of
- * the document when it appears as the first char of the string. Array
+ * the document when it appears as the first char of the string. Array
* elements are navigated using ordinals, counting from 0. JSONPointer strings
* may be extended to any arbitrary number of segments. If the navigation
* is successful, the matched item is returned. A matched item may be a
- * JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building
+ * JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building
* fails, an appropriate exception is thrown. If the navigation fails to find
- * a match, a JSONPointerException is thrown.
- *
+ * a match, a JSONPointerException is thrown.
+ *
* @author JSON.org
* @version 2016-05-14
*/
@@ -55,76 +55,6 @@ public class JSONPointer {
// used for URL encoding and decoding
private static final String ENCODING = "utf-8";
-
- /**
- * This class allows the user to build a JSONPointer in steps, using
- * exactly one segment in each step.
- */
- public static class Builder {
-
- // Segments for the eventual JSONPointer string
- private final List refTokens = new ArrayList();
-
- /**
- * Creates a {@code JSONPointer} instance using the tokens previously set using the
- * {@link #append(String)} method calls.
- */
- public JSONPointer build() {
- return new JSONPointer(this.refTokens);
- }
-
- /**
- * Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
- *
- * Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
- * argument of this method MUST NOT be escaped. If you want to query the property called
- * {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
- * need to escape it as {@code "a~0b"}.
- *
- * @param token the new token to be appended to the list
- * @return {@code this}
- * @throws NullPointerException if {@code token} is null
- */
- public Builder append(String token) {
- if (token == null) {
- throw new NullPointerException("token cannot be null");
- }
- this.refTokens.add(token);
- return this;
- }
-
- /**
- * Adds an integer to the reference token list. Although not necessarily, mostly this token will
- * denote an array index.
- *
- * @param arrayIndex the array index to be added to the token list
- * @return {@code this}
- */
- public Builder append(int arrayIndex) {
- this.refTokens.add(String.valueOf(arrayIndex));
- return this;
- }
- }
-
- /**
- * Static factory method for {@link Builder}. Example usage:
- *
- *
- * JSONPointer pointer = JSONPointer.builder()
- * .append("obj")
- * .append("other~key").append("another/key")
- * .append("\"")
- * .append(0)
- * .build();
- *
- *
- * @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
- * {@link Builder#append(String)} calls.
- */
- public static Builder builder() {
- return new Builder();
- }
-
// Segments for the JSONPointer string
private final List refTokens;
@@ -132,7 +62,7 @@ public class JSONPointer {
* Pre-parses and initializes a new {@code JSONPointer} instance. If you want to
* evaluate the same JSON Pointer on different JSON documents then it is recommended
* to keep the {@code JSONPointer} instances due to performance considerations.
- *
+ *
* @param pointer the JSON String or URI Fragment representation of the JSON pointer.
* @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
*/
@@ -163,7 +93,7 @@ public class JSONPointer {
do {
prevSlashIdx = slashIdx + 1;
slashIdx = refs.indexOf('/', prevSlashIdx);
- if(prevSlashIdx == slashIdx || prevSlashIdx == refs.length()) {
+ if (prevSlashIdx == slashIdx || prevSlashIdx == refs.length()) {
// found 2 slashes in a row ( obj//next )
// or single slash at the end of a string ( obj/test/ )
this.refTokens.add("");
@@ -186,18 +116,79 @@ public class JSONPointer {
this.refTokens = new ArrayList(refTokens);
}
+ /**
+ * Static factory method for {@link Builder}. Example usage:
+ *
+ *
+ * JSONPointer pointer = JSONPointer.builder()
+ * .append("obj")
+ * .append("other~key").append("another/key")
+ * .append("\"")
+ * .append(0)
+ * .build();
+ *
+ *
+ * @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
+ * {@link Builder#append(String)} calls.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
private static String unescape(String token) {
return token.replace("~1", "/").replace("~0", "~")
.replace("\\\"", "\"")
.replace("\\\\", "\\");
}
+ /**
+ * Matches a JSONArray element by ordinal position
+ *
+ * @param current the JSONArray to be evaluated
+ * @param indexToken the array index in string form
+ * @return the matched object. If no matching item is found a
+ * @throws JSONPointerException is thrown if the index is out of bounds
+ */
+ private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
+ try {
+ int index = Integer.parseInt(indexToken);
+ JSONArray currentArr = (JSONArray) current;
+ if (index >= currentArr.length()) {
+ throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken,
+ Integer.valueOf(currentArr.length())));
+ }
+ try {
+ return currentArr.get(index);
+ } catch (JSONException e) {
+ throw new JSONPointerException("Error reading value at index position " + index, e);
+ }
+ } catch (NumberFormatException e) {
+ throw new JSONPointerException(format("%s is not an array index", indexToken), e);
+ }
+ }
+
+ /**
+ * Escapes path segment values to an unambiguous form.
+ * The escape char to be inserted is '~'. The chars to be escaped
+ * are ~, which maps to ~0, and /, which maps to ~1. Backslashes
+ * and double quote chars are also escaped.
+ *
+ * @param token the JSONPointer segment value to be escaped
+ * @return the escaped value for the token
+ */
+ private static String escape(String token) {
+ return token.replace("~", "~0")
+ .replace("/", "~1")
+ .replace("\\", "\\\\")
+ .replace("\"", "\\\"");
+ }
+
/**
* Evaluates this JSON Pointer on the given {@code document}. The {@code document}
* is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty
* JSON Pointer ({@code ""}) can be evaluated on any JSON values and in such case the
- * returned value will be {@code document} itself.
- *
+ * returned value will be {@code document} itself.
+ *
* @param document the JSON document which should be the subject of querying.
* @return the result of the evaluation
* @throws JSONPointerException if an error occurs during evaluation
@@ -221,31 +212,6 @@ public class JSONPointer {
return current;
}
- /**
- * Matches a JSONArray element by ordinal position
- * @param current the JSONArray to be evaluated
- * @param indexToken the array index in string form
- * @return the matched object. If no matching item is found a
- * @throws JSONPointerException is thrown if the index is out of bounds
- */
- private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
- try {
- int index = Integer.parseInt(indexToken);
- JSONArray currentArr = (JSONArray) current;
- if (index >= currentArr.length()) {
- throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken,
- Integer.valueOf(currentArr.length())));
- }
- try {
- return currentArr.get(index);
- } catch (JSONException e) {
- throw new JSONPointerException("Error reading value at index position " + index, e);
- }
- } catch (NumberFormatException e) {
- throw new JSONPointerException(format("%s is not an array index", indexToken), e);
- }
- }
-
/**
* Returns a string representing the JSONPointer path value using string
* representation
@@ -253,27 +219,12 @@ public class JSONPointer {
@Override
public String toString() {
StringBuilder rval = new StringBuilder("");
- for (String token: this.refTokens) {
+ for (String token : this.refTokens) {
rval.append('/').append(escape(token));
}
return rval.toString();
}
- /**
- * Escapes path segment values to an unambiguous form.
- * The escape char to be inserted is '~'. The chars to be escaped
- * are ~, which maps to ~0, and /, which maps to ~1. Backslashes
- * and double quote chars are also escaped.
- * @param token the JSONPointer segment value to be escaped
- * @return the escaped value for the token
- */
- private static String escape(String token) {
- return token.replace("~", "~0")
- .replace("/", "~1")
- .replace("\\", "\\\\")
- .replace("\"", "\\\"");
- }
-
/**
* Returns a string representing the JSONPointer path value using URI
* fragment identifier representation
@@ -289,5 +240,55 @@ public class JSONPointer {
throw new RuntimeException(e);
}
}
-
+
+ /**
+ * This class allows the user to build a JSONPointer in steps, using
+ * exactly one segment in each step.
+ */
+ public static class Builder {
+
+ // Segments for the eventual JSONPointer string
+ private final List refTokens = new ArrayList();
+
+ /**
+ * Creates a {@code JSONPointer} instance using the tokens previously set using the
+ * {@link #append(String)} method calls.
+ */
+ public JSONPointer build() {
+ return new JSONPointer(this.refTokens);
+ }
+
+ /**
+ * Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
+ *
+ * Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
+ * argument of this method MUST NOT be escaped. If you want to query the property called
+ * {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
+ * need to escape it as {@code "a~0b"}.
+ *
+ * @param token the new token to be appended to the list
+ * @return {@code this}
+ * @throws NullPointerException if {@code token} is null
+ */
+ public Builder append(String token) {
+ if (token == null) {
+ throw new NullPointerException("token cannot be null");
+ }
+ this.refTokens.add(token);
+ return this;
+ }
+
+ /**
+ * Adds an integer to the reference token list. Although not necessarily, mostly this token will
+ * denote an array index.
+ *
+ * @param arrayIndex the array index to be added to the token list
+ * @return {@code this}
+ */
+ public Builder append(int arrayIndex) {
+ this.refTokens.add(String.valueOf(arrayIndex));
+ return this;
+ }
+ }
+
}
diff --git a/src/main/java/json/JSONPointerException.java b/src/main/java/json/JSONPointerException.java
index 294d4e3..68eafee 100644
--- a/src/main/java/json/JSONPointerException.java
+++ b/src/main/java/json/JSONPointerException.java
@@ -27,7 +27,7 @@ SOFTWARE.
/**
* The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
* during evaluating a pointer.
- *
+ *
* @author JSON.org
* @version 2016-05-13
*/
diff --git a/src/main/java/json/JSONPropertyIgnore.java b/src/main/java/json/JSONPropertyIgnore.java
index c2b18bd..dd81c36 100644
--- a/src/main/java/json/JSONPropertyIgnore.java
+++ b/src/main/java/json/JSONPropertyIgnore.java
@@ -40,4 +40,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* present at any level in the class hierarchy, then the method will
* not be serialized from the bean into the JSONObject.
*/
-public @interface JSONPropertyIgnore { }
+public @interface JSONPropertyIgnore {
+}
diff --git a/src/main/java/json/JSONString.java b/src/main/java/json/JSONString.java
index dbf7fb2..0a75428 100644
--- a/src/main/java/json/JSONString.java
+++ b/src/main/java/json/JSONString.java
@@ -1,4 +1,5 @@
package json;
+
/**
* The JSONString
interface allows a toJSONString()
* method so that a class can change the behavior of
diff --git a/src/main/java/json/JSONStringer.java b/src/main/java/json/JSONStringer.java
index 46979bb..5b7b0be 100644
--- a/src/main/java/json/JSONStringer.java
+++ b/src/main/java/json/JSONStringer.java
@@ -53,6 +53,7 @@ import java.io.StringWriter;
* you. Objects and arrays can be nested up to 20 levels deep.
*
* This can sometimes be easier than using a JSONObject to build a string.
+ *
* @author JSON.org
* @version 2015-12-09
*/
@@ -70,6 +71,7 @@ public class JSONStringer extends JSONWriter {
* problem in the construction of the JSON text (such as the calls to
* array
were not properly balanced with calls to
* endArray
).
+ *
* @return The JSON text.
*/
@Override
diff --git a/src/main/java/json/JSONTokener.java b/src/main/java/json/JSONTokener.java
index f7f450e..632d1cf 100644
--- a/src/main/java/json/JSONTokener.java
+++ b/src/main/java/json/JSONTokener.java
@@ -30,37 +30,54 @@ SOFTWARE.
* A JSONTokener takes a source string and extracts characters and tokens from
* it. It is used by the JSONObject and JSONArray constructors to parse
* JSON source strings.
+ *
* @author JSON.org
* @version 2014-05-03
*/
public class JSONTokener {
- /** current read character position on the current line. */
- private long character;
- /** flag to indicate if the end of the input has been found. */
- private boolean eof;
- /** current read index of the input. */
- private long index;
- /** current line of the input. */
- private long line;
- /** previous character read from the input. */
- private char previous;
- /** Reader for the input. */
+ /**
+ * Reader for the input.
+ */
private final Reader reader;
- /** flag to indicate that a previous character was requested. */
+ /**
+ * current read character position on the current line.
+ */
+ private long character;
+ /**
+ * flag to indicate if the end of the input has been found.
+ */
+ private boolean eof;
+ /**
+ * current read index of the input.
+ */
+ private long index;
+ /**
+ * current line of the input.
+ */
+ private long line;
+ /**
+ * previous character read from the input.
+ */
+ private char previous;
+ /**
+ * flag to indicate that a previous character was requested.
+ */
private boolean usePrevious;
- /** the number of characters read in the previous line. */
+ /**
+ * the number of characters read in the previous line.
+ */
private long characterPreviousLine;
/**
* Construct a JSONTokener from a Reader. The caller must close the Reader.
*
- * @param reader A reader.
+ * @param reader A reader.
*/
public JSONTokener(Reader reader) {
this.reader = reader.markSupported()
? reader
- : new BufferedReader(reader);
+ : new BufferedReader(reader);
this.eof = false;
this.usePrevious = false;
this.previous = 0;
@@ -73,6 +90,7 @@ public class JSONTokener {
/**
* Construct a JSONTokener from an InputStream. The caller must close the input stream.
+ *
* @param inputStream The source.
*/
public JSONTokener(InputStream inputStream) {
@@ -83,47 +101,18 @@ public class JSONTokener {
/**
* Construct a JSONTokener from a string.
*
- * @param s A source string.
+ * @param s A source string.
*/
public JSONTokener(String s) {
this(new StringReader(s));
}
-
- /**
- * Back up one character. This provides a sort of lookahead capability,
- * so that you can test for a digit or letter before attempting to parse
- * the next number or identifier.
- * @throws JSONException Thrown if trying to step back more than 1 step
- * or if already at the start of the string
- */
- public void back() throws JSONException {
- if (this.usePrevious || this.index <= 0) {
- throw new JSONException("Stepping back two steps is not supported");
- }
- this.decrementIndexes();
- this.usePrevious = true;
- this.eof = false;
- }
-
- /**
- * Decrements the indexes for the {@link #back()} method based on the previous character read.
- */
- private void decrementIndexes() {
- this.index--;
- if(this.previous=='\r' || this.previous == '\n') {
- this.line--;
- this.character=this.characterPreviousLine ;
- } else if(this.character > 0){
- this.character--;
- }
- }
-
/**
* Get the hex value of a character (base16).
+ *
* @param c A character between '0' and '9' or between 'A' and 'F' or
- * between 'a' and 'f'.
- * @return An int between 0 and 15, or -1 if c was not a hex digit.
+ * between 'a' and 'f'.
+ * @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
public static int dehexchar(char c) {
if (c >= '0' && c <= '9') {
@@ -138,9 +127,39 @@ public class JSONTokener {
return -1;
}
+ /**
+ * Back up one character. This provides a sort of lookahead capability,
+ * so that you can test for a digit or letter before attempting to parse
+ * the next number or identifier.
+ *
+ * @throws JSONException Thrown if trying to step back more than 1 step
+ * or if already at the start of the string
+ */
+ public void back() throws JSONException {
+ if (this.usePrevious || this.index <= 0) {
+ throw new JSONException("Stepping back two steps is not supported");
+ }
+ this.decrementIndexes();
+ this.usePrevious = true;
+ this.eof = false;
+ }
+
+ /**
+ * Decrements the indexes for the {@link #back()} method based on the previous character read.
+ */
+ private void decrementIndexes() {
+ this.index--;
+ if (this.previous == '\r' || this.previous == '\n') {
+ this.line--;
+ this.character = this.characterPreviousLine;
+ } else if (this.character > 0) {
+ this.character--;
+ }
+ }
+
/**
* Checks if the end of the input has been reached.
- *
+ *
* @return true if at the end of the file and we didn't step back
*/
public boolean end() {
@@ -151,12 +170,13 @@ public class JSONTokener {
/**
* Determine if the source string still contains characters that next()
* can consume.
+ *
* @return true if not yet at the end of the source.
* @throws JSONException thrown if there is an error stepping forward
- * or backward while checking for more data.
+ * or backward while checking for more data.
*/
public boolean more() throws JSONException {
- if(this.usePrevious) {
+ if (this.usePrevious) {
return true;
}
try {
@@ -166,7 +186,7 @@ public class JSONTokener {
}
try {
// -1 is EOF, but next() can not consume the null character '\0'
- if(this.reader.read() <= 0) {
+ if (this.reader.read() <= 0) {
this.eof = true;
return false;
}
@@ -208,21 +228,22 @@ public class JSONTokener {
/**
* Increments the internal indexes according to the previous character
* read and the character passed as the current character.
+ *
* @param c the current character read.
*/
private void incrementIndexes(int c) {
- if(c > 0) {
+ if (c > 0) {
this.index++;
- if(c=='\r') {
+ if (c == '\r') {
this.line++;
this.characterPreviousLine = this.character;
- this.character=0;
- }else if (c=='\n') {
- if(this.previous != '\r') {
+ this.character = 0;
+ } else if (c == '\n') {
+ if (this.previous != '\r') {
this.line++;
this.characterPreviousLine = this.character;
}
- this.character=0;
+ this.character = 0;
} else {
this.character++;
}
@@ -232,6 +253,7 @@ public class JSONTokener {
/**
* Consume the next character, and check that it matches a specified
* character.
+ *
* @param c The character to match.
* @return The character.
* @throws JSONException if the character does not match.
@@ -239,7 +261,7 @@ public class JSONTokener {
public char next(char c) throws JSONException {
char n = this.next();
if (n != c) {
- if(n > 0) {
+ if (n > 0) {
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
n + "'");
}
@@ -252,11 +274,10 @@ public class JSONTokener {
/**
* Get the next n characters.
*
- * @param n The number of characters to take.
- * @return A string of n characters.
- * @throws JSONException
- * Substring bounds error if there are not
- * n characters remaining in the source string.
+ * @param n The number of characters to take.
+ * @return A string of n characters.
+ * @throws JSONException Substring bounds error if there are not
+ * n characters remaining in the source string.
*/
public String next(int n) throws JSONException {
if (n == 0) {
@@ -279,11 +300,12 @@ public class JSONTokener {
/**
* Get the next char in the string, skipping whitespace.
+ *
+ * @return A character, or 0 if there are no more characters.
* @throws JSONException Thrown if there is an error reading the source string.
- * @return A character, or 0 if there are no more characters.
*/
public char nextClean() throws JSONException {
- for (;;) {
+ for (; ; ) {
char c = this.next();
if (c == 0 || c > ' ') {
return c;
@@ -297,62 +319,63 @@ public class JSONTokener {
* Backslash processing is done. The formal JSON format does not
* allow strings in single quotes, but an implementation is allowed to
* accept them.
+ *
* @param quote The quoting character, either
- * "
(double quote) or
- * '
(single quote).
- * @return A String.
+ * "
(double quote) or
+ * '
(single quote).
+ * @return A String.
* @throws JSONException Unterminated string.
*/
public String nextString(char quote) throws JSONException {
char c;
StringBuilder sb = new StringBuilder();
- for (;;) {
+ for (; ; ) {
c = this.next();
switch (c) {
- case 0:
- case '\n':
- case '\r':
- throw this.syntaxError("Unterminated string");
- case '\\':
- c = this.next();
- switch (c) {
- case 'b':
- sb.append('\b');
- break;
- case 't':
- sb.append('\t');
- break;
- case 'n':
- sb.append('\n');
- break;
- case 'f':
- sb.append('\f');
- break;
- case 'r':
- sb.append('\r');
- break;
- case 'u':
- try {
- sb.append((char)Integer.parseInt(this.next(4), 16));
- } catch (NumberFormatException e) {
- throw this.syntaxError("Illegal escape.", e);
+ case 0:
+ case '\n':
+ case '\r':
+ throw this.syntaxError("Unterminated string");
+ case '\\':
+ c = this.next();
+ switch (c) {
+ case 'b':
+ sb.append('\b');
+ break;
+ case 't':
+ sb.append('\t');
+ break;
+ case 'n':
+ sb.append('\n');
+ break;
+ case 'f':
+ sb.append('\f');
+ break;
+ case 'r':
+ sb.append('\r');
+ break;
+ case 'u':
+ try {
+ sb.append((char) Integer.parseInt(this.next(4), 16));
+ } catch (NumberFormatException e) {
+ throw this.syntaxError("Illegal escape.", e);
+ }
+ break;
+ case '"':
+ case '\'':
+ case '\\':
+ case '/':
+ sb.append(c);
+ break;
+ default:
+ throw this.syntaxError("Illegal escape.");
}
break;
- case '"':
- case '\'':
- case '\\':
- case '/':
- sb.append(c);
- break;
default:
- throw this.syntaxError("Illegal escape.");
- }
- break;
- default:
- if (c == quote) {
- return sb.toString();
- }
- sb.append(c);
+ if (c == quote) {
+ return sb.toString();
+ }
+ sb.append(c);
}
}
}
@@ -361,14 +384,15 @@ public class JSONTokener {
/**
* Get the text up but not including the specified character or the
* end of line, whichever comes first.
- * @param delimiter A delimiter character.
- * @return A string.
+ *
+ * @param delimiter A delimiter character.
+ * @return A string.
* @throws JSONException Thrown if there is an error while searching
- * for the delimiter
+ * for the delimiter
*/
public String nextTo(char delimiter) throws JSONException {
StringBuilder sb = new StringBuilder();
- for (;;) {
+ for (; ; ) {
char c = this.next();
if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
if (c != 0) {
@@ -384,15 +408,16 @@ public class JSONTokener {
/**
* Get the text up but not including one of the specified delimiter
* characters or the end of line, whichever comes first.
+ *
* @param delimiters A set of delimiter characters.
* @return A string, trimmed.
* @throws JSONException Thrown if there is an error while searching
- * for the delimiter
+ * for the delimiter
*/
public String nextTo(String delimiters) throws JSONException {
char c;
StringBuilder sb = new StringBuilder();
- for (;;) {
+ for (; ; ) {
c = this.next();
if (delimiters.indexOf(c) >= 0 || c == 0 ||
c == '\n' || c == '\r') {
@@ -409,24 +434,24 @@ public class JSONTokener {
/**
* Get the next value. The value can be a Boolean, Double, Integer,
* JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
- * @throws JSONException If syntax error.
*
* @return An object.
+ * @throws JSONException If syntax error.
*/
public Object nextValue() throws JSONException {
char c = this.nextClean();
String string;
switch (c) {
- case '"':
- case '\'':
- return this.nextString(c);
- case '{':
- this.back();
- return new JSONObject(this);
- case '[':
- this.back();
- return new JSONArray(this);
+ case '"':
+ case '\'':
+ return this.nextString(c);
+ case '{':
+ this.back();
+ return new JSONObject(this);
+ case '[':
+ this.back();
+ return new JSONArray(this);
}
/*
@@ -458,11 +483,12 @@ public class JSONTokener {
/**
* Skip characters until the next character is the requested character.
* If the requested character is not found, no characters are skipped.
+ *
* @param to A character to skip to.
* @return The requested character, or zero if the requested character
* is not found.
* @throws JSONException Thrown if there is an error while searching
- * for the to character
+ * for the to character
*/
public char skipTo(char to) throws JSONException {
char c;
@@ -496,7 +522,7 @@ public class JSONTokener {
* Make a JSONException to signal a syntax error.
*
* @param message The error message.
- * @return A JSONException object, suitable for throwing
+ * @return A JSONException object, suitable for throwing
*/
public JSONException syntaxError(String message) {
return new JSONException(message + this.toString());
@@ -505,9 +531,9 @@ public class JSONTokener {
/**
* Make a JSONException to signal a syntax error.
*
- * @param message The error message.
+ * @param message The error message.
* @param causedBy The throwable that caused the error.
- * @return A JSONException object, suitable for throwing
+ * @return A JSONException object, suitable for throwing
*/
public JSONException syntaxError(String message, Throwable causedBy) {
return new JSONException(message + this.toString(), causedBy);
diff --git a/src/main/java/json/JSONWriter.java b/src/main/java/json/JSONWriter.java
index 1576383..044b4ed 100644
--- a/src/main/java/json/JSONWriter.java
+++ b/src/main/java/json/JSONWriter.java
@@ -54,18 +54,16 @@ SOFTWARE.
* you. Objects and arrays can be nested up to 200 levels deep.
*
* This can sometimes be easier than using a JSONObject to build a string.
+ *
* @author JSON.org
* @version 2016-08-08
*/
public class JSONWriter {
private static final int maxdepth = 200;
-
/**
- * The comma flag determines if a comma should be output before the next
- * value.
+ * The object/array stack.
*/
- private boolean comma;
-
+ private final JSONObject stack[];
/**
* The current mode. Values:
* 'a' (array),
@@ -75,21 +73,19 @@ public class JSONWriter {
* 'o' (object).
*/
protected char mode;
-
- /**
- * The object/array stack.
- */
- private final JSONObject stack[];
-
- /**
- * The stack top index. A value of 0 indicates that the stack is empty.
- */
- private int top;
-
/**
* The writer that will receive the output.
*/
protected Appendable writer;
+ /**
+ * The comma flag determines if a comma should be output before the next
+ * value.
+ */
+ private boolean comma;
+ /**
+ * The stack top index. A value of 0 indicates that the stack is empty.
+ */
+ private int top;
/**
* Make a fresh JSONWriter. It can be used to build one JSON text.
@@ -102,200 +98,6 @@ public class JSONWriter {
this.writer = w;
}
- /**
- * Append a value.
- * @param string A string value.
- * @return this
- * @throws JSONException If the value is out of sequence.
- */
- private JSONWriter append(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null pointer");
- }
- if (this.mode == 'o' || this.mode == 'a') {
- try {
- if (this.comma && this.mode == 'a') {
- this.writer.append(',');
- }
- this.writer.append(string);
- } catch (IOException e) {
- // Android as of API 25 does not support this exception constructor
- // however we won't worry about it. If an exception is happening here
- // it will just throw a "Method not found" exception instead.
- throw new JSONException(e);
- }
- if (this.mode == 'o') {
- this.mode = 'k';
- }
- this.comma = true;
- return this;
- }
- throw new JSONException("Value out of sequence.");
- }
-
- /**
- * Begin appending a new array. All values until the balancing
- * endArray
will be appended to this array. The
- * endArray
method must be called to mark the array's end.
- * @return this
- * @throws JSONException If the nesting is too deep, or if the object is
- * started in the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter array() throws JSONException {
- if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
- this.push(null);
- this.append("[");
- this.comma = false;
- return this;
- }
- throw new JSONException("Misplaced array.");
- }
-
- /**
- * End something.
- * @param m Mode
- * @param c Closing character
- * @return this
- * @throws JSONException If unbalanced.
- */
- private JSONWriter end(char m, char c) throws JSONException {
- if (this.mode != m) {
- throw new JSONException(m == 'a'
- ? "Misplaced endArray."
- : "Misplaced endObject.");
- }
- this.pop(m);
- try {
- this.writer.append(c);
- } catch (IOException e) {
- // Android as of API 25 does not support this exception constructor
- // however we won't worry about it. If an exception is happening here
- // it will just throw a "Method not found" exception instead.
- throw new JSONException(e);
- }
- this.comma = true;
- return this;
- }
-
- /**
- * End an array. This method most be called to balance calls to
- * array
.
- * @return this
- * @throws JSONException If incorrectly nested.
- */
- public JSONWriter endArray() throws JSONException {
- return this.end('a', ']');
- }
-
- /**
- * End an object. This method most be called to balance calls to
- * object
.
- * @return this
- * @throws JSONException If incorrectly nested.
- */
- public JSONWriter endObject() throws JSONException {
- return this.end('k', '}');
- }
-
- /**
- * Append a key. The key will be associated with the next value. In an
- * object, every value must be preceded by a key.
- * @param string A key string.
- * @return this
- * @throws JSONException If the key is out of place. For example, keys
- * do not belong in arrays or if the key is null.
- */
- public JSONWriter key(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null key.");
- }
- if (this.mode == 'k') {
- try {
- JSONObject topObject = this.stack[this.top - 1];
- // don't use the built in putOnce method to maintain Android support
- if(topObject.has(string)) {
- throw new JSONException("Duplicate key \"" + string + "\"");
- }
- topObject.put(string, true);
- if (this.comma) {
- this.writer.append(',');
- }
- this.writer.append(JSONObject.quote(string));
- this.writer.append(':');
- this.comma = false;
- this.mode = 'o';
- return this;
- } catch (IOException e) {
- // Android as of API 25 does not support this exception constructor
- // however we won't worry about it. If an exception is happening here
- // it will just throw a "Method not found" exception instead.
- throw new JSONException(e);
- }
- }
- throw new JSONException("Misplaced key.");
- }
-
-
- /**
- * Begin appending a new object. All keys and values until the balancing
- * endObject
will be appended to this object. The
- * endObject
method must be called to mark the object's end.
- * @return this
- * @throws JSONException If the nesting is too deep, or if the object is
- * started in the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter object() throws JSONException {
- if (this.mode == 'i') {
- this.mode = 'o';
- }
- if (this.mode == 'o' || this.mode == 'a') {
- this.append("{");
- this.push(new JSONObject());
- this.comma = false;
- return this;
- }
- throw new JSONException("Misplaced object.");
-
- }
-
-
- /**
- * Pop an array or object scope.
- * @param c The scope to close.
- * @throws JSONException If nesting is wrong.
- */
- private void pop(char c) throws JSONException {
- if (this.top <= 0) {
- throw new JSONException("Nesting error.");
- }
- char m = this.stack[this.top - 1] == null ? 'a' : 'k';
- if (m != c) {
- throw new JSONException("Nesting error.");
- }
- this.top -= 1;
- this.mode = this.top == 0
- ? 'd'
- : this.stack[this.top - 1] == null
- ? 'a'
- : 'k';
- }
-
- /**
- * Push an array or object scope.
- * @param jo The scope to open.
- * @throws JSONException If nesting is too deep.
- */
- private void push(JSONObject jo) throws JSONException {
- if (this.top >= maxdepth) {
- throw new JSONException("Nesting too deep.");
- }
- this.stack[this.top] = jo;
- this.mode = jo == null ? 'a' : 'k';
- this.top += 1;
- }
-
/**
* Make a JSON text of an Object value. If the object has an
* value.toJSONString() method, then that method will be used to produce the
@@ -311,14 +113,12 @@ public class JSONWriter {
*
* Warning: This method assumes that the data structure is acyclical.
*
- * @param value
- * The value to be serialized.
+ * @param value The value to be serialized.
* @return a printable, displayable, transmittable representation of the
- * object, beginning with {
(left
- * brace) and ending with }
(right
- * brace).
- * @throws JSONException
- * If the value is or contains an invalid number.
+ * object, beginning with {
(left
+ * brace) and ending with }
(right
+ * brace).
+ * @throws JSONException If the value is or contains an invalid number.
*/
public static String valueToString(Object value) throws JSONException {
if (value == null || value.equals(null)) {
@@ -339,7 +139,7 @@ public class JSONWriter {
if (value instanceof Number) {
// not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
final String numberAsString = JSONObject.numberToString((Number) value);
- if(JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) {
+ if (JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) {
// Close enough to a JSON number that we will return it unquoted
return numberAsString;
}
@@ -362,15 +162,217 @@ public class JSONWriter {
if (value.getClass().isArray()) {
return new JSONArray(value).toString();
}
- if(value instanceof Enum>){
- return JSONObject.quote(((Enum>)value).name());
+ if (value instanceof Enum>) {
+ return JSONObject.quote(((Enum>) value).name());
}
return JSONObject.quote(value.toString());
}
+ /**
+ * Append a value.
+ *
+ * @param string A string value.
+ * @return this
+ * @throws JSONException If the value is out of sequence.
+ */
+ private JSONWriter append(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null pointer");
+ }
+ if (this.mode == 'o' || this.mode == 'a') {
+ try {
+ if (this.comma && this.mode == 'a') {
+ this.writer.append(',');
+ }
+ this.writer.append(string);
+ } catch (IOException e) {
+ // Android as of API 25 does not support this exception constructor
+ // however we won't worry about it. If an exception is happening here
+ // it will just throw a "Method not found" exception instead.
+ throw new JSONException(e);
+ }
+ if (this.mode == 'o') {
+ this.mode = 'k';
+ }
+ this.comma = true;
+ return this;
+ }
+ throw new JSONException("Value out of sequence.");
+ }
+
+ /**
+ * Begin appending a new array. All values until the balancing
+ * endArray
will be appended to this array. The
+ * endArray
method must be called to mark the array's end.
+ *
+ * @return this
+ * @throws JSONException If the nesting is too deep, or if the object is
+ * started in the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter array() throws JSONException {
+ if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
+ this.push(null);
+ this.append("[");
+ this.comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced array.");
+ }
+
+ /**
+ * End something.
+ *
+ * @param m Mode
+ * @param c Closing character
+ * @return this
+ * @throws JSONException If unbalanced.
+ */
+ private JSONWriter end(char m, char c) throws JSONException {
+ if (this.mode != m) {
+ throw new JSONException(m == 'a'
+ ? "Misplaced endArray."
+ : "Misplaced endObject.");
+ }
+ this.pop(m);
+ try {
+ this.writer.append(c);
+ } catch (IOException e) {
+ // Android as of API 25 does not support this exception constructor
+ // however we won't worry about it. If an exception is happening here
+ // it will just throw a "Method not found" exception instead.
+ throw new JSONException(e);
+ }
+ this.comma = true;
+ return this;
+ }
+
+ /**
+ * End an array. This method most be called to balance calls to
+ * array
.
+ *
+ * @return this
+ * @throws JSONException If incorrectly nested.
+ */
+ public JSONWriter endArray() throws JSONException {
+ return this.end('a', ']');
+ }
+
+ /**
+ * End an object. This method most be called to balance calls to
+ * object
.
+ *
+ * @return this
+ * @throws JSONException If incorrectly nested.
+ */
+ public JSONWriter endObject() throws JSONException {
+ return this.end('k', '}');
+ }
+
+ /**
+ * Append a key. The key will be associated with the next value. In an
+ * object, every value must be preceded by a key.
+ *
+ * @param string A key string.
+ * @return this
+ * @throws JSONException If the key is out of place. For example, keys
+ * do not belong in arrays or if the key is null.
+ */
+ public JSONWriter key(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null key.");
+ }
+ if (this.mode == 'k') {
+ try {
+ JSONObject topObject = this.stack[this.top - 1];
+ // don't use the built in putOnce method to maintain Android support
+ if (topObject.has(string)) {
+ throw new JSONException("Duplicate key \"" + string + "\"");
+ }
+ topObject.put(string, true);
+ if (this.comma) {
+ this.writer.append(',');
+ }
+ this.writer.append(JSONObject.quote(string));
+ this.writer.append(':');
+ this.comma = false;
+ this.mode = 'o';
+ return this;
+ } catch (IOException e) {
+ // Android as of API 25 does not support this exception constructor
+ // however we won't worry about it. If an exception is happening here
+ // it will just throw a "Method not found" exception instead.
+ throw new JSONException(e);
+ }
+ }
+ throw new JSONException("Misplaced key.");
+ }
+
+ /**
+ * Begin appending a new object. All keys and values until the balancing
+ * endObject
will be appended to this object. The
+ * endObject
method must be called to mark the object's end.
+ *
+ * @return this
+ * @throws JSONException If the nesting is too deep, or if the object is
+ * started in the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter object() throws JSONException {
+ if (this.mode == 'i') {
+ this.mode = 'o';
+ }
+ if (this.mode == 'o' || this.mode == 'a') {
+ this.append("{");
+ this.push(new JSONObject());
+ this.comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced object.");
+
+ }
+
+ /**
+ * Pop an array or object scope.
+ *
+ * @param c The scope to close.
+ * @throws JSONException If nesting is wrong.
+ */
+ private void pop(char c) throws JSONException {
+ if (this.top <= 0) {
+ throw new JSONException("Nesting error.");
+ }
+ char m = this.stack[this.top - 1] == null ? 'a' : 'k';
+ if (m != c) {
+ throw new JSONException("Nesting error.");
+ }
+ this.top -= 1;
+ this.mode = this.top == 0
+ ? 'd'
+ : this.stack[this.top - 1] == null
+ ? 'a'
+ : 'k';
+ }
+
+ /**
+ * Push an array or object scope.
+ *
+ * @param jo The scope to open.
+ * @throws JSONException If nesting is too deep.
+ */
+ private void push(JSONObject jo) throws JSONException {
+ if (this.top >= maxdepth) {
+ throw new JSONException("Nesting too deep.");
+ }
+ this.stack[this.top] = jo;
+ this.mode = jo == null ? 'a' : 'k';
+ this.top += 1;
+ }
+
/**
* Append either the value true
or the value
* false
.
+ *
* @param b A boolean.
* @return this
* @throws JSONException
@@ -381,6 +383,7 @@ public class JSONWriter {
/**
* Append a double value.
+ *
* @param d A double.
* @return this
* @throws JSONException If the number is not finite.
@@ -391,6 +394,7 @@ public class JSONWriter {
/**
* Append a long value.
+ *
* @param l A long.
* @return this
* @throws JSONException
@@ -402,8 +406,9 @@ public class JSONWriter {
/**
* Append an object value.
+ *
* @param object The object to append. It can be null, or a Boolean, Number,
- * String, JSONObject, or JSONArray, or an object that implements JSONString.
+ * String, JSONObject, or JSONArray, or an object that implements JSONString.
* @return this
* @throws JSONException If the value is out of sequence.
*/
diff --git a/target/classes/com/io/yutian/livemutually/liveroom/Chat.class b/target/classes/com/io/yutian/livemutually/liveroom/Chat.class
index 4ea9b4d..e7ce687 100644
Binary files a/target/classes/com/io/yutian/livemutually/liveroom/Chat.class and b/target/classes/com/io/yutian/livemutually/liveroom/Chat.class differ
diff --git a/target/classes/com/io/yutian/livemutually/liveroom/Follow.class b/target/classes/com/io/yutian/livemutually/liveroom/Follow.class
index c1def0c..c553d24 100644
Binary files a/target/classes/com/io/yutian/livemutually/liveroom/Follow.class and b/target/classes/com/io/yutian/livemutually/liveroom/Follow.class differ
diff --git a/target/classes/com/io/yutian/livemutually/liveroom/Like.class b/target/classes/com/io/yutian/livemutually/liveroom/Like.class
index 9bad31e..f5ae478 100644
Binary files a/target/classes/com/io/yutian/livemutually/liveroom/Like.class and b/target/classes/com/io/yutian/livemutually/liveroom/Like.class differ
diff --git a/target/classes/com/io/yutian/livemutually/liveroom/LiveRoomWatcher.class b/target/classes/com/io/yutian/livemutually/liveroom/LiveRoomWatcher.class
index e8b3ff2..de12657 100644
Binary files a/target/classes/com/io/yutian/livemutually/liveroom/LiveRoomWatcher.class and b/target/classes/com/io/yutian/livemutually/liveroom/LiveRoomWatcher.class differ
diff --git a/target/classes/com/io/yutian/livemutually/liveroom/User.class b/target/classes/com/io/yutian/livemutually/liveroom/User.class
index 40bccba..7623357 100644
Binary files a/target/classes/com/io/yutian/livemutually/liveroom/User.class and b/target/classes/com/io/yutian/livemutually/liveroom/User.class differ
diff --git a/target/classes/com/io/yutian/livemutually/manager/KSLiveRoomManager.class b/target/classes/com/io/yutian/livemutually/manager/KSLiveRoomManager.class
index 86ac787..dfb5f8a 100644
Binary files a/target/classes/com/io/yutian/livemutually/manager/KSLiveRoomManager.class and b/target/classes/com/io/yutian/livemutually/manager/KSLiveRoomManager.class differ
diff --git a/target/classes/com/io/yutian/livemutually/wss/KSAPILiveRoomWatcher.class b/target/classes/com/io/yutian/livemutually/wss/KSAPILiveRoomWatcher.class
index 01fe355..f8819cb 100644
Binary files a/target/classes/com/io/yutian/livemutually/wss/KSAPILiveRoomWatcher.class and b/target/classes/com/io/yutian/livemutually/wss/KSAPILiveRoomWatcher.class differ
diff --git a/target/classes/com/io/yutian/livemutually/wss/KuaiShouChat.class b/target/classes/com/io/yutian/livemutually/wss/KuaiShouChat.class
index afb66a6..07e8d9d 100644
Binary files a/target/classes/com/io/yutian/livemutually/wss/KuaiShouChat.class and b/target/classes/com/io/yutian/livemutually/wss/KuaiShouChat.class differ
diff --git a/target/classes/com/io/yutian/livemutually/wss/KuaiShouLike.class b/target/classes/com/io/yutian/livemutually/wss/KuaiShouLike.class
index aca5146..01e8038 100644
Binary files a/target/classes/com/io/yutian/livemutually/wss/KuaiShouLike.class and b/target/classes/com/io/yutian/livemutually/wss/KuaiShouLike.class differ
diff --git a/target/classes/com/io/yutian/livemutually/wss/KuaiShouUser.class b/target/classes/com/io/yutian/livemutually/wss/KuaiShouUser.class
index 2fcee99..4646905 100644
Binary files a/target/classes/com/io/yutian/livemutually/wss/KuaiShouUser.class and b/target/classes/com/io/yutian/livemutually/wss/KuaiShouUser.class differ
diff --git a/target/classes/com/io/yutian/mclive/Main.class b/target/classes/com/io/yutian/mclive/Main.class
index b1cea0e..0173846 100644
Binary files a/target/classes/com/io/yutian/mclive/Main.class and b/target/classes/com/io/yutian/mclive/Main.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/LiveChatEvents.class b/target/classes/com/io/yutian/mclive/event/LiveChatEvents.class
index 8f9fa30..fffe719 100644
Binary files a/target/classes/com/io/yutian/mclive/event/LiveChatEvents.class and b/target/classes/com/io/yutian/mclive/event/LiveChatEvents.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/LiveEnterEvents.class b/target/classes/com/io/yutian/mclive/event/LiveEnterEvents.class
index 8577bd3..2b22494 100644
Binary files a/target/classes/com/io/yutian/mclive/event/LiveEnterEvents.class and b/target/classes/com/io/yutian/mclive/event/LiveEnterEvents.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/LiveFollowEvents.class b/target/classes/com/io/yutian/mclive/event/LiveFollowEvents.class
index 4421290..963ecb2 100644
Binary files a/target/classes/com/io/yutian/mclive/event/LiveFollowEvents.class and b/target/classes/com/io/yutian/mclive/event/LiveFollowEvents.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/LiveGiftEvents.class b/target/classes/com/io/yutian/mclive/event/LiveGiftEvents.class
index fb71780..9e27727 100644
Binary files a/target/classes/com/io/yutian/mclive/event/LiveGiftEvents.class and b/target/classes/com/io/yutian/mclive/event/LiveGiftEvents.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/LiveLikeEvents.class b/target/classes/com/io/yutian/mclive/event/LiveLikeEvents.class
index 6e5bfdc..111588d 100644
Binary files a/target/classes/com/io/yutian/mclive/event/LiveLikeEvents.class and b/target/classes/com/io/yutian/mclive/event/LiveLikeEvents.class differ
diff --git a/target/classes/com/io/yutian/mclive/event/ZhuboAPI.class b/target/classes/com/io/yutian/mclive/event/ZhuboAPI.class
index 8c67c76..e98bc97 100644
Binary files a/target/classes/com/io/yutian/mclive/event/ZhuboAPI.class and b/target/classes/com/io/yutian/mclive/event/ZhuboAPI.class differ
diff --git a/target/classes/com/io/yutian/verify/AESUtil.class b/target/classes/com/io/yutian/verify/AESUtil.class
index 9ce7a3a..f5c58ae 100644
Binary files a/target/classes/com/io/yutian/verify/AESUtil.class and b/target/classes/com/io/yutian/verify/AESUtil.class differ
diff --git a/target/classes/com/io/yutian/verify/PluginVerifyResult.class b/target/classes/com/io/yutian/verify/PluginVerifyResult.class
index d483c3d..61010ce 100644
Binary files a/target/classes/com/io/yutian/verify/PluginVerifyResult.class and b/target/classes/com/io/yutian/verify/PluginVerifyResult.class differ
diff --git a/target/classes/com/io/yutian/verify/VerifyHandler.class b/target/classes/com/io/yutian/verify/VerifyHandler.class
index a20f5e7..0562ac7 100644
Binary files a/target/classes/com/io/yutian/verify/VerifyHandler.class and b/target/classes/com/io/yutian/verify/VerifyHandler.class differ
diff --git a/target/classes/json/JSONArray.class b/target/classes/json/JSONArray.class
index 1564b0f..248b38a 100644
Binary files a/target/classes/json/JSONArray.class and b/target/classes/json/JSONArray.class differ
diff --git a/target/classes/json/JSONException.class b/target/classes/json/JSONException.class
index a12d327..0e19e22 100644
Binary files a/target/classes/json/JSONException.class and b/target/classes/json/JSONException.class differ
diff --git a/target/classes/json/JSONObject$Null.class b/target/classes/json/JSONObject$Null.class
index 2a408e7..9c6a784 100644
Binary files a/target/classes/json/JSONObject$Null.class and b/target/classes/json/JSONObject$Null.class differ
diff --git a/target/classes/json/JSONObject.class b/target/classes/json/JSONObject.class
index 246e34d..eeaf6c3 100644
Binary files a/target/classes/json/JSONObject.class and b/target/classes/json/JSONObject.class differ
diff --git a/target/classes/json/JSONPointer$Builder.class b/target/classes/json/JSONPointer$Builder.class
index 8c00583..c5621b7 100644
Binary files a/target/classes/json/JSONPointer$Builder.class and b/target/classes/json/JSONPointer$Builder.class differ
diff --git a/target/classes/json/JSONPointer.class b/target/classes/json/JSONPointer.class
index 6852361..73e5045 100644
Binary files a/target/classes/json/JSONPointer.class and b/target/classes/json/JSONPointer.class differ
diff --git a/target/classes/json/JSONPointerException.class b/target/classes/json/JSONPointerException.class
index f7d9c66..9d0242e 100644
Binary files a/target/classes/json/JSONPointerException.class and b/target/classes/json/JSONPointerException.class differ
diff --git a/target/classes/json/JSONPropertyIgnore.class b/target/classes/json/JSONPropertyIgnore.class
index 5e092d5..5e2afb6 100644
Binary files a/target/classes/json/JSONPropertyIgnore.class and b/target/classes/json/JSONPropertyIgnore.class differ
diff --git a/target/classes/json/JSONPropertyName.class b/target/classes/json/JSONPropertyName.class
index 6fae440..fad21d5 100644
Binary files a/target/classes/json/JSONPropertyName.class and b/target/classes/json/JSONPropertyName.class differ
diff --git a/target/classes/json/JSONString.class b/target/classes/json/JSONString.class
index 2ca4132..45cd76d 100644
Binary files a/target/classes/json/JSONString.class and b/target/classes/json/JSONString.class differ
diff --git a/target/classes/json/JSONStringer.class b/target/classes/json/JSONStringer.class
index ab5b7d5..f797072 100644
Binary files a/target/classes/json/JSONStringer.class and b/target/classes/json/JSONStringer.class differ
diff --git a/target/classes/json/JSONTokener.class b/target/classes/json/JSONTokener.class
index 5ca4c55..5b426bf 100644
Binary files a/target/classes/json/JSONTokener.class and b/target/classes/json/JSONTokener.class differ
diff --git a/target/classes/json/JSONWriter.class b/target/classes/json/JSONWriter.class
index ffb752b..9afad21 100644
Binary files a/target/classes/json/JSONWriter.class and b/target/classes/json/JSONWriter.class differ