You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ud...@apache.org on 2017/02/17 21:58:09 UTC
[1/8] geode git commit: Revert "GEODE-2142: Spotless"
Repository: geode
Updated Branches:
refs/heads/develop 2e3a88f7b -> 0805036e8
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONTokener.java b/geode-json/src/main/java/org/json/JSONTokener.java
index 21c9fb0..59eb4bc 100755
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
@@ -20,620 +22,637 @@ import java.io.IOException;
import java.io.Reader;
/**
- * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>) encoded string into
- * the corresponding object. Most clients of this class will use only need the
- * {@link #JSONTokener(String) constructor} and {@link #nextValue} method. Example usage:
- *
- * <pre>
- * String json = "{" + " \"query\": \"Pizza\", " + " \"locations\": [ 94043, 90210 ] " + "}";
+ * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
+ * encoded string into the corresponding object. Most clients of
+ * this class will use only need the {@link #JSONTokener(String) constructor}
+ * and {@link #nextValue} method. Example usage: <pre>
+ * String json = "{"
+ * + " \"query\": \"Pizza\", "
+ * + " \"locations\": [ 94043, 90210 ] "
+ * + "}";
*
* JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
* String query = object.getString("query");
- * JSONArray locations = object.getJSONArray("locations");
- * </pre>
+ * JSONArray locations = object.getJSONArray("locations");</pre>
*
- * <p>
- * For best interoperability and performance use JSON that complies with RFC 4627, such as that
- * generated by {@link JSONStringer}. For legacy reasons this parser is lenient, so a successful
- * parse does not indicate that the input string was valid JSON. All of the following syntax errors
- * will be ignored:
+ * <p>For best interoperability and performance use JSON that complies with
+ * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
+ * this parser is lenient, so a successful parse does not indicate that the
+ * input string was valid JSON. All of the following syntax errors will be
+ * ignored:
* <ul>
- * <li>End of line comments starting with {@code //} or {@code #} and ending with a newline
- * character.
- * <li>C-style comments starting with {@code /*} and ending with {@code *}{@code /}. Such comments
- * may not be nested.
+ * <li>End of line comments starting with {@code //} or {@code #} and ending
+ * with a newline character.
+ * <li>C-style comments starting with {@code /*} and ending with
+ * {@code *}{@code /}. Such comments may not be nested.
* <li>Strings that are unquoted or {@code 'single quoted'}.
* <li>Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
* <li>Octal integers prefixed with {@code 0}.
* <li>Array elements separated by {@code ;}.
- * <li>Unnecessary array separators. These are interpreted as if null was the omitted value.
+ * <li>Unnecessary array separators. These are interpreted as if null was the
+ * omitted value.
* <li>Key-value pairs separated by {@code =} or {@code =>}.
* <li>Key-value pairs separated by {@code ;}.
* </ul>
*
- * <p>
- * Each tokener may be used to parse a single JSON string. Instances of this class are not thread
- * safe. Although this class is nonfinal, it was not designed for inheritance and should not be
- * subclassed. In particular, self-use by overrideable methods is not specified. See <i>Effective
- * Java</i> Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * <p>Each tokener may be used to parse a single JSON string. Instances of this
+ * class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
* information.
*/
public class JSONTokener {
- /**
- * The input JSON.
- */
- private final String in;
-
- /**
- * The index of the next character to be returned by {@link #next}. When the input is exhausted,
- * this equals the input's length.
- */
- private int pos;
-
- /**
- * @param in JSON encoded string. Null is not permitted and will yield a tokener that throws
- * {@code NullPointerExceptions} when methods are called.
- */
- public JSONTokener(String in) {
- // consume an optional byte order mark (BOM) if it exists
- if (in != null && in.startsWith("\ufeff")) {
- in = in.substring(1);
- }
- this.in = in;
- }
-
- public JSONTokener(Reader input) throws IOException {
- StringBuilder s = new StringBuilder();
- char[] readBuf = new char[102400];
- int n = input.read(readBuf);
- while (n >= 0) {
- s.append(readBuf, 0, n);
- n = input.read(readBuf);
+ /**
+ * The input JSON.
+ */
+ private final String in;
+
+ /**
+ * The index of the next character to be returned by {@link #next}. When
+ * the input is exhausted, this equals the input's length.
+ */
+ private int pos;
+
+ /**
+ * @param in JSON encoded string. Null is not permitted and will yield a
+ * tokener that throws {@code NullPointerExceptions} when methods are
+ * called.
+ */
+ public JSONTokener(String in) {
+ // consume an optional byte order mark (BOM) if it exists
+ if (in != null && in.startsWith("\ufeff")) {
+ in = in.substring(1);
+ }
+ this.in = in;
}
- in = s.toString();
- pos = 0;
- }
-
- /**
- * Returns the next value from the input.
- *
- * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double or
- * {@link JSONObject#NULL}.
- * @throws JSONException if the input is malformed.
- */
- public Object nextValue() throws JSONException {
- int c = nextCleanInternal();
- switch (c) {
- case -1:
- throw syntaxError("End of input");
-
- case '{':
- return readObject();
-
- case '[':
- return readArray();
-
- case '\'':
- case '"':
- return nextString((char) c);
-
- default:
- pos--;
- return readLiteral();
+
+ public JSONTokener(Reader input) throws IOException {
+ StringBuilder s = new StringBuilder();
+ char[] readBuf = new char[102400];
+ int n = input.read(readBuf);
+ while (n >= 0) {
+ s.append(readBuf, 0, n);
+ n = input.read(readBuf);
+ }
+ in = s.toString();
+ pos = 0;
}
- }
-
- private int nextCleanInternal() throws JSONException {
- while (pos < in.length()) {
- int c = in.charAt(pos++);
- switch (c) {
- case '\t':
- case ' ':
- case '\n':
- case '\r':
- continue;
-
- case '/':
- if (pos == in.length()) {
- return c;
- }
-
- char peek = in.charAt(pos);
- switch (peek) {
- case '*':
- // skip a /* c-style comment */
- pos++;
- int commentEnd = in.indexOf("*/", pos);
- if (commentEnd == -1) {
- throw syntaxError("Unterminated comment");
- }
- pos = commentEnd + 2;
- continue;
-
- case '/':
- // skip a // end-of-line comment
- pos++;
- skipToEndOfLine();
- continue;
+
+ /**
+ * Returns the next value from the input.
+ *
+ * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double or {@link JSONObject#NULL}.
+ * @throws JSONException if the input is malformed.
+ */
+ public Object nextValue() throws JSONException {
+ int c = nextCleanInternal();
+ switch (c) {
+ case -1:
+ throw syntaxError("End of input");
+
+ case '{':
+ return readObject();
+
+ case '[':
+ return readArray();
+
+ case '\'':
+ case '"':
+ return nextString((char) c);
default:
- return c;
- }
-
- case '#':
- /*
- * Skip a # hash end-of-line comment. The JSON RFC doesn't specify this behavior, but it's
- * required to parse existing documents. See http://b/2571423.
- */
- skipToEndOfLine();
- continue;
-
- default:
- return c;
- }
+ pos--;
+ return readLiteral();
+ }
}
- return -1;
- }
-
- /**
- * Advances the position until after the next newline character. If the line is terminated by
- * "\r\n", the '\n' must be consumed as whitespace by the caller.
- */
- private void skipToEndOfLine() {
- for (; pos < in.length(); pos++) {
- char c = in.charAt(pos);
- if (c == '\r' || c == '\n') {
- pos++;
- break;
- }
+ private int nextCleanInternal() throws JSONException {
+ while (pos < in.length()) {
+ int c = in.charAt(pos++);
+ switch (c) {
+ case '\t':
+ case ' ':
+ case '\n':
+ case '\r':
+ continue;
+
+ case '/':
+ if (pos == in.length()) {
+ return c;
+ }
+
+ char peek = in.charAt(pos);
+ switch (peek) {
+ case '*':
+ // skip a /* c-style comment */
+ pos++;
+ int commentEnd = in.indexOf("*/", pos);
+ if (commentEnd == -1) {
+ throw syntaxError("Unterminated comment");
+ }
+ pos = commentEnd + 2;
+ continue;
+
+ case '/':
+ // skip a // end-of-line comment
+ pos++;
+ skipToEndOfLine();
+ continue;
+
+ default:
+ return c;
+ }
+
+ case '#':
+ /*
+ * Skip a # hash end-of-line comment. The JSON RFC doesn't
+ * specify this behavior, but it's required to parse
+ * existing documents. See http://b/2571423.
+ */
+ skipToEndOfLine();
+ continue;
+
+ default:
+ return c;
+ }
+ }
+
+ return -1;
}
- }
-
- /**
- * Returns the string up to but not including {@code quote}, unescaping any character escape
- * sequences encountered along the way. The opening quote should have already been read. This
- * consumes the closing quote, but does not include it in the returned string.
- *
- * @param quote either ' or ".
- * @return The unescaped string.
- * @throws JSONException if the string isn't terminated by a closing quote correctly.
- */
- public String nextString(char quote) throws JSONException {
- /*
- * For strings that are free of escape sequences, we can just extract the result as a substring
- * of the input. But if we encounter an escape sequence, we need to use a StringBuilder to
- * compose the result.
+
+ /**
+ * Advances the position until after the next newline character. If the line
+ * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
+ * caller.
*/
- StringBuilder builder = null;
-
- /* the index of the first character not yet appended to the builder. */
- int start = pos;
-
- while (pos < in.length()) {
- int c = in.charAt(pos++);
- if (c == quote) {
- if (builder == null) {
- // a new string avoids leaking memory
- // noinspection RedundantStringConstructorCall
- return new String(in.substring(start, pos - 1));
- } else {
- builder.append(in, start, pos - 1);
- return builder.toString();
+ private void skipToEndOfLine() {
+ for (; pos < in.length(); pos++) {
+ char c = in.charAt(pos);
+ if (c == '\r' || c == '\n') {
+ pos++;
+ break;
+ }
}
- }
+ }
- if (c == '\\') {
- if (pos == in.length()) {
- throw syntaxError("Unterminated escape sequence");
+ /**
+ * Returns the string up to but not including {@code quote}, unescaping any
+ * character escape sequences encountered along the way. The opening quote
+ * should have already been read. This consumes the closing quote, but does
+ * not include it in the returned string.
+ *
+ * @param quote either ' or ".
+ * @return The unescaped string.
+ * @throws JSONException if the string isn't terminated by a closing quote correctly.
+ */
+ public String nextString(char quote) throws JSONException {
+ /*
+ * For strings that are free of escape sequences, we can just extract
+ * the result as a substring of the input. But if we encounter an escape
+ * sequence, we need to use a StringBuilder to compose the result.
+ */
+ StringBuilder builder = null;
+
+ /* the index of the first character not yet appended to the builder. */
+ int start = pos;
+
+ while (pos < in.length()) {
+ int c = in.charAt(pos++);
+ if (c == quote) {
+ if (builder == null) {
+ // a new string avoids leaking memory
+ //noinspection RedundantStringConstructorCall
+ return new String(in.substring(start, pos - 1));
+ } else {
+ builder.append(in, start, pos - 1);
+ return builder.toString();
+ }
+ }
+
+ if (c == '\\') {
+ if (pos == in.length()) {
+ throw syntaxError("Unterminated escape sequence");
+ }
+ if (builder == null) {
+ builder = new StringBuilder();
+ }
+ builder.append(in, start, pos - 1);
+ builder.append(readEscapeCharacter());
+ start = pos;
+ }
}
- if (builder == null) {
- builder = new StringBuilder();
+
+ throw syntaxError("Unterminated string");
+ }
+
+ /**
+ * Unescapes the character identified by the character or characters that
+ * immediately follow a backslash. The backslash '\' should have already
+ * been read. This supports both unicode escapes "u000A" and two-character
+ * escapes "\n".
+ */
+ private char readEscapeCharacter() throws JSONException {
+ char escaped = in.charAt(pos++);
+ switch (escaped) {
+ case 'u':
+ if (pos + 4 > in.length()) {
+ throw syntaxError("Unterminated escape sequence");
+ }
+ String hex = in.substring(pos, pos + 4);
+ pos += 4;
+ try {
+ return (char) Integer.parseInt(hex, 16);
+ } catch (NumberFormatException nfe) {
+ throw syntaxError("Invalid escape sequence: " + hex);
+ }
+
+ case 't':
+ return '\t';
+
+ case 'b':
+ return '\b';
+
+ case 'n':
+ return '\n';
+
+ case 'r':
+ return '\r';
+
+ case 'f':
+ return '\f';
+
+ case '\'':
+ case '"':
+ case '\\':
+ default:
+ return escaped;
}
- builder.append(in, start, pos - 1);
- builder.append(readEscapeCharacter());
- start = pos;
- }
}
- throw syntaxError("Unterminated string");
- }
-
- /**
- * Unescapes the character identified by the character or characters that immediately follow a
- * backslash. The backslash '\' should have already been read. This supports both unicode escapes
- * "u000A" and two-character escapes "\n".
- */
- private char readEscapeCharacter() throws JSONException {
- char escaped = in.charAt(pos++);
- switch (escaped) {
- case 'u':
- if (pos + 4 > in.length()) {
- throw syntaxError("Unterminated escape sequence");
+ /**
+ * Reads a null, boolean, numeric or unquoted string literal value. Numeric
+ * values will be returned as an Integer, Long, or Double, in that order of
+ * preference.
+ */
+ private Object readLiteral() throws JSONException {
+ String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+ if (literal.length() == 0) {
+ throw syntaxError("Expected literal value");
+ } else if ("null".equalsIgnoreCase(literal)) {
+ return JSONObject.NULL;
+ } else if ("true".equalsIgnoreCase(literal)) {
+ return Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(literal)) {
+ return Boolean.FALSE;
+ }
+
+ /* try to parse as an integral type... */
+ if (literal.indexOf('.') == -1) {
+ int base = 10;
+ String number = literal;
+ if (number.startsWith("0x") || number.startsWith("0X")) {
+ number = number.substring(2);
+ base = 16;
+ } else if (number.startsWith("0") && number.length() > 1) {
+ number = number.substring(1);
+ base = 8;
+ }
+ try {
+ long longValue = Long.parseLong(number, base);
+ if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+ return (int) longValue;
+ } else {
+ return longValue;
+ }
+ } catch (NumberFormatException e) {
+ /*
+ * This only happens for integral numbers greater than
+ * Long.MAX_VALUE, numbers in exponential form (5e-10) and
+ * unquoted strings. Fall through to try floating point.
+ */
+ }
}
- String hex = in.substring(pos, pos + 4);
- pos += 4;
+
+ /* ...next try to parse as a floating point... */
try {
- return (char) Integer.parseInt(hex, 16);
- } catch (NumberFormatException nfe) {
- throw syntaxError("Invalid escape sequence: " + hex);
+ return Double.valueOf(literal);
+ } catch (NumberFormatException ignored) {
}
- case 't':
- return '\t';
+ /* ... finally give up. We have an unquoted string */
+ //noinspection RedundantStringConstructorCall
+ return new String(literal); // a new string avoids leaking memory
+ }
- case 'b':
- return '\b';
+ /**
+ * Returns the string up to but not including any of the given characters or
+ * a newline character. This does not consume the excluded character.
+ */
+ private String nextToInternal(String excluded) {
+ int start = pos;
+ for (; pos < in.length(); pos++) {
+ char c = in.charAt(pos);
+ if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+ return in.substring(start, pos);
+ }
+ }
+ return in.substring(start);
+ }
- case 'n':
- return '\n';
+ /**
+ * Reads a sequence of key/value pairs and the trailing closing brace '}' of
+ * an object. The opening brace '{' should have already been read.
+ */
+ private JSONObject readObject() throws JSONException {
+ JSONObject result = new JSONObject();
+
+ /* Peek to see if this is the empty object. */
+ int first = nextCleanInternal();
+ if (first == '}') {
+ return result;
+ } else if (first != -1) {
+ pos--;
+ }
- case 'r':
- return '\r';
+ while (true) {
+ Object name = nextValue();
+ if (!(name instanceof String)) {
+ if (name == null) {
+ throw syntaxError("Names cannot be null");
+ } else {
+ throw syntaxError("Names must be strings, but " + name
+ + " is of type " + name.getClass().getName());
+ }
+ }
+
+ /*
+ * Expect the name/value separator to be either a colon ':', an
+ * equals sign '=', or an arrow "=>". The last two are bogus but we
+ * include them because that's what the original implementation did.
+ */
+ int separator = nextCleanInternal();
+ if (separator != ':' && separator != '=') {
+ throw syntaxError("Expected ':' after " + name);
+ }
+ if (pos < in.length() && in.charAt(pos) == '>') {
+ pos++;
+ }
+
+ result.put((String) name, nextValue());
+
+ switch (nextCleanInternal()) {
+ case '}':
+ return result;
+ case ';':
+ case ',':
+ continue;
+ default:
+ throw syntaxError("Unterminated object");
+ }
+ }
+ }
- case 'f':
- return '\f';
+ /**
+ * Reads a sequence of values and the trailing closing brace ']' of an
+ * array. The opening brace '[' should have already been read. Note that
+ * "[]" yields an empty array, but "[,]" returns a two-element array
+ * equivalent to "[null,null]".
+ */
+ private JSONArray readArray() throws JSONException {
+ JSONArray result = new JSONArray();
+
+ /* to cover input that ends with ",]". */
+ boolean hasTrailingSeparator = false;
+
+ while (true) {
+ switch (nextCleanInternal()) {
+ case -1:
+ throw syntaxError("Unterminated array");
+ case ']':
+ if (hasTrailingSeparator) {
+ result.put(null);
+ }
+ return result;
+ case ',':
+ case ';':
+ /* A separator without a value first means "null". */
+ result.put(null);
+ hasTrailingSeparator = true;
+ continue;
+ default:
+ pos--;
+ }
+
+ result.put(nextValue());
+
+ switch (nextCleanInternal()) {
+ case ']':
+ return result;
+ case ',':
+ case ';':
+ hasTrailingSeparator = true;
+ continue;
+ default:
+ throw syntaxError("Unterminated array");
+ }
+ }
+ }
- case '\'':
- case '"':
- case '\\':
- default:
- return escaped;
+ /**
+ * Returns an exception containing the given message plus the current
+ * position and the entire input string.
+ *
+ * @param message The message we want to include.
+ * @return An exception that we can throw.
+ */
+ public JSONException syntaxError(String message) {
+ return new JSONException(message + this);
}
- }
-
- /**
- * Reads a null, boolean, numeric or unquoted string literal value. Numeric values will be
- * returned as an Integer, Long, or Double, in that order of preference.
- */
- private Object readLiteral() throws JSONException {
- String literal = nextToInternal("{}[]/\\:,=;# \t\f");
-
- if (literal.length() == 0) {
- throw syntaxError("Expected literal value");
- } else if ("null".equalsIgnoreCase(literal)) {
- return JSONObject.NULL;
- } else if ("true".equalsIgnoreCase(literal)) {
- return Boolean.TRUE;
- } else if ("false".equalsIgnoreCase(literal)) {
- return Boolean.FALSE;
+
+ /**
+ * Returns the current position and the entire input string.
+ */
+ @Override
+ public String toString() {
+ // consistent with the original implementation
+ return " at character " + pos + " of " + in;
}
- /* try to parse as an integral type... */
- if (literal.indexOf('.') == -1) {
- int base = 10;
- String number = literal;
- if (number.startsWith("0x") || number.startsWith("0X")) {
- number = number.substring(2);
- base = 16;
- } else if (number.startsWith("0") && number.length() > 1) {
- number = number.substring(1);
- base = 8;
- }
- try {
- long longValue = Long.parseLong(number, base);
- if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
- return (int) longValue;
- } else {
- return longValue;
- }
- } catch (NumberFormatException e) {
- /*
- * This only happens for integral numbers greater than Long.MAX_VALUE, numbers in
- * exponential form (5e-10) and unquoted strings. Fall through to try floating point.
- */
- }
+ /*
+ * Legacy APIs.
+ *
+ * None of the methods below are on the critical path of parsing JSON
+ * documents. They exist only because they were exposed by the original
+ * implementation and may be used by some clients.
+ */
+
+ /**
+ * Returns true until the input has been exhausted.
+ *
+ * @return true if more input exists.
+ */
+ public boolean more() {
+ return pos < in.length();
}
- /* ...next try to parse as a floating point... */
- try {
- return Double.valueOf(literal);
- } catch (NumberFormatException ignored) {
+ /**
+ * Returns the next available character, or the null character '\0' if all
+ * input has been exhausted. The return value of this method is ambiguous
+ * for JSON strings that contain the character '\0'.
+ *
+ * @return the next character.
+ */
+ public char next() {
+ return pos < in.length() ? in.charAt(pos++) : '\0';
}
- /* ... finally give up. We have an unquoted string */
- // noinspection RedundantStringConstructorCall
- return new String(literal); // a new string avoids leaking memory
- }
-
- /**
- * Returns the string up to but not including any of the given characters or a newline character.
- * This does not consume the excluded character.
- */
- private String nextToInternal(String excluded) {
- int start = pos;
- for (; pos < in.length(); pos++) {
- char c = in.charAt(pos);
- if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
- return in.substring(start, pos);
- }
+ /**
+ * Returns the next available character if it equals {@code c}. Otherwise an
+ * exception is thrown.
+ *
+ * @param c The character we are looking for.
+ * @return the next character.
+ * @throws JSONException If the next character isn't {@code c}
+ */
+ public char next(char c) throws JSONException {
+ char result = next();
+ if (result != c) {
+ throw syntaxError("Expected " + c + " but was " + result);
+ }
+ return result;
}
- return in.substring(start);
- }
-
- /**
- * Reads a sequence of key/value pairs and the trailing closing brace '}' of an object. The
- * opening brace '{' should have already been read.
- */
- private JSONObject readObject() throws JSONException {
- JSONObject result = new JSONObject();
-
- /* Peek to see if this is the empty object. */
- int first = nextCleanInternal();
- if (first == '}') {
- return result;
- } else if (first != -1) {
- pos--;
+
+ /**
+ * Returns the next character that is not whitespace and does not belong to
+ * a comment. If the input is exhausted before such a character can be
+ * found, the null character '\0' is returned. The return value of this
+ * method is ambiguous for JSON strings that contain the character '\0'.
+ *
+ * @return The next non-whitespace character.
+ * @throws JSONException Should not be possible.
+ */
+ public char nextClean() throws JSONException {
+ int nextCleanInt = nextCleanInternal();
+ return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
}
- while (true) {
- Object name = nextValue();
- if (!(name instanceof String)) {
- if (name == null) {
- throw syntaxError("Names cannot be null");
- } else {
- throw syntaxError(
- "Names must be strings, but " + name + " is of type " + name.getClass().getName());
+ /**
+ * Returns the next {@code length} characters of the input.
+ *
+ * <p>The returned string shares its backing character array with this
+ * tokener's input string. If a reference to the returned string may be held
+ * indefinitely, you should use {@code new String(result)} to copy it first
+ * to avoid memory leaks.
+ *
+ * @param length The desired number of characters to return.
+ * @return The next few characters.
+ * @throws JSONException if the remaining input is not long enough to
+ * satisfy this request.
+ */
+ public String next(int length) throws JSONException {
+ if (pos + length > in.length()) {
+ throw syntaxError(length + " is out of bounds");
}
- }
-
- /*
- * Expect the name/value separator to be either a colon ':', an equals sign '=', or an arrow
- * "=>". The last two are bogus but we include them because that's what the original
- * implementation did.
- */
- int separator = nextCleanInternal();
- if (separator != ':' && separator != '=') {
- throw syntaxError("Expected ':' after " + name);
- }
- if (pos < in.length() && in.charAt(pos) == '>') {
- pos++;
- }
-
- result.put((String) name, nextValue());
-
- switch (nextCleanInternal()) {
- case '}':
- return result;
- case ';':
- case ',':
- continue;
- default:
- throw syntaxError("Unterminated object");
- }
- }
- }
-
- /**
- * Reads a sequence of values and the trailing closing brace ']' of an array. The opening brace
- * '[' should have already been read. Note that "[]" yields an empty array, but "[,]" returns a
- * two-element array equivalent to "[null,null]".
- */
- private JSONArray readArray() throws JSONException {
- JSONArray result = new JSONArray();
-
- /* to cover input that ends with ",]". */
- boolean hasTrailingSeparator = false;
-
- while (true) {
- switch (nextCleanInternal()) {
- case -1:
- throw syntaxError("Unterminated array");
- case ']':
- if (hasTrailingSeparator) {
- result.put(null);
- }
- return result;
- case ',':
- case ';':
- /* A separator without a value first means "null". */
- result.put(null);
- hasTrailingSeparator = true;
- continue;
- default:
- pos--;
- }
-
- result.put(nextValue());
-
- switch (nextCleanInternal()) {
- case ']':
- return result;
- case ',':
- case ';':
- hasTrailingSeparator = true;
- continue;
- default:
- throw syntaxError("Unterminated array");
- }
+ String result = in.substring(pos, pos + length);
+ pos += length;
+ return result;
}
- }
-
- /**
- * Returns an exception containing the given message plus the current position and the entire
- * input string.
- *
- * @param message The message we want to include.
- * @return An exception that we can throw.
- */
- public JSONException syntaxError(String message) {
- return new JSONException(message + this);
- }
-
- /**
- * Returns the current position and the entire input string.
- */
- @Override
- public String toString() {
- // consistent with the original implementation
- return " at character " + pos + " of " + in;
- }
-
- /*
- * Legacy APIs.
- *
- * None of the methods below are on the critical path of parsing JSON documents. They exist only
- * because they were exposed by the original implementation and may be used by some clients.
- */
-
- /**
- * Returns true until the input has been exhausted.
- *
- * @return true if more input exists.
- */
- public boolean more() {
- return pos < in.length();
- }
-
- /**
- * Returns the next available character, or the null character '\0' if all input has been
- * exhausted. The return value of this method is ambiguous for JSON strings that contain the
- * character '\0'.
- *
- * @return the next character.
- */
- public char next() {
- return pos < in.length() ? in.charAt(pos++) : '\0';
- }
-
- /**
- * Returns the next available character if it equals {@code c}. Otherwise an exception is thrown.
- *
- * @param c The character we are looking for.
- * @return the next character.
- * @throws JSONException If the next character isn't {@code c}
- */
- public char next(char c) throws JSONException {
- char result = next();
- if (result != c) {
- throw syntaxError("Expected " + c + " but was " + result);
+
+ /**
+ * Returns the {@link String#trim trimmed} string holding the characters up
+ * to but not including the first of:
+ * <ul>
+ * <li>any character in {@code excluded}
+ * <li>a newline character '\n'
+ * <li>a carriage return '\r'
+ * </ul>
+ *
+ * <p>The returned string shares its backing character array with this
+ * tokener's input string. If a reference to the returned string may be held
+ * indefinitely, you should use {@code new String(result)} to copy it first
+ * to avoid memory leaks.
+ *
+ * @param excluded The limiting string where the search should stop.
+ * @return a possibly-empty string
+ */
+ public String nextTo(String excluded) {
+ if (excluded == null) {
+ throw new NullPointerException("excluded == null");
+ }
+ return nextToInternal(excluded).trim();
}
- return result;
- }
-
- /**
- * Returns the next character that is not whitespace and does not belong to a comment. If the
- * input is exhausted before such a character can be found, the null character '\0' is returned.
- * The return value of this method is ambiguous for JSON strings that contain the character '\0'.
- *
- * @return The next non-whitespace character.
- * @throws JSONException Should not be possible.
- */
- public char nextClean() throws JSONException {
- int nextCleanInt = nextCleanInternal();
- return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
- }
-
- /**
- * Returns the next {@code length} characters of the input.
- *
- * <p>
- * The returned string shares its backing character array with this tokener's input string. If a
- * reference to the returned string may be held indefinitely, you should use
- * {@code new String(result)} to copy it first to avoid memory leaks.
- *
- * @param length The desired number of characters to return.
- * @return The next few characters.
- * @throws JSONException if the remaining input is not long enough to satisfy this request.
- */
- public String next(int length) throws JSONException {
- if (pos + length > in.length()) {
- throw syntaxError(length + " is out of bounds");
+
+ /**
+ * Equivalent to {@code nextTo(String.valueOf(excluded))}.
+ *
+ * @param excluded The limiting character.
+ * @return a possibly-empty string
+ */
+ public String nextTo(char excluded) {
+ return nextToInternal(String.valueOf(excluded)).trim();
}
- String result = in.substring(pos, pos + length);
- pos += length;
- return result;
- }
-
- /**
- * Returns the {@link String#trim trimmed} string holding the characters up to but not including
- * the first of:
- * <ul>
- * <li>any character in {@code excluded}
- * <li>a newline character '\n'
- * <li>a carriage return '\r'
- * </ul>
- *
- * <p>
- * The returned string shares its backing character array with this tokener's input string. If a
- * reference to the returned string may be held indefinitely, you should use
- * {@code new String(result)} to copy it first to avoid memory leaks.
- *
- * @param excluded The limiting string where the search should stop.
- * @return a possibly-empty string
- */
- public String nextTo(String excluded) {
- if (excluded == null) {
- throw new NullPointerException("excluded == null");
+
+ /**
+ * Advances past all input up to and including the next occurrence of
+ * {@code thru}. If the remaining input doesn't contain {@code thru}, the
+ * input is exhausted.
+ *
+ * @param thru The string to skip over.
+ */
+ public void skipPast(String thru) {
+ int thruStart = in.indexOf(thru, pos);
+ pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
}
- return nextToInternal(excluded).trim();
- }
-
- /**
- * Equivalent to {@code nextTo(String.valueOf(excluded))}.
- *
- * @param excluded The limiting character.
- * @return a possibly-empty string
- */
- public String nextTo(char excluded) {
- return nextToInternal(String.valueOf(excluded)).trim();
- }
-
- /**
- * Advances past all input up to and including the next occurrence of {@code thru}. If the
- * remaining input doesn't contain {@code thru}, the input is exhausted.
- *
- * @param thru The string to skip over.
- */
- public void skipPast(String thru) {
- int thruStart = in.indexOf(thru, pos);
- pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
- }
-
- /**
- * Advances past all input up to but not including the next occurrence of {@code to}. If the
- * remaining input doesn't contain {@code to}, the input is unchanged.
- *
- * @param to The character we want to skip to.
- * @return The value of {@code to} or null.
- */
- public char skipTo(char to) {
- int index = in.indexOf(to, pos);
- if (index != -1) {
- pos = index;
- return to;
- } else {
- return '\0';
+
+ /**
+ * Advances past all input up to but not including the next occurrence of
+ * {@code to}. If the remaining input doesn't contain {@code to}, the input
+ * is unchanged.
+ *
+ * @param to The character we want to skip to.
+ * @return The value of {@code to} or null.
+ */
+ public char skipTo(char to) {
+ int index = in.indexOf(to, pos);
+ if (index != -1) {
+ pos = index;
+ return to;
+ } else {
+ return '\0';
+ }
}
- }
-
- /**
- * Unreads the most recent character of input. If no input characters have been read, the input is
- * unchanged.
- */
- public void back() {
- if (--pos == -1) {
- pos = 0;
+
+ /**
+ * Unreads the most recent character of input. If no input characters have
+ * been read, the input is unchanged.
+ */
+ public void back() {
+ if (--pos == -1) {
+ pos = 0;
+ }
}
- }
-
- /**
- * Returns the integer [0..15] value for the given hex character, or -1 for non-hex input.
- *
- * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other character will yield a -1
- * result.
- * @return The decoded integer.
- */
- public static int dehexchar(char hex) {
- if (hex >= '0' && hex <= '9') {
- return hex - '0';
- } else if (hex >= 'A' && hex <= 'F') {
- return hex - 'A' + 10;
- } else if (hex >= 'a' && hex <= 'f') {
- return hex - 'a' + 10;
- } else {
- return -1;
+
+ /**
+ * Returns the integer [0..15] value for the given hex character, or -1
+ * for non-hex input.
+ *
+ * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
+ * character will yield a -1 result.
+ * @return The decoded integer.
+ */
+ public static int dehexchar(char hex) {
+ if (hex >= '0' && hex <= '9') {
+ return hex - '0';
+ } else if (hex >= 'A' && hex <= 'F') {
+ return hex - 'A' + 10;
+ } else if (hex >= 'a' && hex <= 'f') {
+ return hex - 'a' + 10;
+ } else {
+ return -1;
+ }
}
- }
}
[7/8] geode git commit: Revert "GEODE-2142: Removal of non-compliant
org.json implementation."
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONArray.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONArray.java b/geode-json/src/main/java/org/json/JSONArray.java
old mode 100755
new mode 100644
index 074624d..edaefa4
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,759 +1,868 @@
+package org.json;
+
/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-package org.json;
-
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
-
-// Note: this class was written without inspecting the non-free org.json sourcecode.
+import java.util.Iterator;
+import java.util.Map;
/**
- * A dense indexed sequence of values. Values may be any mix of
- * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
- * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
- * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
- * infinities}, or of any type not listed here.
- *
- * {@code JSONArray} has the same type coercion behavior and
- * optional/mandatory accessors as {@link JSONObject}. See that class'
- * documentation for details.
+ * A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in
+ * square brackets with commas separating the values. The internal form is an object having
+ * <code>get</code> and <code>opt</code> methods for accessing the values by index, and
+ * <code>put</code> methods for adding or replacing values. The values can be any of these types:
+ * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
+ * <code>String</code>, or the <code>JSONObject.NULL object</code>.
+ * <p>
+ * The constructor can convert a JSON text into a Java object. The <code>toString</code> method
+ * converts to JSON text.
+ * <p>
+ * A <code>get</code> method returns a value if one can be found, and throws an exception if one
+ * cannot be found. An <code>opt</code> method returns a default value instead of throwing an
+ * exception, and so is useful for obtaining optional values.
+ * <p>
+ * The generic <code>get()</code> and <code>opt()</code> methods return an object which you can cast
+ * or query for type. There are also typed <code>get</code> and <code>opt</code> methods that do
+ * type checking and type coercion for you.
+ * <p>
+ * The texts produced by the <code>toString</code> methods strictly conform to JSON syntax rules.
+ * The constructors are more forgiving in the texts they will accept:
+ * <ul>
+ * <li>An extra <code>,</code> <small>(comma)</small> may appear just before the closing
+ * bracket.</li>
+ * <li>The <code>null</code> value will be inserted when there is <code>,</code>
+ * <small>(comma)</small> elision.</li>
+ * <li>Strings may be quoted with <code>'</code> <small>(single quote)</small>.</li>
+ * <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
+ * and if they do not contain leading or trailing spaces, and if they do not contain any of these
+ * characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they
+ * are not the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li>
+ * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as well as by
+ * <code>,</code> <small>(comma)</small>.</li>
+ * </ul>
*
- * <strong>Warning:</strong> this class represents null in two incompatible
- * ways: the standard Java {@code null} reference, and the sentinel value {@link
- * JSONObject#NULL}. In particular, {@code get} fails if the requested index
- * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
- *
- * Instances of this class are not thread safe. Although this class is
- * non-final, it was not designed for inheritance and should not be subclassed.
- * In particular, self-use by overridable methods is not specified. See
- * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
- * prohibit it" for further information.
+ * @author JSON.org
+ * @version 2012-04-20
*/
public class JSONArray {
- private final List<Object> values;
-
- /**
- * Creates a {@code JSONArray} with no values.
- */
- public JSONArray() {
- values = new ArrayList<Object>();
- }
-
- /**
- * Creates a new {@code JSONArray} by copying all values from the given
- * collection.
- *
- * @param copyFrom a collection whose values are of supported types.
- * Unsupported values are not permitted and will yield an array in an
- * inconsistent state.
- */
- /* Accept a raw type for API compatibility */
- public JSONArray(Collection<?> copyFrom) {
- this();
- if (copyFrom != null) {
- for (Object aCopyFrom : copyFrom) {
- put(JSONObject.wrap(aCopyFrom));
- }
- }
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the next array in the
- * tokener.
- *
- * @param readFrom a tokener whose nextValue() method will yield a
- * {@code JSONArray}.
- * @throws JSONException if the parse fails or doesn't yield a
- * {@code JSONArray}.
- */
- public JSONArray(JSONTokener readFrom) throws JSONException {
- /*
- * Getting the parser to populate this could get tricky. Instead, just
- * parse to temporary JSONArray and then steal the data from that.
- */
- Object object = readFrom.nextValue();
- if (object instanceof JSONArray) {
- values = ((JSONArray) object).values;
- } else {
- throw JSON.typeMismatch(object, "JSONArray");
- }
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the JSON string.
- *
- * @param json a JSON-encoded string containing an array.
- * @throws JSONException if the parse fails or doesn't yield a {@code
- * JSONArray}.
- */
- public JSONArray(String json) throws JSONException {
- this(new JSONTokener(json));
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the given primitive array.
- *
- * @param array The values to use.
- * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
- */
- public JSONArray(Object array) throws JSONException {
- if (!array.getClass().isArray()) {
- throw new JSONException("Not a primitive array: " + array.getClass());
- }
- final int length = Array.getLength(array);
- values = new ArrayList<Object>(length);
- for (int i = 0; i < length; ++i) {
- put(JSONObject.wrap(Array.get(array, i)));
- }
- }
-
- /**
- * @return Returns the number of values in this array.
- */
- public int length() {
- return values.size();
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(boolean value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this array.
- * @throws JSONException If the value is unacceptable.
- */
- public JSONArray put(double value) throws JSONException {
- values.add(JSON.checkDouble(value));
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(int value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(long value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
- *
- * @param value any collection.
- * @return this array.
- */
- public JSONArray put(Collection<?> value) {
- if (value == null) {
- return put((Object)null);
- }
- values.add(new JSONArray(value));
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
- * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
- * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
- * infinities}. Unsupported values are not permitted and will cause the
- * array to be in an inconsistent state.
- * @return this array.
- */
- public JSONArray put(Object value) {
- values.add(value);
- return this;
- }
-
- /**
- * Same as {@link #put}, with added validity checks.
- *
- * @param value The value to append.
- */
- void checkedPut(Object value) throws JSONException {
- if (value instanceof Number) {
- JSON.checkDouble(((Number) value).doubleValue());
- }
-
- put(value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array
- * to the required length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException This should never happen.
- */
- public JSONArray put(int index, boolean value) throws JSONException {
- return put(index, (Boolean) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array
- * to the required length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this array.
- * @throws JSONException If the value is not a finite value.
- */
- public JSONArray put(int index, double value) throws JSONException {
- return put(index, (Double) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array
- * to the required length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, int value) throws JSONException {
- return put(index, (Integer) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array
- * to the required length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, long value) throws JSONException {
- return put(index, (Long) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray},
- * null padding this array to the required length if necessary. If a value already
- * exists at {@code index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, Collection<?> value) throws JSONException {
- if (value == null) {
- return put(index, (Object)null);
- }
- return put(index, new JSONArray(value));
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array
- * to the required length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
- * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
- * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
- * infinities}.
- * @return this array.
- * @throws JSONException If the value cannot be represented as a finite double value.
- */
- public JSONArray put(int index, Object value) throws JSONException {
- if (value instanceof Number) {
- // deviate from the original by checking all Numbers, not just floats & doubles
- JSON.checkDouble(((Number) value).doubleValue());
- }
- while (values.size() <= index) {
- values.add(null);
- }
- values.set(index, value);
- return this;
- }
-
- /**
- * Returns true if this array has no value at {@code index}, or if its value
- * is the {@code null} reference or {@link JSONObject#NULL}.
- *
- * @param index Which value to check.
- * @return true if the value is null.
- */
- public boolean isNull(int index) {
- Object value = opt(index);
- return value == null || value == JSONObject.NULL;
- }
-
- /**
- * Returns the value at {@code index}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if this array has no value at {@code index}, or if
- * that value is the {@code null} reference. This method returns
- * normally if the value is {@code JSONObject#NULL}.
- */
- public Object get(int index) throws JSONException {
- try {
- Object value = values.get(index);
- if (value == null) {
- throw new JSONException("Value at " + index + " is null.");
- }
- return value;
- } catch (IndexOutOfBoundsException e) {
- throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
- }
- }
-
- /**
- * Returns the value at {@code index}, or null if the array has no value
- * at {@code index}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public Object opt(int index) {
- if (index < 0 || index >= values.size()) {
- return null;
- }
- return values.get(index);
- }
-
- /**
- * Removes and returns the value at {@code index}, or null if the array has no value
- * at {@code index}.
- *
- * @param index Which value to remove.
- * @return The value previously at the specified location.
- */
- public Object remove(int index) {
- if (index < 0 || index >= values.size()) {
- return null;
- }
- return values.remove(index);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can
- * be coerced to a boolean.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or
- * cannot be coerced to a boolean.
- */
- public boolean getBoolean(int index) throws JSONException {
- Object object = get(index);
- Boolean result = JSON.toBoolean(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "boolean");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can
- * be coerced to a boolean. Returns false otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public boolean optBoolean(int index) {
- return optBoolean(index, false);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can
- * be coerced to a boolean. Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback the fallback value to return if no value exists.
- * @return the value at the specified location or the fallback value.
- */
- public boolean optBoolean(int index, boolean fallback) {
- Object object = opt(index);
- Boolean result = JSON.toBoolean(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can
- * be coerced to a double.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or
- * cannot be coerced to a double.
- */
- public double getDouble(int index) throws JSONException {
- Object object = get(index);
- Double result = JSON.toDouble(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "double");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can
- * be coerced to a double. Returns {@code NaN} otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public double optDouble(int index) {
- return optDouble(index, Double.NaN);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can
- * be coerced to a double. Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public double optDouble(int index, double fallback) {
- Object object = opt(index);
- Double result = JSON.toDouble(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or
- * can be coerced to an int.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or
- * cannot be coerced to a int.
- */
- public int getInt(int index) throws JSONException {
- Object object = get(index);
- Integer result = JSON.toInteger(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "int");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or
- * can be coerced to an int. Returns 0 otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public int optInt(int index) {
- return optInt(index, 0);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or
- * can be coerced to an int. Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public int optInt(int index, int fallback) {
- Object object = opt(index);
- Integer result = JSON.toInteger(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or
- * can be coerced to a long.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or
- * cannot be coerced to a long.
- */
- public long getLong(int index) throws JSONException {
- Object object = get(index);
- Long result = JSON.toLong(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "long");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or
- * can be coerced to a long. Returns 0 otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public long optLong(int index) {
- return optLong(index, 0L);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or
- * can be coerced to a long. Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public long optLong(int index, long fallback) {
- Object object = opt(index);
- Long result = JSON.toLong(object);
- return result != null ? result : fallback;
- }
- /**
- * Returns the value at {@code index} if it exists, coercing it if
- * necessary.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if no such value exists.
- */
- public String getString(int index) throws JSONException {
- Object object = get(index);
- String result = JSON.toString(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "String");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists, coercing it if
- * necessary. Returns the empty string if no such value exists.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public String optString(int index) {
- return optString(index, "");
- }
-
- /**
- * Returns the value at {@code index} if it exists, coercing it if
- * necessary. Returns {@code fallback} if no such value exists.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public String optString(int index, String fallback) {
- Object object = opt(index);
- String result = JSON.toString(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONArray}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value doesn't exist or is not a {@code
- * JSONArray}.
- */
- public JSONArray getJSONArray(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONArray) {
- return (JSONArray) object;
+ /**
+ * The arrayList where the JSONArray's properties are kept.
+ */
+ private final ArrayList myArrayList;
+
+
+ /**
+ * Construct an empty JSONArray.
+ */
+ public JSONArray() {
+ this.myArrayList = new ArrayList();
+ }
+
+ /**
+ * Construct a JSONArray from a JSONTokener.
+ *
+ * @param x A JSONTokener
+ * @throws JSONException If there is a syntax error.
+ */
+ public JSONArray(JSONTokener x) throws JSONException {
+ this();
+ if (x.nextClean() != '[') {
+ throw x.syntaxError("A JSONArray text must start with '['");
+ }
+ if (x.nextClean() != ']') {
+ x.back();
+ for (;;) {
+ if (x.nextClean() == ',') {
+ x.back();
+ this.myArrayList.add(JSONObject.NULL);
} else {
- throw JSON.typeMismatch(index, object, "JSONArray");
+ x.back();
+ this.myArrayList.add(x.nextValue());
}
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONArray}. Returns null otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public JSONArray optJSONArray(int index) {
- Object object = opt(index);
- return object instanceof JSONArray ? (JSONArray) object : null;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONObject}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value doesn't exist or is not a {@code
- * JSONObject}.
- */
- public JSONObject getJSONObject(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONObject) {
- return (JSONObject) object;
- } else {
- throw JSON.typeMismatch(index, object, "JSONObject");
- }
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONObject}. Returns null otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public JSONObject optJSONObject(int index) {
- Object object = opt(index);
- return object instanceof JSONObject ? (JSONObject) object : null;
- }
-
- /**
- * Returns a new object whose values are the values in this array, and whose
- * names are the values in {@code names}. Names and values are paired up by
- * index from 0 through to the shorter array's length. Names that are not
- * strings will be coerced to strings. This method returns null if either
- * array is empty.
- *
- * @param names The names to apply to the returned values.
- * @return the newly constructed object.
- * @throws JSONException Should not be possible.
- */
- public JSONObject toJSONObject(JSONArray names) throws JSONException {
- JSONObject result = new JSONObject();
- int length = Math.min(names.length(), values.size());
- if (length == 0) {
- return null;
- }
- for (int i = 0; i < length; i++) {
- String name = JSON.toString(names.opt(i));
- result.put(name, opt(i));
- }
- return result;
- }
-
- /**
- * Returns a new string by alternating this array's values with {@code
- * separator}. This array's string values are quoted and have their special
- * characters escaped. For example, the array containing the strings '12"
- * pizza', 'taco' and 'soda' joined on '+' returns this:
- * <pre>"12\" pizza"+"taco"+"soda"</pre>
- *
- * @param separator The string used to separate the returned values.
- * @return the conjoined values.
- * @throws JSONException Only if there is a coding error.
- */
- public String join(String separator) throws JSONException {
- JSONStringer stringer = new JSONStringer();
- stringer.open(JSONStringer.Scope.NULL, "");
- for (int i = 0, size = values.size(); i < size; i++) {
- if (i > 0) {
- stringer.out.append(separator);
+ switch (x.nextClean()) {
+ case ';':
+ case ',':
+ if (x.nextClean() == ']') {
+ return;
}
- stringer.value(values.get(i));
+ x.back();
+ break;
+ case ']':
+ return;
+ default:
+ throw x.syntaxError("Expected a ',' or ']'");
}
- stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
- return stringer.out.toString();
- }
-
- /**
- * Encodes this array as a compact JSON string, such as:
- * <pre>[94043,90210]</pre>
- *
- * @return The string form of this array.
- */
- @Override
- public String toString() {
- try {
- JSONStringer stringer = new JSONStringer();
- writeTo(stringer);
- return stringer.toString();
- } catch (JSONException e) {
- return null;
+ }
+ }
+ }
+
+
+ /**
+ * Construct a JSONArray from a source JSON text.
+ *
+ * @param source A string that begins with <code>[</code> <small>(left bracket)</small> and
+ * ends with <code>]</code> <small>(right bracket)</small>.
+ * @throws JSONException If there is a syntax error.
+ */
+ public JSONArray(String source) throws JSONException {
+ this(new JSONTokener(source));
+ }
+
+
+ /**
+ * Construct a JSONArray from a Collection.
+ *
+ * @param collection A Collection.
+ */
+ public JSONArray(Collection collection) {
+ this.myArrayList = new ArrayList();
+ if (collection != null) {
+ Iterator iter = collection.iterator();
+ while (iter.hasNext()) {
+ this.myArrayList.add(JSONObject.wrap(iter.next()));
+ }
+ }
+ }
+
+
+ /**
+ * Construct a JSONArray from an array
+ *
+ * @throws JSONException If not an array.
+ */
+ public JSONArray(Object array) throws JSONException {
+ this();
+ if (array.getClass().isArray()) {
+ int length = Array.getLength(array);
+ for (int i = 0; i < length; i += 1) {
+ this.put(JSONObject.wrap(Array.get(array, i)));
+ }
+ } else {
+ throw new JSONException("JSONArray initial value should be a string or collection or array.");
+ }
+ }
+
+
+ /**
+ * Get the object value associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return An object value.
+ * @throws JSONException If there is no value for the index.
+ */
+ public Object get(int index) throws JSONException {
+ Object object = this.opt(index);
+ if (object == null) {
+ throw new JSONException("JSONArray[" + index + "] not found.");
+ }
+ return object;
+ }
+
+
+ /**
+ * Get the boolean value associated with an index. The string values "true" and "false" are
+ * converted to boolean.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return The truth.
+ * @throws JSONException If there is no value for the index or if the value is not convertible to
+ * boolean.
+ */
+ public boolean getBoolean(int index) throws JSONException {
+ Object object = this.get(index);
+ 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 new JSONException("JSONArray[" + index + "] is not a boolean.");
+ }
+
+
+ /**
+ * Get the double value associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return The value.
+ * @throws JSONException If the key is not found or if the value cannot be converted to a number.
+ */
+ public double getDouble(int index) throws JSONException {
+ Object object = this.get(index);
+ try {
+ return object instanceof Number ? ((Number) object).doubleValue()
+ : Double.parseDouble((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONArray[" + index + "] is not a number.");
+ }
+ }
+
+
+ /**
+ * Get the int value associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return The value.
+ * @throws JSONException If the key is not found or if the value is not a number.
+ */
+ public int getInt(int index) throws JSONException {
+ Object object = this.get(index);
+ try {
+ return object instanceof Number ? ((Number) object).intValue()
+ : Integer.parseInt((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONArray[" + index + "] is not a number.");
+ }
+ }
+
+
+ /**
+ * Get the JSONArray associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return A JSONArray value.
+ * @throws JSONException If there is no value for the index. or if the value is not a JSONArray
+ */
+ public JSONArray getJSONArray(int index) throws JSONException {
+ Object object = this.get(index);
+ if (object instanceof JSONArray) {
+ return (JSONArray) object;
+ }
+ throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
+ }
+
+
+ /**
+ * Get the JSONObject associated with an index.
+ *
+ * @param index subscript
+ * @return A JSONObject value.
+ * @throws JSONException If there is no value for the index or if the value is not a JSONObject
+ */
+ public JSONObject getJSONObject(int index) throws JSONException {
+ Object object = this.get(index);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
+ }
+ throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
+ }
+
+
+ /**
+ * Get the long value associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return The value.
+ * @throws JSONException If the key is not found or if the value cannot be converted to a number.
+ */
+ public long getLong(int index) throws JSONException {
+ Object object = this.get(index);
+ try {
+ return object instanceof Number ? ((Number) object).longValue()
+ : Long.parseLong((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONArray[" + index + "] is not a number.");
+ }
+ }
+
+
+ /**
+ * Get the string associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return A string value.
+ * @throws JSONException If there is no string value for the index.
+ */
+ public String getString(int index) throws JSONException {
+ Object object = this.get(index);
+ if (object instanceof String) {
+ return (String) object;
+ }
+ throw new JSONException("JSONArray[" + index + "] not a string.");
+ }
+
+
+ /**
+ * Determine if the value is null.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return true if the value at the index is null, or if there is no value.
+ */
+ public boolean isNull(int index) {
+ return JSONObject.NULL.equals(this.opt(index));
+ }
+
+
+ /**
+ * Make a string from the contents of this JSONArray. The <code>separator</code> string is
+ * inserted between each element. Warning: This method assumes that the data structure is
+ * acyclical.
+ *
+ * @param separator A string that will be inserted between the elements.
+ * @return a string.
+ * @throws JSONException If the array contains an invalid number.
+ */
+ public String join(String separator) throws JSONException {
+ int len = this.length();
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < len; i += 1) {
+ if (i > 0) {
+ sb.append(separator);
+ }
+ sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * Get the number of elements in the JSONArray, included nulls.
+ *
+ * @return The length (or size).
+ */
+ public int length() {
+ return this.myArrayList.size();
+ }
+
+
+ /**
+ * Get the optional object value associated with an index.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return An object value, or null if there is no object at that index.
+ */
+ public Object opt(int index) {
+ return (index < 0 || index >= this.length()) ? null : this.myArrayList.get(index);
+ }
+
+
+ /**
+ * Get the optional boolean value associated with an index. It returns false if there is no value
+ * at that index, or if the value is not Boolean.TRUE or the String "true".
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return The truth.
+ */
+ public boolean optBoolean(int index) {
+ return this.optBoolean(index, false);
+ }
+
+
+ /**
+ * Get the optional boolean value associated with an index. It returns the defaultValue if there
+ * is no value at that index or if it is not a Boolean or the String "true" or "false" (case
+ * insensitive).
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @param defaultValue A boolean default.
+ * @return The truth.
+ */
+ public boolean optBoolean(int index, boolean defaultValue) {
+ try {
+ return this.getBoolean(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+
+ /**
+ * 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 index The index must be between 0 and length() - 1.
+ * @return The value.
+ */
+ public double optDouble(int index) {
+ return this.optDouble(index, Double.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 index subscript
+ * @param defaultValue The default value.
+ * @return The value.
+ */
+ public double optDouble(int index, double defaultValue) {
+ try {
+ return this.getDouble(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+
+ /**
+ * Get the optional int value associated with an index. Zero 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 index The index must be between 0 and length() - 1.
+ * @return The value.
+ */
+ public int optInt(int index) {
+ return this.optInt(index, 0);
+ }
+
+
+ /**
+ * Get the optional int 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 index The index must be between 0 and length() - 1.
+ * @param defaultValue The default value.
+ * @return The value.
+ */
+ public int optInt(int index, int defaultValue) {
+ try {
+ return this.getInt(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+
+ /**
+ * Get the optional JSONArray associated with an index.
+ *
+ * @param index subscript
+ * @return A JSONArray value, or null if the index has no value, or if the value is not a
+ * JSONArray.
+ */
+ public JSONArray optJSONArray(int index) {
+ Object o = this.opt(index);
+ return o instanceof JSONArray ? (JSONArray) o : null;
+ }
+
+
+ /**
+ * Get the optional JSONObject associated with an index. Null is returned if the key is not found,
+ * or null if the index has no value, or if the value is not a JSONObject.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return A JSONObject value.
+ */
+ public JSONObject optJSONObject(int index) {
+ Object o = this.opt(index);
+ return o instanceof JSONObject ? (JSONObject) o : null;
+ }
+
+
+ /**
+ * Get the optional long value associated with an index. Zero 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 index The index must be between 0 and length() - 1.
+ * @return The value.
+ */
+ public long optLong(int index) {
+ return this.optLong(index, 0);
+ }
+
+
+ /**
+ * Get the optional long 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 index The index must be between 0 and length() - 1.
+ * @param defaultValue The default value.
+ * @return The value.
+ */
+ public long optLong(int index, long defaultValue) {
+ try {
+ return this.getLong(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+
+ /**
+ * Get the optional string value associated with an index. It returns an empty string if there is
+ * no value at that index. If the value is not a string and is not null, then it is coverted to a
+ * string.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @return A String value.
+ */
+ public String optString(int index) {
+ return this.optString(index, "");
+ }
+
+
+ /**
+ * Get the optional string associated with an index. The defaultValue is returned if the key is
+ * not found.
+ *
+ * @param index The index must be between 0 and length() - 1.
+ * @param defaultValue The default value.
+ * @return A String value.
+ */
+ public String optString(int index, String defaultValue) {
+ Object object = this.opt(index);
+ return JSONObject.NULL.equals(object) ? defaultValue : object.toString();
+ }
+
+
+ /**
+ * Append a boolean value. This increases the array's length by one.
+ *
+ * @param value A boolean value.
+ * @return this.
+ */
+ public JSONArray put(boolean value) {
+ this.put(value ? Boolean.TRUE : Boolean.FALSE);
+ return this;
+ }
+
+
+ /**
+ * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a
+ * Collection.
+ *
+ * @param value A Collection value.
+ * @return this.
+ */
+ public JSONArray put(Collection value) {
+ this.put(new JSONArray(value));
+ return this;
+ }
+
+
+ /**
+ * Append a double value. This increases the array's length by one.
+ *
+ * @param value A double value.
+ * @throws JSONException if the value is not finite.
+ * @return this.
+ */
+ public JSONArray put(double value) throws JSONException {
+ Double d = new Double(value);
+ JSONObject.testValidity(d);
+ this.put(d);
+ return this;
+ }
+
+
+ /**
+ * Append an int value. This increases the array's length by one.
+ *
+ * @param value An int value.
+ * @return this.
+ */
+ public JSONArray put(int value) {
+ this.put(new Integer(value));
+ return this;
+ }
+
+
+ /**
+ * Append an long value. This increases the array's length by one.
+ *
+ * @param value A long value.
+ * @return this.
+ */
+ public JSONArray put(long value) {
+ this.put(new Long(value));
+ return this;
+ }
+
+
+ /**
+ * Put a value in the JSONArray, where the value will be a JSONObject which is produced from a
+ * Map.
+ *
+ * @param value A Map value.
+ * @return this.
+ */
+ public JSONArray put(Map value) {
+ this.put(new JSONObject(value));
+ return this;
+ }
+
+
+ /**
+ * Append an object value. This increases the array's length by one.
+ *
+ * @param value An object value. The value should be a Boolean, Double, Integer, JSONArray,
+ * JSONObject, Long, or String, or the JSONObject.NULL object.
+ * @return this.
+ */
+ public JSONArray put(Object value) {
+ this.myArrayList.add(value);
+ return this;
+ }
+
+
+ /**
+ * Put or replace a boolean value in the JSONArray. If the index is greater than the length of the
+ * JSONArray, then null elements will be added as necessary to pad it out.
+ *
+ * @param index The subscript.
+ * @param value A boolean value.
+ * @return this.
+ * @throws JSONException If the index is negative.
+ */
+ public JSONArray put(int index, boolean value) throws JSONException {
+ this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
+ return this;
+ }
+
+
+ /**
+ * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a
+ * Collection.
+ *
+ * @param index The subscript.
+ * @param value A Collection value.
+ * @return this.
+ * @throws JSONException If the index is negative or if the value is not finite.
+ */
+ public JSONArray put(int index, Collection value) throws JSONException {
+ this.put(index, new JSONArray(value));
+ return this;
+ }
+
+
+ /**
+ * Put or replace a double value. If the index is greater than the length of the JSONArray, then
+ * null elements will be added as necessary to pad it out.
+ *
+ * @param index The subscript.
+ * @param value A double value.
+ * @return this.
+ * @throws JSONException If the index is negative or if the value is not finite.
+ */
+ public JSONArray put(int index, double value) throws JSONException {
+ this.put(index, new Double(value));
+ return this;
+ }
+
+
+ /**
+ * Put or replace an int value. If the index is greater than the length of the JSONArray, then
+ * null elements will be added as necessary to pad it out.
+ *
+ * @param index The subscript.
+ * @param value An int value.
+ * @return this.
+ * @throws JSONException If the index is negative.
+ */
+ public JSONArray put(int index, int value) throws JSONException {
+ this.put(index, new Integer(value));
+ return this;
+ }
+
+
+ /**
+ * Put or replace a long value. If the index is greater than the length of the JSONArray, then
+ * null elements will be added as necessary to pad it out.
+ *
+ * @param index The subscript.
+ * @param value A long value.
+ * @return this.
+ * @throws JSONException If the index is negative.
+ */
+ public JSONArray put(int index, long value) throws JSONException {
+ this.put(index, new Long(value));
+ return this;
+ }
+
+
+ /**
+ * Put a value in the JSONArray, where the value will be a JSONObject that is produced from a Map.
+ *
+ * @param index The subscript.
+ * @param value The Map value.
+ * @return this.
+ * @throws JSONException If the index is negative or if the the value is an invalid number.
+ */
+ public JSONArray put(int index, Map value) throws JSONException {
+ this.put(index, new JSONObject(value));
+ return this;
+ }
+
+
+ /**
+ * Put or replace an object value in the JSONArray. If the index is greater than the length of the
+ * JSONArray, then null elements will be added as necessary to pad it out.
+ *
+ * @param index The subscript.
+ * @param value The value to put into the array. The value should be a Boolean, Double, Integer,
+ * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
+ * @return this.
+ * @throws JSONException If the index is negative or if the the value is an invalid number.
+ */
+ public JSONArray put(int index, Object value) throws JSONException {
+ JSONObject.testValidity(value);
+ if (index < 0) {
+ throw new JSONException("JSONArray[" + index + "] not found.");
+ }
+ if (index < this.length()) {
+ this.myArrayList.set(index, value);
+ } else {
+ while (index != this.length()) {
+ this.put(JSONObject.NULL);
+ }
+ this.put(value);
+ }
+ return this;
+ }
+
+
+ /**
+ * Remove an index and close the hole.
+ *
+ * @param index The index of the element to be removed.
+ * @return The value that was associated with the index, or null if there was no value.
+ */
+ public Object remove(int index) {
+ Object o = this.opt(index);
+ this.myArrayList.remove(index);
+ return o;
+ }
+
+
+ /**
+ * Produce a JSONObject by combining a JSONArray of names with the values of this JSONArray.
+ *
+ * @param names A JSONArray containing a list of key strings. These will be paired with the
+ * values.
+ * @return A JSONObject, or null if there are no names or if this JSONArray has no values.
+ * @throws JSONException If any of the names are null.
+ */
+ public JSONObject toJSONObject(JSONArray names) throws JSONException {
+ if (names == null || names.length() == 0 || this.length() == 0) {
+ return null;
+ }
+ JSONObject jo = new JSONObject();
+ for (int i = 0; i < names.length(); i += 1) {
+ jo.put(names.getString(i), this.opt(i));
+ }
+ return jo;
+ }
+
+
+ /**
+ * Make a JSON text of this JSONArray. For compactness, no unnecessary whitespace is added. If it
+ * is not possible to produce a syntactically correct JSON text then null will be returned
+ * instead. This could occur if the array contains an invalid number.
+ * <p>
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ * @return a printable, displayable, transmittable representation of the array.
+ */
+ public String toString() {
+ try {
+ return '[' + this.join(",") + ']';
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Make a prettyprinted JSON text of this JSONArray. 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, transmittable representation of the object, beginning with
+ * <code>[</code> <small>(left bracket)</small> and ending with
+ * <code>]</code> <small>(right bracket)</small>.
+ * @throws JSONException
+ */
+ public String toString(int indentFactor) throws JSONException {
+ StringWriter sw = new StringWriter();
+ synchronized (sw.getBuffer()) {
+ return this.write(sw, indentFactor, 0).toString();
+ }
+ }
+
+ /**
+ * Write the contents of the JSONArray as JSON text to a writer. For compactness, no whitespace is
+ * added.
+ * <p>
+ * 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 JSONArray as JSON text to a writer. For compactness, no whitespace is
+ * added.
+ * <p>
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ * @param indentFactor The number of spaces to add to each level of indentation.
+ * @param indent The indention of the top level.
+ * @return The writer.
+ * @throws JSONException
+ */
+ Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
+ try {
+ boolean commanate = false;
+ int length = this.length();
+ writer.write('[');
+
+ if (length == 1) {
+ JSONObject.writeValue(writer, this.myArrayList.get(0), indentFactor, indent);
+ } else if (length != 0) {
+ final int newindent = indent + indentFactor;
+
+ for (int i = 0; i < length; i += 1) {
+ if (commanate) {
+ writer.write(',');
+ }
+ if (indentFactor > 0) {
+ writer.write('\n');
+ }
+ JSONObject.indent(writer, newindent);
+ JSONObject.writeValue(writer, this.myArrayList.get(i), indentFactor, newindent);
+ commanate = true;
}
- }
-
- /**
- * Encodes this array as a human readable JSON string for debugging, such
- * as:
- * <pre>
- * [
- * 94043,
- * 90210
- * ]</pre>
- *
- * @param indentSpaces the number of spaces to indent for each level of
- * nesting.
- * @return The string form of this array.
- * @throws JSONException Only if there is a coding error.
- */
- public String toString(int indentSpaces) throws JSONException {
- JSONStringer stringer = new JSONStringer(indentSpaces);
- writeTo(stringer);
- return stringer.toString();
- }
-
- void writeTo(JSONStringer stringer) throws JSONException {
- stringer.array();
- for (Object value : values) {
- stringer.value(value);
+ if (indentFactor > 0) {
+ writer.write('\n');
}
- stringer.endArray();
- }
-
- @Override
- public boolean equals(Object o) {
- return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
- }
-
- @Override
- public int hashCode() {
- // diverge from the original, which doesn't implement hashCode
- return values.hashCode();
- }
+ JSONObject.indent(writer, indent);
+ }
+ writer.write(']');
+ return writer;
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONException.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONException.java b/geode-json/src/main/java/org/json/JSONException.java
index 1292e86..b65efe2 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,57 +1,30 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package org.json;
-// Note: this class was written without inspecting the non-free org.json sourcecode.
-
/**
- * Thrown to indicate a problem with the JSON API. Such problems include:
- * <ul>
- * <li>Attempts to parse or construct malformed documents
- * <li>Use of null as a name
- * <li>Use of numeric types not available to JSON, such as {@link
- * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
- * <li>Lookups using an out of range index or nonexistent name
- * <li>Type mismatches on lookups
- * </ul>
- *
- * <p>Although this is a checked exception, it is rarely recoverable. Most
- * callers should simply wrap this exception in an unchecked exception and
- * rethrow:
- * <pre> public JSONArray toJSONObject() {
- * try {
- * JSONObject result = new JSONObject();
- * ...
- * } catch (JSONException e) {
- * throw new RuntimeException(e);
- * }
- * }</pre>
+ * The JSONException is thrown by the JSON.org classes when things are amiss.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
*/
-public class JSONException extends RuntimeException {
+public class JSONException extends Exception {
+ private static final long serialVersionUID = 0;
+ private Throwable cause;
- public JSONException(String s) {
- super(s);
- }
+ /**
+ * Constructs a JSONException with an explanatory message.
+ *
+ * @param message Detail about the reason for the exception.
+ */
+ public JSONException(String message) {
+ super(message);
+ }
- public JSONException(Throwable cause) {
- super(cause);
- }
+ public JSONException(Throwable cause) {
+ super(cause.getMessage());
+ this.cause = cause;
+ }
- public JSONException(String message, Throwable cause) {
- super(message, cause);
- }
+ public Throwable getCause() {
+ return this.cause;
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONML.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONML.java b/geode-json/src/main/java/org/json/JSONML.java
new file mode 100755
index 0000000..b535614
--- /dev/null
+++ b/geode-json/src/main/java/org/json/JSONML.java
@@ -0,0 +1,454 @@
+package org.json;
+
+/*
+ * Copyright (c) 2008 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import java.util.Iterator;
+
+
+/**
+ * This provides static methods to convert an XML text into a JSONArray or JSONObject, and to covert
+ * a JSONArray or JSONObject into an XML text using the JsonML transform.
+ *
+ * @author JSON.org
+ * @version 2012-03-28
+ */
+public class JSONML {
+
+ /**
+ * Parse XML values and store them in a JSONArray.
+ *
+ * @param x The XMLTokener containing the source string.
+ * @param arrayForm true if array form, false if object form.
+ * @param ja The JSONArray that is containing the current tag or null if we are at the outermost
+ * level.
+ * @return A JSONArray if the value is the outermost tag, otherwise null.
+ * @throws JSONException
+ */
+ private static Object parse(XMLTokener x, boolean arrayForm, JSONArray ja) throws JSONException {
+ String attribute;
+ char c;
+ String closeTag = null;
+ int i;
+ JSONArray newja = null;
+ JSONObject newjo = null;
+ Object token;
+ String tagName = null;
+
+ // Test for and skip past these forms:
+ // <!-- ... -->
+ // <![ ... ]]>
+ // <! ... >
+ // <? ... ?>
+
+ while (true) {
+ if (!x.more()) {
+ throw x.syntaxError("Bad XML");
+ }
+ token = x.nextContent();
+ if (token == XML.LT) {
+ token = x.nextToken();
+ if (token instanceof Character) {
+ if (token == XML.SLASH) {
+
+ // Close tag </
+
+ token = x.nextToken();
+ if (!(token instanceof String)) {
+ throw new JSONException("Expected a closing name instead of '" + token + "'.");
+ }
+ if (x.nextToken() != XML.GT) {
+ throw x.syntaxError("Misshaped close tag");
+ }
+ return token;
+ } else if (token == XML.BANG) {
+
+ // <!
+
+ c = x.next();
+ if (c == '-') {
+ if (x.next() == '-') {
+ x.skipPast("-->");
+ } else {
+ x.back();
+ }
+ } else if (c == '[') {
+ token = x.nextToken();
+ if (token.equals("CDATA") && x.next() == '[') {
+ if (ja != null) {
+ ja.put(x.nextCDATA());
+ }
+ } else {
+ throw x.syntaxError("Expected 'CDATA['");
+ }
+ } else {
+ i = 1;
+ do {
+ token = x.nextMeta();
+ if (token == null) {
+ throw x.syntaxError("Missing '>' after '<!'.");
+ } else if (token == XML.LT) {
+ i += 1;
+ } else if (token == XML.GT) {
+ i -= 1;
+ }
+ } while (i > 0);
+ }
+ } else if (token == XML.QUEST) {
+
+ // <?
+
+ x.skipPast("?>");
+ } else {
+ throw x.syntaxError("Misshaped tag");
+ }
+
+ // Open tag <
+
+ } else {
+ if (!(token instanceof String)) {
+ throw x.syntaxError("Bad tagName '" + token + "'.");
+ }
+ tagName = (String) token;
+ newja = new JSONArray();
+ newjo = new JSONObject();
+ if (arrayForm) {
+ newja.put(tagName);
+ if (ja != null) {
+ ja.put(newja);
+ }
+ } else {
+ newjo.put("tagName", tagName);
+ if (ja != null) {
+ ja.put(newjo);
+ }
+ }
+ token = null;
+ for (;;) {
+ if (token == null) {
+ token = x.nextToken();
+ }
+ if (token == null) {
+ throw x.syntaxError("Misshaped tag");
+ }
+ if (!(token instanceof String)) {
+ break;
+ }
+
+ // attribute = value
+
+ attribute = (String) token;
+ if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
+ throw x.syntaxError("Reserved attribute.");
+ }
+ token = x.nextToken();
+ if (token == XML.EQ) {
+ token = x.nextToken();
+ if (!(token instanceof String)) {
+ throw x.syntaxError("Missing value");
+ }
+ newjo.accumulate(attribute, XML.stringToValue((String) token));
+ token = null;
+ } else {
+ newjo.accumulate(attribute, "");
+ }
+ }
+ if (arrayForm && newjo.length() > 0) {
+ newja.put(newjo);
+ }
+
+ // Empty tag <.../>
+
+ if (token == XML.SLASH) {
+ if (x.nextToken() != XML.GT) {
+ throw x.syntaxError("Misshaped tag");
+ }
+ if (ja == null) {
+ if (arrayForm) {
+ return newja;
+ } else {
+ return newjo;
+ }
+ }
+
+ // Content, between <...> and </...>
+
+ } else {
+ if (token != XML.GT) {
+ throw x.syntaxError("Misshaped tag");
+ }
+ closeTag = (String) parse(x, arrayForm, newja);
+ if (closeTag != null) {
+ if (!closeTag.equals(tagName)) {
+ throw x.syntaxError("Mismatched '" + tagName + "' and '" + closeTag + "'");
+ }
+ tagName = null;
+ if (!arrayForm && newja.length() > 0) {
+ newjo.put("childNodes", newja);
+ }
+ if (ja == null) {
+ if (arrayForm) {
+ return newja;
+ } else {
+ return newjo;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (ja != null) {
+ ja.put(token instanceof String ? XML.stringToValue((String) token) : token);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML
+ * transform. Each XML tag is represented as a JSONArray in which the first element is the tag
+ * name. If the tag has attributes, then the second element will be JSONObject containing the
+ * name/value pairs. If the tag contains children, then strings and JSONArrays will represent the
+ * child tags. Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
+ *
+ * @param string The source string.
+ * @return A JSONArray containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(String string) throws JSONException {
+ return toJSONArray(new XMLTokener(string));
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML
+ * transform. Each XML tag is represented as a JSONArray in which the first element is the tag
+ * name. If the tag has attributes, then the second element will be JSONObject containing the
+ * name/value pairs. If the tag contains children, then strings and JSONArrays will represent the
+ * child content and tags. Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
+ *
+ * @param x An XMLTokener.
+ * @return A JSONArray containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
+ return (JSONArray) parse(x, true, null);
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML
+ * transform. Each XML tag is represented as a JSONObject with a "tagName" property. If the tag
+ * has attributes, then the attributes will be in the JSONObject as properties. If the tag
+ * contains children, the object will have a "childNodes" property which will be an array of
+ * strings and JsonML JSONObjects.
+ *
+ * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
+ *
+ * @param x An XMLTokener of the XML source text.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
+ return (JSONObject) parse(x, false, null);
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML
+ * transform. Each XML tag is represented as a JSONObject with a "tagName" property. If the tag
+ * has attributes, then the attributes will be in the JSONObject as properties. If the tag
+ * contains children, the object will have a "childNodes" property which will be an array of
+ * strings and JsonML JSONObjects.
+ *
+ * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
+ *
+ * @param string The XML source text.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ return toJSONObject(new XMLTokener(string));
+ }
+
+
+ /**
+ * Reverse the JSONML transformation, making an XML text from a JSONArray.
+ *
+ * @param ja A JSONArray.
+ * @return An XML string.
+ * @throws JSONException
+ */
+ public static String toString(JSONArray ja) throws JSONException {
+ int i;
+ JSONObject jo;
+ String key;
+ Iterator keys;
+ int length;
+ Object object;
+ StringBuffer sb = new StringBuffer();
+ String tagName;
+ String value;
+
+ // Emit <tagName
+
+ tagName = ja.getString(0);
+ XML.noSpace(tagName);
+ tagName = XML.escape(tagName);
+ sb.append('<');
+ sb.append(tagName);
+
+ object = ja.opt(1);
+ if (object instanceof JSONObject) {
+ i = 2;
+ jo = (JSONObject) object;
+
+ // Emit the attributes
+
+ keys = jo.keys();
+ while (keys.hasNext()) {
+ key = keys.next().toString();
+ XML.noSpace(key);
+ value = jo.optString(key);
+ if (value != null) {
+ sb.append(' ');
+ sb.append(XML.escape(key));
+ sb.append('=');
+ sb.append('"');
+ sb.append(XML.escape(value));
+ sb.append('"');
+ }
+ }
+ } else {
+ i = 1;
+ }
+
+ // Emit content in body
+
+ length = ja.length();
+ if (i >= length) {
+ sb.append('/');
+ sb.append('>');
+ } else {
+ sb.append('>');
+ do {
+ object = ja.get(i);
+ i += 1;
+ if (object != null) {
+ if (object instanceof String) {
+ sb.append(XML.escape(object.toString()));
+ } else if (object instanceof JSONObject) {
+ sb.append(toString((JSONObject) object));
+ } else if (object instanceof JSONArray) {
+ sb.append(toString((JSONArray) object));
+ }
+ }
+ } while (i < length);
+ sb.append('<');
+ sb.append('/');
+ sb.append(tagName);
+ sb.append('>');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Reverse the JSONML transformation, making an XML text from a JSONObject. The JSONObject must
+ * contain a "tagName" property. If it has children, then it must have a "childNodes" property
+ * containing an array of objects. The other properties are attributes with string values.
+ *
+ * @param jo A JSONObject.
+ * @return An XML string.
+ * @throws JSONException
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ int i;
+ JSONArray ja;
+ String key;
+ Iterator keys;
+ int length;
+ Object object;
+ String tagName;
+ String value;
+
+ // Emit <tagName
+
+ tagName = jo.optString("tagName");
+ if (tagName == null) {
+ return XML.escape(jo.toString());
+ }
+ XML.noSpace(tagName);
+ tagName = XML.escape(tagName);
+ sb.append('<');
+ sb.append(tagName);
+
+ // Emit the attributes
+
+ keys = jo.keys();
+ while (keys.hasNext()) {
+ key = keys.next().toString();
+ if (!"tagName".equals(key) && !"childNodes".equals(key)) {
+ XML.noSpace(key);
+ value = jo.optString(key);
+ if (value != null) {
+ sb.append(' ');
+ sb.append(XML.escape(key));
+ sb.append('=');
+ sb.append('"');
+ sb.append(XML.escape(value));
+ sb.append('"');
+ }
+ }
+ }
+
+ // Emit content in body
+
+ ja = jo.optJSONArray("childNodes");
+ if (ja == null) {
+ sb.append('/');
+ sb.append('>');
+ } else {
+ sb.append('>');
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ object = ja.get(i);
+ if (object != null) {
+ if (object instanceof String) {
+ sb.append(XML.escape(object.toString()));
+ } else if (object instanceof JSONObject) {
+ sb.append(toString((JSONObject) object));
+ } else if (object instanceof JSONArray) {
+ sb.append(toString((JSONArray) object));
+ } else {
+ sb.append(object.toString());
+ }
+ }
+ }
+ sb.append('<');
+ sb.append('/');
+ sb.append(tagName);
+ sb.append('>');
+ }
+ return sb.toString();
+ }
+}
[6/8] geode git commit: Revert "GEODE-2142: Removal of non-compliant
org.json implementation."
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONObject.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONObject.java b/geode-json/src/main/java/org/json/JSONObject.java
index d5de19f..a2c6d8b 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,1005 +1,1525 @@
+package org.json;
+
/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-package org.json;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.Locale;
import java.util.Map;
+import java.util.ResourceBundle;
import java.util.Set;
-import java.util.TreeMap;
-
-// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * A modifiable set of name/value mappings. Names are unique, non-null strings.
- * Values may be any mix of {@link JSONObject JSONObjects}, {@link JSONArray
- * JSONArrays}, Strings, Booleans, Integers, Longs, Doubles or {@link #NULL}.
- * Values may not be {@code null}, {@link Double#isNaN() NaNs}, {@link
- * Double#isInfinite() infinities}, or of any type not listed here.
+ * A JSONObject is an unordered collection of name/value pairs. Its external form is a string
+ * wrapped in curly braces with colons between the names and values, and commas between the values
+ * and names. The internal form is an object having <code>get</code> and <code>opt</code> methods
+ * for accessing the values by name, and <code>put</code> methods for adding or replacing values by
+ * name. The values can be any of these types: <code>Boolean</code>, <code>JSONArray</code>,
+ * <code>JSONObject</code>, <code>Number</code>, <code>String</code>, or the
+ * <code>JSONObject.NULL</code> object. A JSONObject constructor can be used to convert an external
+ * form JSON text into an internal form whose values can be retrieved with the <code>get</code> and
+ * <code>opt</code> methods, or to convert values into a JSON text using the <code>put</code> and
+ * <code>toString</code> methods. A <code>get</code> method returns a value if one can be found, and
+ * throws an exception if one cannot be found. An <code>opt</code> method returns a default value
+ * instead of throwing an exception, and so is useful for obtaining optional values.
+ * <p>
+ * The generic <code>get()</code> and <code>opt()</code> methods return an object, which you can
+ * cast or query for type. There are also typed <code>get</code> and <code>opt</code> methods that
+ * do type checking and type coercion for you. The opt methods differ from the get methods in that
+ * they do not throw. Instead, they return a specified value, such as null.
+ * <p>
+ * The <code>put</code> methods add or replace values in an object. For example,
*
- * <p>This class can coerce values to another type when requested.
- * <ul>
- * <li>When the requested type is a boolean, strings will be coerced using a
- * case-insensitive comparison to "true" and "false".
- * <li>When the requested type is a double, other {@link Number} types will
- * be coerced using {@link Number#doubleValue() doubleValue}. Strings
- * that can be coerced using {@link Double#valueOf(String)} will be.
- * <li>When the requested type is an int, other {@link Number} types will
- * be coerced using {@link Number#intValue() intValue}. Strings
- * that can be coerced using {@link Double#valueOf(String)} will be,
- * and then cast to int.
- * <li><a name="lossy">When the requested type is a long, other {@link Number} types will
- * be coerced using {@link Number#longValue() longValue}. Strings
- * that can be coerced using {@link Double#valueOf(String)} will be,
- * and then cast to long. This two-step conversion is lossy for very
- * large values. For example, the string "9223372036854775806" yields the
- * long 9223372036854775807.</a>
- * <li>When the requested type is a String, other non-null values will be
- * coerced using {@link String#valueOf(Object)}. Although null cannot be
- * coerced, the sentinel value {@link JSONObject#NULL} is coerced to the
- * string "null".
- * </ul>
+ * <pre>
+ * myString = new JSONObject().put("JSON", "Hello, World!").toString();
+ * </pre>
*
- * <p>This class can look up both mandatory and optional values:
+ * produces the string <code>{"JSON": "Hello, World"}</code>.
+ * <p>
+ * The texts produced by the <code>toString</code> methods strictly conform to the JSON syntax
+ * rules. The constructors are more forgiving in the texts they will accept:
* <ul>
- * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This
- * fails with a {@code JSONException} if the requested name has no value
- * or if the value cannot be coerced to the requested type.
- * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This
- * returns a system- or user-supplied default if the requested name has no
- * value or if the value cannot be coerced to the requested type.
+ * <li>An extra <code>,</code> <small>(comma)</small> may appear just before the closing
+ * brace.</li>
+ * <li>Strings may be quoted with <code>'</code> <small>(single quote)</small>.</li>
+ * <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
+ * and if they do not contain leading or trailing spaces, and if they do not contain any of these
+ * characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they
+ * are not the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li>
+ * <li>Keys can be followed by <code>=</code> or <code>=></code> as well as by <code>:</code>.</li>
+ * <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as well as by
+ * <code>,</code> <small>(comma)</small>.</li>
* </ul>
*
- * <p><strong>Warning:</strong> this class represents null in two incompatible
- * ways: the standard Java {@code null} reference, and the sentinel value {@link
- * JSONObject#NULL}. In particular, calling {@code put(name, null)} removes the
- * named entry from the object but {@code put(name, JSONObject.NULL)} stores an
- * entry whose value is {@code JSONObject.NULL}.
- *
- * <p>Instances of this class are not thread safe. Although this class is
- * nonfinal, it was not designed for inheritance and should not be subclassed.
- * In particular, self-use by overrideable methods is not specified. See
- * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
- * prohibit it" for further information.
+ * @author JSON.org
+ * @version 2012-05-29
*/
public class JSONObject {
-
- private static final Double NEGATIVE_ZERO = -0d;
-
- public static ThreadLocal<Set> cyclicDependencySet = new ThreadLocal();
- public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
-
/**
- * A sentinel value used to explicitly define a name with no value. Unlike
- * {@code null}, names with this value:
- * <ul>
- * <li>show up in the {@link #names} array
- * <li>show up in the {@link #keys} iterator
- * <li>return {@code true} for {@link #has(String)}
- * <li>do not throw on {@link #get(String)}
- * <li>are included in the encoded JSON string.
- * </ul>
- *
- * <p>This value violates the general contract of {@link Object#equals} by
- * returning true when compared to {@code null}. Its {@link #toString}
- * method returns "null".
+ * JSONObject.NULL is equivalent to the value that JavaScript calls null, whilst Java's null is
+ * equivalent to the value that JavaScript calls undefined.
*/
- public static final Object NULL = new Object() {
- @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
- @Override
- public boolean equals(Object o) {
- return o == this || o == null; // API specifies this broken equals implementation
+ 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.
+ */
+ protected final Object clone() {
+ return this;
}
- // at least make the broken equals(null) consistent with Objects.hashCode(null).
- @Override
- public int hashCode() {
- return 0;
+ /**
+ * 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.
+ */
+ public boolean equals(Object object) {
+ return object == null || object == this;
}
- @Override
+ /**
+ * Get the "null" string value.
+ *
+ * @return The string "null".
+ */
public String toString() {
return "null";
}
- };
+ }
+
+
+ /**
+ * The map where the JSONObject's properties are kept.
+ */
+ private final Map map;
+
+
+ /**
+ * It is sometimes more convenient and less ambiguous to have a <code>NULL</code> object than to
+ * use Java's <code>null</code> value. <code>JSONObject.NULL.equals(null)</code> returns
+ * <code>true</code>. <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
+ */
+ public static final Object NULL = new Null();
+
+
+ public static ThreadLocal<Set> cyclicDependencySet = new ThreadLocal();
+ public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
- private final LinkedHashMap<String, Object> nameValuePairs;
/**
- * Creates a {@code JSONObject} with no name/value mappings.
+ * Construct an empty JSONObject.
*/
public JSONObject() {
- nameValuePairs = new LinkedHashMap<String, Object>();
+ this.map = new LinkedHashMap();
}
+
/**
- * Creates a new {@code JSONObject} by copying all name/value mappings from
- * the given map.
- * @param copyFrom a map whose keys are of type {@link String} and whose values are of supported
- * types.
- * @throws NullPointerException if any of the map's keys are null.
+ * Construct a JSONObject from a subset of another JSONObject. An array of strings is used to
+ * identify the keys that should be copied. Missing keys are ignored.
+ *
+ * @param jo A JSONObject.
+ * @param names An array of strings.
*/
- /* (accept a raw type for API compatibility) */
- public JSONObject(Map copyFrom) {
+ public JSONObject(JSONObject jo, String[] names) {
this();
- Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
- for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
- /*
- * Deviate from the original by checking that keys are non-null and
- * of the proper type. (We still defer validating the values).
- */
- String key = (String) entry.getKey();
- if (key == null) {
- throw new NullPointerException("key == null");
+ for (int i = 0; i < names.length; i += 1) {
+ try {
+ this.putOnce(names[i], jo.opt(names[i]));
+ } catch (Exception ignore) {
}
- nameValuePairs.put(key, wrap(entry.getValue()));
}
}
+
/**
- * Creates a new {@code JSONObject} with name/value mappings from the next
- * object in the tokener.
- * @param readFrom a tokener whose nextValue() method will yield a {@code JSONObject}.
- * @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
+ * Construct a JSONObject from a JSONTokener.
+ *
+ * @param x A JSONTokener object containing the source string.
+ * @throws JSONException If there is a syntax error in the source string or a duplicated key.
*/
- public JSONObject(JSONTokener readFrom) throws JSONException {
- /*
- * Getting the parser to populate this could get tricky. Instead, just
- * parse to temporary JSONObject and then steal the data from that.
- */
- Object object = readFrom.nextValue();
- if (object instanceof JSONObject) {
- this.nameValuePairs = ((JSONObject) object).nameValuePairs;
- } else {
- throw JSON.typeMismatch(object, "JSONObject");
+ public JSONObject(JSONTokener x) throws JSONException {
+ this();
+ char c;
+ String key;
+
+ if (x.nextClean() != '{') {
+ throw x.syntaxError("A JSONObject text must begin with '{'");
}
- }
+ for (;;) {
+ c = x.nextClean();
+ switch (c) {
+ case 0:
+ throw x.syntaxError("A JSONObject text must end with '}'");
+ case '}':
+ return;
+ default:
+ x.back();
+ key = x.nextValue().toString();
+ }
- /**
- * Creates a new {@code JSONObject} with name/value mappings from the JSON
- * string.
- * @param json a JSON-encoded string containing an object.
- * @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
- */
- public JSONObject(String json) throws JSONException {
- this(new JSONTokener(json));
+ // The key is followed by ':'. We will also tolerate '=' or '=>'.
+
+ c = x.nextClean();
+ if (c == '=') {
+ if (x.next() != '>') {
+ x.back();
+ }
+ } else if (c != ':') {
+ throw x.syntaxError("Expected a ':' after a key");
+ }
+ this.putOnce(key, x.nextValue());
+
+ // Pairs are separated by ','. We will also tolerate ';'.
+
+ switch (x.nextClean()) {
+ case ';':
+ case ',':
+ if (x.nextClean() == '}') {
+ return;
+ }
+ x.back();
+ break;
+ case '}':
+ return;
+ default:
+ throw x.syntaxError("Expected a ',' or '}'");
+ }
+ }
}
+
/**
- * Creates a new {@code JSONObject} by copying mappings for the listed names
- * from the given object. Names that aren't present in {@code copyFrom} will
- * be skipped.
- * @param copyFrom The source object.
- * @param names The names of the fields to copy.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * Construct a JSONObject from a Map.
+ *
+ * @param map A map object that can be used to initialize the contents of the JSONObject.
*/
- public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
- this();
- for (String name : names) {
- Object value = copyFrom.opt(name);
- if (value != null) {
- nameValuePairs.put(name, value);
+ public JSONObject(Map map) {
+ this.map = new LinkedHashMap();
+ if (map != null) {
+ Iterator i = map.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Map.Entry) i.next();
+ Object value = e.getValue();
+ if (value != null) {
+ this.map.put(e.getKey(), wrap(value));
+ }
}
}
}
+
/**
- * Creates a json object from a bean
- * @param bean the bean to create the json object from
- * @throws JSONException If there is an exception while reading the bean
+ * Construct a JSONObject from an Object using bean getters. It reflects on all of the public
+ * methods of the object. For each of the methods with no parameters and a name starting with
+ * <code>"get"</code> or <code>"is"</code> followed by an uppercase letter, the method is invoked,
+ * and a key and the value returned from the getter method are put into the new JSONObject.
+ *
+ * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix. If the second
+ * remaining character is not upper case, then the first character is converted to lower case.
+ *
+ * For example, if an object has a method named <code>"getName"</code>, and if the result of
+ * calling <code>object.getName()</code> is <code>"Larry Fine"</code>, then the JSONObject will
+ * contain <code>"name": "Larry Fine"</code>.
+ *
+ * @param bean An object that has getter methods that should be used to make a JSONObject.
*/
- public JSONObject(Object bean) throws JSONException {
- this(propertiesAsMap(bean));
+ public JSONObject(Object bean) {
+ this();
+ this.populateMap(bean);
}
- //This is custom properties mapping specific for GEODE
- private static Map<String, Object> propertiesAsMap(Object bean) {
- Map<String, Object> props = new TreeMap();
- 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 (int i = 0; i < methods.length; i += 1) {
+ /**
+ * Construct a JSONObject from an Object, using reflection to find the public members. The
+ * resulting JSONObject's keys will be the strings from the names array, and the values will be
+ * the field values associated with those keys in the object. If a key is not found or not
+ * visible, then it will not be copied into the new JSONObject.
+ *
+ * @param object An object that has fields that should be used to make a JSONObject.
+ * @param names An array of strings, the names of the fields to be obtained from the object.
+ */
+ public JSONObject(Object object, String names[]) {
+ this();
+ Class c = object.getClass();
+ for (int i = 0; i < names.length; i += 1) {
+ String name = names[i];
try {
- Method method = methods[i];
- if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
- String name = method.getName();
- String key = "";
- if (name.startsWith("get")) {
- if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
- key = "";
- } else {
- key = name.substring(3);
- }
- } else if (name.startsWith("is")) {
- key = name.substring(2);
- }
- if (key.length() > 0 && Character.isUpperCase(key.charAt(0))
- && method.getParameterTypes().length == 0) {
- if (key.length() == 1) {
- key = key.toLowerCase();
- } else if (!Character.isUpperCase(key.charAt(1))) {
- key = key.substring(0, 1).toLowerCase() + key.substring(1);
- }
- Object result = method.invoke(bean, (Object[]) null);
- if (result != null) {
- props.put(key, wrap(result));
- } else if (!method.getReturnType().isArray()) {
- props.put(key, JSONObject.NULL);
- }
- }
- }
+ this.putOpt(name, c.getField(name).get(object));
} catch (Exception ignore) {
}
}
- props.put("type-class", klass.getCanonicalName());
- return props;
}
- public static String[] getNames(JSONObject x) {
- Set<String> names = x.keySet();
- String[] r = new String[names.size()];
- int i = 0;
- for (String name : names) {
- r[i++] = name;
- }
- return r;
- }
/**
- * Returns the number of name/value mappings in this object.
- * @return the length of this.
+ * Construct a JSONObject from a source JSON text string. This is the most commonly used
+ * JSONObject constructor.
+ *
+ * @param source A string beginning with <code>{</code> <small>(left brace)</small> and
+ * ending with <code>}</code> <small>(right brace)</small>.
+ * @exception JSONException If there is a syntax error in the source string or a duplicated key.
*/
- public int length() {
- return nameValuePairs.size();
+ public JSONObject(String source) throws JSONException {
+ this(new JSONTokener(source));
}
+
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value
- * mapping with the same name.
- * @param name The name of the value to insert.
- * @param value The value to insert.
- * @return this object.
- * @throws JSONException Should not be possible.
+ * Construct a JSONObject from a ResourceBundle.
+ *
+ * @param baseName The ResourceBundle base name.
+ * @param locale The Locale to load the ResourceBundle for.
+ * @throws JSONException If any JSONExceptions are detected.
*/
- public JSONObject put(String name, boolean value) throws JSONException {
- nameValuePairs.put(checkName(name), value);
- return this;
+ public JSONObject(String baseName, Locale locale) throws JSONException {
+ this();
+ ResourceBundle bundle =
+ ResourceBundle.getBundle(baseName, locale, Thread.currentThread().getContextClassLoader());
+
+ // Iterate through the keys in the bundle.
+
+ Enumeration keys = bundle.getKeys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ if (key instanceof String) {
+
+ // Go through the path, ensuring that there is a nested JSONObject for each
+ // segment except the last. Add the value using the last segment's name into
+ // the deepest nested JSONObject.
+
+ String[] path = ((String) key).split("\\.");
+ int last = path.length - 1;
+ JSONObject target = this;
+ for (int i = 0; i < last; i += 1) {
+ String segment = path[i];
+ JSONObject nextTarget = target.optJSONObject(segment);
+ if (nextTarget == null) {
+ nextTarget = new JSONObject();
+ target.put(segment, nextTarget);
+ }
+ target = nextTarget;
+ }
+ target.put(path[last], bundle.getString((String) key));
+ }
+ }
}
+
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value
- * mapping with the same name.
- * @param name The name for the new value.
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
- * Double#isInfinite() infinities}.
- * @return this object.
- * @throws JSONException if value is NaN or infinite.
+ * 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 an invalid number or if the key is null.
*/
- public JSONObject put(String name, double value) throws JSONException {
- nameValuePairs.put(checkName(name), JSON.checkDouble(value));
+ 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;
}
+
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value
- * mapping with the same name.
- * @param name The name for the new value.
- * @param value The new value.
- * @return this object.
- * @throws JSONException Should not be possible.
+ * 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 key is null or if the current value associated with the key is not
+ * a JSONArray.
*/
- public JSONObject put(String name, int value) throws JSONException {
- nameValuePairs.put(checkName(name), value);
+ 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 new JSONException("JSONObject[" + key + "] is not a JSONArray.");
+ }
return this;
}
+
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value
- * mapping with the same name.
- * @param name The name of the new value.
- * @param value The new value to insert.
- * @return this object.
- * @throws JSONException Should not be possible.
+ * Produce a string from a double. The string "null" will be returned if the number is not finite.
+ *
+ * @param d A double.
+ * @return A String.
*/
- public JSONObject put(String name, long value) throws JSONException {
- nameValuePairs.put(checkName(name), value);
- return this;
+ public static String doubleToString(double d) {
+ if (Double.isInfinite(d) || Double.isNaN(d)) {
+ return "null";
+ }
+
+ // Shave off trailing zeros and decimal point, if possible.
+
+ String string = Double.toString(d);
+ if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) {
+ while (string.endsWith("0")) {
+ string = string.substring(0, string.length() - 1);
+ }
+ if (string.endsWith(".")) {
+ string = string.substring(0, string.length() - 1);
+ }
+ }
+ return string;
}
+
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value
- * mapping with the same name. If the value is {@code null}, any existing
- * mapping for {@code name} is removed.
- * @param name The name of the new value.
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link #NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or {@link
- * Double#isInfinite() infinities}.
- * @return this object.
- * @throws JSONException if the value is an invalid double (infinite or NaN).
+ * 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 JSONObject put(String name, Object value) throws JSONException {
- if (value == null) {
- nameValuePairs.remove(name);
- return this;
+ public Object get(String key) throws JSONException {
+ if (key == null) {
+ throw new JSONException("Null key.");
}
- if (value instanceof Number) {
- // deviate from the original by checking all Numbers, not just floats & doubles
- JSON.checkDouble(((Number) value).doubleValue());
+ Object object = this.opt(key);
+ if (object == null) {
+ throw new JSONException("JSONObject[" + quote(key) + "] not found.");
}
- nameValuePairs.put(checkName(name), value);
- return this;
+ return object;
}
+
/**
- * Put a key/value pair in the JSONObject, where the value will be a JSONArray which is produced
- * from a Collection.
+ * Get the boolean value associated with a key.
*
* @param key A key string.
- * @param value A Collection value.
- * @return this.
- * @throws JSONException
+ * @return The truth.
+ * @throws JSONException if the value is not a Boolean or the String "true" or "false".
*/
- public JSONObject put(String key, Collection value) throws JSONException {
- this.put(key, new JSONArray(value));
- return this;
+ 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 new JSONException("JSONObject[" + quote(key) + "] is not a Boolean.");
}
+
/**
- * Equivalent to {@code put(name, value)} when both parameters are non-null;
- * does nothing otherwise.
- * @param name The name of the value to insert.
- * @param value The value to insert.
- * @return this object.
- * @throws JSONException if the value is an invalid double (infinite or NaN).
+ * 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 JSONObject putOpt(String name, Object value) throws JSONException {
- if (name == null || value == null) {
- return this;
+ public double getDouble(String key) throws JSONException {
+ Object object = this.get(key);
+ try {
+ return object instanceof Number ? ((Number) object).doubleValue()
+ : Double.parseDouble((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONObject[" + quote(key) + "] is not a number.");
}
- return put(name, value);
}
+
/**
- * Appends {@code value} to the array already mapped to {@code name}. If
- * this object has no mapping for {@code name}, this inserts a new mapping.
- * If the mapping exists but its value is not an array, the existing
- * and new values are inserted in order into a new array which is itself
- * mapped to {@code name}. In aggregate, this allows values to be added to a
- * mapping one at a time.
+ * Get the int value associated with a key.
*
- * Note that {@code append(String, Object)} provides better semantics.
- * In particular, the mapping for {@code name} will <b>always</b> be a
- * {@link JSONArray}. Using {@code accumulate} will result in either a
- * {@link JSONArray} or a mapping whose type is the type of {@code value}
- * depending on the number of calls to it.
- * @param name The name of the field to change.
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link #NULL} or null. May not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
- * infinities}.
- * @return this object after mutation.
- * @throws JSONException If the object being added is an invalid number.
+ * @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.
*/
- // TODO: Change {@code append) to {@link #append} when append is
- // unhidden.
- public JSONObject accumulate(String name, Object value) throws JSONException {
- Object current = nameValuePairs.get(checkName(name));
- if (current == null) {
- return put(name, value);
+ public int getInt(String key) throws JSONException {
+ Object object = this.get(key);
+ try {
+ return object instanceof Number ? ((Number) object).intValue()
+ : Integer.parseInt((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONObject[" + quote(key) + "] is not an int.");
}
+ }
- if (current instanceof JSONArray) {
- JSONArray array = (JSONArray) current;
- array.checkedPut(value);
- } else {
- JSONArray array = new JSONArray();
- array.checkedPut(current);
- array.checkedPut(value);
- nameValuePairs.put(name, array);
+
+ /**
+ * 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;
}
- return this;
+ throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray.");
}
+
/**
- * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
- * mapping for {@code name} will be inserted if no mapping exists. If the existing
- * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException}
- * will be thrown.
- * @param name The name of the array to which the value should be appended.
- * @param value The value to append.
- * @return this object.
- * @throws JSONException if {@code name} is {@code null} or if the mapping for {@code name} is
- * non-null and is not a {@link JSONArray}.
+ * 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 append(String name, Object value) throws JSONException {
- Object current = nameValuePairs.get(checkName(name));
-
- final JSONArray array;
- if (current instanceof JSONArray) {
- array = (JSONArray) current;
- } else if (current == null) {
- JSONArray newArray = new JSONArray();
- nameValuePairs.put(name, newArray);
- array = newArray;
- } else {
- throw new JSONException("Key " + name + " is not a JSONArray");
+ public JSONObject getJSONObject(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
}
+ throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONObject.");
+ }
- array.checkedPut(value);
- return this;
+ /**
+ * 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 {
+ Object object = this.get(key);
+ try {
+ return object instanceof Number ? ((Number) object).longValue()
+ : Long.parseLong((String) object);
+ } catch (Exception e) {
+ throw new JSONException("JSONObject[" + quote(key) + "] is not a long.");
+ }
}
- String checkName(String name) throws JSONException {
- if (name == null) {
- throw new JSONException("Names must be non-null");
+
+ /**
+ * Get an array of field names from a JSONObject.
+ *
+ * @return An array of field names, or null if there are no names.
+ */
+ public static String[] getNames(JSONObject jo) {
+ int length = jo.length();
+ if (length == 0) {
+ return null;
}
- return name;
+ Iterator iterator = jo.keys();
+ String[] names = new String[length];
+ int i = 0;
+ while (iterator.hasNext()) {
+ names[i] = (String) iterator.next();
+ i += 1;
+ }
+ return names;
}
+
/**
- * Removes the named mapping if it exists; does nothing otherwise.
- * @param name The name of the mapping to remove.
- * @return the value previously mapped by {@code name}, or null if there was no such mapping.
+ * Get an array of field names from an Object.
+ *
+ * @return An array of field names, or null if there are no names.
*/
- public Object remove(String name) {
- return nameValuePairs.remove(name);
+ public static String[] getNames(Object object) {
+ if (object == null) {
+ return null;
+ }
+ Class klass = object.getClass();
+ Field[] fields = klass.getFields();
+ int length = fields.length;
+ if (length == 0) {
+ return null;
+ }
+ String[] names = new String[length];
+ for (int i = 0; i < length; i += 1) {
+ names[i] = fields[i].getName();
+ }
+ return names;
}
+
/**
- * Returns true if this object has no mapping for {@code name} or if it has
- * a mapping whose value is {@link #NULL}.
- * @param name The name of the value to check on.
- * @return true if the field doesn't exist or is 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 boolean isNull(String name) {
- Object value = nameValuePairs.get(name);
- return value == null || value == NULL;
+ public String getString(String key) throws JSONException {
+ Object object = this.get(key);
+ if (object instanceof String) {
+ return (String) object;
+ }
+ throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
}
+
/**
- * Returns true if this object has a mapping for {@code name}. The mapping
- * may be {@link #NULL}.
- * @param name The name of the value to check on.
- * @return true if this object has a field named {@code name}
+ * 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 name) {
- return nameValuePairs.containsKey(name);
+ public boolean has(String key) {
+ return this.map.containsKey(key);
}
+
/**
- * Returns the value mapped by {@code name}, or throws if no such mapping exists.
- * @param name The name of the value to get.
- * @return The value.
- * @throws JSONException if no such mapping exists.
+ * Increment a property of a JSONObject. If there is no such property, create one with a value of
+ * 1. If there is such a property, and if it is an Integer, Long, Double, or Float, then add one
+ * to it.
+ *
+ * @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 Object get(String name) throws JSONException {
- Object result = nameValuePairs.get(name);
- if (result == null) {
- throw new JSONException("No value for " + name);
+ 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() + 1);
+ } else if (value instanceof Double) {
+ this.put(key, ((Double) value).doubleValue() + 1);
+ } else if (value instanceof Float) {
+ this.put(key, ((Float) value).floatValue() + 1);
+ } else {
+ throw new JSONException("Unable to increment [" + quote(key) + "].");
}
- return result;
+ return this;
}
+
/**
- * Returns the value mapped by {@code name}, or null if no such mapping
- * exists.
- * @param name The name of the value to get.
- * @return The value.
+ * 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 Object opt(String name) {
- return nameValuePairs.get(name);
+ public boolean isNull(String key) {
+ return JSONObject.NULL.equals(this.opt(key));
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean, or throws otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
- * @throws JSONException if the mapping doesn't exist or cannot be coerced to a boolean.
+ * Get an enumeration of the keys of the JSONObject.
+ *
+ * @return An iterator of the keys.
*/
- public boolean getBoolean(String name) throws JSONException {
- Object object = get(name);
- Boolean result = JSON.toBoolean(object);
- if (result == null) {
- throw JSON.typeMismatch(name, object, "boolean");
- }
- return result;
+ public Iterator keys() {
+ return this.map.keySet().iterator();
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean, or false otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
+ * Get the number of keys stored in the JSONObject.
+ *
+ * @return The number of keys in the JSONObject.
*/
- public boolean optBoolean(String name) {
- return optBoolean(name, false);
+ public int length() {
+ return this.map.size();
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean, or {@code fallback} otherwise.
- * @param name The name of the field we want.
- * @param fallback The value to return if the field isn't there.
- * @return The selected value or the fallback.
+ * 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 boolean optBoolean(String name, boolean fallback) {
- Object object = opt(name);
- Boolean result = JSON.toBoolean(object);
- return result != null ? result : fallback;
+ public JSONArray names() {
+ JSONArray ja = new JSONArray();
+ Iterator keys = this.keys();
+ while (keys.hasNext()) {
+ ja.put(keys.next());
+ }
+ return ja.length() == 0 ? null : ja;
}
/**
- * Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double, or throws otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
- * @throws JSONException if the mapping doesn't exist or cannot be coerced to a double.
+ * Produce a string from a Number.
+ *
+ * @param number A Number
+ * @return A String.
+ * @throws JSONException If n is a non-finite number.
*/
- public double getDouble(String name) throws JSONException {
- Object object = get(name);
- Double result = JSON.toDouble(object);
- if (result == null) {
- throw JSON.typeMismatch(name, object, "double");
+ public static String numberToString(Number number) throws JSONException {
+ if (number == null) {
+ throw new JSONException("Null pointer");
}
- return result;
+ testValidity(number);
+
+ // Shave off trailing zeros and decimal point, if possible.
+
+ String string = number.toString();
+ if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) {
+ while (string.endsWith("0")) {
+ string = string.substring(0, string.length() - 1);
+ }
+ if (string.endsWith(".")) {
+ string = string.substring(0, string.length() - 1);
+ }
+ }
+ return string;
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double, or {@code NaN} otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
+ * 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 double optDouble(String name) {
- return optDouble(name, Double.NaN);
+ public Object opt(String key) {
+ return key == null ? null : this.map.get(key);
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double, or {@code fallback} otherwise.
- * @param name The name of the field we want.
- * @param fallback The value to return if the field isn't there.
- * @return The selected value or the fallback.
+ * 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 double optDouble(String name, double fallback) {
- Object object = opt(name);
- Double result = JSON.toDouble(object);
- return result != null ? result : fallback;
+ public boolean optBoolean(String key) {
+ return this.optBoolean(key, false);
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int, or throws otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
- * @throws JSONException if the mapping doesn't exist or cannot be coerced to an int.
+ * 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 int getInt(String name) throws JSONException {
- Object object = get(name);
- Integer result = JSON.toInteger(object);
- if (result == null) {
- throw JSON.typeMismatch(name, object, "int");
+ public boolean optBoolean(String key, boolean defaultValue) {
+ try {
+ return this.getBoolean(key);
+ } catch (Exception e) {
+ return defaultValue;
}
- return result;
}
- /**
- * Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int, or 0 otherwise.
- * @param name The name of the field we want.
- * @return The selected value if it exists.
- */
- public int optInt(String name) {
- return optInt(name, 0);
- }
/**
- * Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int, or {@code fallback} otherwise.
- * @param name The name of the field we want.
- * @param fallback The value to return if the field isn't there.
- * @return The selected value or the fallback.
+ * 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 int optInt(String name, int fallback) {
- Object object = opt(name);
- Integer result = JSON.toInteger(object);
- return result != null ? result : fallback;
+ public double optDouble(String key) {
+ return this.optDouble(key, Double.NaN);
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long, or throws otherwise.
- * Note that JSON represents numbers as doubles,
+ * 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.
*
- * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers
- * via JSON without loss.
- * @param name The name of the field that we want.
- * @return The value of the field.
- * @throws JSONException if the mapping doesn't exist or cannot be coerced to a long.
+ * @param key A key string.
+ * @param defaultValue The default.
+ * @return An object which is the value.
*/
- public long getLong(String name) throws JSONException {
- Object object = get(name);
- Long result = JSON.toLong(object);
- if (result == null) {
- throw JSON.typeMismatch(name, object, "long");
+ public double optDouble(String key, double defaultValue) {
+ try {
+ return this.getDouble(key);
+ } catch (Exception e) {
+ return defaultValue;
}
- return result;
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
- * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
- * @param name The name of the field we want.
- * @return The selected value.
+ * 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 long optLong(String name) {
- return optLong(name, 0L);
+ public int optInt(String key) {
+ return this.optInt(key, 0);
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
- * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
- * numbers via JSON.
- * @param name The name of the field we want.
- * @param fallback The value to return if the field isn't there.
- * @return The selected value or the fallback.
+ * 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 long optLong(String name, long fallback) {
- Object object = opt(name);
- Long result = JSON.toLong(object);
- return result != null ? result : fallback;
+ public int optInt(String key, int defaultValue) {
+ try {
+ return this.getInt(key);
+ } catch (Exception e) {
+ return defaultValue;
+ }
}
+
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary, or throws if no such mapping exists.
- * @param name The name of the field we want.
- * @return The value of the field.
- * @throws JSONException if no such mapping exists.
+ * 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 String getString(String name) throws JSONException {
- Object object = get(name);
- String result = JSON.toString(object);
- if (result == null) {
- throw JSON.typeMismatch(name, object, "String");
- }
- return result;
+ public JSONArray optJSONArray(String key) {
+ Object o = this.opt(key);
+ return o instanceof JSONArray ? (JSONArray) o : null;
}
+
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary, or the empty string if no such mapping exists.
- * @param name The name of the field we want.
- * @return The value of the field.
+ * 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 String optString(String name) {
- return optString(name, "");
+ public JSONObject optJSONObject(String key) {
+ Object object = this.opt(key);
+ return object instanceof JSONObject ? (JSONObject) object : null;
}
+
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary, or {@code fallback} if no such mapping exists.
- * @param name The name of the field that we want.
- * @param fallback The value to return if the field doesn't exist.
- * @return The value of the field or fallback.
+ * 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 String optString(String name, String fallback) {
- Object object = opt(name);
- String result = JSON.toString(object);
- return result != null ? result : fallback;
+ public long optLong(String key) {
+ return this.optLong(key, 0);
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONArray}, or throws otherwise.
- * @param name The field we want to get.
- * @return The value of the field (if it is a JSONArray.
- * @throws JSONException if the mapping doesn't exist or is not a {@code JSONArray}.
+ * 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 JSONArray getJSONArray(String name) throws JSONException {
- Object object = get(name);
- if (object instanceof JSONArray) {
- return (JSONArray) object;
- } else {
- throw JSON.typeMismatch(name, object, "JSONArray");
+ public long optLong(String key, long defaultValue) {
+ try {
+ return this.getLong(key);
+ } catch (Exception e) {
+ return defaultValue;
}
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONArray}, or null otherwise.
- * @param name The name of the field we want.
- * @return The value of the specified field (assuming it is a JSNOArray
+ * 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 JSONArray optJSONArray(String name) {
- Object object = opt(name);
- return object instanceof JSONArray ? (JSONArray) object : null;
+ public String optString(String key) {
+ return this.optString(key, "");
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONObject}, or throws otherwise.
- * @param name The name of the field that we want.
- * @return a specified field value (if it is a JSONObject)
- * @throws JSONException if the mapping doesn't exist or is not a {@code JSONObject}.
+ * 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 JSONObject getJSONObject(String name) throws JSONException {
- Object object = get(name);
- if (object instanceof JSONObject) {
- return (JSONObject) object;
- } else {
- throw JSON.typeMismatch(name, object, "JSONObject");
+ public String optString(String key, String defaultValue) {
+ Object object = this.opt(key);
+ return NULL.equals(object) ? defaultValue : object.toString();
+ }
+
+
+ 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 (int i = 0; i < methods.length; i += 1) {
+ try {
+ Method method = methods[i];
+ if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
+ String name = method.getName();
+ String key = "";
+ if (name.startsWith("get")) {
+ if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
+ key = "";
+ } else {
+ key = name.substring(3);
+ }
+ } else if (name.startsWith("is")) {
+ key = name.substring(2);
+ }
+ if (key.length() > 0 && Character.isUpperCase(key.charAt(0))
+ && method.getParameterTypes().length == 0) {
+ if (key.length() == 1) {
+ key = key.toLowerCase();
+ } else if (!Character.isUpperCase(key.charAt(1))) {
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
+ }
+ Object result = method.invoke(bean, (Object[]) null);
+ if (result != null) {
+ this.map.put(key, wrap(result));
+ } else if (!method.getReturnType().isArray()) {
+ this.map.put(key, JSONObject.NULL);
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ }
}
+ this.map.put("type-class", klass.getCanonicalName());
}
+
/**
- * Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONObject}, or null otherwise.
- * @param name The name of the value we want.
- * @return The specified value.
+ * 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 key is null.
*/
- public JSONObject optJSONObject(String name) {
- Object object = opt(name);
- return object instanceof JSONObject ? (JSONObject) object : null;
+ public JSONObject put(String key, boolean value) throws JSONException {
+ this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
+ return this;
}
+
/**
- * Returns an array with the values corresponding to {@code names}. The
- * array contains null for names that aren't mapped. This method returns
- * null if {@code names} is either null or empty.
- * @param names The names of the fields that we want the values for.
- * @return The selected values.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * 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
*/
- public JSONArray toJSONArray(JSONArray names) throws JSONException {
- JSONArray result = new JSONArray();
- if (names == null) {
- return null;
- }
- int length = names.length();
- if (length == 0) {
- return null;
- }
- for (int i = 0; i < length; i++) {
- String name = JSON.toString(names.opt(i));
- result.put(opt(name));
- }
- return result;
+ public JSONObject put(String key, Collection value) throws JSONException {
+ this.put(key, new JSONArray(value));
+ return this;
}
+
/**
- * Returns an iterator of the {@code String} names in this object. The
- * returned iterator supports {@link Iterator#remove() remove}, which will
- * remove the corresponding mapping from this object. If this object is
- * modified after the iterator is returned, the iterator's behavior is
- * undefined. The order of the keys is undefined.
- * @return an iterator over the keys.
+ * 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 key is null or if the number is invalid.
*/
- public Iterator<String> keys() {
- return nameValuePairs.keySet().iterator();
+ public JSONObject put(String key, double value) throws JSONException {
+ this.put(key, new Double(value));
+ return this;
}
+
/**
- * Returns the set of {@code String} names in this object. The returned set
- * is a view of the keys in this object. {@link Set#remove(Object)} will remove
- * the corresponding mapping from this object and set iterator behaviour
- * is undefined if this object is modified after it is returned.
+ * Put a key/int pair in the JSONObject.
*
- * See {@link #keys()}.
- * @return The names in this object.
+ * @param key A key string.
+ * @param value An int which is the value.
+ * @return this.
+ * @throws JSONException If the key is null.
*/
- public Set<String> keySet() {
- return nameValuePairs.keySet();
+ public JSONObject put(String key, int value) throws JSONException {
+ this.put(key, new Integer(value));
+ return this;
}
+
/**
- * Returns an array containing the string names in this object. This method
- * returns null if this object contains no mappings.
- * @return the names.
+ * 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 key is null.
*/
- public JSONArray names() {
- return nameValuePairs.isEmpty()
- ? null
- : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
+ public JSONObject put(String key, long value) throws JSONException {
+ this.put(key, new Long(value));
+ return this;
}
+
/**
- * Encodes this object as a compact JSON string, such as:
- * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
+ * 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
*/
- @Override
- public String toString() {
- try {
- JSONStringer stringer = new JSONStringer();
- writeTo(stringer);
- return stringer.toString();
- } catch (JSONException e) {
- return null;
+ public JSONObject put(String key, Map value) throws JSONException {
+ this.put(key, new JSONObject(value));
+ return this;
+ }
+
+
+ /**
+ * 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 or if the key is null.
+ */
+ public JSONObject put(String key, Object value) throws JSONException {
+ if (key == null) {
+ throw new JSONException("Null key.");
+ }
+ if (value != null) {
+ testValidity(value);
+ this.map.put(key, value);
+ } else {
+ this.remove(key);
}
+ return this;
}
+
/**
- * Encodes this object as a human readable JSON string for debugging, such
- * as:
- * <pre>
- * {
- * "query": "Pizza",
- * "locations": [
- * 94043,
- * 90210
- * ]
- * }</pre>
- * @param indentSpaces the number of spaces to indent for each level of nesting.
- * @return The string containing the pretty form of this.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * 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
+ * @param value
+ * @return his.
+ * @throws JSONException if the key is a duplicate
*/
- public String toString(int indentSpaces) throws JSONException {
- JSONStringer stringer = new JSONStringer(indentSpaces);
- writeTo(stringer);
- return stringer.toString();
+ 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 + "\"");
+ }
+ this.put(key, value);
+ }
+ return this;
}
- void writeTo(JSONStringer stringer) throws JSONException {
- stringer.object();
- for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
- stringer.key(entry.getKey()).value(entry.getValue());
+
+ /**
+ * 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) {
+ this.put(key, value);
}
- stringer.endObject();
+ return this;
}
+
/**
- * Encodes the number as a JSON string.
- * @param number a finite value. May not be {@link Double#isNaN() NaNs} or {@link
- * Double#isInfinite() infinities}.
- * @return The encoded number in string form.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * Produce a string in double quotes with backslash sequences in all the right places. A backslash
+ * will be inserted within </, producing <\/, allowing JSON text to be delivered in HTML. In JSON
+ * text, a string cannot contain a control character or an unescaped quote or backslash.
+ *
+ * @param string A String
+ * @return A String correctly formatted for insertion in a JSON text.
*/
- public static String numberToString(Number number) throws JSONException {
- if (number == null) {
- throw new JSONException("Number must be non-null");
+ public static String quote(String string) {
+ StringWriter sw = new StringWriter();
+ synchronized (sw.getBuffer()) {
+ try {
+ return quote(string, sw).toString();
+ } catch (IOException ignored) {
+ // will never happen - we are writing to a string writer
+ return "";
+ }
}
+ }
- double doubleValue = number.doubleValue();
- JSON.checkDouble(doubleValue);
+ public static Writer quote(String string, Writer w) throws IOException {
+ if (string == null || string.length() == 0) {
+ w.write("\"\"");
+ return w;
+ }
- // the original returns "-0" instead of "-0.0" for negative zero
- if (number.equals(NEGATIVE_ZERO)) {
- return "-0";
+ char b;
+ char c = 0;
+ String hhhh;
+ int i;
+ int len = string.length();
+
+ w.write('"');
+ for (i = 0; i < len; i += 1) {
+ b = c;
+ c = string.charAt(i);
+ switch (c) {
+ case '\\':
+ case '"':
+ w.write('\\');
+ w.write(c);
+ break;
+ case '/':
+ if (b == '<') {
+ w.write('\\');
+ }
+ w.write(c);
+ break;
+ case '\b':
+ w.write("\\b");
+ break;
+ case '\t':
+ w.write("\\t");
+ break;
+ case '\n':
+ w.write("\\n");
+ break;
+ case '\f':
+ w.write("\\f");
+ break;
+ case '\r':
+ w.write("\\r");
+ break;
+ default:
+ if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
+ hhhh = "000" + Integer.toHexString(c);
+ w.write("\\u" + hhhh.substring(hhhh.length() - 4));
+ } else {
+ w.write(c);
+ }
+ }
}
+ w.write('"');
+ return w;
+ }
- long longValue = number.longValue();
- if (doubleValue == (double) longValue) {
- return Long.toString(longValue);
+ /**
+ * 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);
+ }
+
+ /**
+ * 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.
+ * @return A simple JSON value.
+ */
+ public static Object stringToValue(String string) {
+ Double d;
+ if (string.equals("")) {
+ return string;
+ }
+ if (string.equalsIgnoreCase("true")) {
+ return Boolean.TRUE;
+ }
+ if (string.equalsIgnoreCase("false")) {
+ return Boolean.FALSE;
+ }
+ if (string.equalsIgnoreCase("null")) {
+ return JSONObject.NULL;
}
- return number.toString();
+ /*
+ * If it might be a number, try converting it. If a number cannot be produced, then the value
+ * will just be a string. Note that the plus and implied string conventions are non-standard. A
+ * JSON parser may accept non-JSON forms as long as it accepts all correct JSON forms.
+ */
+
+ char b = string.charAt(0);
+ if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
+ try {
+ if (string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1) {
+ d = Double.valueOf(string);
+ if (!d.isInfinite() && !d.isNaN()) {
+ return d;
+ }
+ } else {
+ Long myLong = new Long(string);
+ if (myLong.longValue() == myLong.intValue()) {
+ return new Integer(myLong.intValue());
+ } else {
+ return myLong;
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ }
+ return string;
+ }
+
+
+ /**
+ * 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.
+ */
+ public static void testValidity(Object o) throws JSONException {
+ if (o != null) {
+ if (o instanceof Double) {
+ if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
+ throw new JSONException("JSON does not allow non-finite numbers.");
+ }
+ } else if (o instanceof Float) {
+ if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
+ throw new JSONException("JSON does not allow non-finite numbers.");
+ }
+ }
+ }
}
+
/**
- * Encodes {@code data} as a JSON string. This applies quotes and any
- * necessary character escaping.
- * @param data the string to encode. Null will be interpreted as an empty string.
- * @return the quoted string.
+ * 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 static String quote(String data) {
- if (data == null) {
- return "\"\"";
+ public JSONArray toJSONArray(JSONArray names) throws JSONException {
+ if (names == null || names.length() == 0) {
+ 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.
+ * <p>
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ * @return a printable, displayable, portable, transmittable representation of the object,
+ * beginning with <code>{</code> <small>(left brace)</small> and ending with
+ * <code>}</code> <small>(right brace)</small>.
+ */
+ public String toString() {
try {
- JSONStringer stringer = new JSONStringer();
- stringer.open(JSONStringer.Scope.NULL, "");
- stringer.value(data);
- stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
- return stringer.toString();
- } catch (JSONException e) {
- throw new AssertionError();
+ return this.toString(0);
+ } catch (Exception e) {
+ return null;
}
}
+
/**
- * Wraps the given object if necessary.
+ * Make a prettyprinted JSON text of this JSONObject.
+ * <p>
+ * 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 <code>{</code> <small>(left brace)</small> and ending with
+ * <code>}</code> <small>(right brace)</small>.
+ * @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 JSON text. The method is required to produce a strictly
+ * conforming text. If the object does not contain a toJSONString method (which is the most common
+ * case), then a text will be produced by other means. If the value is an array or Collection,
+ * then a JSONArray will be made from it and its toJSONString method will be called. If the value
+ * is a MAP, then a JSONObject will be made from it and its toJSONString method will be called.
+ * Otherwise, the value's toString method will be called, and the result will be quoted.
*
- * <p>If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
- * {@code JSONObject}, no wrapping is necessary. If the object is {@code NULL}, no wrapping is
- * necessary. If the object is an array or {@code Collection}, returns an equivalent {@code
- * JSONArray}. If the object is a {@code Map}, returns an equivalent {@code JSONObject}. If the
- * object is a primitive wrapper type or {@code String}, returns the object. If the object is from
- * a {@code java} package, returns the result of {@code toString}. If the object is some other
- * kind of object then it is assumed to be a bean and is converted to a JSONObject. If wrapping
- * fails, returns null.
- * @param o The object to wrap.
- * @return The wrapped (if necessary) form of the object {$code o}
+ * <p>
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ * @param value The value to be serialized.
+ * @return a printable, displayable, transmittable representation of the object, beginning with
+ * <code>{</code> <small>(left brace)</small> and ending with
+ * <code>}</code> <small>(right brace)</small>.
+ * @throws JSONException If the value is or contains an invalid number.
*/
- public static Object wrap(Object o) {
- if (o == null) {
- return NULL;
+ public static String valueToString(Object value) throws JSONException {
+ if (value == null || value.equals(null)) {
+ return "null";
+ }
+ if (value instanceof JSONString) {
+ Object object;
+ try {
+ object = ((JSONString) value).toJSONString();
+ } catch (Exception e) {
+ throw new JSONException(e);
+ }
+ if (object instanceof String) {
+ return (String) object;
+ }
+ throw new JSONException("Bad value from toJSONString: " + object);
+ }
+ if (value instanceof Number) {
+ return numberToString((Number) value);
+ }
+ if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) {
+ return value.toString();
}
- if (o instanceof JSONArray || o instanceof JSONObject) {
- return o;
+ if (value instanceof Map) {
+ return new JSONObject((Map) value).toString();
}
- if (o.equals(NULL)) {
- return o;
+ if (value instanceof Collection) {
+ return new JSONArray((Collection) value).toString();
}
+ if (value.getClass().isArray()) {
+ return new JSONArray(value).toString();
+ }
+ return quote(value.toString());
+ }
+
+ /**
+ * Wrap an object, if necessary. If the object is null, return the NULL object. If it is an array
+ * or collection, wrap it in a JSONArray. If it is a map, wrap it in a JSONObject. If it is a
+ * standard property (Double, String, et al) then it is already wrapped. Otherwise, if it comes
+ * from 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
+ * @return The wrapped value
+ */
+ public static Object wrap(Object object) {
try {
- if (o instanceof Collection) {
- return new JSONArray((Collection) o);
- } else if (o.getClass().isArray()) {
- return new JSONArray(o);
+ if (object == null) {
+ return NULL;
}
- if (o instanceof Map) {
- return new JSONObject((Map) o);
+ if (object instanceof JSONObject || object instanceof JSONArray || NULL.equals(object)
+ || object instanceof JSONString || object instanceof Byte || object instanceof Character
+ || object instanceof Short || object instanceof Integer || object instanceof Long
+ || object instanceof Boolean || object instanceof Float || object instanceof Double
+ || object instanceof String) {
+ return object;
}
- if (o instanceof Boolean ||
- o instanceof Byte ||
- o instanceof Character ||
- o instanceof Double ||
- o instanceof Float ||
- o instanceof Integer ||
- o instanceof Long ||
- o instanceof Short ||
- o instanceof String) {
- return o;
+
+ if (object instanceof Collection) {
+ return new JSONArray((Collection) object);
+ }
+ if (object.getClass().isArray()) {
+ return new JSONArray(object);
}
- // GEODE-2142: Added check to ignore GemFireCacheImpl
-// if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
-// return o.toString();
-// }
- Package objectPackage = o.getClass().getPackage();
+ if (object instanceof Map) {
+ return new JSONObject((Map) object);
+ }
+ Package objectPackage = object.getClass().getPackage();
String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
- if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || o instanceof Enum<?>
- || o.getClass().getClassLoader() == null
- || o.getClass().getName().contains("GemFireCacheImpl")) {
- return o.toString();
+ if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.")
+ || object.getClass().getClassLoader() == null
+ || object.getClass().getName().contains("GemFireCacheImpl")) {
+ return object.toString();
}
-// if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
-// || objectPackageName.startsWith("javax.")
-// || o.getClass().getClassLoader() == null
-// o.getClass().getName().contains("GemFireCacheImpl")) {
-// return o.toString();
-// }
- // GEODE-2142: Added the cyclicalDepCheck
+
if (cyclicDepChkEnabled.get() != null && cyclicDependencySet.get() != null) {
- if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(o)) {
+ if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(object)) {
// break cyclic reference
- return o.getClass().getCanonicalName();
+ return object.getClass().getCanonicalName();
} else {
- cyclicDependencySet.get().add(o);
- return new JSONObject(o);
+ cyclicDependencySet.get().add(object);
+ return new JSONObject(object);
+ }
+ } else
+ return new JSONObject(object);
+
+ } catch (Exception exception) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Write the contents of the JSONObject as JSON text to a writer. For compactness, no whitespace
+ * is added.
+ * <p>
+ * 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 {
+ if (value == null || value.equals(null)) {
+ writer.write("null");
+ } else if (value instanceof JSONObject) {
+ ((JSONObject) value).write(writer, indentFactor, indent);
+ } else if (value instanceof JSONArray) {
+ ((JSONArray) value).write(writer, indentFactor, indent);
+ } else if (value instanceof Map) {
+ new JSONObject((Map) value).write(writer, indentFactor, indent);
+ } else if (value instanceof Collection) {
+ new JSONArray((Collection) value).write(writer, indentFactor, indent);
+ } else if (value.getClass().isArray()) {
+ new JSONArray(value).write(writer, indentFactor, indent);
+ } else if (value instanceof Number) {
+ writer.write(numberToString((Number) value));
+ } else if (value instanceof Boolean) {
+ writer.write(value.toString());
+ } else if (value instanceof JSONString) {
+ Object o;
+ try {
+ o = ((JSONString) value).toJSONString();
+ } catch (Exception e) {
+ throw new JSONException(e);
+ }
+ writer.write(o != null ? o.toString() : quote(value.toString()));
+ } else {
+ quote(value.toString(), writer);
+ }
+ return writer;
+ }
+
+ static final void indent(Writer writer, int indent) throws IOException {
+ for (int i = 0; i < indent; i += 1) {
+ writer.write(' ');
+ }
+ }
+
+ /**
+ * Write the contents of the JSONObject as JSON text to a writer. For compactness, no whitespace
+ * is added.
+ * <p>
+ * Warning: This method assumes that the data structure is acyclical.
+ *
+ * @return The writer.
+ * @throws JSONException
+ */
+ Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
+ try {
+ boolean commanate = false;
+ final int length = this.length();
+ Iterator keys = this.keys();
+ writer.write('{');
+
+ if (length == 1) {
+ Object key = keys.next();
+ writer.write(quote(key.toString()));
+ writer.write(':');
+ if (indentFactor > 0) {
+ writer.write(' ');
+ }
+ writeValue(writer, this.map.get(key), indentFactor, indent);
+ } else if (length != 0) {
+ final int newindent = indent + indentFactor;
+ while (keys.hasNext()) {
+ Object key = keys.next();
+ if (commanate) {
+ writer.write(',');
+ }
+ if (indentFactor > 0) {
+ writer.write('\n');
+ }
+ indent(writer, newindent);
+ writer.write(quote(key.toString()));
+ writer.write(':');
+ if (indentFactor > 0) {
+ writer.write(' ');
+ }
+ writeValue(writer, this.map.get(key), indentFactor, newindent);
+ commanate = true;
+ }
+ if (indentFactor > 0) {
+ writer.write('\n');
}
- } else {
- return new JSONObject(o);
+ indent(writer, indent);
}
- } catch (Exception ignored) {
+ writer.write('}');
+ return writer;
+ } catch (IOException exception) {
+ throw new JSONException(exception);
}
- return null;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONString.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONString.java b/geode-json/src/main/java/org/json/JSONString.java
index 34815a8..4a09d89 100755
--- a/geode-json/src/main/java/org/json/JSONString.java
+++ b/geode-json/src/main/java/org/json/JSONString.java
@@ -1,18 +1,17 @@
package org.json;
+
/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
- * method so that a class can change the behavior of
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The
- * <code>toJSONString</code> method will be used instead of the default behavior
- * of using the Object's <code>toString()</code> method and quoting the result.
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class
+ * can change the behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
+ * and <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will
+ * be used instead of the default behavior of using the Object's <code>toString()</code> method and
+ * quoting the result.
*/
public interface JSONString {
/**
- * The <code>toJSONString</code> method allows a class to produce its own JSON
- * serialization.
+ * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
*
* @return A strictly syntactically correct JSON text.
*/
public String toJSONString();
-}
\ No newline at end of file
+}
[8/8] geode git commit: Revert "GEODE-2142: Removal of non-compliant
org.json implementation."
Posted by ud...@apache.org.
Revert "GEODE-2142: Removal of non-compliant org.json implementation."
This reverts commit b3ec80bc72fee3a40da297945a85d8df6c2a6460.
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/0805036e
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/0805036e
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/0805036e
Branch: refs/heads/develop
Commit: 0805036e81756e3d843f3227e94927a520a07946
Parents: 1253d78
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 13:57:54 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 13:57:54 2017 -0800
----------------------------------------------------------------------
.../geode/management/internal/cli/CliUtil.java | 42 +
.../internal/cli/commands/ConfigCommands.java | 3 +-
...xportImportClusterConfigurationCommands.java | 2 +-
.../cli/functions/ExportConfigFunction.java | 4 +-
.../internal/cli/json/GfJsonObject.java | 54 +-
.../internal/cli/result/AbstractResultData.java | 56 +-
.../cli/result/CompositeResultData.java | 46 +
.../internal/cli/result/ResultBuilder.java | 30 +
.../cli/commands/CliCommandTestBase.java | 6 +-
geode-json/src/main/java/org/json/CDL.java | 272 +++
geode-json/src/main/java/org/json/Cookie.java | 162 ++
.../src/main/java/org/json/CookieList.java | 87 +
geode-json/src/main/java/org/json/HTTP.java | 185 ++
.../src/main/java/org/json/HTTPTokener.java | 77 +
geode-json/src/main/java/org/json/JSON.java | 116 --
.../src/main/java/org/json/JSONArray.java | 1587 +++++++-------
.../src/main/java/org/json/JSONException.java | 71 +-
geode-json/src/main/java/org/json/JSONML.java | 454 ++++
.../src/main/java/org/json/JSONObject.java | 1952 +++++++++++-------
.../src/main/java/org/json/JSONString.java | 17 +-
.../src/main/java/org/json/JSONStringer.java | 531 +----
.../src/main/java/org/json/JSONTokener.java | 1013 ++++-----
.../src/main/java/org/json/JSONWriter.java | 321 +++
geode-json/src/main/java/org/json/XML.java | 504 +++++
.../src/main/java/org/json/XMLTokener.java | 362 ++++
25 files changed, 5196 insertions(+), 2758 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
index a505001..8525b58 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
@@ -440,6 +440,11 @@ public class CliUtil {
compressedDataLength = compresser.deflate(buffer);
totalCompressedDataLength += compressedDataLength;
+ // System.out.println(compressedDataLength);
+ // System.out.println("uc: b "+buffer.length);
+ // System.out.println("uc: r "+result.length);
+ // System.out.println("uc: nr "+newResult.length);
+ // System.out.println();
System.arraycopy(buffer, 0, newResult, result.length, buffer.length);
result = newResult;
} while (compressedDataLength != 0);
@@ -495,6 +500,43 @@ public class CliUtil {
}
}
+ public static void main(String[] args) {
+ try {
+ byte[][] filesToBytes =
+ filesToBytes(new String[] {"/export/abhishek1/work/aspenmm/GFTryouts/test.json"});
+
+ System.out.println(filesToBytes[1].length);
+
+ DeflaterInflaterData compressBytes = compressBytes(filesToBytes[1]);
+ System.out.println(compressBytes);
+
+ DeflaterInflaterData uncompressBytes =
+ uncompressBytes(compressBytes.data, compressBytes.dataLength);
+ System.out.println(uncompressBytes);
+
+ System.out.println(new String(uncompressBytes.getData()));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (DataFormatException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main1(String[] args) {
+ try {
+ byte[][] fileToBytes = filesToBytes(new String[] {"../dumped/source/lib"});
+
+ bytesToFiles(fileToBytes, "../dumped/dest/lib/", true);
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
public static boolean contains(Object[] array, Object object) {
boolean contains = false;
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
index 283f09d..12a0a64 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
@@ -234,8 +234,7 @@ public class ConfigCommands extends AbstractCommandsSupport {
false);
}
}
- Result result = ResultBuilder.buildResult(infoData);
- return result;
+ return ResultBuilder.buildResult(infoData);
} catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
index 7485d9f..e94af4f 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
@@ -75,7 +75,6 @@ public class ExportImportClusterConfigurationCommands extends AbstractCommandsSu
public Result exportSharedConfig(@CliOption(key = {CliStrings.EXPORT_SHARED_CONFIG__FILE},
mandatory = true, help = CliStrings.EXPORT_SHARED_CONFIG__FILE__HELP) String zipFileName) {
- System.err.println("Out 1");
InternalLocator locator = InternalLocator.getLocator();
if (!locator.isSharedConfigurationRunning()) {
return ResultBuilder.createGemFireErrorResult(CliStrings.SHARED_CONFIGURATION_NOT_STARTED);
@@ -100,6 +99,7 @@ public class ExportImportClusterConfigurationCommands extends AbstractCommandsSu
sc.writeConfigToFile(config);
}
ZipUtils.zipDirectory(sc.getSharedConfigurationDirPath(), zipFile.getCanonicalPath());
+
InfoResultData infoData = ResultBuilder.createInfoResultData();
byte[] byteData = FileUtils.readFileToByteArray(zipFile);
infoData.addAsFile(zipFileName, byteData, InfoResultData.FILE_TYPE_BINARY,
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
index 64bc374..49e27b0 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
@@ -93,10 +93,12 @@ public class ExportConfigFunction implements Function, InternalEntity {
.append(lineSeparator);
}
}
+
CliFunctionResult result = new CliFunctionResult(memberId,
new String[] {xmlWriter.toString(), propStringBuf.toString()});
- System.err.println("ExportConfigFunction.execute CLI function result: "+result);
+
context.getResultSender().lastResult(result);
+
} catch (CacheClosedException cce) {
CliFunctionResult result = new CliFunctionResult(memberId, false, null);
context.getResultSender().lastResult(result);
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
index 9137f72..69666ff 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
@@ -49,6 +49,22 @@ public class GfJsonObject {
this.jsonObject = (JSONObject) bean;
} else {
this.jsonObject = new JSONObject(bean);
+ // If we want to print out the values of the primitive arrays and report back
+ // Class klass = bean.getClass();
+ // if(klass.isArray() && klass.getComponentType().isPrimitive()){
+ // String str = "";
+ // int length = Array.getLength(bean);
+ // for (int i = 0; i < length; i++) {
+ // if(i==0)
+ // str += (Array.get(bean, i));
+ // else
+ // str +=(","+Array.get(bean, i));
+ // }
+ // try {
+ // this.jsonObject.put("Value", str);
+ // } catch (JSONException ignore) {
+ // }
+ // }
}
if (checkCyclicDep) {
JSONObject.cyclicDepChkEnabled.set(false);
@@ -72,9 +88,9 @@ public class GfJsonObject {
}
}
-// public GfJsonObject(Object bean, String[] paramNames) {
-// this.jsonObject = new JSONObject(bean, paramNames);
-// }
+ public GfJsonObject(Object bean, String[] paramNames) {
+ this.jsonObject = new JSONObject(bean, paramNames);
+ }
/**
*
@@ -237,21 +253,21 @@ public class GfJsonObject {
return this;
}
-// /**
-// *
-// * @param key
-// * @param value
-// * @return this GfJsonObject
-// * @throws GfJsonException if the key is a duplicate
-// */
-// public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
-// try {
-// jsonObject.putOnce(key, value);
-// } catch (JSONException e) {
-// throw new GfJsonException(e.getMessage());
-// }
-// return this;
-// }
+ /**
+ *
+ * @param key
+ * @param value
+ * @return this GfJsonObject
+ * @throws GfJsonException if the key is a duplicate
+ */
+ public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
+ try {
+ jsonObject.putOnce(key, value);
+ } catch (JSONException e) {
+ throw new GfJsonException(e.getMessage());
+ }
+ return this;
+ }
/**
*
@@ -346,7 +362,7 @@ public class GfJsonObject {
}
}
- private Object extractInternalForGfJsonOrReturnSame(Object value) {
+ private static Object extractInternalForGfJsonOrReturnSame(Object value) {
Object returnedValue = value;
if (value instanceof GfJsonObject) {
returnedValue = ((GfJsonObject) value).getInternalJsonObject();
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
index 81ab511..e08d9b7 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
@@ -20,10 +20,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
import java.text.MessageFormat;
-import java.util.Base64;
import java.util.zip.DataFormatException;
import org.apache.geode.management.cli.Result.Status;
@@ -154,10 +151,26 @@ public abstract class AbstractResultData implements ResultData {
if (addTimeStampToName) {
fileName = addTimeStampBeforeLastDot(fileName);
}
- return addAsFile(fileName, bytes, fileType, message);
+ return addAsFile(fileName.getBytes(), bytes, fileType, message);
}
- private ResultData addAsFile(String fileName, byte[] data, int fileType, String message) {
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ byte[][] filesToBytes = CliUtil.filesToBytes(new String[] {filePath});
+
+ byte[] bytes = filesToBytes[0];
+ if (addTimeStampToName) {
+ String fileName = new String(filesToBytes[0]);
+ fileName = addTimeStampBeforeLastDot(fileName);
+ bytes = fileName.getBytes();
+ }
+ return addAsFile(bytes, filesToBytes[1], fileType, message);
+ }
+
+ private ResultData addAsFile(byte[] fileName, byte[] data, int fileType, String message) {
+ // System.out.println("fileType :: "+fileType);
+ // System.out.println("FILE_TYPE_BINARY :: "+FILE_TYPE_BINARY);
+ // System.out.println("FILE_TYPE_TEXT :: "+FILE_TYPE_TEXT);
if (fileType != FILE_TYPE_BINARY && fileType != FILE_TYPE_TEXT) {
throw new IllegalArgumentException("Unsupported file type is specified.");
}
@@ -173,12 +186,14 @@ public abstract class AbstractResultData implements ResultData {
sectionData.put(FILE_NAME_FIELD, fileName);
sectionData.put(FILE_TYPE_FIELD, fileType);
- sectionData.put(FILE_MESSAGE, message);
- DeflaterInflaterData deflaterInflaterData = CliUtil.compressBytes(data);
- sectionData.put(FILE_DATA_FIELD, Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
- sectionData.put(DATA_LENGTH_FIELD,deflaterInflaterData.getDataLength());
+ sectionData.put(FILE_MESSAGE, message.getBytes());
+ sectionData.putAsJSONObject(FILE_DATA_FIELD, CliUtil.compressBytes(data));
+ // System.out.println(data);
+ // sectionData.put(FILE_DATA_FIELD, Base64.encodeBytes(data, Base64.GZIP));
} catch (GfJsonException e) {
throw new ResultDataException(e.getMessage());
+ // } catch (IOException e) {
+ // e.printStackTrace();
}
return this;
}
@@ -208,30 +223,29 @@ public abstract class AbstractResultData implements ResultData {
// build file name
byte[] fileNameBytes = null;
- String fileName = null;
GfJsonArray fileNameJsonBytes = object.getJSONArray(FILE_NAME_FIELD);
if (fileNameJsonBytes != null) { // if in gfsh
fileNameBytes = GfJsonArray.toByteArray(fileNameJsonBytes);
- fileName = new String(fileNameBytes);
} else { // if on member
- fileName = (String) object.get(FILE_NAME_FIELD);
+ fileNameBytes = (byte[]) object.get(FILE_NAME_FIELD);
}
+ String fileName = new String(fileNameBytes);
// build file message
byte[] fileMessageBytes = null;
- String fileMessage = null;
GfJsonArray fileMessageJsonBytes = object.getJSONArray(FILE_MESSAGE);
if (fileMessageJsonBytes != null) { // if in gfsh
fileMessageBytes = GfJsonArray.toByteArray(fileMessageJsonBytes);
- fileMessage = new String(fileMessageBytes);
} else { // if on member
- fileMessage = (String) object.get(FILE_MESSAGE);
+ fileMessageBytes = (byte[]) object.get(FILE_MESSAGE);
}
+ String fileMessage = new String(fileMessageBytes);
- String fileDataString = (String) object.get(FILE_DATA_FIELD);
- int fileDataLength = (int) object.get(DATA_LENGTH_FIELD);
- byte[] byteArray = Base64.getDecoder().decode(fileDataString);
- byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray,fileDataLength).getData();
+ GfJsonObject fileDataBytes = object.getJSONObject(FILE_DATA_FIELD);
+ byte[] byteArray = GfJsonArray.toByteArray(fileDataBytes.getJSONArray(DATA_FIELD));
+ int dataLength = fileDataBytes.getInt(DATA_LENGTH_FIELD);
+ DeflaterInflaterData uncompressBytes = CliUtil.uncompressBytes(byteArray, dataLength);
+ byte[] uncompressed = uncompressBytes.getData();
boolean isGfshVM = CliUtil.isGfshVM();
File fileToDumpData = new File(fileName);
@@ -285,13 +299,13 @@ public abstract class AbstractResultData implements ResultData {
if (fileType == FILE_TYPE_TEXT) {
FileWriter fw = new FileWriter(fileToDumpData);
BufferedWriter bw = new BufferedWriter(fw);
- bw.write(new String(uncompressBytes));
+ bw.write(new String(uncompressed));
bw.flush();
fw.flush();
fw.close();
} else if (fileType == FILE_TYPE_BINARY) {
FileOutputStream fos = new FileOutputStream(fileToDumpData);
- fos.write(uncompressBytes);
+ fos.write(uncompressed);
fos.flush();
fos.close();
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
index c1db133..7d0d23b 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
@@ -324,4 +324,50 @@ public class CompositeResultData extends AbstractResultData {
// }
}
+ public static void main(String[] args) {
+ CompositeResultData crd = new CompositeResultData();
+
+ SectionResultData r1Section = crd.addSection("R1");
+ r1Section.addData("Region", "R1").addData("IsPartitioned", false).addData("IsPersistent", true)
+ .addData("Disk Store", "DiskStore1").addData("Group", "Group1");
+ TabularResultData r1Table = r1Section.addTable("R1Members");
+ r1Table.accumulate("Member Id", "host1(3467):12435:12423")
+ .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
+ .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1);
+ r1Table.accumulate("Member Id", "host3(5756):57665:90923")
+ .accumulate("PrimaryEntryCount", 25000).accumulate("BackupEntryCount", 10000)
+ .accumulate("Memory(MB)", "200").accumulate("NumOfCopies", 1);
+
+ SectionResultData r3Section = crd.addSection("R3");
+ r3Section.addData("Region", "R3").addData("IsPartitioned", true).addData("IsPersistent", true)
+ .addData("Disk Store", "DiskStore2").addData("Group", "Group2")
+ .addData("ColocatedWith", "-");
+ SectionResultData r3SubSection = r3Section.addSection("R3Config");
+ r3SubSection.addData("Configuration", "");
+ r3SubSection.addData("Config1", "abcd");
+ r3SubSection.addData("Config2", "abcde");
+ r3SubSection.addData("Config3", "abcdfg");
+ TabularResultData r3Table = r3Section.addTable("R3Members");
+ r3Table.accumulate("Member Id", "host1(3467):12435:12423")
+ .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
+ .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1)
+ .accumulate("NumOfBuckets", 100);
+ r3Table.accumulate("Member Id", "host2(3353):23545:14723")
+ .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
+ .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1)
+ .accumulate("NumOfBuckets", 100);
+ r3Table.accumulate("Member Id", "host3(5756):57665:90923")
+ .accumulate("PrimaryEntryCount", 25000).accumulate("BackupEntryCount", 10000)
+ .accumulate("Memory(MB)", "200").accumulate("NumOfCopies", 1)
+ .accumulate("NumOfBuckets", 100);
+
+ try {
+ System.out.println(crd.getGfJsonObject().toIndentedString(/* 2 */0));
+
+ } catch (GfJsonException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
index 9bd2bf9..06060a4 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
@@ -301,6 +301,12 @@ public class ResultBuilder {
}
@Override
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ throw new UnsupportedOperationException("This is read only result data");
+ }
+
+ @Override
public TabularResultData accumulate(String accumulateFor, Object value) {
throw new UnsupportedOperationException("This is read only result data");
}
@@ -320,6 +326,12 @@ public class ResultBuilder {
}
@Override
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ throw new UnsupportedOperationException("This is read only result data");
+ }
+
+ @Override
public ErrorResultData addLine(String line) {
throw new UnsupportedOperationException("This is read only result data");
}
@@ -339,6 +351,12 @@ public class ResultBuilder {
}
@Override
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ throw new UnsupportedOperationException("This is read only result data");
+ }
+
+ @Override
public ErrorResultData addLine(String line) {
throw new UnsupportedOperationException("This is read only result data");
}
@@ -363,6 +381,12 @@ public class ResultBuilder {
}
@Override
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ throw new UnsupportedOperationException("This is read only result data");
+ }
+
+ @Override
public SectionResultData addSection() {
throw new UnsupportedOperationException("This is read only result data");
}
@@ -392,6 +416,12 @@ public class ResultBuilder {
}
@Override
+ public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
+ boolean addTimeStampToName) throws FileNotFoundException, IOException {
+ throw new UnsupportedOperationException("This is read only result data");
+ }
+
+ @Override
public ObjectResultData<CliJsonSerializable> addCollection(
Collection<CliJsonSerializable> infoBeans) {
throw new UnsupportedOperationException("This is read only result data");
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
index 239810b..21426d6 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
@@ -360,11 +360,7 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase {
CommandResult result = null;
try {
- Object result1 = shell.getResult();
- if (result1 instanceof String) {
- System.err.println("result1 = " + result1);
- }
- result = (CommandResult) result1; // TODO: this can result in ClassCastException if
+ result = (CommandResult) shell.getResult(); // TODO: this can result in ClassCastException if
// command resulted in error
} catch (InterruptedException ex) {
error("shell received InterruptedException");
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/CDL.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/CDL.java b/geode-json/src/main/java/org/json/CDL.java
new file mode 100755
index 0000000..d78935b
--- /dev/null
+++ b/geode-json/src/main/java/org/json/CDL.java
@@ -0,0 +1,272 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * This provides static methods to convert comma delimited text into a JSONArray, and to covert a
+ * JSONArray into comma delimited text. Comma delimited text is a very popular format for data
+ * interchange. It is understood by most database, spreadsheet, and organizer programs.
+ * <p>
+ * Each row of text represents a row in a table or a data record. Each row ends with a NEWLINE
+ * character. Each row contains one or more values. Values are separated by commas. A value can
+ * contain any character except for comma, unless is is wrapped in single quotes or double quotes.
+ * <p>
+ * The first row usually contains the names of the columns.
+ * <p>
+ * A comma delimited list can be converted into a JSONArray of JSONObjects. The names for the
+ * elements in the JSONObjects can be taken from the names in the first row.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class CDL {
+
+ /**
+ * Get the next value. The value can be wrapped in quotes. The value can be empty.
+ *
+ * @param x A JSONTokener of the source text.
+ * @return The value string, or null if empty.
+ * @throws JSONException if the quoted string is badly formed.
+ */
+ private static String getValue(JSONTokener x) throws JSONException {
+ char c;
+ char q;
+ StringBuffer sb;
+ do {
+ c = x.next();
+ } while (c == ' ' || c == '\t');
+ switch (c) {
+ case 0:
+ return null;
+ case '"':
+ case '\'':
+ q = c;
+ sb = new StringBuffer();
+ for (;;) {
+ c = x.next();
+ if (c == q) {
+ break;
+ }
+ if (c == 0 || c == '\n' || c == '\r') {
+ throw x.syntaxError("Missing close quote '" + q + "'.");
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ case ',':
+ x.back();
+ return "";
+ default:
+ x.back();
+ return x.nextTo(',');
+ }
+ }
+
+ /**
+ * Produce a JSONArray of strings from a row of comma delimited values.
+ *
+ * @param x A JSONTokener of the source text.
+ * @return A JSONArray of strings.
+ * @throws JSONException
+ */
+ public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
+ JSONArray ja = new JSONArray();
+ for (;;) {
+ String value = getValue(x);
+ char c = x.next();
+ if (value == null || (ja.length() == 0 && value.length() == 0 && c != ',')) {
+ return null;
+ }
+ ja.put(value);
+ for (;;) {
+ if (c == ',') {
+ break;
+ }
+ if (c != ' ') {
+ if (c == '\n' || c == '\r' || c == 0) {
+ return ja;
+ }
+ throw x.syntaxError("Bad character '" + c + "' (" + (int) c + ").");
+ }
+ c = x.next();
+ }
+ }
+ }
+
+ /**
+ * Produce a JSONObject from a row of comma delimited text, using a parallel JSONArray of strings
+ * to provides the names of the elements.
+ *
+ * @param names A JSONArray of names. This is commonly obtained from the first row of a comma
+ * delimited text file using the rowToJSONArray method.
+ * @param x A JSONTokener of the source text.
+ * @return A JSONObject combining the names and values.
+ * @throws JSONException
+ */
+ public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) throws JSONException {
+ JSONArray ja = rowToJSONArray(x);
+ return ja != null ? ja.toJSONObject(names) : null;
+ }
+
+ /**
+ * Produce a comma delimited text row from a JSONArray. Values containing the comma character will
+ * be quoted. Troublesome characters may be removed.
+ *
+ * @param ja A JSONArray of strings.
+ * @return A string ending in NEWLINE.
+ */
+ public static String rowToString(JSONArray ja) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < ja.length(); i += 1) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ Object object = ja.opt(i);
+ if (object != null) {
+ String string = object.toString();
+ if (string.length() > 0 && (string.indexOf(',') >= 0 || string.indexOf('\n') >= 0
+ || string.indexOf('\r') >= 0 || string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
+ sb.append('"');
+ int length = string.length();
+ for (int j = 0; j < length; j += 1) {
+ char c = string.charAt(j);
+ if (c >= ' ' && c != '"') {
+ sb.append(c);
+ }
+ }
+ sb.append('"');
+ } else {
+ sb.append(string);
+ }
+ }
+ }
+ sb.append('\n');
+ return sb.toString();
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a
+ * source of names.
+ *
+ * @param string The comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(String string) throws JSONException {
+ return toJSONArray(new JSONTokener(string));
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a
+ * source of names.
+ *
+ * @param x The JSONTokener containing the comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
+ return toJSONArray(rowToJSONArray(x), x);
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied
+ * JSONArray as the source of element names.
+ *
+ * @param names A JSONArray of strings.
+ * @param string The comma delimited text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONArray names, String string) throws JSONException {
+ return toJSONArray(names, new JSONTokener(string));
+ }
+
+ /**
+ * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied
+ * JSONArray as the source of element names.
+ *
+ * @param names A JSONArray of strings.
+ * @param x A JSONTokener of the source text.
+ * @return A JSONArray of JSONObjects.
+ * @throws JSONException
+ */
+ public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException {
+ if (names == null || names.length() == 0) {
+ return null;
+ }
+ JSONArray ja = new JSONArray();
+ for (;;) {
+ JSONObject jo = rowToJSONObject(names, x);
+ if (jo == null) {
+ break;
+ }
+ ja.put(jo);
+ }
+ if (ja.length() == 0) {
+ return null;
+ }
+ return ja;
+ }
+
+
+ /**
+ * Produce a comma delimited text from a JSONArray of JSONObjects. The first row will be a list of
+ * names obtained by inspecting the first JSONObject.
+ *
+ * @param ja A JSONArray of JSONObjects.
+ * @return A comma delimited text.
+ * @throws JSONException
+ */
+ public static String toString(JSONArray ja) throws JSONException {
+ JSONObject jo = ja.optJSONObject(0);
+ if (jo != null) {
+ JSONArray names = jo.names();
+ if (names != null) {
+ return rowToString(names) + toString(names, ja);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Produce a comma delimited text from a JSONArray of JSONObjects using a provided list of names.
+ * The list of names is not included in the output.
+ *
+ * @param names A JSONArray of strings.
+ * @param ja A JSONArray of JSONObjects.
+ * @return A comma delimited text.
+ * @throws JSONException
+ */
+ public static String toString(JSONArray names, JSONArray ja) throws JSONException {
+ if (names == null || names.length() == 0) {
+ return null;
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < ja.length(); i += 1) {
+ JSONObject jo = ja.optJSONObject(i);
+ if (jo != null) {
+ sb.append(rowToString(jo.toJSONArray(names)));
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/Cookie.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/Cookie.java b/geode-json/src/main/java/org/json/Cookie.java
new file mode 100755
index 0000000..21f88d8
--- /dev/null
+++ b/geode-json/src/main/java/org/json/Cookie.java
@@ -0,0 +1,162 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Convert a web browser cookie specification to a JSONObject and back. JSON and Cookies are both
+ * notations for name/value pairs.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class Cookie {
+
+ /**
+ * Produce a copy of a string in which the characters '+', '%', '=', ';' and control characters
+ * are replaced with "%hh". This is a gentle form of URL encoding, attempting to cause as little
+ * distortion to the string as possible. The characters '=' and ';' are meta characters in
+ * cookies. By convention, they are escaped using the URL-encoding. This is only a convention, not
+ * a standard. Often, cookies are expected to have encoded values. We encode '=' and ';' because
+ * we must. We encode '%' and '+' because they are meta characters in URL encoding.
+ *
+ * @param string The source string.
+ * @return The escaped result.
+ */
+ public static String escape(String string) {
+ char c;
+ String s = string.trim();
+ StringBuffer sb = new StringBuffer();
+ int length = s.length();
+ for (int i = 0; i < length; i += 1) {
+ c = s.charAt(i);
+ if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
+ sb.append('%');
+ sb.append(Character.forDigit((char) ((c >>> 4) & 0x0f), 16));
+ sb.append(Character.forDigit((char) (c & 0x0f), 16));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * Convert a cookie specification string into a JSONObject. The string will contain a name value
+ * pair separated by '='. The name and the value will be unescaped, possibly converting '+' and
+ * '%' sequences. The cookie properties may follow, separated by ';', also represented as
+ * name=value (except the secure property, which does not have a value). The name will be stored
+ * under the key "name", and the value will be stored under the key "value". This method does not
+ * do checking or validation of the parameters. It only converts the cookie string into a
+ * JSONObject.
+ *
+ * @param string The cookie specification string.
+ * @return A JSONObject containing "name", "value", and possibly other members.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ String name;
+ JSONObject jo = new JSONObject();
+ Object value;
+ JSONTokener x = new JSONTokener(string);
+ jo.put("name", x.nextTo('='));
+ x.next('=');
+ jo.put("value", x.nextTo(';'));
+ x.next();
+ while (x.more()) {
+ name = unescape(x.nextTo("=;"));
+ if (x.next() != '=') {
+ if (name.equals("secure")) {
+ value = Boolean.TRUE;
+ } else {
+ throw x.syntaxError("Missing '=' in cookie parameter.");
+ }
+ } else {
+ value = unescape(x.nextTo(';'));
+ x.next();
+ }
+ jo.put(name, value);
+ }
+ return jo;
+ }
+
+
+ /**
+ * Convert a JSONObject into a cookie specification string. The JSONObject must contain "name" and
+ * "value" members. If the JSONObject contains "expires", "domain", "path", or "secure" members,
+ * they will be appended to the cookie specification string. All other members are ignored.
+ *
+ * @param jo A JSONObject
+ * @return A cookie specification string
+ * @throws JSONException
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(escape(jo.getString("name")));
+ sb.append("=");
+ sb.append(escape(jo.getString("value")));
+ if (jo.has("expires")) {
+ sb.append(";expires=");
+ sb.append(jo.getString("expires"));
+ }
+ if (jo.has("domain")) {
+ sb.append(";domain=");
+ sb.append(escape(jo.getString("domain")));
+ }
+ if (jo.has("path")) {
+ sb.append(";path=");
+ sb.append(escape(jo.getString("path")));
+ }
+ if (jo.optBoolean("secure")) {
+ sb.append(";secure");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert <code>%</code><i>hh</i> sequences to single characters, and convert plus to space.
+ *
+ * @param string A string that may contain <code>+</code> <small>(plus)</small> and
+ * <code>%</code><i>hh</i> sequences.
+ * @return The unescaped string.
+ */
+ public static String unescape(String string) {
+ int length = string.length();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < length; ++i) {
+ char c = string.charAt(i);
+ if (c == '+') {
+ c = ' ';
+ } else if (c == '%' && i + 2 < length) {
+ int d = JSONTokener.dehexchar(string.charAt(i + 1));
+ int e = JSONTokener.dehexchar(string.charAt(i + 2));
+ if (d >= 0 && e >= 0) {
+ c = (char) (d * 16 + e);
+ i += 2;
+ }
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/CookieList.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/CookieList.java b/geode-json/src/main/java/org/json/CookieList.java
new file mode 100755
index 0000000..35e1a97
--- /dev/null
+++ b/geode-json/src/main/java/org/json/CookieList.java
@@ -0,0 +1,87 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import java.util.Iterator;
+
+/**
+ * Convert a web browser cookie list string to a JSONObject and back.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class CookieList {
+
+ /**
+ * Convert a cookie list into a JSONObject. A cookie list is a sequence of name/value pairs. The
+ * names are separated from the values by '='. The pairs are separated by ';'. The names and the
+ * values will be unescaped, possibly converting '+' and '%' sequences.
+ *
+ * To add a cookie to a cooklist, cookielistJSONObject.put(cookieJSONObject.getString("name"),
+ * cookieJSONObject.getString("value"));
+ *
+ * @param string A cookie list string
+ * @return A JSONObject
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ JSONObject jo = new JSONObject();
+ JSONTokener x = new JSONTokener(string);
+ while (x.more()) {
+ String name = Cookie.unescape(x.nextTo('='));
+ x.next('=');
+ jo.put(name, Cookie.unescape(x.nextTo(';')));
+ x.next();
+ }
+ return jo;
+ }
+
+
+ /**
+ * Convert a JSONObject into a cookie list. A cookie list is a sequence of name/value pairs. The
+ * names are separated from the values by '='. The pairs are separated by ';'. The characters '%',
+ * '+', '=', and ';' in the names and values are replaced by "%hh".
+ *
+ * @param jo A JSONObject
+ * @return A cookie list string
+ * @throws JSONException
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ boolean b = false;
+ Iterator keys = jo.keys();
+ String string;
+ StringBuffer sb = new StringBuffer();
+ while (keys.hasNext()) {
+ string = keys.next().toString();
+ if (!jo.isNull(string)) {
+ if (b) {
+ sb.append(';');
+ }
+ sb.append(Cookie.escape(string));
+ sb.append("=");
+ sb.append(Cookie.escape(jo.getString(string)));
+ b = true;
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/HTTP.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/HTTP.java b/geode-json/src/main/java/org/json/HTTP.java
new file mode 100755
index 0000000..1e815aa
--- /dev/null
+++ b/geode-json/src/main/java/org/json/HTTP.java
@@ -0,0 +1,185 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import java.util.Iterator;
+
+/**
+ * Convert an HTTP header to a JSONObject and back.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class HTTP {
+
+ /** Carriage return/line feed. */
+ public static final String CRLF = "\r\n";
+
+ /**
+ * Convert an HTTP header string into a JSONObject. It can be a request header or a response
+ * header. A request header will contain
+ *
+ * <pre>
+ * {
+ * Method: "POST" (for example),
+ * "Request-URI": "/" (for example),
+ * "HTTP-Version": "HTTP/1.1" (for example)
+ * }
+ * </pre>
+ *
+ * A response header will contain
+ *
+ * <pre>
+ * {
+ * "HTTP-Version": "HTTP/1.1" (for example),
+ * "Status-Code": "200" (for example),
+ * "Reason-Phrase": "OK" (for example)
+ * }
+ * </pre>
+ *
+ * In addition, the other parameters in the header will be captured, using the HTTP field names as
+ * JSON names, so that
+ *
+ * <pre>
+ * Date: Sun, 26 May 2002 18:06:04 GMT
+ * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
+ * Cache-Control: no-cache
+ * </pre>
+ *
+ * become
+ *
+ * <pre>
+ * {...
+ * Date: "Sun, 26 May 2002 18:06:04 GMT",
+ * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
+ * "Cache-Control": "no-cache",
+ * ...}
+ * </pre>
+ *
+ * It does no further checking or conversion. It does not parse dates. It does not do '%'
+ * transforms on URLs.
+ *
+ * @param string An HTTP header string.
+ * @return A JSONObject containing the elements and attributes of the XML string.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ JSONObject jo = new JSONObject();
+ HTTPTokener x = new HTTPTokener(string);
+ String token;
+
+ token = x.nextToken();
+ if (token.toUpperCase().startsWith("HTTP")) {
+
+ // Response
+
+ jo.put("HTTP-Version", token);
+ jo.put("Status-Code", x.nextToken());
+ jo.put("Reason-Phrase", x.nextTo('\0'));
+ x.next();
+
+ } else {
+
+ // Request
+
+ jo.put("Method", token);
+ jo.put("Request-URI", x.nextToken());
+ jo.put("HTTP-Version", x.nextToken());
+ }
+
+ // Fields
+
+ while (x.more()) {
+ String name = x.nextTo(':');
+ x.next(':');
+ jo.put(name, x.nextTo('\0'));
+ x.next();
+ }
+ return jo;
+ }
+
+
+ /**
+ * Convert a JSONObject into an HTTP header. A request header must contain
+ *
+ * <pre>
+ * {
+ * Method: "POST" (for example),
+ * "Request-URI": "/" (for example),
+ * "HTTP-Version": "HTTP/1.1" (for example)
+ * }
+ * </pre>
+ *
+ * A response header must contain
+ *
+ * <pre>
+ * {
+ * "HTTP-Version": "HTTP/1.1" (for example),
+ * "Status-Code": "200" (for example),
+ * "Reason-Phrase": "OK" (for example)
+ * }
+ * </pre>
+ *
+ * Any other members of the JSONObject will be output as HTTP fields. The result will end with two
+ * CRLF pairs.
+ *
+ * @param jo A JSONObject
+ * @return An HTTP header string.
+ * @throws JSONException if the object does not contain enough information.
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ Iterator keys = jo.keys();
+ String string;
+ StringBuffer sb = new StringBuffer();
+ if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
+ sb.append(jo.getString("HTTP-Version"));
+ sb.append(' ');
+ sb.append(jo.getString("Status-Code"));
+ sb.append(' ');
+ sb.append(jo.getString("Reason-Phrase"));
+ } else if (jo.has("Method") && jo.has("Request-URI")) {
+ sb.append(jo.getString("Method"));
+ sb.append(' ');
+ sb.append('"');
+ sb.append(jo.getString("Request-URI"));
+ sb.append('"');
+ sb.append(' ');
+ sb.append(jo.getString("HTTP-Version"));
+ } else {
+ throw new JSONException("Not enough material for an HTTP header.");
+ }
+ sb.append(CRLF);
+ while (keys.hasNext()) {
+ string = keys.next().toString();
+ if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string)
+ && !"Reason-Phrase".equals(string) && !"Method".equals(string)
+ && !"Request-URI".equals(string) && !jo.isNull(string)) {
+ sb.append(string);
+ sb.append(": ");
+ sb.append(jo.getString(string));
+ sb.append(CRLF);
+ }
+ }
+ sb.append(CRLF);
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/HTTPTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/HTTPTokener.java b/geode-json/src/main/java/org/json/HTTPTokener.java
new file mode 100755
index 0000000..72c9b88
--- /dev/null
+++ b/geode-json/src/main/java/org/json/HTTPTokener.java
@@ -0,0 +1,77 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * The HTTPTokener extends the JSONTokener to provide additional methods for the parsing of HTTP
+ * headers.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class HTTPTokener extends JSONTokener {
+
+ /**
+ * Construct an HTTPTokener from a string.
+ *
+ * @param string A source string.
+ */
+ public HTTPTokener(String string) {
+ super(string);
+ }
+
+
+ /**
+ * Get the next token or string. This is used in parsing HTTP headers.
+ *
+ * @throws JSONException
+ * @return A String.
+ */
+ public String nextToken() throws JSONException {
+ char c;
+ char q;
+ StringBuffer sb = new StringBuffer();
+ do {
+ c = next();
+ } while (Character.isWhitespace(c));
+ if (c == '"' || c == '\'') {
+ q = c;
+ for (;;) {
+ c = next();
+ if (c < ' ') {
+ throw syntaxError("Unterminated string.");
+ }
+ if (c == q) {
+ return sb.toString();
+ }
+ sb.append(c);
+ }
+ }
+ for (;;) {
+ if (c == 0 || Character.isWhitespace(c)) {
+ return sb.toString();
+ }
+ sb.append(c);
+ c = next();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSON.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSON.java b/geode-json/src/main/java/org/json/JSON.java
deleted file mode 100755
index 1b32e69..0000000
--- a/geode-json/src/main/java/org/json/JSON.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.json;
-
-class JSON {
- /**
- * Returns the input if it is a JSON-permissible value; throws otherwise.
- */
- static double checkDouble(double d) throws JSONException {
- if (Double.isInfinite(d) || Double.isNaN(d)) {
- throw new JSONException("Forbidden numeric value: " + d);
- }
- return d;
- }
-
- static Boolean toBoolean(Object value) {
- if (value instanceof Boolean) {
- return (Boolean) value;
- } else if (value instanceof String) {
- String stringValue = (String) value;
- if ("true".equalsIgnoreCase(stringValue)) {
- return true;
- } else if ("false".equalsIgnoreCase(stringValue)) {
- return false;
- }
- }
- return null;
- }
-
- static Double toDouble(Object value) {
- if (value instanceof Double) {
- return (Double) value;
- } else if (value instanceof Number) {
- return ((Number) value).doubleValue();
- } else if (value instanceof String) {
- try {
- return Double.valueOf((String) value);
- } catch (NumberFormatException ignored) {
- }
- }
- return null;
- }
-
- static Integer toInteger(Object value) {
- if (value instanceof Integer) {
- return (Integer) value;
- } else if (value instanceof Number) {
- return ((Number) value).intValue();
- } else if (value instanceof String) {
- try {
- return (int) Double.parseDouble((String) value);
- } catch (NumberFormatException ignored) {
- }
- }
- return null;
- }
-
- static Long toLong(Object value) {
- if (value instanceof Long) {
- return (Long) value;
- } else if (value instanceof Number) {
- return ((Number) value).longValue();
- } else if (value instanceof String) {
- try {
- return (long) Double.parseDouble((String) value);
- } catch (NumberFormatException ignored) {
- }
- }
- return null;
- }
-
- static String toString(Object value) {
- if (value instanceof String) {
- return (String) value;
- } else if (value != null) {
- return String.valueOf(value);
- }
- return null;
- }
-
- public static JSONException typeMismatch(Object indexOrName, Object actual,
- String requiredType) throws JSONException {
- if (actual == null) {
- throw new JSONException("Value at " + indexOrName + " is null.");
- } else {
- throw new JSONException("Value " + actual + " at " + indexOrName
- + " of type " + actual.getClass().getName()
- + " cannot be converted to " + requiredType);
- }
- }
-
- public static JSONException typeMismatch(Object actual, String requiredType)
- throws JSONException {
- if (actual == null) {
- throw new JSONException("Value is null.");
- } else {
- throw new JSONException("Value " + actual
- + " of type " + actual.getClass().getName()
- + " cannot be converted to " + requiredType);
- }
- }
-}
[4/8] geode git commit: Revert "GEODE-2142: Removal of non-compliant
org.json implementation."
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/XMLTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/XMLTokener.java b/geode-json/src/main/java/org/json/XMLTokener.java
new file mode 100755
index 0000000..f56a1f6
--- /dev/null
+++ b/geode-json/src/main/java/org/json/XMLTokener.java
@@ -0,0 +1,362 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * The XMLTokener extends the JSONTokener to provide additional methods for the parsing of XML
+ * texts.
+ *
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class XMLTokener extends JSONTokener {
+
+
+ /**
+ * The table of entity values. It initially contains Character values for amp, apos, gt, lt, quot.
+ */
+ public static final java.util.HashMap entity;
+
+ static {
+ entity = new java.util.HashMap(8);
+ entity.put("amp", XML.AMP);
+ entity.put("apos", XML.APOS);
+ entity.put("gt", XML.GT);
+ entity.put("lt", XML.LT);
+ entity.put("quot", XML.QUOT);
+ }
+
+ /**
+ * Construct an XMLTokener from a string.
+ *
+ * @param s A source string.
+ */
+ public XMLTokener(String s) {
+ super(s);
+ }
+
+ /**
+ * Get the text in the CDATA block.
+ *
+ * @return The string up to the <code>]]></code>.
+ * @throws JSONException If the <code>]]></code> is not found.
+ */
+ public String nextCDATA() throws JSONException {
+ char c;
+ int i;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = next();
+ if (end()) {
+ throw syntaxError("Unclosed CDATA");
+ }
+ sb.append(c);
+ i = sb.length() - 3;
+ if (i >= 0 && sb.charAt(i) == ']' && sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
+ sb.setLength(i);
+ return sb.toString();
+ }
+ }
+ }
+
+
+ /**
+ * Get the next XML outer token, trimming whitespace. There are two kinds of tokens: the '<'
+ * character which begins a markup tag, and the content text between markup tags.
+ *
+ * @return A string, or a '<' Character, or null if there is no more source text.
+ * @throws JSONException
+ */
+ public Object nextContent() throws JSONException {
+ char c;
+ StringBuffer sb;
+ do {
+ c = next();
+ } while (Character.isWhitespace(c));
+ if (c == 0) {
+ return null;
+ }
+ if (c == '<') {
+ return XML.LT;
+ }
+ sb = new StringBuffer();
+ for (;;) {
+ if (c == '<' || c == 0) {
+ back();
+ return sb.toString().trim();
+ }
+ if (c == '&') {
+ sb.append(nextEntity(c));
+ } else {
+ sb.append(c);
+ }
+ c = next();
+ }
+ }
+
+
+ /**
+ * Return the next entity. These entities are translated to Characters:
+ * <code>& ' > < "</code>.
+ *
+ * @param ampersand An ampersand character.
+ * @return A Character or an entity String if the entity is not recognized.
+ * @throws JSONException If missing ';' in XML entity.
+ */
+ public Object nextEntity(char ampersand) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ char c = next();
+ if (Character.isLetterOrDigit(c) || c == '#') {
+ sb.append(Character.toLowerCase(c));
+ } else if (c == ';') {
+ break;
+ } else {
+ throw syntaxError("Missing ';' in XML entity: &" + sb);
+ }
+ }
+ String string = sb.toString();
+ Object object = entity.get(string);
+ return object != null ? object : ampersand + string + ";";
+ }
+
+
+ /**
+ * Returns the next XML meta token. This is used for skipping over <!...> and <?...?> structures.
+ *
+ * @return Syntax characters (<code>< > / = ! ?</code>) are returned as Character, and strings and
+ * names are returned as Boolean. We don't care what the values actually are.
+ * @throws JSONException If a string is not properly closed or if the XML is badly structured.
+ */
+ public Object nextMeta() throws JSONException {
+ char c;
+ char q;
+ do {
+ c = next();
+ } while (Character.isWhitespace(c));
+ switch (c) {
+ case 0:
+ throw syntaxError("Misshaped meta tag");
+ case '<':
+ return XML.LT;
+ case '>':
+ return XML.GT;
+ case '/':
+ return XML.SLASH;
+ case '=':
+ return XML.EQ;
+ case '!':
+ return XML.BANG;
+ case '?':
+ return XML.QUEST;
+ case '"':
+ case '\'':
+ q = c;
+ for (;;) {
+ c = next();
+ if (c == 0) {
+ throw syntaxError("Unterminated string");
+ }
+ if (c == q) {
+ return Boolean.TRUE;
+ }
+ }
+ default:
+ for (;;) {
+ c = next();
+ if (Character.isWhitespace(c)) {
+ return Boolean.TRUE;
+ }
+ switch (c) {
+ case 0:
+ case '<':
+ case '>':
+ case '/':
+ case '=':
+ case '!':
+ case '?':
+ case '"':
+ case '\'':
+ back();
+ return Boolean.TRUE;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Get the next XML Token. These tokens are found inside of angle brackets. It may be one of these
+ * characters: <code>/ > = ! ?</code> or it may be a string wrapped in single quotes or double
+ * quotes, or it may be a name.
+ *
+ * @return a String or a Character.
+ * @throws JSONException If the XML is not well formed.
+ */
+ public Object nextToken() throws JSONException {
+ char c;
+ char q;
+ StringBuffer sb;
+ do {
+ c = next();
+ } while (Character.isWhitespace(c));
+ switch (c) {
+ case 0:
+ throw syntaxError("Misshaped element");
+ case '<':
+ throw syntaxError("Misplaced '<'");
+ case '>':
+ return XML.GT;
+ case '/':
+ return XML.SLASH;
+ case '=':
+ return XML.EQ;
+ case '!':
+ return XML.BANG;
+ case '?':
+ return XML.QUEST;
+
+ // Quoted string
+
+ case '"':
+ case '\'':
+ q = c;
+ sb = new StringBuffer();
+ for (;;) {
+ c = next();
+ if (c == 0) {
+ throw syntaxError("Unterminated string");
+ }
+ if (c == q) {
+ return sb.toString();
+ }
+ if (c == '&') {
+ sb.append(nextEntity(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ default:
+
+ // Name
+
+ sb = new StringBuffer();
+ for (;;) {
+ sb.append(c);
+ c = next();
+ if (Character.isWhitespace(c)) {
+ return sb.toString();
+ }
+ switch (c) {
+ case 0:
+ return sb.toString();
+ case '>':
+ case '/':
+ case '=':
+ case '!':
+ case '?':
+ case '[':
+ case ']':
+ back();
+ return sb.toString();
+ case '<':
+ case '"':
+ case '\'':
+ throw syntaxError("Bad character in a name");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Skip characters until past the requested string. If it is not found, we are left at the end of
+ * the source with a result of false.
+ *
+ * @param to A string to skip past.
+ * @throws JSONException
+ */
+ public boolean skipPast(String to) throws JSONException {
+ boolean b;
+ char c;
+ int i;
+ int j;
+ int offset = 0;
+ int length = to.length();
+ char[] circle = new char[length];
+
+ /*
+ * First fill the circle buffer with as many characters as are in the to string. If we reach an
+ * early end, bail.
+ */
+
+ for (i = 0; i < length; i += 1) {
+ c = next();
+ if (c == 0) {
+ return false;
+ }
+ circle[i] = c;
+ }
+ /*
+ * We will loop, possibly for all of the remaining characters.
+ */
+ for (;;) {
+ j = offset;
+ b = true;
+ /*
+ * Compare the circle buffer with the to string.
+ */
+ for (i = 0; i < length; i += 1) {
+ if (circle[j] != to.charAt(i)) {
+ b = false;
+ break;
+ }
+ j += 1;
+ if (j >= length) {
+ j -= length;
+ }
+ }
+ /*
+ * If we exit the loop with b intact, then victory is ours.
+ */
+ if (b) {
+ return true;
+ }
+ /*
+ * Get the next character. If there isn't one, then defeat is ours.
+ */
+ c = next();
+ if (c == 0) {
+ return false;
+ }
+ /*
+ * Shove the character in the circle buffer and advance the circle offset. The offset is mod
+ * n.
+ */
+ circle[offset] = c;
+ offset += 1;
+ if (offset >= length) {
+ offset -= length;
+ }
+ }
+ }
+}
[2/8] geode git commit: Revert "GEODE-2142: Spotless"
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONObject.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONObject.java b/geode-json/src/main/java/org/json/JSONObject.java
index bddfb56..d5de19f 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
@@ -31,53 +33,55 @@ import java.util.TreeMap;
// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * A modifiable set of name/value mappings. Names are unique, non-null strings. Values may be any
- * mix of {@link JSONObject JSONObjects}, {@link JSONArray JSONArrays}, Strings, Booleans, Integers,
- * Longs, Doubles or {@link #NULL}. Values may not be {@code null}, {@link Double#isNaN() NaNs},
- * {@link Double#isInfinite() infinities}, or of any type not listed here.
+ * A modifiable set of name/value mappings. Names are unique, non-null strings.
+ * Values may be any mix of {@link JSONObject JSONObjects}, {@link JSONArray
+ * JSONArrays}, Strings, Booleans, Integers, Longs, Doubles or {@link #NULL}.
+ * Values may not be {@code null}, {@link Double#isNaN() NaNs}, {@link
+ * Double#isInfinite() infinities}, or of any type not listed here.
*
- * <p>
- * This class can coerce values to another type when requested.
+ * <p>This class can coerce values to another type when requested.
* <ul>
- * <li>When the requested type is a boolean, strings will be coerced using a case-insensitive
- * comparison to "true" and "false".
- * <li>When the requested type is a double, other {@link Number} types will be coerced using
- * {@link Number#doubleValue() doubleValue}. Strings that can be coerced using
- * {@link Double#valueOf(String)} will be.
- * <li>When the requested type is an int, other {@link Number} types will be coerced using
- * {@link Number#intValue() intValue}. Strings that can be coerced using
- * {@link Double#valueOf(String)} will be, and then cast to int.
- * <li><a name="lossy">When the requested type is a long, other {@link Number} types will be coerced
- * using {@link Number#longValue() longValue}. Strings that can be coerced using
- * {@link Double#valueOf(String)} will be, and then cast to long. This two-step conversion is lossy
- * for very large values. For example, the string "9223372036854775806" yields the long
- * 9223372036854775807.</a>
- * <li>When the requested type is a String, other non-null values will be coerced using
- * {@link String#valueOf(Object)}. Although null cannot be coerced, the sentinel value
- * {@link JSONObject#NULL} is coerced to the string "null".
+ * <li>When the requested type is a boolean, strings will be coerced using a
+ * case-insensitive comparison to "true" and "false".
+ * <li>When the requested type is a double, other {@link Number} types will
+ * be coerced using {@link Number#doubleValue() doubleValue}. Strings
+ * that can be coerced using {@link Double#valueOf(String)} will be.
+ * <li>When the requested type is an int, other {@link Number} types will
+ * be coerced using {@link Number#intValue() intValue}. Strings
+ * that can be coerced using {@link Double#valueOf(String)} will be,
+ * and then cast to int.
+ * <li><a name="lossy">When the requested type is a long, other {@link Number} types will
+ * be coerced using {@link Number#longValue() longValue}. Strings
+ * that can be coerced using {@link Double#valueOf(String)} will be,
+ * and then cast to long. This two-step conversion is lossy for very
+ * large values. For example, the string "9223372036854775806" yields the
+ * long 9223372036854775807.</a>
+ * <li>When the requested type is a String, other non-null values will be
+ * coerced using {@link String#valueOf(Object)}. Although null cannot be
+ * coerced, the sentinel value {@link JSONObject#NULL} is coerced to the
+ * string "null".
* </ul>
*
- * <p>
- * This class can look up both mandatory and optional values:
+ * <p>This class can look up both mandatory and optional values:
* <ul>
- * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This fails with a
- * {@code JSONException} if the requested name has no value or if the value cannot be coerced to the
- * requested type.
- * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This returns a system- or
- * user-supplied default if the requested name has no value or if the value cannot be coerced to the
- * requested type.
+ * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This
+ * fails with a {@code JSONException} if the requested name has no value
+ * or if the value cannot be coerced to the requested type.
+ * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This
+ * returns a system- or user-supplied default if the requested name has no
+ * value or if the value cannot be coerced to the requested type.
* </ul>
*
- * <p>
- * <strong>Warning:</strong> this class represents null in two incompatible ways: the standard Java
- * {@code null} reference, and the sentinel value {@link JSONObject#NULL}. In particular, calling
- * {@code put(name, null)} removes the named entry from the object but
- * {@code put(name, JSONObject.NULL)} stores an entry whose value is {@code JSONObject.NULL}.
+ * <p><strong>Warning:</strong> this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, calling {@code put(name, null)} removes the
+ * named entry from the object but {@code put(name, JSONObject.NULL)} stores an
+ * entry whose value is {@code JSONObject.NULL}.
*
- * <p>
- * Instances of this class are not thread safe. Although this class is nonfinal, it was not designed
- * for inheritance and should not be subclassed. In particular, self-use by overrideable methods is
- * not specified. See <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * <p>Instances of this class are not thread safe. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overrideable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
* prohibit it" for further information.
*/
public class JSONObject {
@@ -88,8 +92,8 @@ public class JSONObject {
public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
/**
- * A sentinel value used to explicitly define a name with no value. Unlike {@code null}, names
- * with this value:
+ * A sentinel value used to explicitly define a name with no value. Unlike
+ * {@code null}, names with this value:
* <ul>
* <li>show up in the {@link #names} array
* <li>show up in the {@link #keys} iterator
@@ -98,9 +102,9 @@ public class JSONObject {
* <li>are included in the encoded JSON string.
* </ul>
*
- * <p>
- * This value violates the general contract of {@link Object#equals} by returning true when
- * compared to {@code null}. Its {@link #toString} method returns "null".
+ * <p>This value violates the general contract of {@link Object#equals} by
+ * returning true when compared to {@code null}. Its {@link #toString}
+ * method returns "null".
*/
public static final Object NULL = new Object() {
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@@ -131,21 +135,21 @@ public class JSONObject {
}
/**
- * Creates a new {@code JSONObject} by copying all name/value mappings from the given map.
- *
+ * Creates a new {@code JSONObject} by copying all name/value mappings from
+ * the given map.
* @param copyFrom a map whose keys are of type {@link String} and whose values are of supported
- * types.
+ * types.
* @throws NullPointerException if any of the map's keys are null.
*/
- /* (accept a raw type for API compatibility) */
+ /* (accept a raw type for API compatibility) */
public JSONObject(Map copyFrom) {
this();
Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
- /*
- * Deviate from the original by checking that keys are non-null and of the proper type. (We
- * still defer validating the values).
- */
+ /*
+ * Deviate from the original by checking that keys are non-null and
+ * of the proper type. (We still defer validating the values).
+ */
String key = (String) entry.getKey();
if (key == null) {
throw new NullPointerException("key == null");
@@ -155,16 +159,16 @@ public class JSONObject {
}
/**
- * Creates a new {@code JSONObject} with name/value mappings from the next object in the tokener.
- *
+ * Creates a new {@code JSONObject} with name/value mappings from the next
+ * object in the tokener.
* @param readFrom a tokener whose nextValue() method will yield a {@code JSONObject}.
* @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
*/
public JSONObject(JSONTokener readFrom) throws JSONException {
- /*
- * Getting the parser to populate this could get tricky. Instead, just parse to temporary
- * JSONObject and then steal the data from that.
- */
+ /*
+ * Getting the parser to populate this could get tricky. Instead, just
+ * parse to temporary JSONObject and then steal the data from that.
+ */
Object object = readFrom.nextValue();
if (object instanceof JSONObject) {
this.nameValuePairs = ((JSONObject) object).nameValuePairs;
@@ -174,8 +178,8 @@ public class JSONObject {
}
/**
- * Creates a new {@code JSONObject} with name/value mappings from the JSON string.
- *
+ * Creates a new {@code JSONObject} with name/value mappings from the JSON
+ * string.
* @param json a JSON-encoded string containing an object.
* @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
*/
@@ -184,9 +188,9 @@ public class JSONObject {
}
/**
- * Creates a new {@code JSONObject} by copying mappings for the listed names from the given
- * object. Names that aren't present in {@code copyFrom} will be skipped.
- *
+ * Creates a new {@code JSONObject} by copying mappings for the listed names
+ * from the given object. Names that aren't present in {@code copyFrom} will
+ * be skipped.
* @param copyFrom The source object.
* @param names The names of the fields to copy.
* @throws JSONException On internal errors. Shouldn't happen.
@@ -203,7 +207,6 @@ public class JSONObject {
/**
* Creates a json object from a bean
- *
* @param bean the bean to create the json object from
* @throws JSONException If there is an exception while reading the bean
*/
@@ -211,7 +214,7 @@ public class JSONObject {
this(propertiesAsMap(bean));
}
- // This is custom properties mapping specific for GEODE
+ //This is custom properties mapping specific for GEODE
private static Map<String, Object> propertiesAsMap(Object bean) {
Map<String, Object> props = new TreeMap();
Class klass = bean.getClass();
@@ -270,7 +273,6 @@ public class JSONObject {
/**
* Returns the number of name/value mappings in this object.
- *
* @return the length of this.
*/
public int length() {
@@ -278,9 +280,8 @@ public class JSONObject {
}
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
- * name.
- *
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
* @param name The name of the value to insert.
* @param value The value to insert.
* @return this object.
@@ -292,12 +293,11 @@ public class JSONObject {
}
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
- * name.
- *
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
* @param name The name for the new value.
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
+ * Double#isInfinite() infinities}.
* @return this object.
* @throws JSONException if value is NaN or infinite.
*/
@@ -307,9 +307,8 @@ public class JSONObject {
}
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
- * name.
- *
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
* @param name The name for the new value.
* @param value The new value.
* @return this object.
@@ -321,9 +320,8 @@ public class JSONObject {
}
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
- * name.
- *
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
* @param name The name of the new value.
* @param value The new value to insert.
* @return this object.
@@ -335,13 +333,13 @@ public class JSONObject {
}
/**
- * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
- * name. If the value is {@code null}, any existing mapping for {@code name} is removed.
- *
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name. If the value is {@code null}, any existing
+ * mapping for {@code name} is removed.
* @param name The name of the new value.
* @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link #NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
+ * {@link #NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or {@link
+ * Double#isInfinite() infinities}.
* @return this object.
* @throws JSONException if the value is an invalid double (infinite or NaN).
*/
@@ -373,9 +371,8 @@ public class JSONObject {
}
/**
- * Equivalent to {@code put(name, value)} when both parameters are non-null; does nothing
- * otherwise.
- *
+ * Equivalent to {@code put(name, value)} when both parameters are non-null;
+ * does nothing otherwise.
* @param name The name of the value to insert.
* @param value The value to insert.
* @return this object.
@@ -389,21 +386,22 @@ public class JSONObject {
}
/**
- * Appends {@code value} to the array already mapped to {@code name}. If this object has no
- * mapping for {@code name}, this inserts a new mapping. If the mapping exists but its value is
- * not an array, the existing and new values are inserted in order into a new array which is
- * itself mapped to {@code name}. In aggregate, this allows values to be added to a mapping one at
- * a time.
+ * Appends {@code value} to the array already mapped to {@code name}. If
+ * this object has no mapping for {@code name}, this inserts a new mapping.
+ * If the mapping exists but its value is not an array, the existing
+ * and new values are inserted in order into a new array which is itself
+ * mapped to {@code name}. In aggregate, this allows values to be added to a
+ * mapping one at a time.
*
- * Note that {@code append(String, Object)} provides better semantics. In particular, the mapping
- * for {@code name} will <b>always</b> be a {@link JSONArray}. Using {@code accumulate} will
- * result in either a {@link JSONArray} or a mapping whose type is the type of {@code value}
+ * Note that {@code append(String, Object)} provides better semantics.
+ * In particular, the mapping for {@code name} will <b>always</b> be a
+ * {@link JSONArray}. Using {@code accumulate} will result in either a
+ * {@link JSONArray} or a mapping whose type is the type of {@code value}
* depending on the number of calls to it.
- *
* @param name The name of the field to change.
* @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link #NULL} or null. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
+ * {@link #NULL} or null. May not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}.
* @return this object after mutation.
* @throws JSONException If the object being added is an invalid number.
*/
@@ -428,15 +426,15 @@ public class JSONObject {
}
/**
- * Appends values to the array mapped to {@code name}. A new {@link JSONArray} mapping for
- * {@code name} will be inserted if no mapping exists. If the existing mapping for {@code name} is
- * not a {@link JSONArray}, a {@link JSONException} will be thrown.
- *
+ * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
+ * mapping for {@code name} will be inserted if no mapping exists. If the existing
+ * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException}
+ * will be thrown.
* @param name The name of the array to which the value should be appended.
* @param value The value to append.
* @return this object.
* @throws JSONException if {@code name} is {@code null} or if the mapping for {@code name} is
- * non-null and is not a {@link JSONArray}.
+ * non-null and is not a {@link JSONArray}.
*/
public JSONObject append(String name, Object value) throws JSONException {
Object current = nameValuePairs.get(checkName(name));
@@ -466,7 +464,6 @@ public class JSONObject {
/**
* Removes the named mapping if it exists; does nothing otherwise.
- *
* @param name The name of the mapping to remove.
* @return the value previously mapped by {@code name}, or null if there was no such mapping.
*/
@@ -475,9 +472,8 @@ public class JSONObject {
}
/**
- * Returns true if this object has no mapping for {@code name} or if it has a mapping whose value
- * is {@link #NULL}.
- *
+ * Returns true if this object has no mapping for {@code name} or if it has
+ * a mapping whose value is {@link #NULL}.
* @param name The name of the value to check on.
* @return true if the field doesn't exist or is null.
*/
@@ -487,8 +483,8 @@ public class JSONObject {
}
/**
- * Returns true if this object has a mapping for {@code name}. The mapping may be {@link #NULL}.
- *
+ * Returns true if this object has a mapping for {@code name}. The mapping
+ * may be {@link #NULL}.
* @param name The name of the value to check on.
* @return true if this object has a field named {@code name}
*/
@@ -498,7 +494,6 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name}, or throws if no such mapping exists.
- *
* @param name The name of the value to get.
* @return The value.
* @throws JSONException if no such mapping exists.
@@ -512,8 +507,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name}, or null if no such mapping exists.
- *
+ * Returns the value mapped by {@code name}, or null if no such mapping
+ * exists.
* @param name The name of the value to get.
* @return The value.
*/
@@ -522,9 +517,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or can be coerced to a
- * boolean, or throws otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or throws otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
* @throws JSONException if the mapping doesn't exist or cannot be coerced to a boolean.
@@ -539,9 +533,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or can be coerced to a
- * boolean, or false otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or false otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
*/
@@ -550,9 +543,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a boolean or can be coerced to a
- * boolean, or {@code fallback} otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or {@code fallback} otherwise.
* @param name The name of the field we want.
* @param fallback The value to return if the field isn't there.
* @return The selected value or the fallback.
@@ -564,9 +556,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a double or can be coerced to a
- * double, or throws otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or throws otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
* @throws JSONException if the mapping doesn't exist or cannot be coerced to a double.
@@ -581,9 +572,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a double or can be coerced to a
- * double, or {@code NaN} otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or {@code NaN} otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
*/
@@ -592,9 +582,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a double or can be coerced to a
- * double, or {@code fallback} otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or {@code fallback} otherwise.
* @param name The name of the field we want.
* @param fallback The value to return if the field isn't there.
* @return The selected value or the fallback.
@@ -606,9 +595,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is an int or can be coerced to an
- * int, or throws otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or throws otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
* @throws JSONException if the mapping doesn't exist or cannot be coerced to an int.
@@ -623,9 +611,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is an int or can be coerced to an
- * int, or 0 otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or 0 otherwise.
* @param name The name of the field we want.
* @return The selected value if it exists.
*/
@@ -634,9 +621,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is an int or can be coerced to an
- * int, or {@code fallback} otherwise.
- *
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or {@code fallback} otherwise.
* @param name The name of the field we want.
* @param fallback The value to return if the field isn't there.
* @return The selected value or the fallback.
@@ -648,11 +634,12 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a long or can be coerced to a
- * long, or throws otherwise. Note that JSON represents numbers as doubles,
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or throws otherwise.
+ * Note that JSON represents numbers as doubles,
*
- * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON without loss.
- *
+ * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers
+ * via JSON without loss.
* @param name The name of the field that we want.
* @return The value of the field.
* @throws JSONException if the mapping doesn't exist or cannot be coerced to a long.
@@ -667,10 +654,9 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a long or can be coerced to a
- * long, or 0 otherwise. Note that JSON represents numbers as doubles, so this is
- * <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
- *
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
+ * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
* @param name The name of the field we want.
* @return The selected value.
*/
@@ -679,10 +665,10 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists and is a long or can be coerced to a
- * long, or {@code fallback} otherwise. Note that JSON represents numbers as doubles, so this is
- * <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
- *
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
+ * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
+ * numbers via JSON.
* @param name The name of the field we want.
* @param fallback The value to return if the field isn't there.
* @return The selected value or the fallback.
@@ -694,9 +680,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if necessary, or throws if
- * no such mapping exists.
- *
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or throws if no such mapping exists.
* @param name The name of the field we want.
* @return The value of the field.
* @throws JSONException if no such mapping exists.
@@ -711,9 +696,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if necessary, or the empty
- * string if no such mapping exists.
- *
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or the empty string if no such mapping exists.
* @param name The name of the field we want.
* @return The value of the field.
*/
@@ -722,9 +706,8 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name} if it exists, coercing it if necessary, or
- * {@code fallback} if no such mapping exists.
- *
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or {@code fallback} if no such mapping exists.
* @param name The name of the field that we want.
* @param fallback The value to return if the field doesn't exist.
* @return The value of the field or fallback.
@@ -738,7 +721,6 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
* JSONArray}, or throws otherwise.
- *
* @param name The field we want to get.
* @return The value of the field (if it is a JSONArray.
* @throws JSONException if the mapping doesn't exist or is not a {@code JSONArray}.
@@ -755,7 +737,6 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
* JSONArray}, or null otherwise.
- *
* @param name The name of the field we want.
* @return The value of the specified field (assuming it is a JSNOArray
*/
@@ -767,7 +748,6 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
* JSONObject}, or throws otherwise.
- *
* @param name The name of the field that we want.
* @return a specified field value (if it is a JSONObject)
* @throws JSONException if the mapping doesn't exist or is not a {@code JSONObject}.
@@ -784,7 +764,6 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
* JSONObject}, or null otherwise.
- *
* @param name The name of the value we want.
* @return The specified value.
*/
@@ -794,9 +773,9 @@ public class JSONObject {
}
/**
- * Returns an array with the values corresponding to {@code names}. The array contains null for
- * names that aren't mapped. This method returns null if {@code names} is either null or empty.
- *
+ * Returns an array with the values corresponding to {@code names}. The
+ * array contains null for names that aren't mapped. This method returns
+ * null if {@code names} is either null or empty.
* @param names The names of the fields that we want the values for.
* @return The selected values.
* @throws JSONException On internal errors. Shouldn't happen.
@@ -818,11 +797,11 @@ public class JSONObject {
}
/**
- * Returns an iterator of the {@code String} names in this object. The returned iterator supports
- * {@link Iterator#remove() remove}, which will remove the corresponding mapping from this object.
- * If this object is modified after the iterator is returned, the iterator's behavior is
+ * Returns an iterator of the {@code String} names in this object. The
+ * returned iterator supports {@link Iterator#remove() remove}, which will
+ * remove the corresponding mapping from this object. If this object is
+ * modified after the iterator is returned, the iterator's behavior is
* undefined. The order of the keys is undefined.
- *
* @return an iterator over the keys.
*/
public Iterator<String> keys() {
@@ -830,12 +809,12 @@ public class JSONObject {
}
/**
- * Returns the set of {@code String} names in this object. The returned set is a view of the keys
- * in this object. {@link Set#remove(Object)} will remove the corresponding mapping from this
- * object and set iterator behaviour is undefined if this object is modified after it is returned.
+ * Returns the set of {@code String} names in this object. The returned set
+ * is a view of the keys in this object. {@link Set#remove(Object)} will remove
+ * the corresponding mapping from this object and set iterator behaviour
+ * is undefined if this object is modified after it is returned.
*
* See {@link #keys()}.
- *
* @return The names in this object.
*/
public Set<String> keySet() {
@@ -843,22 +822,19 @@ public class JSONObject {
}
/**
- * Returns an array containing the string names in this object. This method returns null if this
- * object contains no mappings.
- *
+ * Returns an array containing the string names in this object. This method
+ * returns null if this object contains no mappings.
* @return the names.
*/
public JSONArray names() {
- return nameValuePairs.isEmpty() ? null
+ return nameValuePairs.isEmpty()
+ ? null
: new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
}
/**
* Encodes this object as a compact JSON string, such as:
- *
- * <pre>
- * {"query":"Pizza","locations":[94043,90210]}
- * </pre>
+ * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
*/
@Override
public String toString() {
@@ -872,8 +848,8 @@ public class JSONObject {
}
/**
- * Encodes this object as a human readable JSON string for debugging, such as:
- *
+ * Encodes this object as a human readable JSON string for debugging, such
+ * as:
* <pre>
* {
* "query": "Pizza",
@@ -881,9 +857,7 @@ public class JSONObject {
* 94043,
* 90210
* ]
- * }
- * </pre>
- *
+ * }</pre>
* @param indentSpaces the number of spaces to indent for each level of nesting.
* @return The string containing the pretty form of this.
* @throws JSONException On internal errors. Shouldn't happen.
@@ -904,9 +878,8 @@ public class JSONObject {
/**
* Encodes the number as a JSON string.
- *
- * @param number a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
+ * @param number a finite value. May not be {@link Double#isNaN() NaNs} or {@link
+ * Double#isInfinite() infinities}.
* @return The encoded number in string form.
* @throws JSONException On internal errors. Shouldn't happen.
*/
@@ -932,9 +905,8 @@ public class JSONObject {
}
/**
- * Encodes {@code data} as a JSON string. This applies quotes and any necessary character
- * escaping.
- *
+ * Encodes {@code data} as a JSON string. This applies quotes and any
+ * necessary character escaping.
* @param data the string to encode. Null will be interpreted as an empty string.
* @return the quoted string.
*/
@@ -956,8 +928,7 @@ public class JSONObject {
/**
* Wraps the given object if necessary.
*
- * <p>
- * If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
+ * <p>If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
* {@code JSONObject}, no wrapping is necessary. If the object is {@code NULL}, no wrapping is
* necessary. If the object is an array or {@code Collection}, returns an equivalent {@code
* JSONArray}. If the object is a {@code Map}, returns an equivalent {@code JSONObject}. If the
@@ -965,7 +936,6 @@ public class JSONObject {
* a {@code java} package, returns the result of {@code toString}. If the object is some other
* kind of object then it is assumed to be a bean and is converted to a JSONObject. If wrapping
* fails, returns null.
- *
* @param o The object to wrap.
* @return The wrapped (if necessary) form of the object {$code o}
*/
@@ -988,28 +958,34 @@ public class JSONObject {
if (o instanceof Map) {
return new JSONObject((Map) o);
}
- if (o instanceof Boolean || o instanceof Byte || o instanceof Character || o instanceof Double
- || o instanceof Float || o instanceof Integer || o instanceof Long || o instanceof Short
- || o instanceof String) {
+ if (o instanceof Boolean ||
+ o instanceof Byte ||
+ o instanceof Character ||
+ o instanceof Double ||
+ o instanceof Float ||
+ o instanceof Integer ||
+ o instanceof Long ||
+ o instanceof Short ||
+ o instanceof String) {
return o;
}
// GEODE-2142: Added check to ignore GemFireCacheImpl
- // if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
- // return o.toString();
- // }
+// if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
+// return o.toString();
+// }
Package objectPackage = o.getClass().getPackage();
String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
- if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.")
- || o instanceof Enum<?> || o.getClass().getClassLoader() == null
+ if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || o instanceof Enum<?>
+ || o.getClass().getClassLoader() == null
|| o.getClass().getName().contains("GemFireCacheImpl")) {
return o.toString();
}
- // if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
- // || objectPackageName.startsWith("javax.")
- // || o.getClass().getClassLoader() == null
- // o.getClass().getName().contains("GemFireCacheImpl")) {
- // return o.toString();
- // }
+// if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
+// || objectPackageName.startsWith("javax.")
+// || o.getClass().getClassLoader() == null
+// o.getClass().getName().contains("GemFireCacheImpl")) {
+// return o.toString();
+// }
// GEODE-2142: Added the cyclicalDepCheck
if (cyclicDepChkEnabled.get() != null && cyclicDependencySet.get() != null) {
if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(o)) {
@@ -1026,4 +1002,4 @@ public class JSONObject {
}
return null;
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONString.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONString.java b/geode-json/src/main/java/org/json/JSONString.java
index 4a09d89..34815a8 100755
--- a/geode-json/src/main/java/org/json/JSONString.java
+++ b/geode-json/src/main/java/org/json/JSONString.java
@@ -1,17 +1,18 @@
package org.json;
-
/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class
- * can change the behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will
- * be used instead of the default behavior of using the Object's <code>toString()</code> method and
- * quoting the result.
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
+ * method so that a class can change the behavior of
+ * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
+ * and <code>JSONWriter.value(</code>Object<code>)</code>. The
+ * <code>toJSONString</code> method will be used instead of the default behavior
+ * of using the Object's <code>toString()</code> method and quoting the result.
*/
public interface JSONString {
/**
- * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
+ * The <code>toJSONString</code> method allows a class to produce its own JSON
+ * serialization.
*
* @return A strictly syntactically correct JSON text.
*/
public String toJSONString();
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONStringer.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONStringer.java b/geode-json/src/main/java/org/json/JSONStringer.java
index 43224a5..db1121e 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
@@ -21,439 +23,448 @@ import java.util.List;
// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most application
- * developers should use those methods directly and disregard this API. For example:
- *
- * <pre>
+ * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
+ * application developers should use those methods directly and disregard this
+ * API. For example:<pre>
* JSONObject object = ...
- * String json = object.toString();
- * </pre>
+ * String json = object.toString();</pre>
*
- * <p>
- * Stringers only encode well-formed JSON strings. In particular:
+ * <p>Stringers only encode well-formed JSON strings. In particular:
* <ul>
* <li>The stringer must have exactly one top-level array or object.
- * <li>Lexical scopes must be balanced: every call to {@link #array} must have a matching call to
- * {@link #endArray} and every call to {@link #object} must have a matching call to
- * {@link #endObject}.
+ * <li>Lexical scopes must be balanced: every call to {@link #array} must
+ * have a matching call to {@link #endArray} and every call to {@link
+ * #object} must have a matching call to {@link #endObject}.
* <li>Arrays may not contain keys (property names).
* <li>Objects must alternate keys (property names) and values.
- * <li>Values are inserted with either literal {@link #value(Object) value} calls, or by nesting
- * arrays or objects.
+ * <li>Values are inserted with either literal {@link #value(Object) value}
+ * calls, or by nesting arrays or objects.
* </ul>
- * Calls that would result in a malformed JSON string will fail with a {@link JSONException}.
+ * Calls that would result in a malformed JSON string will fail with a
+ * {@link JSONException}.
*
- * <p>
- * This class provides no facility for pretty-printing (ie. indenting) output. To encode indented
- * output, use {@link JSONObject#toString(int)} or {@link JSONArray#toString(int)}.
+ * <p>This class provides no facility for pretty-printing (ie. indenting)
+ * output. To encode indented output, use {@link JSONObject#toString(int)} or
+ * {@link JSONArray#toString(int)}.
*
- * <p>
- * Some implementations of the API support at most 20 levels of nesting. Attempts to create more
- * than 20 levels of nesting may fail with a {@link JSONException}.
+ * <p>Some implementations of the API support at most 20 levels of nesting.
+ * Attempts to create more than 20 levels of nesting may fail with a {@link
+ * JSONException}.
*
- * <p>
- * Each stringer may be used to encode a single top level value. Instances of this class are not
- * thread safe. Although this class is nonfinal, it was not designed for inheritance and should not
- * be subclassed. In particular, self-use by overrideable methods is not specified. See <i>Effective
- * Java</i> Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * <p>Each stringer may be used to encode a single top level value. Instances of
+ * this class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
* information.
*/
public class JSONStringer {
- /**
- * The output data, containing at most one top-level array or object.
- */
- final StringBuilder out = new StringBuilder();
-
- /**
- * Lexical scoping elements within this stringer, necessary to insert the appropriate separator
- * characters (ie. commas and colons) and to detect nesting errors.
- */
- enum Scope {
-
/**
- * An array with no elements requires no separators or newlines before it is closed.
+ * The output data, containing at most one top-level array or object.
*/
- EMPTY_ARRAY,
+ final StringBuilder out = new StringBuilder();
/**
- * A array with at least one value requires a comma and newline before the next element.
+ * Lexical scoping elements within this stringer, necessary to insert the
+ * appropriate separator characters (ie. commas and colons) and to detect
+ * nesting errors.
*/
- NONEMPTY_ARRAY,
+ enum Scope {
+
+ /**
+ * An array with no elements requires no separators or newlines before
+ * it is closed.
+ */
+ EMPTY_ARRAY,
+
+ /**
+ * A array with at least one value requires a comma and newline before
+ * the next element.
+ */
+ NONEMPTY_ARRAY,
+
+ /**
+ * An object with no keys or values requires no separators or newlines
+ * before it is closed.
+ */
+ EMPTY_OBJECT,
+
+ /**
+ * An object whose most recent element is a key. The next element must
+ * be a value.
+ */
+ DANGLING_KEY,
+
+ /**
+ * An object with at least one name/value pair requires a comma and
+ * newline before the next element.
+ */
+ NONEMPTY_OBJECT,
+
+ /**
+ * A special bracketless array needed by JSONStringer.join() and
+ * JSONObject.quote() only. Not used for JSON encoding.
+ */
+ NULL,
+ }
/**
- * An object with no keys or values requires no separators or newlines before it is closed.
+ * Unlike the original implementation, this stack isn't limited to 20
+ * levels of nesting.
*/
- EMPTY_OBJECT,
+ private final List<Scope> stack = new ArrayList<Scope>();
/**
- * An object whose most recent element is a key. The next element must be a value.
+ * A string containing a full set of spaces for a single level of
+ * indentation, or null for no pretty printing.
*/
- DANGLING_KEY,
+ private final String indent;
+
+ public JSONStringer() {
+ indent = null;
+ }
+
+ JSONStringer(int indentSpaces) {
+ char[] indentChars = new char[indentSpaces];
+ Arrays.fill(indentChars, ' ');
+ indent = new String(indentChars);
+ }
/**
- * An object with at least one name/value pair requires a comma and newline before the next
- * element.
+ * Begins encoding a new array. Each call to this method must be paired with
+ * a call to {@link #endArray}.
+ *
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
*/
- NONEMPTY_OBJECT,
+ public JSONStringer array() throws JSONException {
+ return open(Scope.EMPTY_ARRAY, "[");
+ }
/**
- * A special bracketless array needed by JSONStringer.join() and JSONObject.quote() only. Not
- * used for JSON encoding.
+ * Ends encoding the current array.
+ *
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
*/
- NULL,
- }
-
- /**
- * Unlike the original implementation, this stack isn't limited to 20 levels of nesting.
- */
- private final List<Scope> stack = new ArrayList<Scope>();
-
- /**
- * A string containing a full set of spaces for a single level of indentation, or null for no
- * pretty printing.
- */
- private final String indent;
-
- public JSONStringer() {
- indent = null;
- }
-
- JSONStringer(int indentSpaces) {
- char[] indentChars = new char[indentSpaces];
- Arrays.fill(indentChars, ' ');
- indent = new String(indentChars);
- }
-
- /**
- * Begins encoding a new array. Each call to this method must be paired with a call to
- * {@link #endArray}.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer array() throws JSONException {
- return open(Scope.EMPTY_ARRAY, "[");
- }
-
- /**
- * Ends encoding the current array.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer endArray() throws JSONException {
- return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
- }
-
- /**
- * Begins encoding a new object. Each call to this method must be paired with a call to
- * {@link #endObject}.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer object() throws JSONException {
- return open(Scope.EMPTY_OBJECT, "{");
- }
-
- /**
- * Ends encoding the current object.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer endObject() throws JSONException {
- return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
- }
-
- /**
- * Enters a new scope by appending any necessary whitespace and the given bracket.
- */
- JSONStringer open(Scope empty, String openBracket) throws JSONException {
- if (stack.isEmpty() && out.length() > 0) {
- throw new JSONException("Nesting problem: multiple top-level roots");
- }
- beforeValue();
- stack.add(empty);
- out.append(openBracket);
- return this;
- }
-
- /**
- * Closes the current scope by appending any necessary whitespace and the given bracket.
- */
- JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
- Scope context = peek();
- if (context != nonempty && context != empty) {
- throw new JSONException("Nesting problem");
+ public JSONStringer endArray() throws JSONException {
+ return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
}
- stack.remove(stack.size() - 1);
- if (context == nonempty) {
- newline();
- }
- out.append(closeBracket);
- return this;
- }
-
- /**
- * Returns the value on the top of the stack.
- */
- private Scope peek() throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- return stack.get(stack.size() - 1);
- }
-
- /**
- * Replace the value on the top of the stack with the given value.
- */
- private void replaceTop(Scope topOfStack) {
- stack.set(stack.size() - 1, topOfStack);
- }
-
- /**
- * Encodes {@code value}.
- *
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double or
- * null. May not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(Object value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
+ /**
+ * Begins encoding a new object. Each call to this method must be paired
+ * with a call to {@link #endObject}.
+ *
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
+ */
+ public JSONStringer object() throws JSONException {
+ return open(Scope.EMPTY_OBJECT, "{");
}
- if (value instanceof JSONArray) {
- ((JSONArray) value).writeTo(this);
- return this;
+ /**
+ * Ends encoding the current object.
+ *
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
+ */
+ public JSONStringer endObject() throws JSONException {
+ return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+ }
- } else if (value instanceof JSONObject) {
- ((JSONObject) value).writeTo(this);
- return this;
+ /**
+ * Enters a new scope by appending any necessary whitespace and the given
+ * bracket.
+ */
+ JSONStringer open(Scope empty, String openBracket) throws JSONException {
+ if (stack.isEmpty() && out.length() > 0) {
+ throw new JSONException("Nesting problem: multiple top-level roots");
+ }
+ beforeValue();
+ stack.add(empty);
+ out.append(openBracket);
+ return this;
}
- beforeValue();
+ /**
+ * Closes the current scope by appending any necessary whitespace and the
+ * given bracket.
+ */
+ JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+ Scope context = peek();
+ if (context != nonempty && context != empty) {
+ throw new JSONException("Nesting problem");
+ }
+
+ stack.remove(stack.size() - 1);
+ if (context == nonempty) {
+ newline();
+ }
+ out.append(closeBracket);
+ return this;
+ }
- if (value instanceof JSONString) {
- out.append(((JSONString) value).toJSONString());
- return this;
+ /**
+ * Returns the value on the top of the stack.
+ */
+ private Scope peek() throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ return stack.get(stack.size() - 1);
}
- if (value == null || value instanceof Boolean || value == JSONObject.NULL) {
- out.append(value);
+ /**
+ * Replace the value on the top of the stack with the given value.
+ */
+ private void replaceTop(Scope topOfStack) {
+ stack.set(stack.size() - 1, topOfStack);
+ }
- } else if (value instanceof Number) {
- out.append(JSONObject.numberToString((Number) value));
+ /**
+ * Encodes {@code value}.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
+ * or {@link Double#isInfinite() infinities}.
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
+ */
+ public JSONStringer value(Object value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+
+ if (value instanceof JSONArray) {
+ ((JSONArray) value).writeTo(this);
+ return this;
+
+ } else if (value instanceof JSONObject) {
+ ((JSONObject) value).writeTo(this);
+ return this;
+ }
+
+ beforeValue();
+
+ if (value instanceof JSONString) {
+ out.append(((JSONString) value).toJSONString());
+ return this;
+ }
+
+ if (value == null
+ || value instanceof Boolean
+ || value == JSONObject.NULL) {
+ out.append(value);
+
+ } else if (value instanceof Number) {
+ out.append(JSONObject.numberToString((Number) value));
+
+ } else {
+ // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript function calls)
+ // Example: { "name": "testkey", "value": window.myfunction() }
+ if (value.getClass().getSimpleName().contains("JSONFunction")) {
+ // note that no escaping of quotes (or anything else) is done in this case.
+ // that is fine because the only way to get to this point is to
+ // explicitly put a special kind of object into the JSON data structure.
+ out.append(value);
+ } else {
+ string(value.toString());
+ }
+ }
+
+ return this;
+ }
- } else {
- // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript
- // function calls)
- // Example: { "name": "testkey", "value": window.myfunction() }
- if (value.getClass().getSimpleName().contains("JSONFunction")) {
- // note that no escaping of quotes (or anything else) is done in this case.
- // that is fine because the only way to get to this point is to
- // explicitly put a special kind of object into the JSON data structure.
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @param value The value to encode.
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
+ */
+ public JSONStringer value(boolean value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
out.append(value);
- } else {
- string(value.toString());
- }
+ return this;
}
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value The value to encode.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(boolean value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- beforeValue();
- out.append(value);
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(double value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- beforeValue();
- out.append(JSONObject.numberToString(value));
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value The value to encode.
- * @return this stringer.
- * @throws JSONException If we have an internal error. Shouldn't happen.
- */
- public JSONStringer value(long value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this stringer.
+ * @throws JSONException On internal errors. Shouldn't happen.
+ */
+ public JSONStringer value(double value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
+ out.append(JSONObject.numberToString(value));
+ return this;
}
- beforeValue();
- out.append(value);
- return this;
- }
-
- private void string(String value) {
- out.append("\"");
- char currentChar = 0;
-
- for (int i = 0, length = value.length(); i < length; i++) {
- char previousChar = currentChar;
- currentChar = value.charAt(i);
-
- /*
- * From RFC 4627, "All Unicode characters may be placed within the quotation marks except for
- * the characters that must be escaped: quotation mark, reverse solidus, and the control
- * characters (U+0000 through U+001F)."
- */
- switch (currentChar) {
- case '"':
- case '\\':
- out.append('\\').append(currentChar);
- break;
-
- case '/':
- // it makes life easier for HTML embedding of javascript if we escape </ sequences
- if (previousChar == '<') {
- out.append('\\');
- }
- out.append(currentChar);
- break;
-
- case '\t':
- out.append("\\t");
- break;
-
- case '\b':
- out.append("\\b");
- break;
-
- case '\n':
- out.append("\\n");
- break;
-
- case '\r':
- out.append("\\r");
- break;
-
- case '\f':
- out.append("\\f");
- break;
-
- default:
- if (currentChar <= 0x1F) {
- out.append(String.format("\\u%04x", (int) currentChar));
- } else {
- out.append(currentChar);
- }
- break;
- }
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @param value The value to encode.
+ * @return this stringer.
+ * @throws JSONException If we have an internal error. Shouldn't happen.
+ */
+ public JSONStringer value(long value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
+ out.append(value);
+ return this;
}
- out.append("\"");
- }
- private void newline() {
- if (indent == null) {
- return;
+ private void string(String value) {
+ out.append("\"");
+ char currentChar = 0;
+
+ for (int i = 0, length = value.length(); i < length; i++) {
+ char previousChar = currentChar;
+ currentChar = value.charAt(i);
+
+ /*
+ * From RFC 4627, "All Unicode characters may be placed within the
+ * quotation marks except for the characters that must be escaped:
+ * quotation mark, reverse solidus, and the control characters
+ * (U+0000 through U+001F)."
+ */
+ switch (currentChar) {
+ case '"':
+ case '\\':
+ out.append('\\').append(currentChar);
+ break;
+
+ case '/':
+ // it makes life easier for HTML embedding of javascript if we escape </ sequences
+ if (previousChar == '<') {
+ out.append('\\');
+ }
+ out.append(currentChar);
+ break;
+
+ case '\t':
+ out.append("\\t");
+ break;
+
+ case '\b':
+ out.append("\\b");
+ break;
+
+ case '\n':
+ out.append("\\n");
+ break;
+
+ case '\r':
+ out.append("\\r");
+ break;
+
+ case '\f':
+ out.append("\\f");
+ break;
+
+ default:
+ if (currentChar <= 0x1F) {
+ out.append(String.format("\\u%04x", (int) currentChar));
+ } else {
+ out.append(currentChar);
+ }
+ break;
+ }
+
+ }
+ out.append("\"");
}
- out.append("\n");
- for (int i = 0; i < stack.size(); i++) {
- out.append(indent);
+ private void newline() {
+ if (indent == null) {
+ return;
+ }
+
+ out.append("\n");
+ for (int i = 0; i < stack.size(); i++) {
+ out.append(indent);
+ }
}
- }
-
- /**
- * Encodes the key (property name) to this stringer.
- *
- * @param name the name of the forthcoming value. May not be null.
- * @return this stringer.
- * @throws JSONException on internal errors, shouldn't happen.
- */
- public JSONStringer key(String name) throws JSONException {
- if (name == null) {
- throw new JSONException("Names must be non-null");
+
+ /**
+ * Encodes the key (property name) to this stringer.
+ *
+ * @param name the name of the forthcoming value. May not be null.
+ * @return this stringer.
+ * @throws JSONException on internal errors, shouldn't happen.
+ */
+ public JSONStringer key(String name) throws JSONException {
+ if (name == null) {
+ throw new JSONException("Names must be non-null");
+ }
+ beforeKey();
+ string(name);
+ return this;
}
- beforeKey();
- string(name);
- return this;
- }
-
- /**
- * Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect
- * the key's value.
- */
- private void beforeKey() throws JSONException {
- Scope context = peek();
- if (context == Scope.NONEMPTY_OBJECT) { // first in object
- out.append(',');
- } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
- throw new JSONException("Nesting problem");
+
+ /**
+ * Inserts any necessary separators and whitespace before a name. Also
+ * adjusts the stack to expect the key's value.
+ */
+ private void beforeKey() throws JSONException {
+ Scope context = peek();
+ if (context == Scope.NONEMPTY_OBJECT) { // first in object
+ out.append(',');
+ } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+ throw new JSONException("Nesting problem");
+ }
+ newline();
+ replaceTop(Scope.DANGLING_KEY);
}
- newline();
- replaceTop(Scope.DANGLING_KEY);
- }
-
- /**
- * Inserts any necessary separators and whitespace before a literal value, inline array, or inline
- * object. Also adjusts the stack to expect either a closing bracket or another element.
- */
- private void beforeValue() throws JSONException {
- if (stack.isEmpty()) {
- return;
+
+ /**
+ * Inserts any necessary separators and whitespace before a literal value,
+ * inline array, or inline object. Also adjusts the stack to expect either a
+ * closing bracket or another element.
+ */
+ private void beforeValue() throws JSONException {
+ if (stack.isEmpty()) {
+ return;
+ }
+
+ Scope context = peek();
+ if (context == Scope.EMPTY_ARRAY) { // first in array
+ replaceTop(Scope.NONEMPTY_ARRAY);
+ newline();
+ } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+ out.append(',');
+ newline();
+ } else if (context == Scope.DANGLING_KEY) { // value for key
+ out.append(indent == null ? ":" : ": ");
+ replaceTop(Scope.NONEMPTY_OBJECT);
+ } else if (context != Scope.NULL) {
+ throw new JSONException("Nesting problem");
+ }
}
- Scope context = peek();
- if (context == Scope.EMPTY_ARRAY) { // first in array
- replaceTop(Scope.NONEMPTY_ARRAY);
- newline();
- } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
- out.append(',');
- newline();
- } else if (context == Scope.DANGLING_KEY) { // value for key
- out.append(indent == null ? ":" : ": ");
- replaceTop(Scope.NONEMPTY_OBJECT);
- } else if (context != Scope.NULL) {
- throw new JSONException("Nesting problem");
+ /**
+ * Returns the encoded JSON string.
+ *
+ * <p>If invoked with unterminated arrays or unclosed objects, this method's
+ * return value is undefined.
+ *
+ * <p><strong>Warning:</strong> although it contradicts the general contract
+ * of {@link Object#toString}, this method returns null if the stringer
+ * contains no data.
+ */
+ @Override
+ public String toString() {
+ return out.length() == 0 ? null : out.toString();
}
- }
-
- /**
- * Returns the encoded JSON string.
- *
- * <p>
- * If invoked with unterminated arrays or unclosed objects, this method's return value is
- * undefined.
- *
- * <p>
- * <strong>Warning:</strong> although it contradicts the general contract of
- * {@link Object#toString}, this method returns null if the stringer contains no data.
- */
- @Override
- public String toString() {
- return out.length() == 0 ? null : out.toString();
- }
}
[3/8] geode git commit: Revert "GEODE-2142: Spotless"
Posted by ud...@apache.org.
Revert "GEODE-2142: Spotless"
This reverts commit 2e3a88f7bc61796042140aa92b44390b9970b53e.
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/1253d780
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/1253d780
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/1253d780
Branch: refs/heads/develop
Commit: 1253d7808e3d35d2d6868e98e1ccb5bfa1749e35
Parents: 2e3a88f
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 13:56:15 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 13:56:15 2017 -0800
----------------------------------------------------------------------
.../cli/functions/ExportConfigFunction.java | 2 +-
.../internal/cli/json/GfJsonObject.java | 36 +-
.../internal/cli/result/AbstractResultData.java | 7 +-
.../cli/commands/CliCommandTestBase.java | 2 +-
geode-json/src/main/java/org/json/JSON.java | 176 +--
.../src/main/java/org/json/JSONArray.java | 1458 +++++++++---------
.../src/main/java/org/json/JSONException.java | 59 +-
.../src/main/java/org/json/JSONObject.java | 416 +++--
.../src/main/java/org/json/JSONString.java | 17 +-
.../src/main/java/org/json/JSONStringer.java | 779 +++++-----
.../src/main/java/org/json/JSONTokener.java | 1149 +++++++-------
11 files changed, 2061 insertions(+), 2040 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
index 4e92623..64bc374 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
@@ -95,7 +95,7 @@ public class ExportConfigFunction implements Function, InternalEntity {
}
CliFunctionResult result = new CliFunctionResult(memberId,
new String[] {xmlWriter.toString(), propStringBuf.toString()});
- System.err.println("ExportConfigFunction.execute CLI function result: " + result);
+ System.err.println("ExportConfigFunction.execute CLI function result: "+result);
context.getResultSender().lastResult(result);
} catch (CacheClosedException cce) {
CliFunctionResult result = new CliFunctionResult(memberId, false, null);
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
index 8b7e004..9137f72 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
@@ -72,9 +72,9 @@ public class GfJsonObject {
}
}
- // public GfJsonObject(Object bean, String[] paramNames) {
- // this.jsonObject = new JSONObject(bean, paramNames);
- // }
+// public GfJsonObject(Object bean, String[] paramNames) {
+// this.jsonObject = new JSONObject(bean, paramNames);
+// }
/**
*
@@ -237,21 +237,21 @@ public class GfJsonObject {
return this;
}
- // /**
- // *
- // * @param key
- // * @param value
- // * @return this GfJsonObject
- // * @throws GfJsonException if the key is a duplicate
- // */
- // public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
- // try {
- // jsonObject.putOnce(key, value);
- // } catch (JSONException e) {
- // throw new GfJsonException(e.getMessage());
- // }
- // return this;
- // }
+// /**
+// *
+// * @param key
+// * @param value
+// * @return this GfJsonObject
+// * @throws GfJsonException if the key is a duplicate
+// */
+// public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
+// try {
+// jsonObject.putOnce(key, value);
+// } catch (JSONException e) {
+// throw new GfJsonException(e.getMessage());
+// }
+// return this;
+// }
/**
*
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
index f453ec6..81ab511 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
@@ -175,9 +175,8 @@ public abstract class AbstractResultData implements ResultData {
sectionData.put(FILE_TYPE_FIELD, fileType);
sectionData.put(FILE_MESSAGE, message);
DeflaterInflaterData deflaterInflaterData = CliUtil.compressBytes(data);
- sectionData.put(FILE_DATA_FIELD,
- Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
- sectionData.put(DATA_LENGTH_FIELD, deflaterInflaterData.getDataLength());
+ sectionData.put(FILE_DATA_FIELD, Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
+ sectionData.put(DATA_LENGTH_FIELD,deflaterInflaterData.getDataLength());
} catch (GfJsonException e) {
throw new ResultDataException(e.getMessage());
}
@@ -232,7 +231,7 @@ public abstract class AbstractResultData implements ResultData {
String fileDataString = (String) object.get(FILE_DATA_FIELD);
int fileDataLength = (int) object.get(DATA_LENGTH_FIELD);
byte[] byteArray = Base64.getDecoder().decode(fileDataString);
- byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray, fileDataLength).getData();
+ byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray,fileDataLength).getData();
boolean isGfshVM = CliUtil.isGfshVM();
File fileToDumpData = new File(fileName);
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
index 662ff4d..239810b 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
@@ -365,7 +365,7 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase {
System.err.println("result1 = " + result1);
}
result = (CommandResult) result1; // TODO: this can result in ClassCastException if
- // command resulted in error
+ // command resulted in error
} catch (InterruptedException ex) {
error("shell received InterruptedException");
}
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSON.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSON.java b/geode-json/src/main/java/org/json/JSON.java
index 7105cab..1b32e69 100755
--- a/geode-json/src/main/java/org/json/JSON.java
+++ b/geode-json/src/main/java/org/json/JSON.java
@@ -1,112 +1,116 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
class JSON {
- /**
- * Returns the input if it is a JSON-permissible value; throws otherwise.
- */
- static double checkDouble(double d) throws JSONException {
- if (Double.isInfinite(d) || Double.isNaN(d)) {
- throw new JSONException("Forbidden numeric value: " + d);
+ /**
+ * Returns the input if it is a JSON-permissible value; throws otherwise.
+ */
+ static double checkDouble(double d) throws JSONException {
+ if (Double.isInfinite(d) || Double.isNaN(d)) {
+ throw new JSONException("Forbidden numeric value: " + d);
+ }
+ return d;
}
- return d;
- }
- static Boolean toBoolean(Object value) {
- if (value instanceof Boolean) {
- return (Boolean) value;
- } else if (value instanceof String) {
- String stringValue = (String) value;
- if ("true".equalsIgnoreCase(stringValue)) {
- return true;
- } else if ("false".equalsIgnoreCase(stringValue)) {
- return false;
- }
+ static Boolean toBoolean(Object value) {
+ if (value instanceof Boolean) {
+ return (Boolean) value;
+ } else if (value instanceof String) {
+ String stringValue = (String) value;
+ if ("true".equalsIgnoreCase(stringValue)) {
+ return true;
+ } else if ("false".equalsIgnoreCase(stringValue)) {
+ return false;
+ }
+ }
+ return null;
}
- return null;
- }
- static Double toDouble(Object value) {
- if (value instanceof Double) {
- return (Double) value;
- } else if (value instanceof Number) {
- return ((Number) value).doubleValue();
- } else if (value instanceof String) {
- try {
- return Double.valueOf((String) value);
- } catch (NumberFormatException ignored) {
- }
+ static Double toDouble(Object value) {
+ if (value instanceof Double) {
+ return (Double) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).doubleValue();
+ } else if (value instanceof String) {
+ try {
+ return Double.valueOf((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
}
- return null;
- }
- static Integer toInteger(Object value) {
- if (value instanceof Integer) {
- return (Integer) value;
- } else if (value instanceof Number) {
- return ((Number) value).intValue();
- } else if (value instanceof String) {
- try {
- return (int) Double.parseDouble((String) value);
- } catch (NumberFormatException ignored) {
- }
+ static Integer toInteger(Object value) {
+ if (value instanceof Integer) {
+ return (Integer) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).intValue();
+ } else if (value instanceof String) {
+ try {
+ return (int) Double.parseDouble((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
}
- return null;
- }
- static Long toLong(Object value) {
- if (value instanceof Long) {
- return (Long) value;
- } else if (value instanceof Number) {
- return ((Number) value).longValue();
- } else if (value instanceof String) {
- try {
- return (long) Double.parseDouble((String) value);
- } catch (NumberFormatException ignored) {
- }
+ static Long toLong(Object value) {
+ if (value instanceof Long) {
+ return (Long) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).longValue();
+ } else if (value instanceof String) {
+ try {
+ return (long) Double.parseDouble((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
}
- return null;
- }
- static String toString(Object value) {
- if (value instanceof String) {
- return (String) value;
- } else if (value != null) {
- return String.valueOf(value);
+ static String toString(Object value) {
+ if (value instanceof String) {
+ return (String) value;
+ } else if (value != null) {
+ return String.valueOf(value);
+ }
+ return null;
}
- return null;
- }
- public static JSONException typeMismatch(Object indexOrName, Object actual, String requiredType)
- throws JSONException {
- if (actual == null) {
- throw new JSONException("Value at " + indexOrName + " is null.");
- } else {
- throw new JSONException("Value " + actual + " at " + indexOrName + " of type "
- + actual.getClass().getName() + " cannot be converted to " + requiredType);
+ public static JSONException typeMismatch(Object indexOrName, Object actual,
+ String requiredType) throws JSONException {
+ if (actual == null) {
+ throw new JSONException("Value at " + indexOrName + " is null.");
+ } else {
+ throw new JSONException("Value " + actual + " at " + indexOrName
+ + " of type " + actual.getClass().getName()
+ + " cannot be converted to " + requiredType);
+ }
}
- }
- public static JSONException typeMismatch(Object actual, String requiredType)
- throws JSONException {
- if (actual == null) {
- throw new JSONException("Value is null.");
- } else {
- throw new JSONException("Value " + actual + " of type " + actual.getClass().getName()
- + " cannot be converted to " + requiredType);
+ public static JSONException typeMismatch(Object actual, String requiredType)
+ throws JSONException {
+ if (actual == null) {
+ throw new JSONException("Value is null.");
+ } else {
+ throw new JSONException("Value " + actual
+ + " of type " + actual.getClass().getName()
+ + " cannot be converted to " + requiredType);
+ }
}
- }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONArray.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONArray.java b/geode-json/src/main/java/org/json/JSONArray.java
index c961139..074624d 100755
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
@@ -22,726 +24,736 @@ import java.util.List;
// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * A dense indexed sequence of values. Values may be any mix of {@link JSONObject JSONObjects},
- * other {@link JSONArray JSONArrays}, Strings, Booleans, Integers, Longs, Doubles, {@code null} or
- * {@link JSONObject#NULL}. Values may not be {@link Double#isNaN() NaNs},
- * {@link Double#isInfinite() infinities}, or of any type not listed here.
+ * A dense indexed sequence of values. Values may be any mix of
+ * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
+ * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
+ * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
+ * infinities}, or of any type not listed here.
*
- * {@code JSONArray} has the same type coercion behavior and optional/mandatory accessors as
- * {@link JSONObject}. See that class' documentation for details.
+ * {@code JSONArray} has the same type coercion behavior and
+ * optional/mandatory accessors as {@link JSONObject}. See that class'
+ * documentation for details.
*
- * <strong>Warning:</strong> this class represents null in two incompatible ways: the standard Java
- * {@code null} reference, and the sentinel value {@link JSONObject#NULL}. In particular,
- * {@code get} fails if the requested index holds the null reference, but succeeds if it holds
- * {@code JSONObject.NULL}.
+ * <strong>Warning:</strong> this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, {@code get} fails if the requested index
+ * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
*
- * Instances of this class are not thread safe. Although this class is non-final, it was not
- * designed for inheritance and should not be subclassed. In particular, self-use by overridable
- * methods is not specified. See <i>Effective Java</i> Item 17, "Design and Document or inheritance
- * or else prohibit it" for further information.
+ * Instances of this class are not thread safe. Although this class is
+ * non-final, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overridable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
*/
public class JSONArray {
- private final List<Object> values;
-
- /**
- * Creates a {@code JSONArray} with no values.
- */
- public JSONArray() {
- values = new ArrayList<Object>();
- }
-
- /**
- * Creates a new {@code JSONArray} by copying all values from the given collection.
- *
- * @param copyFrom a collection whose values are of supported types. Unsupported values are not
- * permitted and will yield an array in an inconsistent state.
- */
- /* Accept a raw type for API compatibility */
- public JSONArray(Collection<?> copyFrom) {
- this();
- if (copyFrom != null) {
- for (Object aCopyFrom : copyFrom) {
- put(JSONObject.wrap(aCopyFrom));
- }
- }
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the next array in the tokener.
- *
- * @param readFrom a tokener whose nextValue() method will yield a {@code JSONArray}.
- * @throws JSONException if the parse fails or doesn't yield a {@code JSONArray}.
- */
- public JSONArray(JSONTokener readFrom) throws JSONException {
- /*
- * Getting the parser to populate this could get tricky. Instead, just parse to temporary
- * JSONArray and then steal the data from that.
- */
- Object object = readFrom.nextValue();
- if (object instanceof JSONArray) {
- values = ((JSONArray) object).values;
- } else {
- throw JSON.typeMismatch(object, "JSONArray");
- }
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the JSON string.
- *
- * @param json a JSON-encoded string containing an array.
- * @throws JSONException if the parse fails or doesn't yield a {@code
- * JSONArray}.
- */
- public JSONArray(String json) throws JSONException {
- this(new JSONTokener(json));
- }
-
- /**
- * Creates a new {@code JSONArray} with values from the given primitive array.
- *
- * @param array The values to use.
- * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
- */
- public JSONArray(Object array) throws JSONException {
- if (!array.getClass().isArray()) {
- throw new JSONException("Not a primitive array: " + array.getClass());
- }
- final int length = Array.getLength(array);
- values = new ArrayList<Object>(length);
- for (int i = 0; i < length; ++i) {
- put(JSONObject.wrap(Array.get(array, i)));
- }
- }
-
- /**
- * @return Returns the number of values in this array.
- */
- public int length() {
- return values.size();
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(boolean value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this array.
- * @throws JSONException If the value is unacceptable.
- */
- public JSONArray put(double value) throws JSONException {
- values.add(JSON.checkDouble(value));
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(int value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value The value to append.
- * @return this array.
- */
- public JSONArray put(long value) {
- values.add(value);
- return this;
- }
-
- /**
- * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
- *
- * @param value any collection.
- * @return this array.
- */
- public JSONArray put(Collection<?> value) {
- if (value == null) {
- return put((Object) null);
- }
- values.add(new JSONArray(value));
- return this;
- }
-
- /**
- * Appends {@code value} to the end of this array.
- *
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link JSONObject#NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}. Unsupported values are not permitted and will
- * cause the array to be in an inconsistent state.
- * @return this array.
- */
- public JSONArray put(Object value) {
- values.add(value);
- return this;
- }
-
- /**
- * Same as {@link #put}, with added validity checks.
- *
- * @param value The value to append.
- */
- void checkedPut(Object value) throws JSONException {
- if (value instanceof Number) {
- JSON.checkDouble(((Number) value).doubleValue());
- }
-
- put(value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array to the required
- * length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException This should never happen.
- */
- public JSONArray put(int index, boolean value) throws JSONException {
- return put(index, (Boolean) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array to the required
- * length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this array.
- * @throws JSONException If the value is not a finite value.
- */
- public JSONArray put(int index, double value) throws JSONException {
- return put(index, (Double) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array to the required
- * length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, int value) throws JSONException {
- return put(index, (Integer) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array to the required
- * length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, long value) throws JSONException {
- return put(index, (Long) value);
- }
-
- /**
- * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray}, null padding
- * this array to the required length if necessary. If a value already exists at {@code index}, it
- * will be replaced.
- *
- * @param index Where to put the value.
- * @param value The value to set.
- * @return this array.
- * @throws JSONException Should never actually happen.
- */
- public JSONArray put(int index, Collection<?> value) throws JSONException {
- if (value == null) {
- return put(index, (Object) null);
- }
- return put(index, new JSONArray(value));
- }
-
- /**
- * Sets the value at {@code index} to {@code value}, null padding this array to the required
- * length if necessary. If a value already exists at {@code
- * index}, it will be replaced.
- *
- * @param index Where to put the value.
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
- * {@link JSONObject#NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this array.
- * @throws JSONException If the value cannot be represented as a finite double value.
- */
- public JSONArray put(int index, Object value) throws JSONException {
- if (value instanceof Number) {
- // deviate from the original by checking all Numbers, not just floats & doubles
- JSON.checkDouble(((Number) value).doubleValue());
- }
- while (values.size() <= index) {
- values.add(null);
- }
- values.set(index, value);
- return this;
- }
-
- /**
- * Returns true if this array has no value at {@code index}, or if its value is the {@code null}
- * reference or {@link JSONObject#NULL}.
- *
- * @param index Which value to check.
- * @return true if the value is null.
- */
- public boolean isNull(int index) {
- Object value = opt(index);
- return value == null || value == JSONObject.NULL;
- }
-
- /**
- * Returns the value at {@code index}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if this array has no value at {@code index}, or if that value is the
- * {@code null} reference. This method returns normally if the value is
- * {@code JSONObject#NULL}.
- */
- public Object get(int index) throws JSONException {
- try {
- Object value = values.get(index);
- if (value == null) {
- throw new JSONException("Value at " + index + " is null.");
- }
- return value;
- } catch (IndexOutOfBoundsException e) {
- throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
- }
- }
-
- /**
- * Returns the value at {@code index}, or null if the array has no value at {@code index}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public Object opt(int index) {
- if (index < 0 || index >= values.size()) {
- return null;
- }
- return values.get(index);
- }
-
- /**
- * Removes and returns the value at {@code index}, or null if the array has no value at
- * {@code index}.
- *
- * @param index Which value to remove.
- * @return The value previously at the specified location.
- */
- public Object remove(int index) {
- if (index < 0 || index >= values.size()) {
- return null;
- }
- return values.remove(index);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
- * boolean.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
- * boolean.
- */
- public boolean getBoolean(int index) throws JSONException {
- Object object = get(index);
- Boolean result = JSON.toBoolean(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "boolean");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
- * boolean. Returns false otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public boolean optBoolean(int index) {
- return optBoolean(index, false);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
- * boolean. Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback the fallback value to return if no value exists.
- * @return the value at the specified location or the fallback value.
- */
- public boolean optBoolean(int index, boolean fallback) {
- Object object = opt(index);
- Boolean result = JSON.toBoolean(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
- * double.
- */
- public double getDouble(int index) throws JSONException {
- Object object = get(index);
- Double result = JSON.toDouble(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "double");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
- * Returns {@code NaN} otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public double optDouble(int index) {
- return optDouble(index, Double.NaN);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
- * Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public double optDouble(int index, double fallback) {
- Object object = opt(index);
- Double result = JSON.toDouble(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
- * int.
- */
- public int getInt(int index) throws JSONException {
- Object object = get(index);
- Integer result = JSON.toInteger(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "int");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
- * Returns 0 otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public int optInt(int index) {
- return optInt(index, 0);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
- * Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public int optInt(int index, int fallback) {
- Object object = opt(index);
- Integer result = JSON.toInteger(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
- * long.
- */
- public long getLong(int index) throws JSONException {
- Object object = get(index);
- Long result = JSON.toLong(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "long");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
- * Returns 0 otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public long optLong(int index) {
- return optLong(index, 0L);
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
- * Returns {@code fallback} otherwise.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public long optLong(int index, long fallback) {
- Object object = opt(index);
- Long result = JSON.toLong(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists, coercing it if necessary.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if no such value exists.
- */
- public String getString(int index) throws JSONException {
- Object object = get(index);
- String result = JSON.toString(object);
- if (result == null) {
- throw JSON.typeMismatch(index, object, "String");
- }
- return result;
- }
-
- /**
- * Returns the value at {@code index} if it exists, coercing it if necessary. Returns the empty
- * string if no such value exists.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public String optString(int index) {
- return optString(index, "");
- }
-
- /**
- * Returns the value at {@code index} if it exists, coercing it if necessary. Returns
- * {@code fallback} if no such value exists.
- *
- * @param index Which value to get.
- * @param fallback The fallback value to use if no value is at the specified location.
- * @return the value at the specified location or the fallback value.
- */
- public String optString(int index, String fallback) {
- Object object = opt(index);
- String result = JSON.toString(object);
- return result != null ? result : fallback;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONArray}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value doesn't exist or is not a {@code
- * JSONArray}.
- */
- public JSONArray getJSONArray(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONArray) {
- return (JSONArray) object;
- } else {
- throw JSON.typeMismatch(index, object, "JSONArray");
- }
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONArray}. Returns null otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public JSONArray optJSONArray(int index) {
- Object object = opt(index);
- return object instanceof JSONArray ? (JSONArray) object : null;
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONObject}.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- * @throws JSONException if the value doesn't exist or is not a {@code
- * JSONObject}.
- */
- public JSONObject getJSONObject(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONObject) {
- return (JSONObject) object;
- } else {
- throw JSON.typeMismatch(index, object, "JSONObject");
- }
- }
-
- /**
- * Returns the value at {@code index} if it exists and is a {@code
- * JSONObject}. Returns null otherwise.
- *
- * @param index Which value to get.
- * @return the value at the specified location.
- */
- public JSONObject optJSONObject(int index) {
- Object object = opt(index);
- return object instanceof JSONObject ? (JSONObject) object : null;
- }
-
- /**
- * Returns a new object whose values are the values in this array, and whose names are the values
- * in {@code names}. Names and values are paired up by index from 0 through to the shorter array's
- * length. Names that are not strings will be coerced to strings. This method returns null if
- * either array is empty.
- *
- * @param names The names to apply to the returned values.
- * @return the newly constructed object.
- * @throws JSONException Should not be possible.
- */
- public JSONObject toJSONObject(JSONArray names) throws JSONException {
- JSONObject result = new JSONObject();
- int length = Math.min(names.length(), values.size());
- if (length == 0) {
- return null;
- }
- for (int i = 0; i < length; i++) {
- String name = JSON.toString(names.opt(i));
- result.put(name, opt(i));
- }
- return result;
- }
-
- /**
- * Returns a new string by alternating this array's values with {@code
- * separator}. This array's string values are quoted and have their special characters escaped.
- * For example, the array containing the strings '12" pizza', 'taco' and 'soda' joined on '+'
- * returns this:
- *
- * <pre>
- * "12\" pizza" + "taco" + "soda"
- * </pre>
- *
- * @param separator The string used to separate the returned values.
- * @return the conjoined values.
- * @throws JSONException Only if there is a coding error.
- */
- public String join(String separator) throws JSONException {
- JSONStringer stringer = new JSONStringer();
- stringer.open(JSONStringer.Scope.NULL, "");
- for (int i = 0, size = values.size(); i < size; i++) {
- if (i > 0) {
- stringer.out.append(separator);
- }
- stringer.value(values.get(i));
- }
- stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
- return stringer.out.toString();
- }
-
- /**
- * Encodes this array as a compact JSON string, such as:
- *
- * <pre>
- * [94043,90210]
- * </pre>
- *
- * @return The string form of this array.
- */
- @Override
- public String toString() {
- try {
- JSONStringer stringer = new JSONStringer();
- writeTo(stringer);
- return stringer.toString();
- } catch (JSONException e) {
- return null;
- }
- }
-
- /**
- * Encodes this array as a human readable JSON string for debugging, such as:
- *
- * <pre>
- * [
- * 94043,
- * 90210
- * ]
- * </pre>
- *
- * @param indentSpaces the number of spaces to indent for each level of nesting.
- * @return The string form of this array.
- * @throws JSONException Only if there is a coding error.
- */
- public String toString(int indentSpaces) throws JSONException {
- JSONStringer stringer = new JSONStringer(indentSpaces);
- writeTo(stringer);
- return stringer.toString();
- }
-
- void writeTo(JSONStringer stringer) throws JSONException {
- stringer.array();
- for (Object value : values) {
- stringer.value(value);
- }
- stringer.endArray();
- }
-
- @Override
- public boolean equals(Object o) {
- return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
- }
-
- @Override
- public int hashCode() {
- // diverge from the original, which doesn't implement hashCode
- return values.hashCode();
- }
+ private final List<Object> values;
+
+ /**
+ * Creates a {@code JSONArray} with no values.
+ */
+ public JSONArray() {
+ values = new ArrayList<Object>();
+ }
+
+ /**
+ * Creates a new {@code JSONArray} by copying all values from the given
+ * collection.
+ *
+ * @param copyFrom a collection whose values are of supported types.
+ * Unsupported values are not permitted and will yield an array in an
+ * inconsistent state.
+ */
+ /* Accept a raw type for API compatibility */
+ public JSONArray(Collection<?> copyFrom) {
+ this();
+ if (copyFrom != null) {
+ for (Object aCopyFrom : copyFrom) {
+ put(JSONObject.wrap(aCopyFrom));
+ }
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the next array in the
+ * tokener.
+ *
+ * @param readFrom a tokener whose nextValue() method will yield a
+ * {@code JSONArray}.
+ * @throws JSONException if the parse fails or doesn't yield a
+ * {@code JSONArray}.
+ */
+ public JSONArray(JSONTokener readFrom) throws JSONException {
+ /*
+ * Getting the parser to populate this could get tricky. Instead, just
+ * parse to temporary JSONArray and then steal the data from that.
+ */
+ Object object = readFrom.nextValue();
+ if (object instanceof JSONArray) {
+ values = ((JSONArray) object).values;
+ } else {
+ throw JSON.typeMismatch(object, "JSONArray");
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the JSON string.
+ *
+ * @param json a JSON-encoded string containing an array.
+ * @throws JSONException if the parse fails or doesn't yield a {@code
+ * JSONArray}.
+ */
+ public JSONArray(String json) throws JSONException {
+ this(new JSONTokener(json));
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the given primitive array.
+ *
+ * @param array The values to use.
+ * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
+ */
+ public JSONArray(Object array) throws JSONException {
+ if (!array.getClass().isArray()) {
+ throw new JSONException("Not a primitive array: " + array.getClass());
+ }
+ final int length = Array.getLength(array);
+ values = new ArrayList<Object>(length);
+ for (int i = 0; i < length; ++i) {
+ put(JSONObject.wrap(Array.get(array, i)));
+ }
+ }
+
+ /**
+ * @return Returns the number of values in this array.
+ */
+ public int length() {
+ return values.size();
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value The value to append.
+ * @return this array.
+ */
+ public JSONArray put(boolean value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this array.
+ * @throws JSONException If the value is unacceptable.
+ */
+ public JSONArray put(double value) throws JSONException {
+ values.add(JSON.checkDouble(value));
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value The value to append.
+ * @return this array.
+ */
+ public JSONArray put(int value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value The value to append.
+ * @return this array.
+ */
+ public JSONArray put(long value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
+ *
+ * @param value any collection.
+ * @return this array.
+ */
+ public JSONArray put(Collection<?> value) {
+ if (value == null) {
+ return put((Object)null);
+ }
+ values.add(new JSONArray(value));
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+ * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}. Unsupported values are not permitted and will cause the
+ * array to be in an inconsistent state.
+ * @return this array.
+ */
+ public JSONArray put(Object value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Same as {@link #put}, with added validity checks.
+ *
+ * @param value The value to append.
+ */
+ void checkedPut(Object value) throws JSONException {
+ if (value instanceof Number) {
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+
+ put(value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value The value to set.
+ * @return this array.
+ * @throws JSONException This should never happen.
+ */
+ public JSONArray put(int index, boolean value) throws JSONException {
+ return put(index, (Boolean) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this array.
+ * @throws JSONException If the value is not a finite value.
+ */
+ public JSONArray put(int index, double value) throws JSONException {
+ return put(index, (Double) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value The value to set.
+ * @return this array.
+ * @throws JSONException Should never actually happen.
+ */
+ public JSONArray put(int index, int value) throws JSONException {
+ return put(index, (Integer) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value The value to set.
+ * @return this array.
+ * @throws JSONException Should never actually happen.
+ */
+ public JSONArray put(int index, long value) throws JSONException {
+ return put(index, (Long) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray},
+ * null padding this array to the required length if necessary. If a value already
+ * exists at {@code index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value The value to set.
+ * @return this array.
+ * @throws JSONException Should never actually happen.
+ */
+ public JSONArray put(int index, Collection<?> value) throws JSONException {
+ if (value == null) {
+ return put(index, (Object)null);
+ }
+ return put(index, new JSONArray(value));
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param index Where to put the value.
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+ * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}.
+ * @return this array.
+ * @throws JSONException If the value cannot be represented as a finite double value.
+ */
+ public JSONArray put(int index, Object value) throws JSONException {
+ if (value instanceof Number) {
+ // deviate from the original by checking all Numbers, not just floats & doubles
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+ while (values.size() <= index) {
+ values.add(null);
+ }
+ values.set(index, value);
+ return this;
+ }
+
+ /**
+ * Returns true if this array has no value at {@code index}, or if its value
+ * is the {@code null} reference or {@link JSONObject#NULL}.
+ *
+ * @param index Which value to check.
+ * @return true if the value is null.
+ */
+ public boolean isNull(int index) {
+ Object value = opt(index);
+ return value == null || value == JSONObject.NULL;
+ }
+
+ /**
+ * Returns the value at {@code index}.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if this array has no value at {@code index}, or if
+ * that value is the {@code null} reference. This method returns
+ * normally if the value is {@code JSONObject#NULL}.
+ */
+ public Object get(int index) throws JSONException {
+ try {
+ Object value = values.get(index);
+ if (value == null) {
+ throw new JSONException("Value at " + index + " is null.");
+ }
+ return value;
+ } catch (IndexOutOfBoundsException e) {
+ throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
+ }
+ }
+
+ /**
+ * Returns the value at {@code index}, or null if the array has no value
+ * at {@code index}.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public Object opt(int index) {
+ if (index < 0 || index >= values.size()) {
+ return null;
+ }
+ return values.get(index);
+ }
+
+ /**
+ * Removes and returns the value at {@code index}, or null if the array has no value
+ * at {@code index}.
+ *
+ * @param index Which value to remove.
+ * @return The value previously at the specified location.
+ */
+ public Object remove(int index) {
+ if (index < 0 || index >= values.size()) {
+ return null;
+ }
+ return values.remove(index);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a boolean.
+ */
+ public boolean getBoolean(int index) throws JSONException {
+ Object object = get(index);
+ Boolean result = JSON.toBoolean(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "boolean");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean. Returns false otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public boolean optBoolean(int index) {
+ return optBoolean(index, false);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean. Returns {@code fallback} otherwise.
+ *
+ * @param index Which value to get.
+ * @param fallback the fallback value to return if no value exists.
+ * @return the value at the specified location or the fallback value.
+ */
+ public boolean optBoolean(int index, boolean fallback) {
+ Object object = opt(index);
+ Boolean result = JSON.toBoolean(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a double.
+ */
+ public double getDouble(int index) throws JSONException {
+ Object object = get(index);
+ Double result = JSON.toDouble(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "double");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double. Returns {@code NaN} otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public double optDouble(int index) {
+ return optDouble(index, Double.NaN);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double. Returns {@code fallback} otherwise.
+ *
+ * @param index Which value to get.
+ * @param fallback The fallback value to use if no value is at the specified location.
+ * @return the value at the specified location or the fallback value.
+ */
+ public double optDouble(int index, double fallback) {
+ Object object = opt(index);
+ Double result = JSON.toDouble(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a int.
+ */
+ public int getInt(int index) throws JSONException {
+ Object object = get(index);
+ Integer result = JSON.toInteger(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "int");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int. Returns 0 otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public int optInt(int index) {
+ return optInt(index, 0);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int. Returns {@code fallback} otherwise.
+ *
+ * @param index Which value to get.
+ * @param fallback The fallback value to use if no value is at the specified location.
+ * @return the value at the specified location or the fallback value.
+ */
+ public int optInt(int index, int fallback) {
+ Object object = opt(index);
+ Integer result = JSON.toInteger(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a long.
+ */
+ public long getLong(int index) throws JSONException {
+ Object object = get(index);
+ Long result = JSON.toLong(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "long");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long. Returns 0 otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public long optLong(int index) {
+ return optLong(index, 0L);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long. Returns {@code fallback} otherwise.
+ *
+ * @param index Which value to get.
+ * @param fallback The fallback value to use if no value is at the specified location.
+ * @return the value at the specified location or the fallback value.
+ */
+ public long optLong(int index, long fallback) {
+ Object object = opt(index);
+ Long result = JSON.toLong(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if no such value exists.
+ */
+ public String getString(int index) throws JSONException {
+ Object object = get(index);
+ String result = JSON.toString(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "String");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary. Returns the empty string if no such value exists.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public String optString(int index) {
+ return optString(index, "");
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary. Returns {@code fallback} if no such value exists.
+ *
+ * @param index Which value to get.
+ * @param fallback The fallback value to use if no value is at the specified location.
+ * @return the value at the specified location or the fallback value.
+ */
+ public String optString(int index, String fallback) {
+ Object object = opt(index);
+ String result = JSON.toString(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONArray}.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value doesn't exist or is not a {@code
+ * JSONArray}.
+ */
+ public JSONArray getJSONArray(int index) throws JSONException {
+ Object object = get(index);
+ if (object instanceof JSONArray) {
+ return (JSONArray) object;
+ } else {
+ throw JSON.typeMismatch(index, object, "JSONArray");
+ }
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONArray}. Returns null otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public JSONArray optJSONArray(int index) {
+ Object object = opt(index);
+ return object instanceof JSONArray ? (JSONArray) object : null;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONObject}.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ * @throws JSONException if the value doesn't exist or is not a {@code
+ * JSONObject}.
+ */
+ public JSONObject getJSONObject(int index) throws JSONException {
+ Object object = get(index);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
+ } else {
+ throw JSON.typeMismatch(index, object, "JSONObject");
+ }
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONObject}. Returns null otherwise.
+ *
+ * @param index Which value to get.
+ * @return the value at the specified location.
+ */
+ public JSONObject optJSONObject(int index) {
+ Object object = opt(index);
+ return object instanceof JSONObject ? (JSONObject) object : null;
+ }
+
+ /**
+ * Returns a new object whose values are the values in this array, and whose
+ * names are the values in {@code names}. Names and values are paired up by
+ * index from 0 through to the shorter array's length. Names that are not
+ * strings will be coerced to strings. This method returns null if either
+ * array is empty.
+ *
+ * @param names The names to apply to the returned values.
+ * @return the newly constructed object.
+ * @throws JSONException Should not be possible.
+ */
+ public JSONObject toJSONObject(JSONArray names) throws JSONException {
+ JSONObject result = new JSONObject();
+ int length = Math.min(names.length(), values.size());
+ if (length == 0) {
+ return null;
+ }
+ for (int i = 0; i < length; i++) {
+ String name = JSON.toString(names.opt(i));
+ result.put(name, opt(i));
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new string by alternating this array's values with {@code
+ * separator}. This array's string values are quoted and have their special
+ * characters escaped. For example, the array containing the strings '12"
+ * pizza', 'taco' and 'soda' joined on '+' returns this:
+ * <pre>"12\" pizza"+"taco"+"soda"</pre>
+ *
+ * @param separator The string used to separate the returned values.
+ * @return the conjoined values.
+ * @throws JSONException Only if there is a coding error.
+ */
+ public String join(String separator) throws JSONException {
+ JSONStringer stringer = new JSONStringer();
+ stringer.open(JSONStringer.Scope.NULL, "");
+ for (int i = 0, size = values.size(); i < size; i++) {
+ if (i > 0) {
+ stringer.out.append(separator);
+ }
+ stringer.value(values.get(i));
+ }
+ stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+ return stringer.out.toString();
+ }
+
+ /**
+ * Encodes this array as a compact JSON string, such as:
+ * <pre>[94043,90210]</pre>
+ *
+ * @return The string form of this array.
+ */
+ @Override
+ public String toString() {
+ try {
+ JSONStringer stringer = new JSONStringer();
+ writeTo(stringer);
+ return stringer.toString();
+ } catch (JSONException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Encodes this array as a human readable JSON string for debugging, such
+ * as:
+ * <pre>
+ * [
+ * 94043,
+ * 90210
+ * ]</pre>
+ *
+ * @param indentSpaces the number of spaces to indent for each level of
+ * nesting.
+ * @return The string form of this array.
+ * @throws JSONException Only if there is a coding error.
+ */
+ public String toString(int indentSpaces) throws JSONException {
+ JSONStringer stringer = new JSONStringer(indentSpaces);
+ writeTo(stringer);
+ return stringer.toString();
+ }
+
+ void writeTo(JSONStringer stringer) throws JSONException {
+ stringer.array();
+ for (Object value : values) {
+ stringer.value(value);
+ }
+ stringer.endArray();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+ }
+
+ @Override
+ public int hashCode() {
+ // diverge from the original, which doesn't implement hashCode
+ return values.hashCode();
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/1253d780/geode-json/src/main/java/org/json/JSONException.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONException.java b/geode-json/src/main/java/org/json/JSONException.java
index 83fb4b8..1292e86 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,15 +1,17 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.json;
@@ -19,40 +21,37 @@ package org.json;
/**
* Thrown to indicate a problem with the JSON API. Such problems include:
* <ul>
- * <li>Attempts to parse or construct malformed documents
- * <li>Use of null as a name
- * <li>Use of numeric types not available to JSON, such as {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * <li>Lookups using an out of range index or nonexistent name
- * <li>Type mismatches on lookups
+ * <li>Attempts to parse or construct malformed documents
+ * <li>Use of null as a name
+ * <li>Use of numeric types not available to JSON, such as {@link
+ * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+ * <li>Lookups using an out of range index or nonexistent name
+ * <li>Type mismatches on lookups
* </ul>
*
- * <p>
- * Although this is a checked exception, it is rarely recoverable. Most callers should simply wrap
- * this exception in an unchecked exception and rethrow:
- *
- * <pre>
- * public JSONArray toJSONObject() {
+ * <p>Although this is a checked exception, it is rarely recoverable. Most
+ * callers should simply wrap this exception in an unchecked exception and
+ * rethrow:
+ * <pre> public JSONArray toJSONObject() {
* try {
* JSONObject result = new JSONObject();
* ...
* } catch (JSONException e) {
* throw new RuntimeException(e);
* }
- * }
- * </pre>
+ * }</pre>
*/
public class JSONException extends RuntimeException {
- public JSONException(String s) {
- super(s);
- }
+ public JSONException(String s) {
+ super(s);
+ }
- public JSONException(Throwable cause) {
- super(cause);
- }
+ public JSONException(Throwable cause) {
+ super(cause);
+ }
- public JSONException(String message, Throwable cause) {
- super(message, cause);
- }
+ public JSONException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
[5/8] geode git commit: Revert "GEODE-2142: Removal of non-compliant
org.json implementation."
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONStringer.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONStringer.java b/geode-json/src/main/java/org/json/JSONStringer.java
index db1121e..234e174 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,470 +1,75 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package org.json;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+/*
+ * Copyright (c) 2006 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
-// Note: this class was written without inspecting the non-free org.json sourcecode.
+import java.io.StringWriter;
/**
- * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
- * application developers should use those methods directly and disregard this
- * API. For example:<pre>
- * JSONObject object = ...
- * String json = object.toString();</pre>
- *
- * <p>Stringers only encode well-formed JSON strings. In particular:
- * <ul>
- * <li>The stringer must have exactly one top-level array or object.
- * <li>Lexical scopes must be balanced: every call to {@link #array} must
- * have a matching call to {@link #endArray} and every call to {@link
- * #object} must have a matching call to {@link #endObject}.
- * <li>Arrays may not contain keys (property names).
- * <li>Objects must alternate keys (property names) and values.
- * <li>Values are inserted with either literal {@link #value(Object) value}
- * calls, or by nesting arrays or objects.
- * </ul>
- * Calls that would result in a malformed JSON string will fail with a
- * {@link JSONException}.
- *
- * <p>This class provides no facility for pretty-printing (ie. indenting)
- * output. To encode indented output, use {@link JSONObject#toString(int)} or
- * {@link JSONArray#toString(int)}.
- *
- * <p>Some implementations of the API support at most 20 levels of nesting.
- * Attempts to create more than 20 levels of nesting may fail with a {@link
- * JSONException}.
- *
- * <p>Each stringer may be used to encode a single top level value. Instances of
- * this class are not thread safe. Although this class is nonfinal, it was not
- * designed for inheritance and should not be subclassed. In particular,
- * self-use by overrideable methods is not specified. See <i>Effective Java</i>
- * Item 17, "Design and Document or inheritance or else prohibit it" for further
- * information.
+ * JSONStringer provides a quick and convenient way of producing JSON text. The texts produced
+ * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
+ * transmission or storage. Each instance of JSONStringer can produce one JSON text.
+ * <p>
+ * A JSONStringer instance provides a <code>value</code> method for appending values to the text,
+ * and a <code>key</code> method for adding keys before values in objects. There are
+ * <code>array</code> and <code>endArray</code> methods that make and bound array values, and
+ * <code>object</code> and <code>endObject</code> methods which make and bound object values. All of
+ * these methods return the JSONWriter instance, permitting cascade style. For example,
+ *
+ * <pre>
+ * myString = new JSONStringer().object().key("JSON").value("Hello, World!").endObject().toString();
+ * </pre>
+ *
+ * which produces the string
+ *
+ * <pre>
+ * {"JSON":"Hello, World!"}
+ * </pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>. There are no methods
+ * for adding commas or colons. JSONStringer adds them for you. Objects and arrays can be nested up
+ * to 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ *
+ * @author JSON.org
+ * @version 2008-09-18
*/
-public class JSONStringer {
-
- /**
- * The output data, containing at most one top-level array or object.
- */
- final StringBuilder out = new StringBuilder();
-
- /**
- * Lexical scoping elements within this stringer, necessary to insert the
- * appropriate separator characters (ie. commas and colons) and to detect
- * nesting errors.
- */
- enum Scope {
-
- /**
- * An array with no elements requires no separators or newlines before
- * it is closed.
- */
- EMPTY_ARRAY,
-
- /**
- * A array with at least one value requires a comma and newline before
- * the next element.
- */
- NONEMPTY_ARRAY,
-
- /**
- * An object with no keys or values requires no separators or newlines
- * before it is closed.
- */
- EMPTY_OBJECT,
-
- /**
- * An object whose most recent element is a key. The next element must
- * be a value.
- */
- DANGLING_KEY,
-
- /**
- * An object with at least one name/value pair requires a comma and
- * newline before the next element.
- */
- NONEMPTY_OBJECT,
-
- /**
- * A special bracketless array needed by JSONStringer.join() and
- * JSONObject.quote() only. Not used for JSON encoding.
- */
- NULL,
- }
-
- /**
- * Unlike the original implementation, this stack isn't limited to 20
- * levels of nesting.
- */
- private final List<Scope> stack = new ArrayList<Scope>();
-
- /**
- * A string containing a full set of spaces for a single level of
- * indentation, or null for no pretty printing.
- */
- private final String indent;
-
- public JSONStringer() {
- indent = null;
- }
-
- JSONStringer(int indentSpaces) {
- char[] indentChars = new char[indentSpaces];
- Arrays.fill(indentChars, ' ');
- indent = new String(indentChars);
- }
-
- /**
- * Begins encoding a new array. Each call to this method must be paired with
- * a call to {@link #endArray}.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer array() throws JSONException {
- return open(Scope.EMPTY_ARRAY, "[");
- }
-
- /**
- * Ends encoding the current array.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer endArray() throws JSONException {
- return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
- }
-
- /**
- * Begins encoding a new object. Each call to this method must be paired
- * with a call to {@link #endObject}.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer object() throws JSONException {
- return open(Scope.EMPTY_OBJECT, "{");
- }
-
- /**
- * Ends encoding the current object.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer endObject() throws JSONException {
- return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
- }
-
- /**
- * Enters a new scope by appending any necessary whitespace and the given
- * bracket.
- */
- JSONStringer open(Scope empty, String openBracket) throws JSONException {
- if (stack.isEmpty() && out.length() > 0) {
- throw new JSONException("Nesting problem: multiple top-level roots");
- }
- beforeValue();
- stack.add(empty);
- out.append(openBracket);
- return this;
- }
-
- /**
- * Closes the current scope by appending any necessary whitespace and the
- * given bracket.
- */
- JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
- Scope context = peek();
- if (context != nonempty && context != empty) {
- throw new JSONException("Nesting problem");
- }
-
- stack.remove(stack.size() - 1);
- if (context == nonempty) {
- newline();
- }
- out.append(closeBracket);
- return this;
- }
-
- /**
- * Returns the value on the top of the stack.
- */
- private Scope peek() throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- return stack.get(stack.size() - 1);
- }
-
- /**
- * Replace the value on the top of the stack with the given value.
- */
- private void replaceTop(Scope topOfStack) {
- stack.set(stack.size() - 1, topOfStack);
- }
-
- /**
- * Encodes {@code value}.
- *
- * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
- * Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
- * or {@link Double#isInfinite() infinities}.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(Object value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
-
- if (value instanceof JSONArray) {
- ((JSONArray) value).writeTo(this);
- return this;
-
- } else if (value instanceof JSONObject) {
- ((JSONObject) value).writeTo(this);
- return this;
- }
-
- beforeValue();
-
- if (value instanceof JSONString) {
- out.append(((JSONString) value).toJSONString());
- return this;
- }
-
- if (value == null
- || value instanceof Boolean
- || value == JSONObject.NULL) {
- out.append(value);
-
- } else if (value instanceof Number) {
- out.append(JSONObject.numberToString((Number) value));
-
- } else {
- // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript function calls)
- // Example: { "name": "testkey", "value": window.myfunction() }
- if (value.getClass().getSimpleName().contains("JSONFunction")) {
- // note that no escaping of quotes (or anything else) is done in this case.
- // that is fine because the only way to get to this point is to
- // explicitly put a special kind of object into the JSON data structure.
- out.append(value);
- } else {
- string(value.toString());
- }
- }
-
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value The value to encode.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(boolean value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- beforeValue();
- out.append(value);
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
- */
- public JSONStringer value(double value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- beforeValue();
- out.append(JSONObject.numberToString(value));
- return this;
- }
-
- /**
- * Encodes {@code value} to this stringer.
- *
- * @param value The value to encode.
- * @return this stringer.
- * @throws JSONException If we have an internal error. Shouldn't happen.
- */
- public JSONStringer value(long value) throws JSONException {
- if (stack.isEmpty()) {
- throw new JSONException("Nesting problem");
- }
- beforeValue();
- out.append(value);
- return this;
- }
-
- private void string(String value) {
- out.append("\"");
- char currentChar = 0;
-
- for (int i = 0, length = value.length(); i < length; i++) {
- char previousChar = currentChar;
- currentChar = value.charAt(i);
-
- /*
- * From RFC 4627, "All Unicode characters may be placed within the
- * quotation marks except for the characters that must be escaped:
- * quotation mark, reverse solidus, and the control characters
- * (U+0000 through U+001F)."
- */
- switch (currentChar) {
- case '"':
- case '\\':
- out.append('\\').append(currentChar);
- break;
-
- case '/':
- // it makes life easier for HTML embedding of javascript if we escape </ sequences
- if (previousChar == '<') {
- out.append('\\');
- }
- out.append(currentChar);
- break;
-
- case '\t':
- out.append("\\t");
- break;
-
- case '\b':
- out.append("\\b");
- break;
-
- case '\n':
- out.append("\\n");
- break;
-
- case '\r':
- out.append("\\r");
- break;
-
- case '\f':
- out.append("\\f");
- break;
-
- default:
- if (currentChar <= 0x1F) {
- out.append(String.format("\\u%04x", (int) currentChar));
- } else {
- out.append(currentChar);
- }
- break;
- }
-
- }
- out.append("\"");
- }
-
- private void newline() {
- if (indent == null) {
- return;
- }
-
- out.append("\n");
- for (int i = 0; i < stack.size(); i++) {
- out.append(indent);
- }
- }
-
- /**
- * Encodes the key (property name) to this stringer.
- *
- * @param name the name of the forthcoming value. May not be null.
- * @return this stringer.
- * @throws JSONException on internal errors, shouldn't happen.
- */
- public JSONStringer key(String name) throws JSONException {
- if (name == null) {
- throw new JSONException("Names must be non-null");
- }
- beforeKey();
- string(name);
- return this;
- }
-
- /**
- * Inserts any necessary separators and whitespace before a name. Also
- * adjusts the stack to expect the key's value.
- */
- private void beforeKey() throws JSONException {
- Scope context = peek();
- if (context == Scope.NONEMPTY_OBJECT) { // first in object
- out.append(',');
- } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
- throw new JSONException("Nesting problem");
- }
- newline();
- replaceTop(Scope.DANGLING_KEY);
- }
-
- /**
- * Inserts any necessary separators and whitespace before a literal value,
- * inline array, or inline object. Also adjusts the stack to expect either a
- * closing bracket or another element.
- */
- private void beforeValue() throws JSONException {
- if (stack.isEmpty()) {
- return;
- }
-
- Scope context = peek();
- if (context == Scope.EMPTY_ARRAY) { // first in array
- replaceTop(Scope.NONEMPTY_ARRAY);
- newline();
- } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
- out.append(',');
- newline();
- } else if (context == Scope.DANGLING_KEY) { // value for key
- out.append(indent == null ? ":" : ": ");
- replaceTop(Scope.NONEMPTY_OBJECT);
- } else if (context != Scope.NULL) {
- throw new JSONException("Nesting problem");
- }
- }
-
- /**
- * Returns the encoded JSON string.
- *
- * <p>If invoked with unterminated arrays or unclosed objects, this method's
- * return value is undefined.
- *
- * <p><strong>Warning:</strong> although it contradicts the general contract
- * of {@link Object#toString}, this method returns null if the stringer
- * contains no data.
- */
- @Override
- public String toString() {
- return out.length() == 0 ? null : out.toString();
- }
+public class JSONStringer extends JSONWriter {
+ /**
+ * Make a fresh JSONStringer. It can be used to build one JSON text.
+ */
+ public JSONStringer() {
+ super(new StringWriter());
+ }
+
+ /**
+ * Return the JSON text. This method is used to obtain the product of the JSONStringer instance.
+ * It will return <code>null</code> if there was a problem in the construction of the JSON text
+ * (such as the calls to <code>array</code> were not properly balanced with calls to
+ * <code>endArray</code>).
+ *
+ * @return The JSON text.
+ */
+ public String toString() {
+ return this.mode == 'd' ? this.writer.toString() : null;
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONTokener.java b/geode-json/src/main/java/org/json/JSONTokener.java
old mode 100755
new mode 100644
index 59eb4bc..4dd2ba2
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,658 +1,437 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package org.json;
-// Note: this class was written without inspecting the non-free org.json sourcecode.
-
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.Reader;
+import java.io.StringReader;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
/**
- * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
- * encoded string into the corresponding object. Most clients of
- * this class will use only need the {@link #JSONTokener(String) constructor}
- * and {@link #nextValue} method. Example usage: <pre>
- * String json = "{"
- * + " \"query\": \"Pizza\", "
- * + " \"locations\": [ 94043, 90210 ] "
- * + "}";
- *
- * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
- * String query = object.getString("query");
- * JSONArray locations = object.getJSONArray("locations");</pre>
- *
- * <p>For best interoperability and performance use JSON that complies with
- * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
- * this parser is lenient, so a successful parse does not indicate that the
- * input string was valid JSON. All of the following syntax errors will be
- * ignored:
- * <ul>
- * <li>End of line comments starting with {@code //} or {@code #} and ending
- * with a newline character.
- * <li>C-style comments starting with {@code /*} and ending with
- * {@code *}{@code /}. Such comments may not be nested.
- * <li>Strings that are unquoted or {@code 'single quoted'}.
- * <li>Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
- * <li>Octal integers prefixed with {@code 0}.
- * <li>Array elements separated by {@code ;}.
- * <li>Unnecessary array separators. These are interpreted as if null was the
- * omitted value.
- * <li>Key-value pairs separated by {@code =} or {@code =>}.
- * <li>Key-value pairs separated by {@code ;}.
- * </ul>
- *
- * <p>Each tokener may be used to parse a single JSON string. Instances of this
- * class are not thread safe. Although this class is nonfinal, it was not
- * designed for inheritance and should not be subclassed. In particular,
- * self-use by overrideable methods is not specified. See <i>Effective Java</i>
- * Item 17, "Design and Document or inheritance or else prohibit it" for further
- * information.
+ * 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 2012-02-16
*/
public class JSONTokener {
- /**
- * The input JSON.
- */
- private final String in;
-
- /**
- * The index of the next character to be returned by {@link #next}. When
- * the input is exhausted, this equals the input's length.
- */
- private int pos;
-
- /**
- * @param in JSON encoded string. Null is not permitted and will yield a
- * tokener that throws {@code NullPointerExceptions} when methods are
- * called.
- */
- public JSONTokener(String in) {
- // consume an optional byte order mark (BOM) if it exists
- if (in != null && in.startsWith("\ufeff")) {
- in = in.substring(1);
- }
- this.in = in;
+ private long character;
+ private boolean eof;
+ private long index;
+ private long line;
+ private char previous;
+ private Reader reader;
+ private boolean usePrevious;
+
+
+ /**
+ * Construct a JSONTokener from a Reader.
+ *
+ * @param reader A reader.
+ */
+ public JSONTokener(Reader reader) {
+ this.reader = reader.markSupported() ? reader : new BufferedReader(reader);
+ this.eof = false;
+ this.usePrevious = false;
+ this.previous = 0;
+ this.index = 0;
+ this.character = 1;
+ this.line = 1;
+ }
+
+
+ /**
+ * Construct a JSONTokener from an InputStream.
+ */
+ public JSONTokener(InputStream inputStream) throws JSONException {
+ this(new InputStreamReader(inputStream));
+ }
+
+
+ /**
+ * Construct a JSONTokener from a 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.
+ */
+ public void back() throws JSONException {
+ if (this.usePrevious || this.index <= 0) {
+ throw new JSONException("Stepping back two steps is not supported");
}
-
- public JSONTokener(Reader input) throws IOException {
- StringBuilder s = new StringBuilder();
- char[] readBuf = new char[102400];
- int n = input.read(readBuf);
- while (n >= 0) {
- s.append(readBuf, 0, n);
- n = input.read(readBuf);
- }
- in = s.toString();
- pos = 0;
+ this.index -= 1;
+ this.character -= 1;
+ this.usePrevious = true;
+ this.eof = false;
+ }
+
+
+ /**
+ * 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.
+ */
+ public static int dehexchar(char c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
}
-
- /**
- * Returns the next value from the input.
- *
- * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
- * Integer, Long, Double or {@link JSONObject#NULL}.
- * @throws JSONException if the input is malformed.
- */
- public Object nextValue() throws JSONException {
- int c = nextCleanInternal();
- switch (c) {
- case -1:
- throw syntaxError("End of input");
-
- case '{':
- return readObject();
-
- case '[':
- return readArray();
-
- case '\'':
- case '"':
- return nextString((char) c);
-
- default:
- pos--;
- return readLiteral();
- }
+ if (c >= 'A' && c <= 'F') {
+ return c - ('A' - 10);
}
-
- private int nextCleanInternal() throws JSONException {
- while (pos < in.length()) {
- int c = in.charAt(pos++);
- switch (c) {
- case '\t':
- case ' ':
- case '\n':
- case '\r':
- continue;
-
- case '/':
- if (pos == in.length()) {
- return c;
- }
-
- char peek = in.charAt(pos);
- switch (peek) {
- case '*':
- // skip a /* c-style comment */
- pos++;
- int commentEnd = in.indexOf("*/", pos);
- if (commentEnd == -1) {
- throw syntaxError("Unterminated comment");
- }
- pos = commentEnd + 2;
- continue;
-
- case '/':
- // skip a // end-of-line comment
- pos++;
- skipToEndOfLine();
- continue;
-
- default:
- return c;
- }
-
- case '#':
- /*
- * Skip a # hash end-of-line comment. The JSON RFC doesn't
- * specify this behavior, but it's required to parse
- * existing documents. See http://b/2571423.
- */
- skipToEndOfLine();
- continue;
-
- default:
- return c;
- }
- }
-
- return -1;
+ if (c >= 'a' && c <= 'f') {
+ return c - ('a' - 10);
}
-
- /**
- * Advances the position until after the next newline character. If the line
- * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
- * caller.
- */
- private void skipToEndOfLine() {
- for (; pos < in.length(); pos++) {
- char c = in.charAt(pos);
- if (c == '\r' || c == '\n') {
- pos++;
- break;
- }
- }
+ return -1;
+ }
+
+ public boolean end() {
+ return this.eof && !this.usePrevious;
+ }
+
+
+ /**
+ * Determine if the source string still contains characters that next() can consume.
+ *
+ * @return true if not yet at the end of the source.
+ */
+ public boolean more() throws JSONException {
+ this.next();
+ if (this.end()) {
+ return false;
}
-
- /**
- * Returns the string up to but not including {@code quote}, unescaping any
- * character escape sequences encountered along the way. The opening quote
- * should have already been read. This consumes the closing quote, but does
- * not include it in the returned string.
- *
- * @param quote either ' or ".
- * @return The unescaped string.
- * @throws JSONException if the string isn't terminated by a closing quote correctly.
- */
- public String nextString(char quote) throws JSONException {
- /*
- * For strings that are free of escape sequences, we can just extract
- * the result as a substring of the input. But if we encounter an escape
- * sequence, we need to use a StringBuilder to compose the result.
- */
- StringBuilder builder = null;
-
- /* the index of the first character not yet appended to the builder. */
- int start = pos;
-
- while (pos < in.length()) {
- int c = in.charAt(pos++);
- if (c == quote) {
- if (builder == null) {
- // a new string avoids leaking memory
- //noinspection RedundantStringConstructorCall
- return new String(in.substring(start, pos - 1));
- } else {
- builder.append(in, start, pos - 1);
- return builder.toString();
- }
- }
-
- if (c == '\\') {
- if (pos == in.length()) {
- throw syntaxError("Unterminated escape sequence");
- }
- if (builder == null) {
- builder = new StringBuilder();
- }
- builder.append(in, start, pos - 1);
- builder.append(readEscapeCharacter());
- start = pos;
- }
- }
-
- throw syntaxError("Unterminated string");
+ this.back();
+ return true;
+ }
+
+
+ /**
+ * Get the next character in the source string.
+ *
+ * @return The next character, or 0 if past the end of the source string.
+ */
+ public char next() throws JSONException {
+ int c;
+ if (this.usePrevious) {
+ this.usePrevious = false;
+ c = this.previous;
+ } else {
+ try {
+ c = this.reader.read();
+ } catch (IOException exception) {
+ throw new JSONException(exception);
+ }
+
+ if (c <= 0) { // End of stream
+ this.eof = true;
+ c = 0;
+ }
+ }
+ this.index += 1;
+ if (this.previous == '\r') {
+ this.line += 1;
+ this.character = c == '\n' ? 0 : 1;
+ } else if (c == '\n') {
+ this.line += 1;
+ this.character = 0;
+ } else {
+ this.character += 1;
+ }
+ this.previous = (char) c;
+ return this.previous;
+ }
+
+
+ /**
+ * 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.
+ */
+ public char next(char c) throws JSONException {
+ char n = this.next();
+ if (n != c) {
+ throw this.syntaxError("Expected '" + c + "' and instead saw '" + n + "'");
+ }
+ return n;
+ }
+
+
+ /**
+ * 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.
+ */
+ public String next(int n) throws JSONException {
+ if (n == 0) {
+ return "";
}
- /**
- * Unescapes the character identified by the character or characters that
- * immediately follow a backslash. The backslash '\' should have already
- * been read. This supports both unicode escapes "u000A" and two-character
- * escapes "\n".
- */
- private char readEscapeCharacter() throws JSONException {
- char escaped = in.charAt(pos++);
- switch (escaped) {
- case 'u':
- if (pos + 4 > in.length()) {
- throw syntaxError("Unterminated escape sequence");
- }
- String hex = in.substring(pos, pos + 4);
- pos += 4;
- try {
- return (char) Integer.parseInt(hex, 16);
- } catch (NumberFormatException nfe) {
- throw syntaxError("Invalid escape sequence: " + hex);
- }
-
- case 't':
- return '\t';
+ char[] chars = new char[n];
+ int pos = 0;
+ while (pos < n) {
+ chars[pos] = this.next();
+ if (this.end()) {
+ throw this.syntaxError("Substring bounds error");
+ }
+ pos += 1;
+ }
+ return new String(chars);
+ }
+
+
+ /**
+ * Get the next char in the string, skipping whitespace.
+ *
+ * @throws JSONException
+ * @return A character, or 0 if there are no more characters.
+ */
+ public char nextClean() throws JSONException {
+ for (;;) {
+ char c = this.next();
+ if (c == 0 || c > ' ') {
+ return c;
+ }
+ }
+ }
+
+
+ /**
+ * Return the characters up to the next close quote character. 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 <code>"</code> <small>(double quote)</small> or
+ * <code>'</code> <small>(single quote)</small>.
+ * @return A String.
+ * @throws JSONException Unterminated string.
+ */
+ public String nextString(char quote) throws JSONException {
+ char c;
+ StringBuffer sb = new StringBuffer();
+ 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':
- return '\b';
-
+ sb.append('\b');
+ break;
+ case 't':
+ sb.append('\t');
+ break;
case 'n':
- return '\n';
-
- case 'r':
- return '\r';
-
+ sb.append('\n');
+ break;
case 'f':
- return '\f';
-
- case '\'':
+ sb.append('\f');
+ break;
+ case 'r':
+ sb.append('\r');
+ break;
+ case 'u':
+ sb.append((char) Integer.parseInt(this.next(4), 16));
+ break;
case '"':
+ case '\'':
case '\\':
+ case '/':
+ sb.append(c);
+ break;
default:
- return escaped;
- }
- }
-
- /**
- * Reads a null, boolean, numeric or unquoted string literal value. Numeric
- * values will be returned as an Integer, Long, or Double, in that order of
- * preference.
- */
- private Object readLiteral() throws JSONException {
- String literal = nextToInternal("{}[]/\\:,=;# \t\f");
-
- if (literal.length() == 0) {
- throw syntaxError("Expected literal value");
- } else if ("null".equalsIgnoreCase(literal)) {
- return JSONObject.NULL;
- } else if ("true".equalsIgnoreCase(literal)) {
- return Boolean.TRUE;
- } else if ("false".equalsIgnoreCase(literal)) {
- return Boolean.FALSE;
- }
-
- /* try to parse as an integral type... */
- if (literal.indexOf('.') == -1) {
- int base = 10;
- String number = literal;
- if (number.startsWith("0x") || number.startsWith("0X")) {
- number = number.substring(2);
- base = 16;
- } else if (number.startsWith("0") && number.length() > 1) {
- number = number.substring(1);
- base = 8;
- }
- try {
- long longValue = Long.parseLong(number, base);
- if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
- return (int) longValue;
- } else {
- return longValue;
- }
- } catch (NumberFormatException e) {
- /*
- * This only happens for integral numbers greater than
- * Long.MAX_VALUE, numbers in exponential form (5e-10) and
- * unquoted strings. Fall through to try floating point.
- */
- }
- }
-
- /* ...next try to parse as a floating point... */
- try {
- return Double.valueOf(literal);
- } catch (NumberFormatException ignored) {
- }
-
- /* ... finally give up. We have an unquoted string */
- //noinspection RedundantStringConstructorCall
- return new String(literal); // a new string avoids leaking memory
- }
-
- /**
- * Returns the string up to but not including any of the given characters or
- * a newline character. This does not consume the excluded character.
- */
- private String nextToInternal(String excluded) {
- int start = pos;
- for (; pos < in.length(); pos++) {
- char c = in.charAt(pos);
- if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
- return in.substring(start, pos);
- }
- }
- return in.substring(start);
+ throw this.syntaxError("Illegal escape.");
+ }
+ break;
+ default:
+ if (c == quote) {
+ return sb.toString();
+ }
+ sb.append(c);
+ }
}
-
- /**
- * Reads a sequence of key/value pairs and the trailing closing brace '}' of
- * an object. The opening brace '{' should have already been read.
- */
- private JSONObject readObject() throws JSONException {
- JSONObject result = new JSONObject();
-
- /* Peek to see if this is the empty object. */
- int first = nextCleanInternal();
- if (first == '}') {
- return result;
- } else if (first != -1) {
- pos--;
- }
-
- while (true) {
- Object name = nextValue();
- if (!(name instanceof String)) {
- if (name == null) {
- throw syntaxError("Names cannot be null");
- } else {
- throw syntaxError("Names must be strings, but " + name
- + " is of type " + name.getClass().getName());
- }
- }
-
- /*
- * Expect the name/value separator to be either a colon ':', an
- * equals sign '=', or an arrow "=>". The last two are bogus but we
- * include them because that's what the original implementation did.
- */
- int separator = nextCleanInternal();
- if (separator != ':' && separator != '=') {
- throw syntaxError("Expected ':' after " + name);
- }
- if (pos < in.length() && in.charAt(pos) == '>') {
- pos++;
- }
-
- result.put((String) name, nextValue());
-
- switch (nextCleanInternal()) {
- case '}':
- return result;
- case ';':
- case ',':
- continue;
- default:
- throw syntaxError("Unterminated object");
- }
+ }
+
+
+ /**
+ * 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.
+ */
+ public String nextTo(char delimiter) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ char c = this.next();
+ if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
+ if (c != 0) {
+ this.back();
}
+ return sb.toString().trim();
+ }
+ sb.append(c);
}
-
- /**
- * Reads a sequence of values and the trailing closing brace ']' of an
- * array. The opening brace '[' should have already been read. Note that
- * "[]" yields an empty array, but "[,]" returns a two-element array
- * equivalent to "[null,null]".
- */
- private JSONArray readArray() throws JSONException {
- JSONArray result = new JSONArray();
-
- /* to cover input that ends with ",]". */
- boolean hasTrailingSeparator = false;
-
- while (true) {
- switch (nextCleanInternal()) {
- case -1:
- throw syntaxError("Unterminated array");
- case ']':
- if (hasTrailingSeparator) {
- result.put(null);
- }
- return result;
- case ',':
- case ';':
- /* A separator without a value first means "null". */
- result.put(null);
- hasTrailingSeparator = true;
- continue;
- default:
- pos--;
- }
-
- result.put(nextValue());
-
- switch (nextCleanInternal()) {
- case ']':
- return result;
- case ',':
- case ';':
- hasTrailingSeparator = true;
- continue;
- default:
- throw syntaxError("Unterminated array");
- }
+ }
+
+
+ /**
+ * 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.
+ */
+ public String nextTo(String delimiters) throws JSONException {
+ char c;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = this.next();
+ if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') {
+ if (c != 0) {
+ this.back();
}
+ return sb.toString().trim();
+ }
+ sb.append(c);
}
-
- /**
- * Returns an exception containing the given message plus the current
- * position and the entire input string.
- *
- * @param message The message we want to include.
- * @return An exception that we can throw.
- */
- public JSONException syntaxError(String message) {
- return new JSONException(message + this);
- }
-
- /**
- * Returns the current position and the entire input string.
- */
- @Override
- public String toString() {
- // consistent with the original implementation
- return " at character " + pos + " of " + in;
+ }
+
+
+ /**
+ * 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.
+ */
+ 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);
}
/*
- * Legacy APIs.
+ * Handle unquoted text. This could be the values true, false, or null, or it can be a number.
+ * An implementation (such as this one) is allowed to also accept non-standard forms.
*
- * None of the methods below are on the critical path of parsing JSON
- * documents. They exist only because they were exposed by the original
- * implementation and may be used by some clients.
+ * Accumulate characters until we reach the end of the text or a formatting character.
*/
- /**
- * Returns true until the input has been exhausted.
- *
- * @return true if more input exists.
- */
- public boolean more() {
- return pos < in.length();
+ StringBuffer sb = new StringBuffer();
+ while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
+ sb.append(c);
+ c = this.next();
}
+ this.back();
- /**
- * Returns the next available character, or the null character '\0' if all
- * input has been exhausted. The return value of this method is ambiguous
- * for JSON strings that contain the character '\0'.
- *
- * @return the next character.
- */
- public char next() {
- return pos < in.length() ? in.charAt(pos++) : '\0';
+ string = sb.toString().trim();
+ if ("".equals(string)) {
+ throw this.syntaxError("Missing value");
}
-
- /**
- * Returns the next available character if it equals {@code c}. Otherwise an
- * exception is thrown.
- *
- * @param c The character we are looking for.
- * @return the next character.
- * @throws JSONException If the next character isn't {@code c}
- */
- public char next(char c) throws JSONException {
- char result = next();
- if (result != c) {
- throw syntaxError("Expected " + c + " but was " + result);
+ return JSONObject.stringToValue(string);
+ }
+
+
+ /**
+ * 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.
+ */
+ public char skipTo(char to) throws JSONException {
+ char c;
+ try {
+ long startIndex = this.index;
+ long startCharacter = this.character;
+ long startLine = this.line;
+ this.reader.mark(1000000);
+ do {
+ c = this.next();
+ if (c == 0) {
+ this.reader.reset();
+ this.index = startIndex;
+ this.character = startCharacter;
+ this.line = startLine;
+ return c;
}
- return result;
- }
-
- /**
- * Returns the next character that is not whitespace and does not belong to
- * a comment. If the input is exhausted before such a character can be
- * found, the null character '\0' is returned. The return value of this
- * method is ambiguous for JSON strings that contain the character '\0'.
- *
- * @return The next non-whitespace character.
- * @throws JSONException Should not be possible.
- */
- public char nextClean() throws JSONException {
- int nextCleanInt = nextCleanInternal();
- return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
+ } while (c != to);
+ } catch (IOException exc) {
+ throw new JSONException(exc);
}
- /**
- * Returns the next {@code length} characters of the input.
- *
- * <p>The returned string shares its backing character array with this
- * tokener's input string. If a reference to the returned string may be held
- * indefinitely, you should use {@code new String(result)} to copy it first
- * to avoid memory leaks.
- *
- * @param length The desired number of characters to return.
- * @return The next few characters.
- * @throws JSONException if the remaining input is not long enough to
- * satisfy this request.
- */
- public String next(int length) throws JSONException {
- if (pos + length > in.length()) {
- throw syntaxError(length + " is out of bounds");
- }
- String result = in.substring(pos, pos + length);
- pos += length;
- return result;
- }
-
- /**
- * Returns the {@link String#trim trimmed} string holding the characters up
- * to but not including the first of:
- * <ul>
- * <li>any character in {@code excluded}
- * <li>a newline character '\n'
- * <li>a carriage return '\r'
- * </ul>
- *
- * <p>The returned string shares its backing character array with this
- * tokener's input string. If a reference to the returned string may be held
- * indefinitely, you should use {@code new String(result)} to copy it first
- * to avoid memory leaks.
- *
- * @param excluded The limiting string where the search should stop.
- * @return a possibly-empty string
- */
- public String nextTo(String excluded) {
- if (excluded == null) {
- throw new NullPointerException("excluded == null");
- }
- return nextToInternal(excluded).trim();
- }
-
- /**
- * Equivalent to {@code nextTo(String.valueOf(excluded))}.
- *
- * @param excluded The limiting character.
- * @return a possibly-empty string
- */
- public String nextTo(char excluded) {
- return nextToInternal(String.valueOf(excluded)).trim();
- }
-
- /**
- * Advances past all input up to and including the next occurrence of
- * {@code thru}. If the remaining input doesn't contain {@code thru}, the
- * input is exhausted.
- *
- * @param thru The string to skip over.
- */
- public void skipPast(String thru) {
- int thruStart = in.indexOf(thru, pos);
- pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
- }
-
- /**
- * Advances past all input up to but not including the next occurrence of
- * {@code to}. If the remaining input doesn't contain {@code to}, the input
- * is unchanged.
- *
- * @param to The character we want to skip to.
- * @return The value of {@code to} or null.
- */
- public char skipTo(char to) {
- int index = in.indexOf(to, pos);
- if (index != -1) {
- pos = index;
- return to;
- } else {
- return '\0';
- }
- }
-
- /**
- * Unreads the most recent character of input. If no input characters have
- * been read, the input is unchanged.
- */
- public void back() {
- if (--pos == -1) {
- pos = 0;
- }
- }
-
- /**
- * Returns the integer [0..15] value for the given hex character, or -1
- * for non-hex input.
- *
- * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
- * character will yield a -1 result.
- * @return The decoded integer.
- */
- public static int dehexchar(char hex) {
- if (hex >= '0' && hex <= '9') {
- return hex - '0';
- } else if (hex >= 'A' && hex <= 'F') {
- return hex - 'A' + 10;
- } else if (hex >= 'a' && hex <= 'f') {
- return hex - 'a' + 10;
- } else {
- return -1;
- }
- }
+ this.back();
+ return c;
+ }
+
+
+ /**
+ * Make a JSONException to signal a syntax error.
+ *
+ * @param message The error message.
+ * @return A JSONException object, suitable for throwing
+ */
+ public JSONException syntaxError(String message) {
+ return new JSONException(message + this.toString());
+ }
+
+
+ /**
+ * Make a printable string of this JSONTokener.
+ *
+ * @return " at {index} [character {character} line {line}]"
+ */
+ public String toString() {
+ return " at " + this.index + " [character " + this.character + " line " + this.line + "]";
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/JSONWriter.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONWriter.java b/geode-json/src/main/java/org/json/JSONWriter.java
new file mode 100755
index 0000000..7d4704b
--- /dev/null
+++ b/geode-json/src/main/java/org/json/JSONWriter.java
@@ -0,0 +1,321 @@
+package org.json;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/*
+ * Copyright (c) 2006 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * JSONWriter provides a quick and convenient way of producing JSON text. The texts produced
+ * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
+ * transmission or storage. Each instance of JSONWriter can produce one JSON text.
+ * <p>
+ * A JSONWriter instance provides a <code>value</code> method for appending values to the text, and
+ * a <code>key</code> method for adding keys before values in objects. There are <code>array</code>
+ * and <code>endArray</code> methods that make and bound array values, and <code>object</code> and
+ * <code>endObject</code> methods which make and bound object values. All of these methods return
+ * the JSONWriter instance, permitting a cascade style. For example,
+ *
+ * <pre>
+ * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!").endObject();
+ * </pre>
+ *
+ * which writes
+ *
+ * <pre>
+ * {"JSON":"Hello, World!"}
+ * </pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>. There are no methods
+ * for adding commas or colons. JSONWriter adds them for you. Objects and arrays can be nested up to
+ * 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ *
+ * @author JSON.org
+ * @version 2011-11-24
+ */
+public class JSONWriter {
+ private static final int maxdepth = 200;
+
+ /**
+ * The comma flag determines if a comma should be output before the next value.
+ */
+ private boolean comma;
+
+ /**
+ * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k' (key), '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 Writer writer;
+
+ /**
+ * Make a fresh JSONWriter. It can be used to build one JSON text.
+ */
+ public JSONWriter(Writer w) {
+ this.comma = false;
+ this.mode = 'i';
+ this.stack = new JSONObject[maxdepth];
+ this.top = 0;
+ 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.write(',');
+ }
+ this.writer.write(string);
+ } catch (IOException e) {
+ 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 <code>endArray</code> will be
+ * appended to this array. The <code>endArray</code> 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 mode Mode
+ * @param c Closing character
+ * @return this
+ * @throws JSONException If unbalanced.
+ */
+ private JSONWriter end(char mode, char c) throws JSONException {
+ if (this.mode != mode) {
+ throw new JSONException(mode == 'a' ? "Misplaced endArray." : "Misplaced endObject.");
+ }
+ this.pop(mode);
+ try {
+ this.writer.write(c);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ this.comma = true;
+ return this;
+ }
+
+ /**
+ * End an array. This method most be called to balance calls to <code>array</code>.
+ *
+ * @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 <code>object</code>.
+ *
+ * @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 {
+ this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
+ if (this.comma) {
+ this.writer.write(',');
+ }
+ this.writer.write(JSONObject.quote(string));
+ this.writer.write(':');
+ this.comma = false;
+ this.mode = 'o';
+ return this;
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ }
+ throw new JSONException("Misplaced key.");
+ }
+
+
+ /**
+ * Begin appending a new object. All keys and values until the balancing <code>endObject</code>
+ * will be appended to this object. The <code>endObject</code> 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 <code>true</code> or the value <code>false</code>.
+ *
+ * @param b A boolean.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(boolean b) throws JSONException {
+ return this.append(b ? "true" : "false");
+ }
+
+ /**
+ * Append a double value.
+ *
+ * @param d A double.
+ * @return this
+ * @throws JSONException If the number is not finite.
+ */
+ public JSONWriter value(double d) throws JSONException {
+ return this.value(new Double(d));
+ }
+
+ /**
+ * Append a long value.
+ *
+ * @param l A long.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(long l) throws JSONException {
+ return this.append(Long.toString(l));
+ }
+
+
+ /**
+ * 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.
+ * @return this
+ * @throws JSONException If the value is out of sequence.
+ */
+ public JSONWriter value(Object object) throws JSONException {
+ return this.append(JSONObject.valueToString(object));
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0805036e/geode-json/src/main/java/org/json/XML.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/XML.java b/geode-json/src/main/java/org/json/XML.java
new file mode 100755
index 0000000..ae6d61a
--- /dev/null
+++ b/geode-json/src/main/java/org/json/XML.java
@@ -0,0 +1,504 @@
+package org.json;
+
+/*
+ * Copyright (c) 2002 JSON.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import java.util.Iterator;
+
+
+/**
+ * This provides static methods to convert an XML text into a JSONObject, and to covert a JSONObject
+ * into an XML text.
+ *
+ * @author JSON.org
+ * @version 2011-02-11
+ */
+public class XML {
+
+ /** The Character '&'. */
+ public static final Character AMP = new Character('&');
+
+ /** The Character '''. */
+ public static final Character APOS = new Character('\'');
+
+ /** The Character '!'. */
+ public static final Character BANG = new Character('!');
+
+ /** The Character '='. */
+ public static final Character EQ = new Character('=');
+
+ /** The Character '>'. */
+ public static final Character GT = new Character('>');
+
+ /** The Character '<'. */
+ public static final Character LT = new Character('<');
+
+ /** The Character '?'. */
+ public static final Character QUEST = new Character('?');
+
+ /** The Character '"'. */
+ public static final Character QUOT = new Character('"');
+
+ /** The Character '/'. */
+ public static final Character SLASH = new Character('/');
+
+ /**
+ * Replace special characters with XML escapes:
+ *
+ * <pre>
+ * & <small>(ampersand)</small> is replaced by &amp;
+ * < <small>(less than)</small> is replaced by &lt;
+ * > <small>(greater than)</small> is replaced by &gt;
+ * " <small>(double quote)</small> is replaced by &quot;
+ * </pre>
+ *
+ * @param string The string to be escaped.
+ * @return The escaped string.
+ */
+ public static String escape(String string) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, length = string.length(); i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '&':
+ sb.append("&");
+ break;
+ case '<':
+ sb.append("<");
+ break;
+ case '>':
+ sb.append(">");
+ break;
+ case '"':
+ sb.append(""");
+ break;
+ case '\'':
+ sb.append("'");
+ break;
+ default:
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Throw an exception if the string contains whitespace. Whitespace is not allowed in tagNames and
+ * attributes.
+ *
+ * @param string
+ * @throws JSONException
+ */
+ public static void noSpace(String string) throws JSONException {
+ int i, length = string.length();
+ if (length == 0) {
+ throw new JSONException("Empty string.");
+ }
+ for (i = 0; i < length; i += 1) {
+ if (Character.isWhitespace(string.charAt(i))) {
+ throw new JSONException("'" + string + "' contains a space character.");
+ }
+ }
+ }
+
+ /**
+ * Scan the content following the named tag, attaching it to the context.
+ *
+ * @param x The XMLTokener containing the source string.
+ * @param context The JSONObject that will include the new material.
+ * @param name The tag name.
+ * @return true if the close tag is processed.
+ * @throws JSONException
+ */
+ private static boolean parse(XMLTokener x, JSONObject context, String name) throws JSONException {
+ char c;
+ int i;
+ JSONObject jsonobject = null;
+ String string;
+ String tagName;
+ Object token;
+
+ // Test for and skip past these forms:
+ // <!-- ... -->
+ // <! ... >
+ // <![ ... ]]>
+ // <? ... ?>
+ // Report errors for these forms:
+ // <>
+ // <=
+ // <<
+
+ token = x.nextToken();
+
+ // <!
+
+ if (token == BANG) {
+ c = x.next();
+ if (c == '-') {
+ if (x.next() == '-') {
+ x.skipPast("-->");
+ return false;
+ }
+ x.back();
+ } else if (c == '[') {
+ token = x.nextToken();
+ if ("CDATA".equals(token)) {
+ if (x.next() == '[') {
+ string = x.nextCDATA();
+ if (string.length() > 0) {
+ context.accumulate("content", string);
+ }
+ return false;
+ }
+ }
+ throw x.syntaxError("Expected 'CDATA['");
+ }
+ i = 1;
+ do {
+ token = x.nextMeta();
+ if (token == null) {
+ throw x.syntaxError("Missing '>' after '<!'.");
+ } else if (token == LT) {
+ i += 1;
+ } else if (token == GT) {
+ i -= 1;
+ }
+ } while (i > 0);
+ return false;
+ } else if (token == QUEST) {
+
+ // <?
+
+ x.skipPast("?>");
+ return false;
+ } else if (token == SLASH) {
+
+ // Close tag </
+
+ token = x.nextToken();
+ if (name == null) {
+ throw x.syntaxError("Mismatched close tag " + token);
+ }
+ if (!token.equals(name)) {
+ throw x.syntaxError("Mismatched " + name + " and " + token);
+ }
+ if (x.nextToken() != GT) {
+ throw x.syntaxError("Misshaped close tag");
+ }
+ return true;
+
+ } else if (token instanceof Character) {
+ throw x.syntaxError("Misshaped tag");
+
+ // Open tag <
+
+ } else {
+ tagName = (String) token;
+ token = null;
+ jsonobject = new JSONObject();
+ for (;;) {
+ if (token == null) {
+ token = x.nextToken();
+ }
+
+ // attribute = value
+
+ if (token instanceof String) {
+ string = (String) token;
+ token = x.nextToken();
+ if (token == EQ) {
+ token = x.nextToken();
+ if (!(token instanceof String)) {
+ throw x.syntaxError("Missing value");
+ }
+ jsonobject.accumulate(string, XML.stringToValue((String) token));
+ token = null;
+ } else {
+ jsonobject.accumulate(string, "");
+ }
+
+ // Empty tag <.../>
+
+ } else if (token == SLASH) {
+ if (x.nextToken() != GT) {
+ throw x.syntaxError("Misshaped tag");
+ }
+ if (jsonobject.length() > 0) {
+ context.accumulate(tagName, jsonobject);
+ } else {
+ context.accumulate(tagName, "");
+ }
+ return false;
+
+ // Content, between <...> and </...>
+
+ } else if (token == GT) {
+ for (;;) {
+ token = x.nextContent();
+ if (token == null) {
+ if (tagName != null) {
+ throw x.syntaxError("Unclosed tag " + tagName);
+ }
+ return false;
+ } else if (token instanceof String) {
+ string = (String) token;
+ if (string.length() > 0) {
+ jsonobject.accumulate("content", XML.stringToValue(string));
+ }
+
+ // Nested element
+
+ } else if (token == LT) {
+ if (parse(x, jsonobject, tagName)) {
+ if (jsonobject.length() == 0) {
+ context.accumulate(tagName, "");
+ } else if (jsonobject.length() == 1 && jsonobject.opt("content") != null) {
+ context.accumulate(tagName, jsonobject.opt("content"));
+ } else {
+ context.accumulate(tagName, jsonobject);
+ }
+ return false;
+ }
+ }
+ }
+ } else {
+ throw x.syntaxError("Misshaped tag");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Try to convert a string into a number, boolean, or null. If the string can't be converted,
+ * return the string. This is much less ambitious than JSONObject.stringToValue, especially
+ * because it does not attempt to convert plus forms, octal forms, hex forms, or E forms lacking
+ * decimal points.
+ *
+ * @param string A String.
+ * @return A simple JSON value.
+ */
+ public static Object stringToValue(String string) {
+ if ("".equals(string)) {
+ return string;
+ }
+ if ("true".equalsIgnoreCase(string)) {
+ return Boolean.TRUE;
+ }
+ if ("false".equalsIgnoreCase(string)) {
+ return Boolean.FALSE;
+ }
+ if ("null".equalsIgnoreCase(string)) {
+ return JSONObject.NULL;
+ }
+ if ("0".equals(string)) {
+ return new Integer(0);
+ }
+
+ // If it might be a number, try converting it. If that doesn't work,
+ // return the string.
+
+ try {
+ char initial = string.charAt(0);
+ boolean negative = false;
+ if (initial == '-') {
+ initial = string.charAt(1);
+ negative = true;
+ }
+ if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
+ return string;
+ }
+ if ((initial >= '0' && initial <= '9')) {
+ if (string.indexOf('.') >= 0) {
+ return Double.valueOf(string);
+ } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
+ Long myLong = new Long(string);
+ if (myLong.longValue() == myLong.intValue()) {
+ return new Integer(myLong.intValue());
+ } else {
+ return myLong;
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ return string;
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a JSONObject. Some
+ * information may be lost in this transformation because JSON is a data format and XML is a
+ * document format. XML uses elements, attributes, and content text, while JSON uses unordered
+ * collections of name/value pairs and arrays of values. JSON does not does not like to
+ * distinguish between elements and attributes. Sequences of similar elements are represented as
+ * JSONArrays. Content text may be placed in a "content" member. Comments, prologs, DTDs, and
+ * <code><[ [ ]]></code> are ignored.
+ *
+ * @param string The source string.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ JSONObject jo = new JSONObject();
+ XMLTokener x = new XMLTokener(string);
+ while (x.more() && x.skipPast("<")) {
+ parse(x, jo, null);
+ }
+ return jo;
+ }
+
+
+ /**
+ * Convert a JSONObject into a well-formed, element-normal XML string.
+ *
+ * @param object A JSONObject.
+ * @return A string.
+ * @throws JSONException
+ */
+ public static String toString(Object object) throws JSONException {
+ return toString(object, null);
+ }
+
+
+ /**
+ * Convert a JSONObject into a well-formed, element-normal XML string.
+ *
+ * @param object A JSONObject.
+ * @param tagName The optional name of the enclosing tag.
+ * @return A string.
+ * @throws JSONException
+ */
+ public static String toString(Object object, String tagName) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ int i;
+ JSONArray ja;
+ JSONObject jo;
+ String key;
+ Iterator keys;
+ int length;
+ String string;
+ Object value;
+ if (object instanceof JSONObject) {
+
+ // Emit <tagName>
+
+ if (tagName != null) {
+ sb.append('<');
+ sb.append(tagName);
+ sb.append('>');
+ }
+
+ // Loop thru the keys.
+
+ jo = (JSONObject) object;
+ keys = jo.keys();
+ while (keys.hasNext()) {
+ key = keys.next().toString();
+ value = jo.opt(key);
+ if (value == null) {
+ value = "";
+ }
+ if (value instanceof String) {
+ string = (String) value;
+ } else {
+ string = null;
+ }
+
+ // Emit content in body
+
+ if ("content".equals(key)) {
+ if (value instanceof JSONArray) {
+ ja = (JSONArray) value;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ if (i > 0) {
+ sb.append('\n');
+ }
+ sb.append(escape(ja.get(i).toString()));
+ }
+ } else {
+ sb.append(escape(value.toString()));
+ }
+
+ // Emit an array of similar keys
+
+ } else if (value instanceof JSONArray) {
+ ja = (JSONArray) value;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ value = ja.get(i);
+ if (value instanceof JSONArray) {
+ sb.append('<');
+ sb.append(key);
+ sb.append('>');
+ sb.append(toString(value));
+ sb.append("</");
+ sb.append(key);
+ sb.append('>');
+ } else {
+ sb.append(toString(value, key));
+ }
+ }
+ } else if ("".equals(value)) {
+ sb.append('<');
+ sb.append(key);
+ sb.append("/>");
+
+ // Emit a new tag <k>
+
+ } else {
+ sb.append(toString(value, key));
+ }
+ }
+ if (tagName != null) {
+
+ // Emit the </tagname> close tag
+
+ sb.append("</");
+ sb.append(tagName);
+ sb.append('>');
+ }
+ return sb.toString();
+
+ // XML does not have good support for arrays. If an array appears in a place
+ // where XML is lacking, synthesize an <array> element.
+
+ } else {
+ if (object.getClass().isArray()) {
+ object = new JSONArray(object);
+ }
+ if (object instanceof JSONArray) {
+ ja = (JSONArray) object;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
+ }
+ return sb.toString();
+ } else {
+ string = (object == null) ? "null" : escape(object.toString());
+ return (tagName == null) ? "\"" + string + "\""
+ : (string.length() == 0) ? "<" + tagName + "/>"
+ : "<" + tagName + ">" + string + "</" + tagName + ">";
+ }
+ }
+ }
+}