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:01:00 UTC
[1/8] geode git commit: GEODE-2142: Removal of non-compliant org.json
implementation.
Repository: geode
Updated Branches:
refs/heads/develop fe46a433e -> 2e3a88f7b
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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
deleted file mode 100755
index f56a1f6..0000000
--- a/geode-json/src/main/java/org/json/XMLTokener.java
+++ /dev/null
@@ -1,362 +0,0 @@
-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;
- }
- }
- }
-}
[5/8] geode git commit: GEODE-2142: Removal of non-compliant org.json
implementation.
Posted by ud...@apache.org.
GEODE-2142: Removal of non-compliant org.json implementation.
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/b3ec80bc
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/b3ec80bc
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/b3ec80bc
Branch: refs/heads/develop
Commit: b3ec80bc72fee3a40da297945a85d8df6c2a6460
Parents: fe46a43
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 12:47:03 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 12:56:13 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, 2758 insertions(+), 5196 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 8525b58..a505001 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,11 +440,6 @@ 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);
@@ -500,43 +495,6 @@ 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/b3ec80bc/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 12a0a64..283f09d 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,7 +234,8 @@ public class ConfigCommands extends AbstractCommandsSupport {
false);
}
}
- return ResultBuilder.buildResult(infoData);
+ Result result = ResultBuilder.buildResult(infoData);
+ return result;
} catch (VirtualMachineError e) {
SystemFailure.initiateFailure(e);
throw e;
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 e94af4f..7485d9f 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,6 +75,7 @@ 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);
@@ -99,7 +100,6 @@ 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/b3ec80bc/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 49e27b0..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
@@ -93,12 +93,10 @@ 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/b3ec80bc/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 69666ff..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
@@ -49,22 +49,6 @@ 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);
@@ -88,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);
+// }
/**
*
@@ -253,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;
+// }
/**
*
@@ -362,7 +346,7 @@ public class GfJsonObject {
}
}
- private static Object extractInternalForGfJsonOrReturnSame(Object value) {
+ private 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/b3ec80bc/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 e08d9b7..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
@@ -20,7 +20,10 @@ 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;
@@ -151,26 +154,10 @@ public abstract class AbstractResultData implements ResultData {
if (addTimeStampToName) {
fileName = addTimeStampBeforeLastDot(fileName);
}
- return addAsFile(fileName.getBytes(), bytes, fileType, message);
+ return addAsFile(fileName, bytes, fileType, 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);
+ private ResultData addAsFile(String fileName, byte[] data, int fileType, String message) {
if (fileType != FILE_TYPE_BINARY && fileType != FILE_TYPE_TEXT) {
throw new IllegalArgumentException("Unsupported file type is specified.");
}
@@ -186,14 +173,12 @@ public abstract class AbstractResultData implements ResultData {
sectionData.put(FILE_NAME_FIELD, fileName);
sectionData.put(FILE_TYPE_FIELD, fileType);
- 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));
+ 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());
} catch (GfJsonException e) {
throw new ResultDataException(e.getMessage());
- // } catch (IOException e) {
- // e.printStackTrace();
}
return this;
}
@@ -223,29 +208,30 @@ 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
- fileNameBytes = (byte[]) object.get(FILE_NAME_FIELD);
+ fileName = (String) 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
- fileMessageBytes = (byte[]) object.get(FILE_MESSAGE);
+ fileMessage = (String) object.get(FILE_MESSAGE);
}
- String fileMessage = new String(fileMessageBytes);
- 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();
+ 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();
boolean isGfshVM = CliUtil.isGfshVM();
File fileToDumpData = new File(fileName);
@@ -299,13 +285,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(uncompressed));
+ bw.write(new String(uncompressBytes));
bw.flush();
fw.flush();
fw.close();
} else if (fileType == FILE_TYPE_BINARY) {
FileOutputStream fos = new FileOutputStream(fileToDumpData);
- fos.write(uncompressed);
+ fos.write(uncompressBytes);
fos.flush();
fos.close();
}
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 7d0d23b..c1db133 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,50 +324,4 @@ 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/b3ec80bc/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 06060a4..9bd2bf9 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,12 +301,6 @@ 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");
}
@@ -326,12 +320,6 @@ 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");
}
@@ -351,12 +339,6 @@ 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");
}
@@ -381,12 +363,6 @@ 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");
}
@@ -416,12 +392,6 @@ 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/b3ec80bc/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 21426d6..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
@@ -360,7 +360,11 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase {
CommandResult result = null;
try {
- result = (CommandResult) shell.getResult(); // TODO: this can result in ClassCastException if
+ Object result1 = shell.getResult();
+ if (result1 instanceof String) {
+ System.err.println("result1 = " + result1);
+ }
+ result = (CommandResult) result1; // 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/b3ec80bc/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
deleted file mode 100755
index d78935b..0000000
--- a/geode-json/src/main/java/org/json/CDL.java
+++ /dev/null
@@ -1,272 +0,0 @@
-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/b3ec80bc/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
deleted file mode 100755
index 21f88d8..0000000
--- a/geode-json/src/main/java/org/json/Cookie.java
+++ /dev/null
@@ -1,162 +0,0 @@
-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/b3ec80bc/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
deleted file mode 100755
index 35e1a97..0000000
--- a/geode-json/src/main/java/org/json/CookieList.java
+++ /dev/null
@@ -1,87 +0,0 @@
-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/b3ec80bc/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
deleted file mode 100755
index 1e815aa..0000000
--- a/geode-json/src/main/java/org/json/HTTP.java
+++ /dev/null
@@ -1,185 +0,0 @@
-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/b3ec80bc/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
deleted file mode 100755
index 72c9b88..0000000
--- a/geode-json/src/main/java/org/json/HTTPTokener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-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/b3ec80bc/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
new file mode 100755
index 0000000..1b32e69
--- /dev/null
+++ b/geode-json/src/main/java/org/json/JSON.java
@@ -0,0 +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
+ *
+ * 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);
+ }
+ }
+}
[7/8] geode git commit: GEODE-2142: Spotless
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/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..bddfb56 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,17 +1,15 @@
/*
* 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;
@@ -33,55 +31,53 @@ 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 {
@@ -92,8 +88,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
@@ -102,9 +98,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")
@@ -135,21 +131,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");
@@ -159,16 +155,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;
@@ -178,8 +174,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}.
*/
@@ -188,9 +184,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.
@@ -207,6 +203,7 @@ 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
*/
@@ -214,7 +211,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();
@@ -273,6 +270,7 @@ public class JSONObject {
/**
* Returns the number of name/value mappings in this object.
+ *
* @return the length of this.
*/
public int length() {
@@ -280,8 +278,9 @@ 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.
@@ -293,11 +292,12 @@ 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,8 +307,9 @@ 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.
@@ -320,8 +321,9 @@ 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.
@@ -333,13 +335,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).
*/
@@ -371,8 +373,9 @@ 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.
@@ -386,22 +389,21 @@ 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.
*/
@@ -426,15 +428,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));
@@ -464,6 +466,7 @@ 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.
*/
@@ -472,8 +475,9 @@ 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.
*/
@@ -483,8 +487,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}
*/
@@ -494,6 +498,7 @@ 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.
@@ -507,8 +512,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.
*/
@@ -517,8 +522,9 @@ 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.
@@ -533,8 +539,9 @@ 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.
*/
@@ -543,8 +550,9 @@ 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.
@@ -556,8 +564,9 @@ 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.
@@ -572,8 +581,9 @@ 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.
*/
@@ -582,8 +592,9 @@ 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.
@@ -595,8 +606,9 @@ 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.
@@ -611,8 +623,9 @@ 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.
*/
@@ -621,8 +634,9 @@ 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.
@@ -634,12 +648,11 @@ 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.
@@ -654,9 +667,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 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.
*/
@@ -665,10 +679,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.
@@ -680,8 +694,9 @@ 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.
@@ -696,8 +711,9 @@ 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.
*/
@@ -706,8 +722,9 @@ 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.
@@ -721,6 +738,7 @@ 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}.
@@ -737,6 +755,7 @@ 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
*/
@@ -748,6 +767,7 @@ 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}.
@@ -764,6 +784,7 @@ 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.
*/
@@ -773,9 +794,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.
@@ -797,11 +818,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() {
@@ -809,12 +830,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() {
@@ -822,19 +843,22 @@ 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() {
@@ -848,8 +872,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",
@@ -857,7 +881,9 @@ 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.
@@ -878,8 +904,9 @@ 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.
*/
@@ -905,8 +932,9 @@ 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.
*/
@@ -928,7 +956,8 @@ 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
@@ -936,6 +965,7 @@ 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}
*/
@@ -958,34 +988,28 @@ 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)) {
@@ -1002,4 +1026,4 @@ public class JSONObject {
}
return null;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/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
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/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..43224a5 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,17 +1,15 @@
/*
* 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;
@@ -23,448 +21,439 @@ 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();
+ /**
+ * 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,
- }
+ /**
+ * Lexical scoping elements within this stringer, necessary to insert the appropriate separator
+ * characters (ie. commas and colons) and to detect nesting errors.
+ */
+ enum Scope {
/**
- * Unlike the original implementation, this stack isn't limited to 20
- * levels of nesting.
+ * An array with no elements requires no separators or newlines before it is closed.
*/
- private final List<Scope> stack = new ArrayList<Scope>();
+ EMPTY_ARRAY,
/**
- * A string containing a full set of spaces for a single level of
- * indentation, or null for no pretty printing.
+ * A array with at least one value requires a comma and newline before the next element.
*/
- private final String indent;
-
- public JSONStringer() {
- indent = null;
- }
-
- JSONStringer(int indentSpaces) {
- char[] indentChars = new char[indentSpaces];
- Arrays.fill(indentChars, ' ');
- indent = new String(indentChars);
- }
+ NONEMPTY_ARRAY,
/**
- * 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.
+ * An object with no keys or values requires no separators or newlines before it is closed.
*/
- public JSONStringer array() throws JSONException {
- return open(Scope.EMPTY_ARRAY, "[");
- }
+ EMPTY_OBJECT,
/**
- * Ends encoding the current array.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * An object whose most recent element is a key. The next element must be a value.
*/
- public JSONStringer endArray() throws JSONException {
- return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
- }
+ DANGLING_KEY,
/**
- * 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.
+ * An object with at least one name/value pair requires a comma and newline before the next
+ * element.
*/
- public JSONStringer object() throws JSONException {
- return open(Scope.EMPTY_OBJECT, "{");
- }
+ NONEMPTY_OBJECT,
/**
- * Ends encoding the current object.
- *
- * @return this stringer.
- * @throws JSONException On internal errors. Shouldn't happen.
+ * A special bracketless array needed by JSONStringer.join() and JSONObject.quote() only. Not
+ * used for JSON encoding.
*/
- public JSONStringer endObject() throws JSONException {
- return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+ 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");
}
-
- /**
- * 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();
+ 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");
}
- /**
- * 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;
+ stack.remove(stack.size() - 1);
+ if (context == nonempty) {
+ newline();
}
-
- /**
- * 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);
+ 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");
}
-
- /**
- * Replace the value on the top of the stack with the given value.
- */
- private void replaceTop(Scope topOfStack) {
- stack.set(stack.size() - 1, topOfStack);
+ 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");
}
- /**
- * 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;
- }
+ if (value instanceof JSONArray) {
+ ((JSONArray) value).writeTo(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;
+ } else if (value instanceof JSONObject) {
+ ((JSONObject) value).writeTo(this);
+ 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;
+ beforeValue();
+
+ if (value instanceof JSONString) {
+ out.append(((JSONString) value).toJSONString());
+ 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();
+ 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);
- return this;
+ } else {
+ string(value.toString());
+ }
}
- 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("\"");
+ 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");
}
-
- private void newline() {
- if (indent == null) {
- return;
- }
-
- out.append("\n");
- for (int i = 0; i < stack.size(); i++) {
- out.append(indent);
- }
+ 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;
+ }
- /**
- * 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;
}
+ out.append("\"");
+ }
- /**
- * 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);
+ private void newline() {
+ if (indent == null) {
+ 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");
- }
+ 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;
}
- /**
- * 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();
+ 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();
+ }
}
[3/8] geode git commit: GEODE-2142: Removal of non-compliant org.json
implementation.
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 a2c6d8b..d5de19f 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,1525 +1,1005 @@
-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.
+ * 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.
*/
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Field;
+package org.json;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
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 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,
+ * 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.
*
- * <pre>
- * myString = new JSONObject().put("JSON", "Hello, World!").toString();
- * </pre>
+ * <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>
*
- * 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:
+ * <p>This class can look up both mandatory and optional values:
* <ul>
- * <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>
+ * <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>
*
- * @author JSON.org
- * @version 2012-05-29
+ * <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.
*/
public class JSONObject {
+
+ private static final Double NEGATIVE_ZERO = -0d;
+
+ public static ThreadLocal<Set> cyclicDependencySet = new ThreadLocal();
+ public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
+
/**
- * JSONObject.NULL is equivalent to the value that JavaScript calls null, whilst Java's null is
- * equivalent to the value that JavaScript calls undefined.
+ * 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".
*/
- 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;
+ 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
}
- /**
- * 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;
+ // at least make the broken equals(null) consistent with Objects.hashCode(null).
+ @Override
+ public int hashCode() {
+ return 0;
}
- /**
- * Get the "null" string value.
- *
- * @return The string "null".
- */
+ @Override
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;
/**
- * Construct an empty JSONObject.
+ * Creates a {@code JSONObject} with no name/value mappings.
*/
public JSONObject() {
- this.map = new LinkedHashMap();
+ nameValuePairs = new LinkedHashMap<String, Object>();
}
-
/**
- * 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.
+ * 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.
*/
- public JSONObject(JSONObject jo, String[] names) {
+ /* (accept a raw type for API compatibility) */
+ public JSONObject(Map copyFrom) {
this();
- for (int i = 0; i < names.length; i += 1) {
- try {
- this.putOnce(names[i], jo.opt(names[i]));
- } catch (Exception ignore) {
- }
- }
- }
-
-
- /**
- * 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 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();
- }
-
- // 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 '}'");
+ 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");
}
+ nameValuePairs.put(key, wrap(entry.getValue()));
}
}
-
/**
- * Construct a JSONObject from a Map.
- *
- * @param map A map object that can be used to initialize the contents of the JSONObject.
+ * 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(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));
- }
- }
+ 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");
}
}
-
/**
- * 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.
+ * 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(Object bean) {
- this();
- this.populateMap(bean);
+ public JSONObject(String json) throws JSONException {
+ this(new JSONTokener(json));
}
-
/**
- * 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.
+ * 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.
*/
- public JSONObject(Object object, String names[]) {
+ public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
this();
- Class c = object.getClass();
- for (int i = 0; i < names.length; i += 1) {
- String name = names[i];
- try {
- this.putOpt(name, c.getField(name).get(object));
- } catch (Exception ignore) {
+ for (String name : names) {
+ Object value = copyFrom.opt(name);
+ if (value != null) {
+ nameValuePairs.put(name, value);
}
}
}
-
/**
- * 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.
+ * 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
*/
- public JSONObject(String source) throws JSONException {
- this(new JSONTokener(source));
+ public JSONObject(Object bean) throws JSONException {
+ this(propertiesAsMap(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();
- /**
- * 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(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);
+ // 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) {
+ props.put(key, wrap(result));
+ } else if (!method.getReturnType().isArray()) {
+ props.put(key, JSONObject.NULL);
+ }
}
- target = nextTarget;
}
- target.put(path[last], bundle.getString((String) key));
+ } catch (Exception ignore) {
}
}
+ props.put("type-class", klass.getCanonicalName());
+ return props;
}
-
- /**
- * 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 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));
+ 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 this;
+ return r;
}
-
/**
- * 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.
+ * Returns the number of name/value mappings in this object.
+ * @return the length of this.
*/
- 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;
+ public int length() {
+ return nameValuePairs.size();
}
-
/**
- * 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.
+ * 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.
*/
- 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;
+ public JSONObject put(String name, boolean value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
}
-
/**
- * Get the value object associated with a key.
- *
- * @param key A key string.
- * @return The object associated with the key.
- * @throws JSONException if the key is not found.
+ * 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.
*/
- public Object get(String key) throws JSONException {
- if (key == null) {
- throw new JSONException("Null key.");
- }
- Object object = this.opt(key);
- if (object == null) {
- throw new JSONException("JSONObject[" + quote(key) + "] not found.");
- }
- return object;
+ public JSONObject put(String name, double value) throws JSONException {
+ nameValuePairs.put(checkName(name), JSON.checkDouble(value));
+ return this;
}
-
/**
- * Get the boolean value associated with a key.
- *
- * @param key A key string.
- * @return The truth.
- * @throws JSONException if the value is not a Boolean or the String "true" or "false".
+ * 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.
*/
- 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.");
+ public JSONObject put(String name, int value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
}
-
/**
- * 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.
+ * 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.
*/
- 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.");
- }
+ public JSONObject put(String name, long value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
}
-
/**
- * Get the int value associated with a key.
- *
- * @param key A key string.
- * @return The integer value.
- * @throws JSONException if the key is not found or if the value cannot be converted to an
- * integer.
+ * 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).
*/
- 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.");
+ public JSONObject put(String name, Object value) throws JSONException {
+ if (value == null) {
+ nameValuePairs.remove(name);
+ return this;
}
- }
-
-
- /**
- * 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;
+ if (value instanceof Number) {
+ // deviate from the original by checking all Numbers, not just floats & doubles
+ JSON.checkDouble(((Number) value).doubleValue());
}
- throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray.");
+ nameValuePairs.put(checkName(name), value);
+ return this;
}
-
/**
- * Get the JSONObject value associated with a key.
+ * 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.
- * @return A JSONObject which is the value.
- * @throws JSONException if the key is not found or if the value is not a JSONObject.
+ * @param value A Collection value.
+ * @return this.
+ * @throws JSONException
*/
- 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.");
+ public JSONObject put(String key, Collection value) throws JSONException {
+ this.put(key, new JSONArray(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.
+ * 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).
*/
- 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.");
+ public JSONObject putOpt(String name, Object value) throws JSONException {
+ if (name == null || value == null) {
+ return this;
}
+ return put(name, value);
}
-
/**
- * Get an array of field names from a 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.
*
- * @return An array of field names, or null if there are no names.
+ * 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.
*/
- public static String[] getNames(JSONObject jo) {
- int length = jo.length();
- if (length == 0) {
- return null;
- }
- Iterator iterator = jo.keys();
- String[] names = new String[length];
- int i = 0;
- while (iterator.hasNext()) {
- names[i] = (String) iterator.next();
- i += 1;
+ // 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);
}
- return names;
- }
-
- /**
- * Get an array of field names from an Object.
- *
- * @return An array of field names, or null if there are no names.
- */
- 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();
+ 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);
}
- return names;
+ return this;
}
-
/**
- * 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.
+ * 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}.
*/
- public String getString(String key) throws JSONException {
- Object object = this.get(key);
- if (object instanceof String) {
- return (String) object;
+ 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");
}
- throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
- }
+ array.checkedPut(value);
- /**
- * Determine if the JSONObject contains a specific key.
- *
- * @param key A key string.
- * @return true if the key exists in the JSONObject.
- */
- public boolean has(String key) {
- return this.map.containsKey(key);
+ return this;
}
-
- /**
- * 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 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) + "].");
+ String checkName(String name) throws JSONException {
+ if (name == null) {
+ throw new JSONException("Names must be non-null");
}
- return this;
+ return name;
}
-
/**
- * 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.
+ * 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.
*/
- public boolean isNull(String key) {
- return JSONObject.NULL.equals(this.opt(key));
+ public Object remove(String name) {
+ return nameValuePairs.remove(name);
}
-
/**
- * Get an enumeration of the keys of the JSONObject.
- *
- * @return An iterator of the keys.
+ * 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.
*/
- public Iterator keys() {
- return this.map.keySet().iterator();
+ public boolean isNull(String name) {
+ Object value = nameValuePairs.get(name);
+ return value == null || value == NULL;
}
-
/**
- * Get the number of keys stored in the JSONObject.
- *
- * @return The number of keys in the JSONObject.
+ * 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}
*/
- public int length() {
- return this.map.size();
+ public boolean has(String name) {
+ return nameValuePairs.containsKey(name);
}
-
/**
- * 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.
+ * 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.
*/
- public JSONArray names() {
- JSONArray ja = new JSONArray();
- Iterator keys = this.keys();
- while (keys.hasNext()) {
- ja.put(keys.next());
+ public Object get(String name) throws JSONException {
+ Object result = nameValuePairs.get(name);
+ if (result == null) {
+ throw new JSONException("No value for " + name);
}
- return ja.length() == 0 ? null : ja;
+ return result;
}
/**
- * Produce a string from a Number.
- *
- * @param number A Number
- * @return A String.
- * @throws JSONException If n is a non-finite number.
+ * 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.
*/
- public static String numberToString(Number number) throws JSONException {
- if (number == null) {
- throw new JSONException("Null pointer");
- }
- 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;
+ public Object opt(String name) {
+ return nameValuePairs.get(name);
}
-
/**
- * 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.
+ * 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.
*/
- public Object opt(String key) {
- return key == null ? null : this.map.get(key);
+ 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;
}
-
/**
- * 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.
+ * 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.
*/
- public boolean optBoolean(String key) {
- return this.optBoolean(key, false);
+ public boolean optBoolean(String name) {
+ return optBoolean(name, false);
}
-
/**
- * Get an optional boolean associated with a key. It returns the defaultValue if there is no such
- * key, or if it is not a Boolean or the String "true" or "false" (case insensitive).
- *
- * @param key A key string.
- * @param defaultValue The default.
- * @return The truth.
+ * 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.
*/
- public boolean optBoolean(String key, boolean defaultValue) {
- try {
- return this.getBoolean(key);
- } catch (Exception e) {
- return defaultValue;
- }
+ public boolean optBoolean(String name, boolean fallback) {
+ Object object = opt(name);
+ Boolean result = JSON.toBoolean(object);
+ return result != null ? result : 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.
+ * 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.
*/
- public double optDouble(String key) {
- return this.optDouble(key, Double.NaN);
+ 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");
+ }
+ return result;
}
-
/**
- * Get an optional double associated with a key, or the defaultValue if there is no such key or if
- * its value is not a number. If the value is a string, an attempt will be made to evaluate it as
- * a number.
- *
- * @param key A key string.
- * @param defaultValue The default.
- * @return An object which is the value.
+ * 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.
*/
- public double optDouble(String key, double defaultValue) {
- try {
- return this.getDouble(key);
- } catch (Exception e) {
- return defaultValue;
- }
+ public double optDouble(String name) {
+ return optDouble(name, Double.NaN);
}
-
/**
- * 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.
+ * 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.
*/
- public int optInt(String key) {
- return this.optInt(key, 0);
+ public double optDouble(String name, double fallback) {
+ Object object = opt(name);
+ Double result = JSON.toDouble(object);
+ return result != null ? result : 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.
+ * 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.
*/
- public int optInt(String key, int defaultValue) {
- try {
- return this.getInt(key);
- } catch (Exception e) {
- return defaultValue;
+ 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");
}
+ return result;
}
-
/**
- * 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.
+ * 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 JSONArray optJSONArray(String key) {
- Object o = this.opt(key);
- return o instanceof JSONArray ? (JSONArray) o : null;
+ public int optInt(String name) {
+ return optInt(name, 0);
}
-
/**
- * 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.
+ * 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.
*/
- public JSONObject optJSONObject(String key) {
- Object object = this.opt(key);
- return object instanceof JSONObject ? (JSONObject) object : null;
+ public int optInt(String name, int fallback) {
+ Object object = opt(name);
+ Integer result = JSON.toInteger(object);
+ return result != null ? result : 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.
+ * 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,
*
- * @param key A key string.
- * @return An object which is the value.
+ * 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.
*/
- public long optLong(String key) {
- return this.optLong(key, 0);
+ 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");
+ }
+ return result;
}
-
/**
- * 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.
+ * 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.
*/
- public long optLong(String key, long defaultValue) {
- try {
- return this.getLong(key);
- } catch (Exception e) {
- return defaultValue;
- }
+ public long optLong(String name) {
+ return optLong(name, 0L);
}
-
/**
- * 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.
+ * 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.
*/
- public String optString(String key) {
- return this.optString(key, "");
+ public long optLong(String name, long fallback) {
+ Object object = opt(name);
+ Long result = JSON.toLong(object);
+ return result != null ? result : fallback;
}
-
/**
- * 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.
+ * 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.
*/
- 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) {
- }
+ 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");
}
- this.map.put("type-class", klass.getCanonicalName());
+ return result;
}
-
/**
- * 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.
+ * 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.
*/
- public JSONObject put(String key, boolean value) throws JSONException {
- this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
- return this;
+ public String optString(String name) {
+ return optString(name, "");
}
-
/**
- * 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
+ * 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.
*/
- public JSONObject put(String key, Collection value) throws JSONException {
- this.put(key, new JSONArray(value));
- return this;
+ public String optString(String name, String fallback) {
+ Object object = opt(name);
+ String result = JSON.toString(object);
+ return result != null ? result : fallback;
}
-
/**
- * 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.
+ * 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}.
*/
- public JSONObject put(String key, double value) throws JSONException {
- this.put(key, new Double(value));
- return this;
+ 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");
+ }
}
-
/**
- * Put a key/int pair in the JSONObject.
- *
- * @param key A key string.
- * @param value An int which is the value.
- * @return this.
- * @throws JSONException If the key is null.
+ * 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
*/
- public JSONObject put(String key, int value) throws JSONException {
- this.put(key, new Integer(value));
- return this;
+ public JSONArray optJSONArray(String name) {
+ Object object = opt(name);
+ return object instanceof JSONArray ? (JSONArray) object : null;
}
-
/**
- * 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.
+ * 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}.
*/
- public JSONObject put(String key, long value) throws JSONException {
- this.put(key, new Long(value));
- return this;
+ 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");
+ }
}
-
/**
- * 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
+ * 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.
*/
- public JSONObject put(String key, Map value) throws JSONException {
- this.put(key, new JSONObject(value));
- return this;
+ public JSONObject optJSONObject(String name) {
+ Object object = opt(name);
+ return object instanceof JSONObject ? (JSONObject) object : null;
}
-
/**
- * 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.
+ * 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.
*/
- public JSONObject put(String key, Object value) throws JSONException {
- if (key == null) {
- throw new JSONException("Null key.");
+ public JSONArray toJSONArray(JSONArray names) throws JSONException {
+ JSONArray result = new JSONArray();
+ if (names == null) {
+ return null;
}
- if (value != null) {
- testValidity(value);
- this.map.put(key, value);
- } else {
- this.remove(key);
+ int length = names.length();
+ if (length == 0) {
+ return null;
}
- return this;
+ for (int i = 0; i < length; i++) {
+ String name = JSON.toString(names.opt(i));
+ result.put(opt(name));
+ }
+ return result;
}
-
/**
- * 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
+ * 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 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;
+ public Iterator<String> keys() {
+ return nameValuePairs.keySet().iterator();
}
-
/**
- * 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.
+ * 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 JSONObject putOpt(String key, Object value) throws JSONException {
- if (key != null && value != null) {
- this.put(key, value);
- }
- return this;
+ public Set<String> keySet() {
+ return nameValuePairs.keySet();
}
-
/**
- * 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.
+ * Returns an array containing the string names in this object. This method
+ * returns null if this object contains no mappings.
+ * @return the names.
*/
- 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 "";
- }
- }
- }
-
- public static Writer quote(String string, Writer w) throws IOException {
- if (string == null || string.length() == 0) {
- w.write("\"\"");
- return w;
- }
-
- 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;
+ public JSONArray names() {
+ return nameValuePairs.isEmpty()
+ ? null
+ : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
}
/**
- * 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.
+ * Encodes this object as a compact JSON string, such as:
+ * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
*/
- public Object remove(String key) {
- return this.map.remove(key);
+ @Override
+ public String toString() {
+ try {
+ JSONStringer stringer = new JSONStringer();
+ writeTo(stringer);
+ return stringer.toString();
+ } catch (JSONException e) {
+ return null;
+ }
}
/**
- * 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.
+ * 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.
*/
- 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;
- }
-
- /*
- * 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.
- */
+ public String toString(int indentSpaces) throws JSONException {
+ JSONStringer stringer = new JSONStringer(indentSpaces);
+ writeTo(stringer);
+ return stringer.toString();
+ }
- 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) {
- }
+ void writeTo(JSONStringer stringer) throws JSONException {
+ stringer.object();
+ for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
+ stringer.key(entry.getKey()).value(entry.getValue());
}
- return string;
+ stringer.endObject();
}
-
/**
- * 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.
+ * 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.
*/
- 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.");
- }
- }
+ public static String numberToString(Number number) throws JSONException {
+ if (number == null) {
+ throw new JSONException("Number must be non-null");
}
- }
+ double doubleValue = number.doubleValue();
+ JSON.checkDouble(doubleValue);
- /**
- * Produce a JSONArray containing the values of the members of this JSONObject.
- *
- * @param names A JSONArray containing a list of key strings. This determines the sequence of the
- * values in the result.
- * @return A JSONArray of values.
- * @throws JSONException If any of the values are non-finite numbers.
- */
- public JSONArray toJSONArray(JSONArray names) throws JSONException {
- if (names == null || names.length() == 0) {
- return null;
+ // the original returns "-0" instead of "-0.0" for negative zero
+ if (number.equals(NEGATIVE_ZERO)) {
+ return "-0";
}
- 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 {
- return this.toString(0);
- } catch (Exception e) {
- return null;
+ long longValue = number.longValue();
+ if (doubleValue == (double) longValue) {
+ return Long.toString(longValue);
}
- }
+ return number.toString();
+ }
/**
- * 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.
+ * 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.
*/
- public String toString(int indentFactor) throws JSONException {
- StringWriter w = new StringWriter();
- synchronized (w.getBuffer()) {
- return this.write(w, indentFactor, 0).toString();
+ public static String quote(String data) {
+ if (data == null) {
+ return "\"\"";
+ }
+ 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();
}
}
/**
- * 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.
+ * Wraps the given object if necessary.
*
- * <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.
+ * <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}
*/
- 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();
+ public static Object wrap(Object o) {
+ if (o == null) {
+ return NULL;
}
- if (value instanceof Map) {
- return new JSONObject((Map) value).toString();
+ if (o instanceof JSONArray || o instanceof JSONObject) {
+ return o;
}
- if (value instanceof Collection) {
- return new JSONArray((Collection) value).toString();
+ if (o.equals(NULL)) {
+ return o;
}
- 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 (object == null) {
- return NULL;
+ if (o instanceof Collection) {
+ return new JSONArray((Collection) o);
+ } else if (o.getClass().isArray()) {
+ return new JSONArray(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 Map) {
+ return new JSONObject((Map) o);
}
-
- if (object instanceof Collection) {
- return new JSONArray((Collection) object);
- }
- if (object.getClass().isArray()) {
- return new JSONArray(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 Map) {
- return new JSONObject((Map) object);
- }
- Package objectPackage = object.getClass().getPackage();
+ // 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();
String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
- if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.")
- || object.getClass().getClassLoader() == null
- || object.getClass().getName().contains("GemFireCacheImpl")) {
- return object.toString();
+ 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();
+// }
+ // GEODE-2142: Added the cyclicalDepCheck
if (cyclicDepChkEnabled.get() != null && cyclicDependencySet.get() != null) {
- if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(object)) {
+ if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(o)) {
// break cyclic reference
- return object.getClass().getCanonicalName();
+ return o.getClass().getCanonicalName();
} else {
- 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');
+ cyclicDependencySet.get().add(o);
+ return new JSONObject(o);
}
- indent(writer, indent);
+ } else {
+ return new JSONObject(o);
}
- writer.write('}');
- return writer;
- } catch (IOException exception) {
- throw new JSONException(exception);
+ } catch (Exception ignored) {
}
+ return null;
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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
[6/8] geode git commit: GEODE-2142: Spotless
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/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 59eb4bc..21c9fb0 100755
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,17 +1,15 @@
/*
* 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,637 +20,620 @@ 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;
+ /**
+ * 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);
}
-
- 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.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);
}
-
- /**
- * 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);
+ 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();
+ }
+ }
+
+ 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:
- pos--;
- return readLiteral();
- }
+ 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;
+ }
}
- 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;
+ 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;
+ }
}
-
- /**
- * 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.
+ }
+
+ /**
+ * 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.
*/
- private void skipToEndOfLine() {
- for (; pos < in.length(); pos++) {
- char c = in.charAt(pos);
- if (c == '\r' || c == '\n') {
- pos++;
- break;
- }
+ 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();
}
- }
+ }
- /**
- * 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 (c == '\\') {
+ if (pos == in.length()) {
+ throw syntaxError("Unterminated escape sequence");
}
-
- 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;
+ if (builder == null) {
+ builder = new StringBuilder();
}
+ builder.append(in, start, pos - 1);
+ builder.append(readEscapeCharacter());
+ start = pos;
+ }
}
- /**
- * 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.
- */
- }
+ 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");
}
-
- /* ...next try to parse as a floating point... */
+ String hex = in.substring(pos, pos + 4);
+ pos += 4;
try {
- return Double.valueOf(literal);
- } catch (NumberFormatException ignored) {
+ return (char) Integer.parseInt(hex, 16);
+ } catch (NumberFormatException nfe) {
+ throw syntaxError("Invalid escape sequence: " + hex);
}
- /* ... finally give up. We have an unquoted string */
- //noinspection RedundantStringConstructorCall
- return new String(literal); // a new string avoids leaking memory
- }
+ case 't':
+ return '\t';
- /**
- * 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 'b':
+ return '\b';
- /**
- * 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 'n':
+ return '\n';
- 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 'r':
+ return '\r';
- /**
- * 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 'f':
+ return '\f';
- /**
- * 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);
+ case '\'':
+ case '"':
+ case '\\':
+ default:
+ return escaped;
}
-
- /**
- * Returns the current position and the entire input string.
- */
- @Override
- public String toString() {
- // consistent with the original implementation
- return " at character " + pos + " of " + in;
+ }
+
+ /**
+ * 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;
}
- /*
- * 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();
+ /* 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.
+ */
+ }
}
- /**
- * 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';
+ /* ...next try to parse as a floating point... */
+ try {
+ return Double.valueOf(literal);
+ } catch (NumberFormatException ignored) {
}
- /**
- * 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;
+ /* ... 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 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;
+ 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 {@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");
+ 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());
}
- String result = in.substring(pos, pos + length);
- pos += length;
- return result;
+ }
+
+ /*
+ * 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");
+ }
}
-
- /**
- * 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();
+ }
+
+ /**
+ * 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");
+ }
}
-
- /**
- * 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();
+ }
+
+ /**
+ * 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);
}
-
- /**
- * 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 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");
}
-
- /**
- * 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';
- }
+ 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");
}
-
- /**
- * 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;
- }
+ 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';
}
-
- /**
- * 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;
- }
+ }
+
+ /**
+ * 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;
}
+ }
}
[2/8] geode git commit: GEODE-2142: Removal of non-compliant org.json
implementation.
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 234e174..db1121e 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,75 +1,470 @@
-package org.json;
-
/*
- * 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.
+ * 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.
*/
-import java.io.StringWriter;
+package org.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * 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
+ * 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.
*/
-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;
- }
+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();
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 100644
new mode 100755
index 4dd2ba2..59eb4bc
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,437 +1,658 @@
+/*
+ * 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.io.BufferedReader;
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
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.
- */
/**
- * 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
+ * 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.
*/
public class JSONTokener {
- 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");
- }
- 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';
- }
- if (c >= 'A' && c <= 'F') {
- return c - ('A' - 10);
- }
- if (c >= 'a' && c <= 'f') {
- return c - ('a' - 10);
- }
- 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;
+ /**
+ * 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;
}
- 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;
- }
+
+ 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;
- 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;
+
+ /**
+ * 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();
+ }
}
- 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 + "'");
+
+ 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;
}
- 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 "";
+
+ /**
+ * 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;
+ }
+ }
}
- char[] chars = new char[n];
- int pos = 0;
+ /**
+ * 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;
+ }
+ }
- 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;
- }
+ throw syntaxError("Unterminated string");
}
- }
-
-
- /**
- * 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':
- sb.append('\b');
- break;
+
+ /**
+ * 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':
- sb.append('\t');
- break;
+ return '\t';
+
+ case 'b':
+ return '\b';
+
case 'n':
- sb.append('\n');
- break;
- case 'f':
- sb.append('\f');
- break;
+ return '\n';
+
case 'r':
- sb.append('\r');
- break;
- case 'u':
- sb.append((char) Integer.parseInt(this.next(4), 16));
- break;
- case '"':
+ return '\r';
+
+ case 'f':
+ return '\f';
+
case '\'':
+ case '"':
case '\\':
- case '/':
- sb.append(c);
- break;
default:
- throw this.syntaxError("Illegal escape.");
- }
- break;
- default:
- if (c == quote) {
- return sb.toString();
- }
- sb.append(c);
- }
+ 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);
}
- }
-
-
- /**
- * 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();
+
+ /**
+ * 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");
+ }
}
- return sb.toString().trim();
- }
- sb.append(c);
}
- }
-
-
- /**
- * 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();
+
+ /**
+ * 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");
+ }
}
- return sb.toString().trim();
- }
- sb.append(c);
}
- }
-
-
- /**
- * 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);
+
+ /**
+ * 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;
}
/*
- * 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.
+ * Legacy APIs.
*
- * Accumulate characters until we reach the end of the text or a formatting character.
+ * 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.
*/
- StringBuffer sb = new StringBuffer();
- while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
- sb.append(c);
- c = this.next();
+ /**
+ * Returns true until the input has been exhausted.
+ *
+ * @return true if more input exists.
+ */
+ public boolean more() {
+ return pos < in.length();
}
- this.back();
- string = sb.toString().trim();
- if ("".equals(string)) {
- throw this.syntaxError("Missing value");
+ /**
+ * 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';
}
- 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;
+
+ /**
+ * 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);
}
- } while (c != to);
- } catch (IOException exc) {
- throw new JSONException(exc);
+ 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;
}
- 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 + "]";
- }
+ /**
+ * 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;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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
deleted file mode 100755
index 7d4704b..0000000
--- a/geode-json/src/main/java/org/json/JSONWriter.java
+++ /dev/null
@@ -1,321 +0,0 @@
-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/b3ec80bc/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
deleted file mode 100755
index ae6d61a..0000000
--- a/geode-json/src/main/java/org/json/XML.java
+++ /dev/null
@@ -1,504 +0,0 @@
-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 + ">";
- }
- }
- }
-}
[4/8] geode git commit: GEODE-2142: Removal of non-compliant org.json
implementation.
Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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 100644
new mode 100755
index edaefa4..074624d
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,868 +1,759 @@
-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.
+ * 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.
*/
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
+package org.json;
+
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
/**
- * 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>
+ * 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.
*
- * @author JSON.org
- * @version 2012-04-20
+ * <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.
*/
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;
+ }
- /**
- * 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);
+ /**
+ * 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 {
- x.back();
- this.myArrayList.add(x.nextValue());
+ throw JSON.typeMismatch(index, object, "JSONArray");
}
- switch (x.nextClean()) {
- case ';':
- case ',':
- if (x.nextClean() == ']') {
- return;
+ }
+
+ /**
+ * 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);
}
- x.back();
- break;
- case ']':
- return;
- default:
- throw x.syntaxError("Expected a ',' or ']'");
+ stringer.value(values.get(i));
}
- }
- }
- }
-
-
- /**
- * 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;
+ 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;
}
- if (indentFactor > 0) {
- writer.write('\n');
+ }
+
+ /**
+ * 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);
}
- JSONObject.indent(writer, indent);
- }
- writer.write(']');
- return writer;
- } catch (IOException e) {
- throw new JSONException(e);
- }
- }
+ 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/b3ec80bc/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 b65efe2..1292e86 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,30 +1,57 @@
+/*
+ * 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.
+
/**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
- *
- * @author JSON.org
- * @version 2010-12-24
+ * 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>
*/
-public class JSONException extends Exception {
- private static final long serialVersionUID = 0;
- private Throwable cause;
+public class JSONException extends RuntimeException {
- /**
- * Constructs a JSONException with an explanatory message.
- *
- * @param message Detail about the reason for the exception.
- */
- public JSONException(String message) {
- super(message);
- }
+ public JSONException(String s) {
+ super(s);
+ }
- public JSONException(Throwable cause) {
- super(cause.getMessage());
- this.cause = cause;
- }
+ public JSONException(Throwable cause) {
+ super(cause);
+ }
- public Throwable getCause() {
- return this.cause;
- }
+ public JSONException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/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
deleted file mode 100755
index b535614..0000000
--- a/geode-json/src/main/java/org/json/JSONML.java
+++ /dev/null
@@ -1,454 +0,0 @@
-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();
- }
-}
[8/8] geode git commit: GEODE-2142: Spotless
Posted by ud...@apache.org.
GEODE-2142: Spotless
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/2e3a88f7
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/2e3a88f7
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/2e3a88f7
Branch: refs/heads/develop
Commit: 2e3a88f7bc61796042140aa92b44390b9970b53e
Parents: b3ec80b
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 13:00:29 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 13:00:29 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, 2040 insertions(+), 2061 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/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..4e92623 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/2e3a88f7/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..8b7e004 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/2e3a88f7/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..f453ec6 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,8 +175,9 @@ 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());
}
@@ -231,7 +232,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/2e3a88f7/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..662ff4d 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/2e3a88f7/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 1b32e69..7105cab 100755
--- a/geode-json/src/main/java/org/json/JSON.java
+++ b/geode-json/src/main/java/org/json/JSON.java
@@ -1,116 +1,112 @@
/*
* 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);
- }
- return 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;
+ }
- 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 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 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 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 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;
+ 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 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/2e3a88f7/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 074624d..c961139 100755
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,17 +1,15 @@
/*
* 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;
@@ -24,736 +22,726 @@ 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/2e3a88f7/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..83fb4b8 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,17 +1,15 @@
/*
* 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,37 +19,40 @@ 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);
+ }
}