Commit cdf43d88f6894f52f9908aa3a39d35d38905ab82

Authored by ljq
1 parent a37b2416

调度语音识别

Showing 45 changed files with 9199 additions and 80 deletions
@@ -411,6 +411,24 @@ @@ -411,6 +411,24 @@
411 <groupId>org.hibernate</groupId> 411 <groupId>org.hibernate</groupId>
412 <artifactId>hibernate-spatial</artifactId> 412 <artifactId>hibernate-spatial</artifactId>
413 </dependency> 413 </dependency>
  414 +
  415 + <!-- 语音识别 -->
  416 + <dependency>
  417 + <groupId>net.java.dev.jna</groupId>
  418 + <artifactId>jna</artifactId>
  419 + <version>5.7.0</version>
  420 + </dependency>
  421 + <dependency>
  422 + <groupId>com.alphacephei</groupId>
  423 + <artifactId>vosk</artifactId>
  424 + <version>0.3.32</version>
  425 + </dependency>
  426 +
  427 + <dependency>
  428 + <groupId>com.belerweb</groupId>
  429 + <artifactId>pinyin4j</artifactId>
  430 + <version>2.5.1</version>
  431 + </dependency>
414 </dependencies> 432 </dependencies>
415 433
416 <dependencyManagement> 434 <dependencyManagement>
src/main/java/com/bsth/controller/realcontrol/PageForwardingController.java
1 package com.bsth.controller.realcontrol; 1 package com.bsth.controller.realcontrol;
2 2
  3 +import com.bsth.data.zndd.voice.UploadVideoServlet;
3 import com.bsth.entity.sys.Role; 4 import com.bsth.entity.sys.Role;
4 import com.bsth.entity.sys.SysUser; 5 import com.bsth.entity.sys.SysUser;
5 import com.bsth.security.util.SecurityUtils; 6 import com.bsth.security.util.SecurityUtils;
6 import org.slf4j.Logger; 7 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.stereotype.Controller; 10 import org.springframework.stereotype.Controller;
  11 +import org.springframework.web.bind.annotation.PathVariable;
9 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RequestParam;
10 import org.springframework.web.servlet.ModelAndView; 14 import org.springframework.web.servlet.ModelAndView;
11 15
  16 +import javax.servlet.ServletException;
  17 +import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse; 18 import javax.servlet.http.HttpServletResponse;
  19 +import java.io.IOException;
13 20
14 /** 21 /**
15 * 线调登入页面转发 22 * 线调登入页面转发
@@ -21,6 +28,8 @@ public class PageForwardingController { @@ -21,6 +28,8 @@ public class PageForwardingController {
21 28
22 Logger logger = LoggerFactory.getLogger(this.getClass()); 29 Logger logger = LoggerFactory.getLogger(this.getClass());
23 30
  31 + @Autowired
  32 + UploadVideoServlet UploadVideoServlet;
24 @RequestMapping("/v2") 33 @RequestMapping("/v2")
25 public ModelAndView v2(HttpServletResponse response){ 34 public ModelAndView v2(HttpServletResponse response){
26 ModelAndView mv = new ModelAndView(); 35 ModelAndView mv = new ModelAndView();
@@ -51,4 +60,9 @@ public class PageForwardingController { @@ -51,4 +60,9 @@ public class PageForwardingController {
51 mv.setViewName("/real_control_v2/main.html"); 60 mv.setViewName("/real_control_v2/main.html");
52 return mv; 61 return mv;
53 } 62 }
  63 +
  64 + @RequestMapping(value = "zndd/do/{line}")
  65 + public void doPost(@PathVariable("line") String line, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  66 + UploadVideoServlet.doPost(line,request,response);
  67 + }
54 } 68 }
src/main/java/com/bsth/controller/zndd/LoggerZnddController.java
1 package com.bsth.controller.zndd; 1 package com.bsth.controller.zndd;
2 2
3 import com.bsth.controller.BaseController; 3 import com.bsth.controller.BaseController;
  4 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
4 import com.bsth.entity.zndd.LoggerZndd; 5 import com.bsth.entity.zndd.LoggerZndd;
5 import com.bsth.service.zndd.LoggerZnddService; 6 import com.bsth.service.zndd.LoggerZnddService;
6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
7 -import org.springframework.web.bind.annotation.RequestMapping;  
8 -import org.springframework.web.bind.annotation.RequestParam;  
9 -import org.springframework.web.bind.annotation.RestController;  
10 - 8 +import org.springframework.web.bind.annotation.*;
11 import java.util.List; 9 import java.util.List;
12 import java.util.Map; 10 import java.util.Map;
13 11
@@ -17,9 +15,17 @@ public class LoggerZnddController extends BaseController&lt;LoggerZndd, Integer&gt; { @@ -17,9 +15,17 @@ public class LoggerZnddController extends BaseController&lt;LoggerZndd, Integer&gt; {
17 15
18 @Autowired 16 @Autowired
19 LoggerZnddService loggerZnddService; 17 LoggerZnddService loggerZnddService;
  18 +
20 @RequestMapping("listall") 19 @RequestMapping("listall")
21 public List<Map<String, Object>> listAll(@RequestParam Map<String, Object> map){ 20 public List<Map<String, Object>> listAll(@RequestParam Map<String, Object> map){
22 21
23 return loggerZnddService.listAll(map); 22 return loggerZnddService.listAll(map);
24 } 23 }
  24 +
  25 +
  26 + @RequestMapping(value = "/schlist", method = RequestMethod.POST)
  27 + public ScheduleRealInfo schlist(@RequestParam String lineCode,@RequestParam Integer dir){
  28 + return loggerZnddService.schlist(lineCode,dir);
  29 + }
  30 +
25 } 31 }
src/main/java/com/bsth/data/zndd/baidu/org/json/CDL.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 + */
  26 +
  27 +/**
  28 + * This provides static methods to convert comma delimited text into a
  29 + * JSONArray, and to convert a JSONArray into comma delimited text. Comma
  30 + * delimited text is a very popular format for data interchange. It is
  31 + * understood by most database, spreadsheet, and organizer programs.
  32 + * <p>
  33 + * Each row of text represents a row in a table or a data record. Each row
  34 + * ends with a NEWLINE character. Each row contains one or more values.
  35 + * Values are separated by commas. A value can contain any character except
  36 + * for comma, unless is is wrapped in single quotes or double quotes.
  37 + * <p>
  38 + * The first row usually contains the names of the columns.
  39 + * <p>
  40 + * A comma delimited list can be converted into a JSONArray of JSONObjects.
  41 + * The names for the elements in the JSONObjects can be taken from the names
  42 + * in the first row.
  43 + * @author JSON.org
  44 + * @version 2016-05-01
  45 + */
  46 +public class CDL {
  47 +
  48 + /**
  49 + * Get the next value. The value can be wrapped in quotes. The value can
  50 + * be empty.
  51 + * @param x A JSONTokener of the source text.
  52 + * @return The value string, or null if empty.
  53 + * @throws JSONException if the quoted string is badly formed.
  54 + */
  55 + private static String getValue(JSONTokener x) throws JSONException {
  56 + char c;
  57 + char q;
  58 + StringBuffer sb;
  59 + do {
  60 + c = x.next();
  61 + } while (c == ' ' || c == '\t');
  62 + switch (c) {
  63 + case 0:
  64 + return null;
  65 + case '"':
  66 + case '\'':
  67 + q = c;
  68 + sb = new StringBuffer();
  69 + for (;;) {
  70 + c = x.next();
  71 + if (c == q) {
  72 + //Handle escaped double-quote
  73 + char nextC = x.next();
  74 + if(nextC != '\"') {
  75 + // if our quote was the end of the file, don't step
  76 + if(nextC > 0) {
  77 + x.back();
  78 + }
  79 + break;
  80 + }
  81 + }
  82 + if (c == 0 || c == '\n' || c == '\r') {
  83 + throw x.syntaxError("Missing close quote '" + q + "'.");
  84 + }
  85 + sb.append(c);
  86 + }
  87 + return sb.toString();
  88 + case ',':
  89 + x.back();
  90 + return "";
  91 + default:
  92 + x.back();
  93 + return x.nextTo(',');
  94 + }
  95 + }
  96 +
  97 + /**
  98 + * Produce a JSONArray of strings from a row of comma delimited values.
  99 + * @param x A JSONTokener of the source text.
  100 + * @return A JSONArray of strings.
  101 + * @throws JSONException
  102 + */
  103 + public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
  104 + JSONArray ja = new JSONArray();
  105 + for (;;) {
  106 + String value = getValue(x);
  107 + char c = x.next();
  108 + if (value == null ||
  109 + (ja.length() == 0 && value.length() == 0 && c != ',')) {
  110 + return null;
  111 + }
  112 + ja.put(value);
  113 + for (;;) {
  114 + if (c == ',') {
  115 + break;
  116 + }
  117 + if (c != ' ') {
  118 + if (c == '\n' || c == '\r' || c == 0) {
  119 + return ja;
  120 + }
  121 + throw x.syntaxError("Bad character '" + c + "' (" +
  122 + (int)c + ").");
  123 + }
  124 + c = x.next();
  125 + }
  126 + }
  127 + }
  128 +
  129 + /**
  130 + * Produce a JSONObject from a row of comma delimited text, using a
  131 + * parallel JSONArray of strings to provides the names of the elements.
  132 + * @param names A JSONArray of names. This is commonly obtained from the
  133 + * first row of a comma delimited text file using the rowToJSONArray
  134 + * method.
  135 + * @param x A JSONTokener of the source text.
  136 + * @return A JSONObject combining the names and values.
  137 + * @throws JSONException
  138 + */
  139 + public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
  140 + throws JSONException {
  141 + JSONArray ja = rowToJSONArray(x);
  142 + return ja != null ? ja.toJSONObject(names) : null;
  143 + }
  144 +
  145 + /**
  146 + * Produce a comma delimited text row from a JSONArray. Values containing
  147 + * the comma character will be quoted. Troublesome characters may be
  148 + * removed.
  149 + * @param ja A JSONArray of strings.
  150 + * @return A string ending in NEWLINE.
  151 + */
  152 + public static String rowToString(JSONArray ja) {
  153 + StringBuilder sb = new StringBuilder();
  154 + for (int i = 0; i < ja.length(); i += 1) {
  155 + if (i > 0) {
  156 + sb.append(',');
  157 + }
  158 + Object object = ja.opt(i);
  159 + if (object != null) {
  160 + String string = object.toString();
  161 + if (string.length() > 0 && (string.indexOf(',') >= 0 ||
  162 + string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
  163 + string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
  164 + sb.append('"');
  165 + int length = string.length();
  166 + for (int j = 0; j < length; j += 1) {
  167 + char c = string.charAt(j);
  168 + if (c >= ' ' && c != '"') {
  169 + sb.append(c);
  170 + }
  171 + }
  172 + sb.append('"');
  173 + } else {
  174 + sb.append(string);
  175 + }
  176 + }
  177 + }
  178 + sb.append('\n');
  179 + return sb.toString();
  180 + }
  181 +
  182 + /**
  183 + * Produce a JSONArray of JSONObjects from a comma delimited text string,
  184 + * using the first row as a source of names.
  185 + * @param string The comma delimited text.
  186 + * @return A JSONArray of JSONObjects.
  187 + * @throws JSONException
  188 + */
  189 + public static JSONArray toJSONArray(String string) throws JSONException {
  190 + return toJSONArray(new JSONTokener(string));
  191 + }
  192 +
  193 + /**
  194 + * Produce a JSONArray of JSONObjects from a comma delimited text string,
  195 + * using the first row as a source of names.
  196 + * @param x The JSONTokener containing the comma delimited text.
  197 + * @return A JSONArray of JSONObjects.
  198 + * @throws JSONException
  199 + */
  200 + public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
  201 + return toJSONArray(rowToJSONArray(x), x);
  202 + }
  203 +
  204 + /**
  205 + * Produce a JSONArray of JSONObjects from a comma delimited text string
  206 + * using a supplied JSONArray as the source of element names.
  207 + * @param names A JSONArray of strings.
  208 + * @param string The comma delimited text.
  209 + * @return A JSONArray of JSONObjects.
  210 + * @throws JSONException
  211 + */
  212 + public static JSONArray toJSONArray(JSONArray names, String string)
  213 + throws JSONException {
  214 + return toJSONArray(names, new JSONTokener(string));
  215 + }
  216 +
  217 + /**
  218 + * Produce a JSONArray of JSONObjects from a comma delimited text string
  219 + * using a supplied JSONArray as the source of element names.
  220 + * @param names A JSONArray of strings.
  221 + * @param x A JSONTokener of the source text.
  222 + * @return A JSONArray of JSONObjects.
  223 + * @throws JSONException
  224 + */
  225 + public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
  226 + throws JSONException {
  227 + if (names == null || names.length() == 0) {
  228 + return null;
  229 + }
  230 + JSONArray ja = new JSONArray();
  231 + for (;;) {
  232 + JSONObject jo = rowToJSONObject(names, x);
  233 + if (jo == null) {
  234 + break;
  235 + }
  236 + ja.put(jo);
  237 + }
  238 + if (ja.length() == 0) {
  239 + return null;
  240 + }
  241 + return ja;
  242 + }
  243 +
  244 +
  245 + /**
  246 + * Produce a comma delimited text from a JSONArray of JSONObjects. The
  247 + * first row will be a list of names obtained by inspecting the first
  248 + * JSONObject.
  249 + * @param ja A JSONArray of JSONObjects.
  250 + * @return A comma delimited text.
  251 + * @throws JSONException
  252 + */
  253 + public static String toString(JSONArray ja) throws JSONException {
  254 + JSONObject jo = ja.optJSONObject(0);
  255 + if (jo != null) {
  256 + JSONArray names = jo.names();
  257 + if (names != null) {
  258 + return rowToString(names) + toString(names, ja);
  259 + }
  260 + }
  261 + return null;
  262 + }
  263 +
  264 + /**
  265 + * Produce a comma delimited text from a JSONArray of JSONObjects using
  266 + * a provided list of names. The list of names is not included in the
  267 + * output.
  268 + * @param names A JSONArray of strings.
  269 + * @param ja A JSONArray of JSONObjects.
  270 + * @return A comma delimited text.
  271 + * @throws JSONException
  272 + */
  273 + public static String toString(JSONArray names, JSONArray ja)
  274 + throws JSONException {
  275 + if (names == null || names.length() == 0) {
  276 + return null;
  277 + }
  278 + StringBuffer sb = new StringBuffer();
  279 + for (int i = 0; i < ja.length(); i += 1) {
  280 + JSONObject jo = ja.optJSONObject(i);
  281 + if (jo != null) {
  282 + sb.append(rowToString(jo.toJSONArray(names)));
  283 + }
  284 + }
  285 + return sb.toString();
  286 + }
  287 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/Cookie.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +/**
  28 + * Convert a web browser cookie specification to a JSONObject and back.
  29 + * JSON and Cookies are both notations for name/value pairs.
  30 + * @author JSON.org
  31 + * @version 2015-12-09
  32 + */
  33 +public class Cookie {
  34 +
  35 + /**
  36 + * Produce a copy of a string in which the characters '+', '%', '=', ';'
  37 + * and control characters are replaced with "%hh". This is a gentle form
  38 + * of URL encoding, attempting to cause as little distortion to the
  39 + * string as possible. The characters '=' and ';' are meta characters in
  40 + * cookies. By convention, they are escaped using the URL-encoding. This is
  41 + * only a convention, not a standard. Often, cookies are expected to have
  42 + * encoded values. We urlEncode '=' and ';' because we must. We urlEncode '%' and
  43 + * '+' because they are meta characters in URL encoding.
  44 + * @param string The source string.
  45 + * @return The escaped result.
  46 + */
  47 + public static String escape(String string) {
  48 + char c;
  49 + String s = string.trim();
  50 + int length = s.length();
  51 + StringBuilder sb = new StringBuilder(length);
  52 + for (int i = 0; i < length; i += 1) {
  53 + c = s.charAt(i);
  54 + if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
  55 + sb.append('%');
  56 + sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
  57 + sb.append(Character.forDigit((char)(c & 0x0f), 16));
  58 + } else {
  59 + sb.append(c);
  60 + }
  61 + }
  62 + return sb.toString();
  63 + }
  64 +
  65 +
  66 + /**
  67 + * Convert a cookie specification string into a JSONObject. The string
  68 + * will contain a name value pair separated by '='. The name and the value
  69 + * will be unescaped, possibly converting '+' and '%' sequences. The
  70 + * cookie properties may follow, separated by ';', also represented as
  71 + * name=value (except the secure property, which does not have a value).
  72 + * The name will be stored under the key "name", and the value will be
  73 + * stored under the key "value". This method does not do checking or
  74 + * validation of the parameters. It only converts the cookie string into
  75 + * a JSONObject.
  76 + * @param string The cookie specification string.
  77 + * @return A JSONObject containing "name", "value", and possibly other
  78 + * members.
  79 + * @throws JSONException
  80 + */
  81 + public static JSONObject toJSONObject(String string) throws JSONException {
  82 + String name;
  83 + JSONObject jo = new JSONObject();
  84 + Object value;
  85 + JSONTokener x = new JSONTokener(string);
  86 + jo.put("name", x.nextTo('='));
  87 + x.next('=');
  88 + jo.put("value", x.nextTo(';'));
  89 + x.next();
  90 + while (x.more()) {
  91 + name = unescape(x.nextTo("=;"));
  92 + if (x.next() != '=') {
  93 + if (name.equals("secure")) {
  94 + value = Boolean.TRUE;
  95 + } else {
  96 + throw x.syntaxError("Missing '=' in cookie parameter.");
  97 + }
  98 + } else {
  99 + value = unescape(x.nextTo(';'));
  100 + x.next();
  101 + }
  102 + jo.put(name, value);
  103 + }
  104 + return jo;
  105 + }
  106 +
  107 +
  108 + /**
  109 + * Convert a JSONObject into a cookie specification string. The JSONObject
  110 + * must contain "name" and "value" members.
  111 + * If the JSONObject contains "expires", "domain", "path", or "secure"
  112 + * members, they will be appended to the cookie specification string.
  113 + * All other members are ignored.
  114 + * @param jo A JSONObject
  115 + * @return A cookie specification string
  116 + * @throws JSONException
  117 + */
  118 + public static String toString(JSONObject jo) throws JSONException {
  119 + StringBuilder sb = new StringBuilder();
  120 +
  121 + sb.append(escape(jo.getString("name")));
  122 + sb.append("=");
  123 + sb.append(escape(jo.getString("value")));
  124 + if (jo.has("expires")) {
  125 + sb.append(";expires=");
  126 + sb.append(jo.getString("expires"));
  127 + }
  128 + if (jo.has("domain")) {
  129 + sb.append(";domain=");
  130 + sb.append(escape(jo.getString("domain")));
  131 + }
  132 + if (jo.has("path")) {
  133 + sb.append(";path=");
  134 + sb.append(escape(jo.getString("path")));
  135 + }
  136 + if (jo.optBoolean("secure")) {
  137 + sb.append(";secure");
  138 + }
  139 + return sb.toString();
  140 + }
  141 +
  142 + /**
  143 + * Convert <code>%</code><i>hh</i> sequences to single characters, and
  144 + * convert plus to space.
  145 + * @param string A string that may contain
  146 + * <code>+</code>&nbsp;<small>(plus)</small> and
  147 + * <code>%</code><i>hh</i> sequences.
  148 + * @return The unescaped string.
  149 + */
  150 + public static String unescape(String string) {
  151 + int length = string.length();
  152 + StringBuilder sb = new StringBuilder(length);
  153 + for (int i = 0; i < length; ++i) {
  154 + char c = string.charAt(i);
  155 + if (c == '+') {
  156 + c = ' ';
  157 + } else if (c == '%' && i + 2 < length) {
  158 + int d = JSONTokener.dehexchar(string.charAt(i + 1));
  159 + int e = JSONTokener.dehexchar(string.charAt(i + 2));
  160 + if (d >= 0 && e >= 0) {
  161 + c = (char)(d * 16 + e);
  162 + i += 2;
  163 + }
  164 + }
  165 + sb.append(c);
  166 + }
  167 + return sb.toString();
  168 + }
  169 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/CookieList.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 + */
  26 +
  27 +/**
  28 + * Convert a web browser cookie list string to a JSONObject and back.
  29 + * @author JSON.org
  30 + * @version 2015-12-09
  31 + */
  32 +public class CookieList {
  33 +
  34 + /**
  35 + * Convert a cookie list into a JSONObject. A cookie list is a sequence
  36 + * of name/value pairs. The names are separated from the values by '='.
  37 + * The pairs are separated by ';'. The names and the values
  38 + * will be unescaped, possibly converting '+' and '%' sequences.
  39 + *
  40 + * To add a cookie to a cookie list,
  41 + * cookielistJSONObject.put(cookieJSONObject.getString("name"),
  42 + * cookieJSONObject.getString("value"));
  43 + * @param string A cookie list string
  44 + * @return A JSONObject
  45 + * @throws JSONException
  46 + */
  47 + public static JSONObject toJSONObject(String string) throws JSONException {
  48 + JSONObject jo = new JSONObject();
  49 + JSONTokener x = new JSONTokener(string);
  50 + while (x.more()) {
  51 + String name = Cookie.unescape(x.nextTo('='));
  52 + x.next('=');
  53 + jo.put(name, Cookie.unescape(x.nextTo(';')));
  54 + x.next();
  55 + }
  56 + return jo;
  57 + }
  58 +
  59 + /**
  60 + * Convert a JSONObject into a cookie list. A cookie list is a sequence
  61 + * of name/value pairs. The names are separated from the values by '='.
  62 + * The pairs are separated by ';'. The characters '%', '+', '=', and ';'
  63 + * in the names and values are replaced by "%hh".
  64 + * @param jo A JSONObject
  65 + * @return A cookie list string
  66 + * @throws JSONException
  67 + */
  68 + public static String toString(JSONObject jo) throws JSONException {
  69 + boolean b = false;
  70 + final StringBuilder sb = new StringBuilder();
  71 + // Don't use the new entrySet API to maintain Android support
  72 + for (final String key : jo.keySet()) {
  73 + final Object value = jo.opt(key);
  74 + if (!JSONObject.NULL.equals(value)) {
  75 + if (b) {
  76 + sb.append(';');
  77 + }
  78 + sb.append(Cookie.escape(key));
  79 + sb.append("=");
  80 + sb.append(Cookie.escape(value.toString()));
  81 + b = true;
  82 + }
  83 + }
  84 + return sb.toString();
  85 + }
  86 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/HTTP.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +import java.util.Locale;
  28 +
  29 +/**
  30 + * Convert an HTTP header to a JSONObject and back.
  31 + * @author JSON.org
  32 + * @version 2015-12-09
  33 + */
  34 +public class HTTP {
  35 +
  36 + /** Carriage return/line feed. */
  37 + public static final String CRLF = "\r\n";
  38 +
  39 + /**
  40 + * Convert an HTTP header string into a JSONObject. It can be a request
  41 + * header or a response header. A request header will contain
  42 + * <pre>{
  43 + * Method: "POST" (for example),
  44 + * "Request-URI": "/" (for example),
  45 + * "HTTP-Version": "HTTP/1.1" (for example)
  46 + * }</pre>
  47 + * A response header will contain
  48 + * <pre>{
  49 + * "HTTP-Version": "HTTP/1.1" (for example),
  50 + * "Status-Code": "200" (for example),
  51 + * "Reason-Phrase": "OK" (for example)
  52 + * }</pre>
  53 + * In addition, the other parameters in the header will be captured, using
  54 + * the HTTP field names as JSON names, so that <pre>
  55 + * Date: Sun, 26 May 2002 18:06:04 GMT
  56 + * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
  57 + * Cache-Control: no-cache</pre>
  58 + * become
  59 + * <pre>{...
  60 + * Date: "Sun, 26 May 2002 18:06:04 GMT",
  61 + * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
  62 + * "Cache-Control": "no-cache",
  63 + * ...}</pre>
  64 + * It does no further checking or conversion. It does not parse dates.
  65 + * It does not do '%' transforms on URLs.
  66 + * @param string An HTTP header string.
  67 + * @return A JSONObject containing the elements and attributes
  68 + * of the XML string.
  69 + * @throws JSONException
  70 + */
  71 + public static JSONObject toJSONObject(String string) throws JSONException {
  72 + JSONObject jo = new JSONObject();
  73 + HTTPTokener x = new HTTPTokener(string);
  74 + String token;
  75 +
  76 + token = x.nextToken();
  77 + if (token.toUpperCase(Locale.ROOT).startsWith("HTTP")) {
  78 +
  79 +// Response
  80 +
  81 + jo.put("HTTP-Version", token);
  82 + jo.put("Status-Code", x.nextToken());
  83 + jo.put("Reason-Phrase", x.nextTo('\0'));
  84 + x.next();
  85 +
  86 + } else {
  87 +
  88 +// Request
  89 +
  90 + jo.put("Method", token);
  91 + jo.put("Request-URI", x.nextToken());
  92 + jo.put("HTTP-Version", x.nextToken());
  93 + }
  94 +
  95 +// Fields
  96 +
  97 + while (x.more()) {
  98 + String name = x.nextTo(':');
  99 + x.next(':');
  100 + jo.put(name, x.nextTo('\0'));
  101 + x.next();
  102 + }
  103 + return jo;
  104 + }
  105 +
  106 +
  107 + /**
  108 + * Convert a JSONObject into an HTTP header. A request header must contain
  109 + * <pre>{
  110 + * Method: "POST" (for example),
  111 + * "Request-URI": "/" (for example),
  112 + * "HTTP-Version": "HTTP/1.1" (for example)
  113 + * }</pre>
  114 + * A response header must contain
  115 + * <pre>{
  116 + * "HTTP-Version": "HTTP/1.1" (for example),
  117 + * "Status-Code": "200" (for example),
  118 + * "Reason-Phrase": "OK" (for example)
  119 + * }</pre>
  120 + * Any other members of the JSONObject will be output as HTTP fields.
  121 + * The result will end with two CRLF pairs.
  122 + * @param jo A JSONObject
  123 + * @return An HTTP header string.
  124 + * @throws JSONException if the object does not contain enough
  125 + * information.
  126 + */
  127 + public static String toString(JSONObject jo) throws JSONException {
  128 + StringBuilder sb = new StringBuilder();
  129 + if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
  130 + sb.append(jo.getString("HTTP-Version"));
  131 + sb.append(' ');
  132 + sb.append(jo.getString("Status-Code"));
  133 + sb.append(' ');
  134 + sb.append(jo.getString("Reason-Phrase"));
  135 + } else if (jo.has("Method") && jo.has("Request-URI")) {
  136 + sb.append(jo.getString("Method"));
  137 + sb.append(' ');
  138 + sb.append('"');
  139 + sb.append(jo.getString("Request-URI"));
  140 + sb.append('"');
  141 + sb.append(' ');
  142 + sb.append(jo.getString("HTTP-Version"));
  143 + } else {
  144 + throw new JSONException("Not enough material for an HTTP header.");
  145 + }
  146 + sb.append(CRLF);
  147 + // Don't use the new entrySet API to maintain Android support
  148 + for (final String key : jo.keySet()) {
  149 + String value = jo.optString(key);
  150 + if (!"HTTP-Version".equals(key) && !"Status-Code".equals(key) &&
  151 + !"Reason-Phrase".equals(key) && !"Method".equals(key) &&
  152 + !"Request-URI".equals(key) && !JSONObject.NULL.equals(value)) {
  153 + sb.append(key);
  154 + sb.append(": ");
  155 + sb.append(jo.optString(key));
  156 + sb.append(CRLF);
  157 + }
  158 + }
  159 + sb.append(CRLF);
  160 + return sb.toString();
  161 + }
  162 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/HTTPTokener.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +/**
  28 + * The HTTPTokener extends the JSONTokener to provide additional methods
  29 + * for the parsing of HTTP headers.
  30 + * @author JSON.org
  31 + * @version 2015-12-09
  32 + */
  33 +public class HTTPTokener extends JSONTokener {
  34 +
  35 + /**
  36 + * Construct an HTTPTokener from a string.
  37 + * @param string A source string.
  38 + */
  39 + public HTTPTokener(String string) {
  40 + super(string);
  41 + }
  42 +
  43 +
  44 + /**
  45 + * Get the next token or string. This is used in parsing HTTP headers.
  46 + * @throws JSONException
  47 + * @return A String.
  48 + */
  49 + public String nextToken() throws JSONException {
  50 + char c;
  51 + char q;
  52 + StringBuilder sb = new StringBuilder();
  53 + do {
  54 + c = next();
  55 + } while (Character.isWhitespace(c));
  56 + if (c == '"' || c == '\'') {
  57 + q = c;
  58 + for (;;) {
  59 + c = next();
  60 + if (c < ' ') {
  61 + throw syntaxError("Unterminated string.");
  62 + }
  63 + if (c == q) {
  64 + return sb.toString();
  65 + }
  66 + sb.append(c);
  67 + }
  68 + }
  69 + for (;;) {
  70 + if (c == 0 || Character.isWhitespace(c)) {
  71 + return sb.toString();
  72 + }
  73 + sb.append(c);
  74 + c = next();
  75 + }
  76 + }
  77 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONArray.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 + Copyright (c) 2002 JSON.org
  5 +
  6 + Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + of this software and associated documentation files (the "Software"), to deal
  8 + in the Software without restriction, including without limitation the rights
  9 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + copies of the Software, and to permit persons to whom the Software is
  11 + furnished to do so, subject to the following conditions:
  12 +
  13 + The above copyright notice and this permission notice shall be included in all
  14 + copies or substantial portions of the Software.
  15 +
  16 + The Software shall be used for Good, not Evil.
  17 +
  18 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 + SOFTWARE.
  25 + */
  26 +
  27 +import java.io.IOException;
  28 +import java.io.StringWriter;
  29 +import java.io.Writer;
  30 +import java.lang.reflect.Array;
  31 +import java.math.BigDecimal;
  32 +import java.math.BigInteger;
  33 +import java.util.*;
  34 +
  35 +/**
  36 + * A JSONArray is an ordered sequence of values. Its external text form is a
  37 + * string wrapped in square brackets with commas separating the values. The
  38 + * internal form is an object having <code>get</code> and <code>opt</code>
  39 + * methods for accessing the values by index, and <code>put</code> methods for
  40 + * adding or replacing values. The values can be any of these types:
  41 + * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
  42 + * <code>Number</code>, <code>String</code>, or the
  43 + * <code>JSONObject.NULL object</code>.
  44 + * <p>
  45 + * The constructor can convert a JSON text into a Java object. The
  46 + * <code>toString</code> method converts to JSON text.
  47 + * <p>
  48 + * A <code>get</code> method returns a value if one can be found, and throws an
  49 + * exception if one cannot be found. An <code>opt</code> method returns a
  50 + * default value instead of throwing an exception, and so is useful for
  51 + * obtaining optional values.
  52 + * <p>
  53 + * The generic <code>get()</code> and <code>opt()</code> methods return an
  54 + * object which you can cast or query for type. There are also typed
  55 + * <code>get</code> and <code>opt</code> methods that do type checking and type
  56 + * coercion for you.
  57 + * <p>
  58 + * The texts produced by the <code>toString</code> methods strictly conform to
  59 + * JSON syntax rules. The constructors are more forgiving in the texts they will
  60 + * accept:
  61 + * <ul>
  62 + * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
  63 + * before the closing bracket.</li>
  64 + * <li>The <code>null</code> value will be inserted when there is <code>,</code>
  65 + * &nbsp;<small>(comma)</small> elision.</li>
  66 + * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
  67 + * quote)</small>.</li>
  68 + * <li>Strings do not need to be quoted at all if they do not begin with a quote
  69 + * or single quote, and if they do not contain leading or trailing spaces, and
  70 + * if they do not contain any of these characters:
  71 + * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
  72 + * if they are not the reserved words <code>true</code>, <code>false</code>, or
  73 + * <code>null</code>.</li>
  74 + * </ul>
  75 + *
  76 + * @author JSON.org
  77 + * @version 2016-08/15
  78 + */
  79 +public class JSONArray implements Iterable<Object> {
  80 +
  81 + /**
  82 + * The arrayList where the JSONArray's properties are kept.
  83 + */
  84 + private final ArrayList<Object> myArrayList;
  85 +
  86 + /**
  87 + * Construct an empty JSONArray.
  88 + */
  89 + public JSONArray() {
  90 + this.myArrayList = new ArrayList<Object>();
  91 + }
  92 +
  93 + /**
  94 + * Construct a JSONArray from a JSONTokener.
  95 + *
  96 + * @param x
  97 + * A JSONTokener
  98 + * @throws JSONException
  99 + * If there is a syntax error.
  100 + */
  101 + public JSONArray(JSONTokener x) throws JSONException {
  102 + this();
  103 + if (x.nextClean() != '[') {
  104 + throw x.syntaxError("A JSONArray text must start with '['");
  105 + }
  106 +
  107 + char nextChar = x.nextClean();
  108 + if (nextChar == 0) {
  109 + // array is unclosed. No ']' found, instead EOF
  110 + throw x.syntaxError("Expected a ',' or ']'");
  111 + }
  112 + if (nextChar != ']') {
  113 + x.back();
  114 + for (;;) {
  115 + if (x.nextClean() == ',') {
  116 + x.back();
  117 + this.myArrayList.add(JSONObject.NULL);
  118 + } else {
  119 + x.back();
  120 + this.myArrayList.add(x.nextValue());
  121 + }
  122 + switch (x.nextClean()) {
  123 + case 0:
  124 + // array is unclosed. No ']' found, instead EOF
  125 + throw x.syntaxError("Expected a ',' or ']'");
  126 + case ',':
  127 + nextChar = x.nextClean();
  128 + if (nextChar == 0) {
  129 + // array is unclosed. No ']' found, instead EOF
  130 + throw x.syntaxError("Expected a ',' or ']'");
  131 + }
  132 + if (nextChar == ']') {
  133 + return;
  134 + }
  135 + x.back();
  136 + break;
  137 + case ']':
  138 + return;
  139 + default:
  140 + throw x.syntaxError("Expected a ',' or ']'");
  141 + }
  142 + }
  143 + }
  144 + }
  145 +
  146 + /**
  147 + * Construct a JSONArray from a source JSON text.
  148 + *
  149 + * @param source
  150 + * A string that begins with <code>[</code>&nbsp;<small>(left
  151 + * bracket)</small> and ends with <code>]</code>
  152 + * &nbsp;<small>(right bracket)</small>.
  153 + * @throws JSONException
  154 + * If there is a syntax error.
  155 + */
  156 + public JSONArray(String source) throws JSONException {
  157 + this(new JSONTokener(source));
  158 + }
  159 +
  160 + /**
  161 + * Construct a JSONArray from a Collection.
  162 + *
  163 + * @param collection
  164 + * A Collection.
  165 + */
  166 + public JSONArray(Collection<?> collection) {
  167 + if (collection == null) {
  168 + this.myArrayList = new ArrayList<Object>();
  169 + } else {
  170 + this.myArrayList = new ArrayList<Object>(collection.size());
  171 + for (Object o: collection){
  172 + this.myArrayList.add(JSONObject.wrap(o));
  173 + }
  174 + }
  175 + }
  176 +
  177 + /**
  178 + * Construct a JSONArray from an array
  179 + *
  180 + * @throws JSONException
  181 + * If not an array.
  182 + */
  183 + public JSONArray(Object array) throws JSONException {
  184 + this();
  185 + if (array.getClass().isArray()) {
  186 + int length = Array.getLength(array);
  187 + this.myArrayList.ensureCapacity(length);
  188 + for (int i = 0; i < length; i += 1) {
  189 + this.put(JSONObject.wrap(Array.get(array, i)));
  190 + }
  191 + } else {
  192 + throw new JSONException(
  193 + "JSONArray initial value should be a string or collection or array.");
  194 + }
  195 + }
  196 +
  197 + @Override
  198 + public Iterator<Object> iterator() {
  199 + return this.myArrayList.iterator();
  200 + }
  201 +
  202 + /**
  203 + * Get the object value associated with an index.
  204 + *
  205 + * @param index
  206 + * The index must be between 0 and length() - 1.
  207 + * @return An object value.
  208 + * @throws JSONException
  209 + * If there is no value for the index.
  210 + */
  211 + public Object get(int index) throws JSONException {
  212 + Object object = this.opt(index);
  213 + if (object == null) {
  214 + throw new JSONException("JSONArray[" + index + "] not found.");
  215 + }
  216 + return object;
  217 + }
  218 +
  219 + /**
  220 + * Get the boolean value associated with an index. The string values "true"
  221 + * and "false" are converted to boolean.
  222 + *
  223 + * @param index
  224 + * The index must be between 0 and length() - 1.
  225 + * @return The truth.
  226 + * @throws JSONException
  227 + * If there is no value for the index or if the value is not
  228 + * convertible to boolean.
  229 + */
  230 + public boolean getBoolean(int index) throws JSONException {
  231 + Object object = this.get(index);
  232 + if (object.equals(Boolean.FALSE)
  233 + || (object instanceof String && ((String) object)
  234 + .equalsIgnoreCase("false"))) {
  235 + return false;
  236 + } else if (object.equals(Boolean.TRUE)
  237 + || (object instanceof String && ((String) object)
  238 + .equalsIgnoreCase("true"))) {
  239 + return true;
  240 + }
  241 + throw new JSONException("JSONArray[" + index + "] is not a boolean.");
  242 + }
  243 +
  244 + /**
  245 + * Get the double value associated with an index.
  246 + *
  247 + * @param index
  248 + * The index must be between 0 and length() - 1.
  249 + * @return The value.
  250 + * @throws JSONException
  251 + * If the key is not found or if the value cannot be converted
  252 + * to a number.
  253 + */
  254 + public double getDouble(int index) throws JSONException {
  255 + Object object = this.get(index);
  256 + try {
  257 + return object instanceof Number ? ((Number) object).doubleValue()
  258 + : Double.parseDouble((String) object);
  259 + } catch (Exception e) {
  260 + throw new JSONException("JSONArray[" + index + "] is not a number.", e);
  261 + }
  262 + }
  263 +
  264 + /**
  265 + * Get the float value associated with a key.
  266 + *
  267 + * @param index
  268 + * The index must be between 0 and length() - 1.
  269 + * @return The numeric value.
  270 + * @throws JSONException
  271 + * if the key is not found or if the value is not a Number
  272 + * object and cannot be converted to a number.
  273 + */
  274 + public float getFloat(int index) throws JSONException {
  275 + Object object = this.get(index);
  276 + try {
  277 + return object instanceof Number ? ((Number) object).floatValue()
  278 + : Float.parseFloat(object.toString());
  279 + } catch (Exception e) {
  280 + throw new JSONException("JSONArray[" + index
  281 + + "] is not a number.", e);
  282 + }
  283 + }
  284 +
  285 + /**
  286 + * Get the Number value associated with a key.
  287 + *
  288 + * @param index
  289 + * The index must be between 0 and length() - 1.
  290 + * @return The numeric value.
  291 + * @throws JSONException
  292 + * if the key is not found or if the value is not a Number
  293 + * object and cannot be converted to a number.
  294 + */
  295 + public Number getNumber(int index) throws JSONException {
  296 + Object object = this.get(index);
  297 + try {
  298 + if (object instanceof Number) {
  299 + return (Number)object;
  300 + }
  301 + return JSONObject.stringToNumber(object.toString());
  302 + } catch (Exception e) {
  303 + throw new JSONException("JSONArray[" + index + "] is not a number.", e);
  304 + }
  305 + }
  306 +
  307 + /**
  308 + * Get the enum value associated with an index.
  309 + *
  310 + * @param clazz
  311 + * The type of enum to retrieve.
  312 + * @param index
  313 + * The index must be between 0 and length() - 1.
  314 + * @return The enum value at the index location
  315 + * @throws JSONException
  316 + * if the key is not found or if the value cannot be converted
  317 + * to an enum.
  318 + */
  319 + public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONException {
  320 + E val = optEnum(clazz, index);
  321 + if(val==null) {
  322 + // JSONException should really take a throwable argument.
  323 + // If it did, I would re-implement this with the Enum.valueOf
  324 + // method and place any thrown exception in the JSONException
  325 + throw new JSONException("JSONArray[" + index + "] is not an enum of type "
  326 + + JSONObject.quote(clazz.getSimpleName()) + ".");
  327 + }
  328 + return val;
  329 + }
  330 +
  331 + /**
  332 + * Get the BigDecimal value associated with an index.
  333 + *
  334 + * @param index
  335 + * The index must be between 0 and length() - 1.
  336 + * @return The value.
  337 + * @throws JSONException
  338 + * If the key is not found or if the value cannot be converted
  339 + * to a BigDecimal.
  340 + */
  341 + public BigDecimal getBigDecimal (int index) throws JSONException {
  342 + Object object = this.get(index);
  343 + try {
  344 + return new BigDecimal(object.toString());
  345 + } catch (Exception e) {
  346 + throw new JSONException("JSONArray[" + index +
  347 + "] could not convert to BigDecimal.", e);
  348 + }
  349 + }
  350 +
  351 + /**
  352 + * Get the BigInteger value associated with an index.
  353 + *
  354 + * @param index
  355 + * The index must be between 0 and length() - 1.
  356 + * @return The value.
  357 + * @throws JSONException
  358 + * If the key is not found or if the value cannot be converted
  359 + * to a BigInteger.
  360 + */
  361 + public BigInteger getBigInteger (int index) throws JSONException {
  362 + Object object = this.get(index);
  363 + try {
  364 + return new BigInteger(object.toString());
  365 + } catch (Exception e) {
  366 + throw new JSONException("JSONArray[" + index +
  367 + "] could not convert to BigInteger.", e);
  368 + }
  369 + }
  370 +
  371 + /**
  372 + * Get the int value associated with an index.
  373 + *
  374 + * @param index
  375 + * The index must be between 0 and length() - 1.
  376 + * @return The value.
  377 + * @throws JSONException
  378 + * If the key is not found or if the value is not a number.
  379 + */
  380 + public int getInt(int index) throws JSONException {
  381 + Object object = this.get(index);
  382 + try {
  383 + return object instanceof Number ? ((Number) object).intValue()
  384 + : Integer.parseInt((String) object);
  385 + } catch (Exception e) {
  386 + throw new JSONException("JSONArray[" + index + "] is not a number.", e);
  387 + }
  388 + }
  389 +
  390 + /**
  391 + * Get the JSONArray associated with an index.
  392 + *
  393 + * @param index
  394 + * The index must be between 0 and length() - 1.
  395 + * @return A JSONArray value.
  396 + * @throws JSONException
  397 + * If there is no value for the index. or if the value is not a
  398 + * JSONArray
  399 + */
  400 + public JSONArray getJSONArray(int index) throws JSONException {
  401 + Object object = this.get(index);
  402 + if (object instanceof JSONArray) {
  403 + return (JSONArray) object;
  404 + }
  405 + throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
  406 + }
  407 +
  408 + /**
  409 + * Get the JSONObject associated with an index.
  410 + *
  411 + * @param index
  412 + * subscript
  413 + * @return A JSONObject value.
  414 + * @throws JSONException
  415 + * If there is no value for the index or if the value is not a
  416 + * JSONObject
  417 + */
  418 + public JSONObject getJSONObject(int index) throws JSONException {
  419 + Object object = this.get(index);
  420 + if (object instanceof JSONObject) {
  421 + return (JSONObject) object;
  422 + }
  423 + throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
  424 + }
  425 +
  426 + /**
  427 + * Get the long value associated with an index.
  428 + *
  429 + * @param index
  430 + * The index must be between 0 and length() - 1.
  431 + * @return The value.
  432 + * @throws JSONException
  433 + * If the key is not found or if the value cannot be converted
  434 + * to a number.
  435 + */
  436 + public long getLong(int index) throws JSONException {
  437 + Object object = this.get(index);
  438 + try {
  439 + return object instanceof Number ? ((Number) object).longValue()
  440 + : Long.parseLong((String) object);
  441 + } catch (Exception e) {
  442 + throw new JSONException("JSONArray[" + index + "] is not a number.", e);
  443 + }
  444 + }
  445 +
  446 + /**
  447 + * Get the string associated with an index.
  448 + *
  449 + * @param index
  450 + * The index must be between 0 and length() - 1.
  451 + * @return A string value.
  452 + * @throws JSONException
  453 + * If there is no string value for the index.
  454 + */
  455 + public String getString(int index) throws JSONException {
  456 + Object object = this.get(index);
  457 + if (object instanceof String) {
  458 + return (String) object;
  459 + }
  460 + throw new JSONException("JSONArray[" + index + "] not a string.");
  461 + }
  462 +
  463 + /**
  464 + * Determine if the value is null.
  465 + *
  466 + * @param index
  467 + * The index must be between 0 and length() - 1.
  468 + * @return true if the value at the index is null, or if there is no value.
  469 + */
  470 + public boolean isNull(int index) {
  471 + return JSONObject.NULL.equals(this.opt(index));
  472 + }
  473 +
  474 + /**
  475 + * Make a string from the contents of this JSONArray. The
  476 + * <code>separator</code> string is inserted between each element. Warning:
  477 + * This method assumes that the data structure is acyclical.
  478 + *
  479 + * @param separator
  480 + * A string that will be inserted between the elements.
  481 + * @return a string.
  482 + * @throws JSONException
  483 + * If the array contains an invalid number.
  484 + */
  485 + public String join(String separator) throws JSONException {
  486 + int len = this.length();
  487 + StringBuilder sb = new StringBuilder();
  488 +
  489 + for (int i = 0; i < len; i += 1) {
  490 + if (i > 0) {
  491 + sb.append(separator);
  492 + }
  493 + sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
  494 + }
  495 + return sb.toString();
  496 + }
  497 +
  498 + /**
  499 + * Get the number of elements in the JSONArray, included nulls.
  500 + *
  501 + * @return The length (or size).
  502 + */
  503 + public int length() {
  504 + return this.myArrayList.size();
  505 + }
  506 +
  507 + /**
  508 + * Get the optional object value associated with an index.
  509 + *
  510 + * @param index
  511 + * The index must be between 0 and length() - 1. If not, null is returned.
  512 + * @return An object value, or null if there is no object at that index.
  513 + */
  514 + public Object opt(int index) {
  515 + return (index < 0 || index >= this.length()) ? null : this.myArrayList
  516 + .get(index);
  517 + }
  518 +
  519 + /**
  520 + * Get the optional boolean value associated with an index. It returns false
  521 + * if there is no value at that index, or if the value is not Boolean.TRUE
  522 + * or the String "true".
  523 + *
  524 + * @param index
  525 + * The index must be between 0 and length() - 1.
  526 + * @return The truth.
  527 + */
  528 + public boolean optBoolean(int index) {
  529 + return this.optBoolean(index, false);
  530 + }
  531 +
  532 + /**
  533 + * Get the optional boolean value associated with an index. It returns the
  534 + * defaultValue if there is no value at that index or if it is not a Boolean
  535 + * or the String "true" or "false" (case insensitive).
  536 + *
  537 + * @param index
  538 + * The index must be between 0 and length() - 1.
  539 + * @param defaultValue
  540 + * A boolean default.
  541 + * @return The truth.
  542 + */
  543 + public boolean optBoolean(int index, boolean defaultValue) {
  544 + try {
  545 + return this.getBoolean(index);
  546 + } catch (Exception e) {
  547 + return defaultValue;
  548 + }
  549 + }
  550 +
  551 + /**
  552 + * Get the optional double value associated with an index. NaN is returned
  553 + * if there is no value for the index, or if the value is not a number and
  554 + * cannot be converted to a number.
  555 + *
  556 + * @param index
  557 + * The index must be between 0 and length() - 1.
  558 + * @return The value.
  559 + */
  560 + public double optDouble(int index) {
  561 + return this.optDouble(index, Double.NaN);
  562 + }
  563 +
  564 + /**
  565 + * Get the optional double value associated with an index. The defaultValue
  566 + * is returned if there is no value for the index, or if the value is not a
  567 + * number and cannot be converted to a number.
  568 + *
  569 + * @param index
  570 + * subscript
  571 + * @param defaultValue
  572 + * The default value.
  573 + * @return The value.
  574 + */
  575 + public double optDouble(int index, double defaultValue) {
  576 + Object val = this.opt(index);
  577 + if (JSONObject.NULL.equals(val)) {
  578 + return defaultValue;
  579 + }
  580 + if (val instanceof Number){
  581 + return ((Number) val).doubleValue();
  582 + }
  583 + if (val instanceof String) {
  584 + try {
  585 + return Double.parseDouble((String) val);
  586 + } catch (Exception e) {
  587 + return defaultValue;
  588 + }
  589 + }
  590 + return defaultValue;
  591 + }
  592 +
  593 + /**
  594 + * Get the optional float value associated with an index. NaN is returned
  595 + * if there is no value for the index, or if the value is not a number and
  596 + * cannot be converted to a number.
  597 + *
  598 + * @param index
  599 + * The index must be between 0 and length() - 1.
  600 + * @return The value.
  601 + */
  602 + public float optFloat(int index) {
  603 + return this.optFloat(index, Float.NaN);
  604 + }
  605 +
  606 + /**
  607 + * Get the optional float value associated with an index. The defaultValue
  608 + * is returned if there is no value for the index, or if the value is not a
  609 + * number and cannot be converted to a number.
  610 + *
  611 + * @param index
  612 + * subscript
  613 + * @param defaultValue
  614 + * The default value.
  615 + * @return The value.
  616 + */
  617 + public float optFloat(int index, float defaultValue) {
  618 + Object val = this.opt(index);
  619 + if (JSONObject.NULL.equals(val)) {
  620 + return defaultValue;
  621 + }
  622 + if (val instanceof Number){
  623 + return ((Number) val).floatValue();
  624 + }
  625 + if (val instanceof String) {
  626 + try {
  627 + return Float.parseFloat((String) val);
  628 + } catch (Exception e) {
  629 + return defaultValue;
  630 + }
  631 + }
  632 + return defaultValue;
  633 + }
  634 +
  635 + /**
  636 + * Get the optional int value associated with an index. Zero is returned if
  637 + * there is no value for the index, or if the value is not a number and
  638 + * cannot be converted to a number.
  639 + *
  640 + * @param index
  641 + * The index must be between 0 and length() - 1.
  642 + * @return The value.
  643 + */
  644 + public int optInt(int index) {
  645 + return this.optInt(index, 0);
  646 + }
  647 +
  648 + /**
  649 + * Get the optional int value associated with an index. The defaultValue is
  650 + * returned if there is no value for the index, or if the value is not a
  651 + * number and cannot be converted to a number.
  652 + *
  653 + * @param index
  654 + * The index must be between 0 and length() - 1.
  655 + * @param defaultValue
  656 + * The default value.
  657 + * @return The value.
  658 + */
  659 + public int optInt(int index, int defaultValue) {
  660 + Object val = this.opt(index);
  661 + if (JSONObject.NULL.equals(val)) {
  662 + return defaultValue;
  663 + }
  664 + if (val instanceof Number){
  665 + return ((Number) val).intValue();
  666 + }
  667 +
  668 + if (val instanceof String) {
  669 + try {
  670 + return new BigDecimal(val.toString()).intValue();
  671 + } catch (Exception e) {
  672 + return defaultValue;
  673 + }
  674 + }
  675 + return defaultValue;
  676 + }
  677 +
  678 + /**
  679 + * Get the enum value associated with a key.
  680 + *
  681 + * @param clazz
  682 + * The type of enum to retrieve.
  683 + * @param index
  684 + * The index must be between 0 and length() - 1.
  685 + * @return The enum value at the index location or null if not found
  686 + */
  687 + public <E extends Enum<E>> E optEnum(Class<E> clazz, int index) {
  688 + return this.optEnum(clazz, index, null);
  689 + }
  690 +
  691 + /**
  692 + * Get the enum value associated with a key.
  693 + *
  694 + * @param clazz
  695 + * The type of enum to retrieve.
  696 + * @param index
  697 + * The index must be between 0 and length() - 1.
  698 + * @param defaultValue
  699 + * The default in case the value is not found
  700 + * @return The enum value at the index location or defaultValue if
  701 + * the value is not found or cannot be assigned to clazz
  702 + */
  703 + public <E extends Enum<E>> E optEnum(Class<E> clazz, int index, E defaultValue) {
  704 + try {
  705 + Object val = this.opt(index);
  706 + if (JSONObject.NULL.equals(val)) {
  707 + return defaultValue;
  708 + }
  709 + if (clazz.isAssignableFrom(val.getClass())) {
  710 + // we just checked it!
  711 + @SuppressWarnings("unchecked")
  712 + E myE = (E) val;
  713 + return myE;
  714 + }
  715 + return Enum.valueOf(clazz, val.toString());
  716 + } catch (IllegalArgumentException e) {
  717 + return defaultValue;
  718 + } catch (NullPointerException e) {
  719 + return defaultValue;
  720 + }
  721 + }
  722 +
  723 +
  724 + /**
  725 + * Get the optional BigInteger value associated with an index. The
  726 + * defaultValue is returned if there is no value for the index, or if the
  727 + * value is not a number and cannot be converted to a number.
  728 + *
  729 + * @param index
  730 + * The index must be between 0 and length() - 1.
  731 + * @param defaultValue
  732 + * The default value.
  733 + * @return The value.
  734 + */
  735 + public BigInteger optBigInteger(int index, BigInteger defaultValue) {
  736 + Object val = this.opt(index);
  737 + if (JSONObject.NULL.equals(val)) {
  738 + return defaultValue;
  739 + }
  740 + if (val instanceof BigInteger){
  741 + return (BigInteger) val;
  742 + }
  743 + if (val instanceof BigDecimal){
  744 + return ((BigDecimal) val).toBigInteger();
  745 + }
  746 + if (val instanceof Double || val instanceof Float){
  747 + return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
  748 + }
  749 + if (val instanceof Long || val instanceof Integer
  750 + || val instanceof Short || val instanceof Byte){
  751 + return BigInteger.valueOf(((Number) val).longValue());
  752 + }
  753 + try {
  754 + final String valStr = val.toString();
  755 + if(JSONObject.isDecimalNotation(valStr)) {
  756 + return new BigDecimal(valStr).toBigInteger();
  757 + }
  758 + return new BigInteger(valStr);
  759 + } catch (Exception e) {
  760 + return defaultValue;
  761 + }
  762 + }
  763 +
  764 + /**
  765 + * Get the optional BigDecimal value associated with an index. The
  766 + * defaultValue is returned if there is no value for the index, or if the
  767 + * value is not a number and cannot be converted to a number.
  768 + *
  769 + * @param index
  770 + * The index must be between 0 and length() - 1.
  771 + * @param defaultValue
  772 + * The default value.
  773 + * @return The value.
  774 + */
  775 + public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
  776 + Object val = this.opt(index);
  777 + if (JSONObject.NULL.equals(val)) {
  778 + return defaultValue;
  779 + }
  780 + if (val instanceof BigDecimal){
  781 + return (BigDecimal) val;
  782 + }
  783 + if (val instanceof BigInteger){
  784 + return new BigDecimal((BigInteger) val);
  785 + }
  786 + if (val instanceof Double || val instanceof Float){
  787 + return new BigDecimal(((Number) val).doubleValue());
  788 + }
  789 + if (val instanceof Long || val instanceof Integer
  790 + || val instanceof Short || val instanceof Byte){
  791 + return new BigDecimal(((Number) val).longValue());
  792 + }
  793 + try {
  794 + return new BigDecimal(val.toString());
  795 + } catch (Exception e) {
  796 + return defaultValue;
  797 + }
  798 + }
  799 +
  800 + /**
  801 + * Get the optional JSONArray associated with an index.
  802 + *
  803 + * @param index
  804 + * subscript
  805 + * @return A JSONArray value, or null if the index has no value, or if the
  806 + * value is not a JSONArray.
  807 + */
  808 + public JSONArray optJSONArray(int index) {
  809 + Object o = this.opt(index);
  810 + return o instanceof JSONArray ? (JSONArray) o : null;
  811 + }
  812 +
  813 + /**
  814 + * Get the optional JSONObject associated with an index. Null is returned if
  815 + * the key is not found, or null if the index has no value, or if the value
  816 + * is not a JSONObject.
  817 + *
  818 + * @param index
  819 + * The index must be between 0 and length() - 1.
  820 + * @return A JSONObject value.
  821 + */
  822 + public JSONObject optJSONObject(int index) {
  823 + Object o = this.opt(index);
  824 + return o instanceof JSONObject ? (JSONObject) o : null;
  825 + }
  826 +
  827 + /**
  828 + * Get the optional long value associated with an index. Zero is returned if
  829 + * there is no value for the index, or if the value is not a number and
  830 + * cannot be converted to a number.
  831 + *
  832 + * @param index
  833 + * The index must be between 0 and length() - 1.
  834 + * @return The value.
  835 + */
  836 + public long optLong(int index) {
  837 + return this.optLong(index, 0);
  838 + }
  839 +
  840 + /**
  841 + * Get the optional long value associated with an index. The defaultValue is
  842 + * returned if there is no value for the index, or if the value is not a
  843 + * number and cannot be converted to a number.
  844 + *
  845 + * @param index
  846 + * The index must be between 0 and length() - 1.
  847 + * @param defaultValue
  848 + * The default value.
  849 + * @return The value.
  850 + */
  851 + public long optLong(int index, long defaultValue) {
  852 + Object val = this.opt(index);
  853 + if (JSONObject.NULL.equals(val)) {
  854 + return defaultValue;
  855 + }
  856 + if (val instanceof Number){
  857 + return ((Number) val).longValue();
  858 + }
  859 +
  860 + if (val instanceof String) {
  861 + try {
  862 + return new BigDecimal(val.toString()).longValue();
  863 + } catch (Exception e) {
  864 + return defaultValue;
  865 + }
  866 + }
  867 + return defaultValue;
  868 + }
  869 +
  870 + /**
  871 + * Get an optional {@link Number} value associated with a key, or <code>null</code>
  872 + * if there is no such key or if the value is not a number. If the value is a string,
  873 + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
  874 + * would be used in cases where type coercion of the number value is unwanted.
  875 + *
  876 + * @param index
  877 + * The index must be between 0 and length() - 1.
  878 + * @return An object which is the value.
  879 + */
  880 + public Number optNumber(int index) {
  881 + return this.optNumber(index, null);
  882 + }
  883 +
  884 + /**
  885 + * Get an optional {@link Number} value associated with a key, or the default if there
  886 + * is no such key or if the value is not a number. If the value is a string,
  887 + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
  888 + * would be used in cases where type coercion of the number value is unwanted.
  889 + *
  890 + * @param index
  891 + * The index must be between 0 and length() - 1.
  892 + * @param defaultValue
  893 + * The default.
  894 + * @return An object which is the value.
  895 + */
  896 + public Number optNumber(int index, Number defaultValue) {
  897 + Object val = this.opt(index);
  898 + if (JSONObject.NULL.equals(val)) {
  899 + return defaultValue;
  900 + }
  901 + if (val instanceof Number){
  902 + return (Number) val;
  903 + }
  904 +
  905 + if (val instanceof String) {
  906 + try {
  907 + return JSONObject.stringToNumber((String) val);
  908 + } catch (Exception e) {
  909 + return defaultValue;
  910 + }
  911 + }
  912 + return defaultValue;
  913 + }
  914 +
  915 + /**
  916 + * Get the optional string value associated with an index. It returns an
  917 + * empty string if there is no value at that index. If the value is not a
  918 + * string and is not null, then it is converted to a string.
  919 + *
  920 + * @param index
  921 + * The index must be between 0 and length() - 1.
  922 + * @return A String value.
  923 + */
  924 + public String optString(int index) {
  925 + return this.optString(index, "");
  926 + }
  927 +
  928 + /**
  929 + * Get the optional string associated with an index. The defaultValue is
  930 + * returned if the key is not found.
  931 + *
  932 + * @param index
  933 + * The index must be between 0 and length() - 1.
  934 + * @param defaultValue
  935 + * The default value.
  936 + * @return A String value.
  937 + */
  938 + public String optString(int index, String defaultValue) {
  939 + Object object = this.opt(index);
  940 + return JSONObject.NULL.equals(object) ? defaultValue : object
  941 + .toString();
  942 + }
  943 +
  944 + /**
  945 + * Append a boolean value. This increases the array's length by one.
  946 + *
  947 + * @param value
  948 + * A boolean value.
  949 + * @return this.
  950 + */
  951 + public JSONArray put(boolean value) {
  952 + this.put(value ? Boolean.TRUE : Boolean.FALSE);
  953 + return this;
  954 + }
  955 +
  956 + /**
  957 + * Put a value in the JSONArray, where the value will be a JSONArray which
  958 + * is produced from a Collection.
  959 + *
  960 + * @param value
  961 + * A Collection value.
  962 + * @return this.
  963 + */
  964 + public JSONArray put(Collection<?> value) {
  965 + this.put(new JSONArray(value));
  966 + return this;
  967 + }
  968 +
  969 + /**
  970 + * Append a double value. This increases the array's length by one.
  971 + *
  972 + * @param value
  973 + * A double value.
  974 + * @throws JSONException
  975 + * if the value is not finite.
  976 + * @return this.
  977 + */
  978 + public JSONArray put(double value) throws JSONException {
  979 + Double d = new Double(value);
  980 + JSONObject.testValidity(d);
  981 + this.put(d);
  982 + return this;
  983 + }
  984 +
  985 + /**
  986 + * Append an int value. This increases the array's length by one.
  987 + *
  988 + * @param value
  989 + * An int value.
  990 + * @return this.
  991 + */
  992 + public JSONArray put(int value) {
  993 + this.put(new Integer(value));
  994 + return this;
  995 + }
  996 +
  997 + /**
  998 + * Append an long value. This increases the array's length by one.
  999 + *
  1000 + * @param value
  1001 + * A long value.
  1002 + * @return this.
  1003 + */
  1004 + public JSONArray put(long value) {
  1005 + this.put(new Long(value));
  1006 + return this;
  1007 + }
  1008 +
  1009 + /**
  1010 + * Put a value in the JSONArray, where the value will be a JSONObject which
  1011 + * is produced from a Map.
  1012 + *
  1013 + * @param value
  1014 + * A Map value.
  1015 + * @return this.
  1016 + */
  1017 + public JSONArray put(Map<?, ?> value) {
  1018 + this.put(new JSONObject(value));
  1019 + return this;
  1020 + }
  1021 +
  1022 + /**
  1023 + * Append an object value. This increases the array's length by one.
  1024 + *
  1025 + * @param value
  1026 + * An object value. The value should be a Boolean, Double,
  1027 + * Integer, JSONArray, JSONObject, Long, or String, or the
  1028 + * JSONObject.NULL object.
  1029 + * @return this.
  1030 + */
  1031 + public JSONArray put(Object value) {
  1032 + this.myArrayList.add(value);
  1033 + return this;
  1034 + }
  1035 +
  1036 + /**
  1037 + * Put or replace a boolean value in the JSONArray. If the index is greater
  1038 + * than the length of the JSONArray, then null elements will be added as
  1039 + * necessary to pad it out.
  1040 + *
  1041 + * @param index
  1042 + * The subscript.
  1043 + * @param value
  1044 + * A boolean value.
  1045 + * @return this.
  1046 + * @throws JSONException
  1047 + * If the index is negative.
  1048 + */
  1049 + public JSONArray put(int index, boolean value) throws JSONException {
  1050 + this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
  1051 + return this;
  1052 + }
  1053 +
  1054 + /**
  1055 + * Put a value in the JSONArray, where the value will be a JSONArray which
  1056 + * is produced from a Collection.
  1057 + *
  1058 + * @param index
  1059 + * The subscript.
  1060 + * @param value
  1061 + * A Collection value.
  1062 + * @return this.
  1063 + * @throws JSONException
  1064 + * If the index is negative or if the value is not finite.
  1065 + */
  1066 + public JSONArray put(int index, Collection<?> value) throws JSONException {
  1067 + this.put(index, new JSONArray(value));
  1068 + return this;
  1069 + }
  1070 +
  1071 + /**
  1072 + * Put or replace a double value. If the index is greater than the length of
  1073 + * the JSONArray, then null elements will be added as necessary to pad it
  1074 + * out.
  1075 + *
  1076 + * @param index
  1077 + * The subscript.
  1078 + * @param value
  1079 + * A double value.
  1080 + * @return this.
  1081 + * @throws JSONException
  1082 + * If the index is negative or if the value is not finite.
  1083 + */
  1084 + public JSONArray put(int index, double value) throws JSONException {
  1085 + this.put(index, new Double(value));
  1086 + return this;
  1087 + }
  1088 +
  1089 + /**
  1090 + * Put or replace an int value. If the index is greater than the length of
  1091 + * the JSONArray, then null elements will be added as necessary to pad it
  1092 + * out.
  1093 + *
  1094 + * @param index
  1095 + * The subscript.
  1096 + * @param value
  1097 + * An int value.
  1098 + * @return this.
  1099 + * @throws JSONException
  1100 + * If the index is negative.
  1101 + */
  1102 + public JSONArray put(int index, int value) throws JSONException {
  1103 + this.put(index, new Integer(value));
  1104 + return this;
  1105 + }
  1106 +
  1107 + /**
  1108 + * Put or replace a long value. If the index is greater than the length of
  1109 + * the JSONArray, then null elements will be added as necessary to pad it
  1110 + * out.
  1111 + *
  1112 + * @param index
  1113 + * The subscript.
  1114 + * @param value
  1115 + * A long value.
  1116 + * @return this.
  1117 + * @throws JSONException
  1118 + * If the index is negative.
  1119 + */
  1120 + public JSONArray put(int index, long value) throws JSONException {
  1121 + this.put(index, new Long(value));
  1122 + return this;
  1123 + }
  1124 +
  1125 + /**
  1126 + * Put a value in the JSONArray, where the value will be a JSONObject that
  1127 + * is produced from a Map.
  1128 + *
  1129 + * @param index
  1130 + * The subscript.
  1131 + * @param value
  1132 + * The Map value.
  1133 + * @return this.
  1134 + * @throws JSONException
  1135 + * If the index is negative or if the the value is an invalid
  1136 + * number.
  1137 + */
  1138 + public JSONArray put(int index, Map<?, ?> value) throws JSONException {
  1139 + this.put(index, new JSONObject(value));
  1140 + return this;
  1141 + }
  1142 +
  1143 + /**
  1144 + * Put or replace an object value in the JSONArray. If the index is greater
  1145 + * than the length of the JSONArray, then null elements will be added as
  1146 + * necessary to pad it out.
  1147 + *
  1148 + * @param index
  1149 + * The subscript.
  1150 + * @param value
  1151 + * The value to put into the array. The value should be a
  1152 + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
  1153 + * String, or the JSONObject.NULL object.
  1154 + * @return this.
  1155 + * @throws JSONException
  1156 + * If the index is negative or if the the value is an invalid
  1157 + * number.
  1158 + */
  1159 + public JSONArray put(int index, Object value) throws JSONException {
  1160 + JSONObject.testValidity(value);
  1161 + if (index < 0) {
  1162 + throw new JSONException("JSONArray[" + index + "] not found.");
  1163 + }
  1164 + if (index < this.length()) {
  1165 + this.myArrayList.set(index, value);
  1166 + } else if(index == this.length()){
  1167 + // simple append
  1168 + this.put(value);
  1169 + } else {
  1170 + // if we are inserting past the length, we want to grow the array all at once
  1171 + // instead of incrementally.
  1172 + this.myArrayList.ensureCapacity(index + 1);
  1173 + while (index != this.length()) {
  1174 + this.put(JSONObject.NULL);
  1175 + }
  1176 + this.put(value);
  1177 + }
  1178 + return this;
  1179 + }
  1180 +
  1181 + /**
  1182 + * Creates a JSONPointer using an initialization string and tries to
  1183 + * match it to an item within this JSONArray. For example, given a
  1184 + * JSONArray initialized with this document:
  1185 + * <pre>
  1186 + * [
  1187 + * {"b":"c"}
  1188 + * ]
  1189 + * </pre>
  1190 + * and this JSONPointer string:
  1191 + * <pre>
  1192 + * "/0/b"
  1193 + * </pre>
  1194 + * Then this method will return the String "c"
  1195 + * A JSONPointerException may be thrown from code called by this method.
  1196 + *
  1197 + * @param jsonPointer string that can be used to create a JSONPointer
  1198 + * @return the item matched by the JSONPointer, otherwise null
  1199 + */
  1200 + public Object query(String jsonPointer) {
  1201 + return query(new JSONPointer(jsonPointer));
  1202 + }
  1203 +
  1204 + /**
  1205 + * Uses a uaer initialized JSONPointer and tries to
  1206 + * match it to an item whithin this JSONArray. For example, given a
  1207 + * JSONArray initialized with this document:
  1208 + * <pre>
  1209 + * [
  1210 + * {"b":"c"}
  1211 + * ]
  1212 + * </pre>
  1213 + * and this JSONPointer:
  1214 + * <pre>
  1215 + * "/0/b"
  1216 + * </pre>
  1217 + * Then this method will return the String "c"
  1218 + * A JSONPointerException may be thrown from code called by this method.
  1219 + *
  1220 + * @param jsonPointer string that can be used to create a JSONPointer
  1221 + * @return the item matched by the JSONPointer, otherwise null
  1222 + */
  1223 + public Object query(JSONPointer jsonPointer) {
  1224 + return jsonPointer.queryFrom(this);
  1225 + }
  1226 +
  1227 + /**
  1228 + * Queries and returns a value from this object using {@code jsonPointer}, or
  1229 + * returns null if the query fails due to a missing key.
  1230 + *
  1231 + * @param jsonPointer the string representation of the JSON pointer
  1232 + * @return the queried value or {@code null}
  1233 + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
  1234 + */
  1235 + public Object optQuery(String jsonPointer) {
  1236 + return optQuery(new JSONPointer(jsonPointer));
  1237 + }
  1238 +
  1239 + /**
  1240 + * Queries and returns a value from this object using {@code jsonPointer}, or
  1241 + * returns null if the query fails due to a missing key.
  1242 + *
  1243 + * @param jsonPointer The JSON pointer
  1244 + * @return the queried value or {@code null}
  1245 + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
  1246 + */
  1247 + public Object optQuery(JSONPointer jsonPointer) {
  1248 + try {
  1249 + return jsonPointer.queryFrom(this);
  1250 + } catch (JSONPointerException e) {
  1251 + return null;
  1252 + }
  1253 + }
  1254 +
  1255 + /**
  1256 + * Remove an index and close the hole.
  1257 + *
  1258 + * @param index
  1259 + * The index of the element to be removed.
  1260 + * @return The value that was associated with the index, or null if there
  1261 + * was no value.
  1262 + */
  1263 + public Object remove(int index) {
  1264 + return index >= 0 && index < this.length()
  1265 + ? this.myArrayList.remove(index)
  1266 + : null;
  1267 + }
  1268 +
  1269 + /**
  1270 + * Determine if two JSONArrays are similar.
  1271 + * They must contain similar sequences.
  1272 + *
  1273 + * @param other The other JSONArray
  1274 + * @return true if they are equal
  1275 + */
  1276 + public boolean similar(Object other) {
  1277 + if (!(other instanceof JSONArray)) {
  1278 + return false;
  1279 + }
  1280 + int len = this.length();
  1281 + if (len != ((JSONArray)other).length()) {
  1282 + return false;
  1283 + }
  1284 + for (int i = 0; i < len; i += 1) {
  1285 + Object valueThis = this.myArrayList.get(i);
  1286 + Object valueOther = ((JSONArray)other).myArrayList.get(i);
  1287 + if(valueThis == valueOther) {
  1288 + continue;
  1289 + }
  1290 + if(valueThis == null) {
  1291 + return false;
  1292 + }
  1293 + if (valueThis instanceof JSONObject) {
  1294 + if (!((JSONObject)valueThis).similar(valueOther)) {
  1295 + return false;
  1296 + }
  1297 + } else if (valueThis instanceof JSONArray) {
  1298 + if (!((JSONArray)valueThis).similar(valueOther)) {
  1299 + return false;
  1300 + }
  1301 + } else if (!valueThis.equals(valueOther)) {
  1302 + return false;
  1303 + }
  1304 + }
  1305 + return true;
  1306 + }
  1307 +
  1308 + /**
  1309 + * Produce a JSONObject by combining a JSONArray of names with the values of
  1310 + * this JSONArray.
  1311 + *
  1312 + * @param names
  1313 + * A JSONArray containing a list of key strings. These will be
  1314 + * paired with the values.
  1315 + * @return A JSONObject, or null if there are no names or if this JSONArray
  1316 + * has no values.
  1317 + * @throws JSONException
  1318 + * If any of the names are null.
  1319 + */
  1320 + public JSONObject toJSONObject(JSONArray names) throws JSONException {
  1321 + if (names == null || names.length() == 0 || this.length() == 0) {
  1322 + return null;
  1323 + }
  1324 + JSONObject jo = new JSONObject(names.length());
  1325 + for (int i = 0; i < names.length(); i += 1) {
  1326 + jo.put(names.getString(i), this.opt(i));
  1327 + }
  1328 + return jo;
  1329 + }
  1330 +
  1331 + /**
  1332 + * Make a JSON text of this JSONArray. For compactness, no unnecessary
  1333 + * whitespace is added. If it is not possible to produce a syntactically
  1334 + * correct JSON text then null will be returned instead. This could occur if
  1335 + * the array contains an invalid number.
  1336 + * <p><b>
  1337 + * Warning: This method assumes that the data structure is acyclical.
  1338 + * </b>
  1339 + *
  1340 + * @return a printable, displayable, transmittable representation of the
  1341 + * array.
  1342 + */
  1343 + @Override
  1344 + public String toString() {
  1345 + try {
  1346 + return this.toString(0);
  1347 + } catch (Exception e) {
  1348 + return null;
  1349 + }
  1350 + }
  1351 +
  1352 + /**
  1353 + * Make a pretty-printed JSON text of this JSONArray.
  1354 + *
  1355 + * <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
  1356 + * one element, then the array will be output on a single line:
  1357 + * <pre>{@code [1]}</pre>
  1358 + *
  1359 + * <p>If an array has 2 or more elements, then it will be output across
  1360 + * multiple lines: <pre>{@code
  1361 + * [
  1362 + * 1,
  1363 + * "value 2",
  1364 + * 3
  1365 + * ]
  1366 + * }</pre>
  1367 + * <p><b>
  1368 + * Warning: This method assumes that the data structure is acyclical.
  1369 + * </b>
  1370 + *
  1371 + * @param indentFactor
  1372 + * The number of spaces to add to each level of indentation.
  1373 + * @return a printable, displayable, transmittable representation of the
  1374 + * object, beginning with <code>[</code>&nbsp;<small>(left
  1375 + * bracket)</small> and ending with <code>]</code>
  1376 + * &nbsp;<small>(right bracket)</small>.
  1377 + * @throws JSONException
  1378 + */
  1379 + public String toString(int indentFactor) throws JSONException {
  1380 + StringWriter sw = new StringWriter();
  1381 + synchronized (sw.getBuffer()) {
  1382 + return this.write(sw, indentFactor, 0).toString();
  1383 + }
  1384 + }
  1385 +
  1386 + /**
  1387 + * Write the contents of the JSONArray as JSON text to a writer. For
  1388 + * compactness, no whitespace is added.
  1389 + * <p><b>
  1390 + * Warning: This method assumes that the data structure is acyclical.
  1391 + *</b>
  1392 + *
  1393 + * @return The writer.
  1394 + * @throws JSONException
  1395 + */
  1396 + public Writer write(Writer writer) throws JSONException {
  1397 + return this.write(writer, 0, 0);
  1398 + }
  1399 +
  1400 + /**
  1401 + * Write the contents of the JSONArray as JSON text to a writer.
  1402 + *
  1403 + * <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
  1404 + * one element, then the array will be output on a single line:
  1405 + * <pre>{@code [1]}</pre>
  1406 + *
  1407 + * <p>If an array has 2 or more elements, then it will be output across
  1408 + * multiple lines: <pre>{@code
  1409 + * [
  1410 + * 1,
  1411 + * "value 2",
  1412 + * 3
  1413 + * ]
  1414 + * }</pre>
  1415 + * <p><b>
  1416 + * Warning: This method assumes that the data structure is acyclical.
  1417 + * </b>
  1418 + *
  1419 + * @param writer
  1420 + * Writes the serialized JSON
  1421 + * @param indentFactor
  1422 + * The number of spaces to add to each level of indentation.
  1423 + * @param indent
  1424 + * The indentation of the top level.
  1425 + * @return The writer.
  1426 + * @throws JSONException
  1427 + */
  1428 + public Writer write(Writer writer, int indentFactor, int indent)
  1429 + throws JSONException {
  1430 + try {
  1431 + boolean commanate = false;
  1432 + int length = this.length();
  1433 + writer.write('[');
  1434 +
  1435 + if (length == 1) {
  1436 + try {
  1437 + JSONObject.writeValue(writer, this.myArrayList.get(0),
  1438 + indentFactor, indent);
  1439 + } catch (Exception e) {
  1440 + throw new JSONException("Unable to write JSONArray value at index: 0", e);
  1441 + }
  1442 + } else if (length != 0) {
  1443 + final int newindent = indent + indentFactor;
  1444 +
  1445 + for (int i = 0; i < length; i += 1) {
  1446 + if (commanate) {
  1447 + writer.write(',');
  1448 + }
  1449 + if (indentFactor > 0) {
  1450 + writer.write('\n');
  1451 + }
  1452 + JSONObject.indent(writer, newindent);
  1453 + try {
  1454 + JSONObject.writeValue(writer, this.myArrayList.get(i),
  1455 + indentFactor, newindent);
  1456 + } catch (Exception e) {
  1457 + throw new JSONException("Unable to write JSONArray value at index: " + i, e);
  1458 + }
  1459 + commanate = true;
  1460 + }
  1461 + if (indentFactor > 0) {
  1462 + writer.write('\n');
  1463 + }
  1464 + JSONObject.indent(writer, indent);
  1465 + }
  1466 + writer.write(']');
  1467 + return writer;
  1468 + } catch (IOException e) {
  1469 + throw new JSONException(e);
  1470 + }
  1471 + }
  1472 +
  1473 + /**
  1474 + * Returns a java.util.List containing all of the elements in this array.
  1475 + * If an element in the array is a JSONArray or JSONObject it will also
  1476 + * be converted.
  1477 + * <p>
  1478 + * Warning: This method assumes that the data structure is acyclical.
  1479 + *
  1480 + * @return a java.util.List containing the elements of this array
  1481 + */
  1482 + public List<Object> toList() {
  1483 + List<Object> results = new ArrayList<Object>(this.myArrayList.size());
  1484 + for (Object element : this.myArrayList) {
  1485 + if (element == null || JSONObject.NULL.equals(element)) {
  1486 + results.add(null);
  1487 + } else if (element instanceof JSONArray) {
  1488 + results.add(((JSONArray) element).toList());
  1489 + } else if (element instanceof JSONObject) {
  1490 + results.add(((JSONObject) element).toMap());
  1491 + } else {
  1492 + results.add(element);
  1493 + }
  1494 + }
  1495 + return results;
  1496 + }
  1497 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONException.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/**
  4 + * The JSONException is thrown by the JSON.org classes when things are amiss.
  5 + *
  6 + * @author JSON.org
  7 + * @version 2015-12-09
  8 + */
  9 +public class JSONException extends RuntimeException {
  10 + /** Serialization ID */
  11 + private static final long serialVersionUID = 0;
  12 +
  13 + /**
  14 + * Constructs a JSONException with an explanatory message.
  15 + *
  16 + * @param message
  17 + * Detail about the reason for the exception.
  18 + */
  19 + public JSONException(final String message) {
  20 + super(message);
  21 + }
  22 +
  23 + /**
  24 + * Constructs a JSONException with an explanatory message and cause.
  25 + *
  26 + * @param message
  27 + * Detail about the reason for the exception.
  28 + * @param cause
  29 + * The cause.
  30 + */
  31 + public JSONException(final String message, final Throwable cause) {
  32 + super(message, cause);
  33 + }
  34 +
  35 + /**
  36 + * Constructs a new JSONException with the specified cause.
  37 + *
  38 + * @param cause
  39 + * The cause.
  40 + */
  41 + public JSONException(final Throwable cause) {
  42 + super(cause.getMessage(), cause);
  43 + }
  44 +
  45 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONML.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2008 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +/**
  28 + * This provides static methods to convert an XML text into a JSONArray or
  29 + * JSONObject, and to covert a JSONArray or JSONObject into an XML text using
  30 + * the JsonML transform.
  31 + *
  32 + * @author JSON.org
  33 + * @version 2016-01-30
  34 + */
  35 +public class JSONML {
  36 + /**
  37 + * Parse XML values and store them in a JSONArray.
  38 + * @param x The XMLTokener containing the source string.
  39 + * @param arrayForm true if array form, false if object form.
  40 + * @param ja The JSONArray that is containing the current tag or null
  41 + * if we are at the outermost level.
  42 + * @param keepStrings Don't type-convert text nodes and attribute values
  43 + * @return A JSONArray if the value is the outermost tag, otherwise null.
  44 + * @throws JSONException
  45 + */
  46 + private static Object parse(
  47 + XMLTokener x,
  48 + boolean arrayForm,
  49 + JSONArray ja,
  50 + boolean keepStrings
  51 + ) throws JSONException {
  52 + String attribute;
  53 + char c;
  54 + String closeTag = null;
  55 + int i;
  56 + JSONArray newja = null;
  57 + JSONObject newjo = null;
  58 + Object token;
  59 + String tagName = null;
  60 +
  61 +// Test for and skip past these forms:
  62 +// <!-- ... -->
  63 +// <![ ... ]]>
  64 +// <! ... >
  65 +// <? ... ?>
  66 +
  67 + while (true) {
  68 + if (!x.more()) {
  69 + throw x.syntaxError("Bad XML");
  70 + }
  71 + token = x.nextContent();
  72 + if (token == XML.LT) {
  73 + token = x.nextToken();
  74 + if (token instanceof Character) {
  75 + if (token == XML.SLASH) {
  76 +
  77 +// Close tag </
  78 +
  79 + token = x.nextToken();
  80 + if (!(token instanceof String)) {
  81 + throw new JSONException(
  82 + "Expected a closing name instead of '" +
  83 + token + "'.");
  84 + }
  85 + if (x.nextToken() != XML.GT) {
  86 + throw x.syntaxError("Misshaped close tag");
  87 + }
  88 + return token;
  89 + } else if (token == XML.BANG) {
  90 +
  91 +// <!
  92 +
  93 + c = x.next();
  94 + if (c == '-') {
  95 + if (x.next() == '-') {
  96 + x.skipPast("-->");
  97 + } else {
  98 + x.back();
  99 + }
  100 + } else if (c == '[') {
  101 + token = x.nextToken();
  102 + if (token.equals("CDATA") && x.next() == '[') {
  103 + if (ja != null) {
  104 + ja.put(x.nextCDATA());
  105 + }
  106 + } else {
  107 + throw x.syntaxError("Expected 'CDATA['");
  108 + }
  109 + } else {
  110 + i = 1;
  111 + do {
  112 + token = x.nextMeta();
  113 + if (token == null) {
  114 + throw x.syntaxError("Missing '>' after '<!'.");
  115 + } else if (token == XML.LT) {
  116 + i += 1;
  117 + } else if (token == XML.GT) {
  118 + i -= 1;
  119 + }
  120 + } while (i > 0);
  121 + }
  122 + } else if (token == XML.QUEST) {
  123 +
  124 +// <?
  125 +
  126 + x.skipPast("?>");
  127 + } else {
  128 + throw x.syntaxError("Misshaped tag");
  129 + }
  130 +
  131 +// Open tag <
  132 +
  133 + } else {
  134 + if (!(token instanceof String)) {
  135 + throw x.syntaxError("Bad tagName '" + token + "'.");
  136 + }
  137 + tagName = (String)token;
  138 + newja = new JSONArray();
  139 + newjo = new JSONObject();
  140 + if (arrayForm) {
  141 + newja.put(tagName);
  142 + if (ja != null) {
  143 + ja.put(newja);
  144 + }
  145 + } else {
  146 + newjo.put("tagName", tagName);
  147 + if (ja != null) {
  148 + ja.put(newjo);
  149 + }
  150 + }
  151 + token = null;
  152 + for (;;) {
  153 + if (token == null) {
  154 + token = x.nextToken();
  155 + }
  156 + if (token == null) {
  157 + throw x.syntaxError("Misshaped tag");
  158 + }
  159 + if (!(token instanceof String)) {
  160 + break;
  161 + }
  162 +
  163 +// attribute = value
  164 +
  165 + attribute = (String)token;
  166 + if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
  167 + throw x.syntaxError("Reserved attribute.");
  168 + }
  169 + token = x.nextToken();
  170 + if (token == XML.EQ) {
  171 + token = x.nextToken();
  172 + if (!(token instanceof String)) {
  173 + throw x.syntaxError("Missing value");
  174 + }
  175 + newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token));
  176 + token = null;
  177 + } else {
  178 + newjo.accumulate(attribute, "");
  179 + }
  180 + }
  181 + if (arrayForm && newjo.length() > 0) {
  182 + newja.put(newjo);
  183 + }
  184 +
  185 +// Empty tag <.../>
  186 +
  187 + if (token == XML.SLASH) {
  188 + if (x.nextToken() != XML.GT) {
  189 + throw x.syntaxError("Misshaped tag");
  190 + }
  191 + if (ja == null) {
  192 + if (arrayForm) {
  193 + return newja;
  194 + }
  195 + return newjo;
  196 + }
  197 +
  198 +// Content, between <...> and </...>
  199 +
  200 + } else {
  201 + if (token != XML.GT) {
  202 + throw x.syntaxError("Misshaped tag");
  203 + }
  204 + closeTag = (String)parse(x, arrayForm, newja, keepStrings);
  205 + if (closeTag != null) {
  206 + if (!closeTag.equals(tagName)) {
  207 + throw x.syntaxError("Mismatched '" + tagName +
  208 + "' and '" + closeTag + "'");
  209 + }
  210 + tagName = null;
  211 + if (!arrayForm && newja.length() > 0) {
  212 + newjo.put("childNodes", newja);
  213 + }
  214 + if (ja == null) {
  215 + if (arrayForm) {
  216 + return newja;
  217 + }
  218 + return newjo;
  219 + }
  220 + }
  221 + }
  222 + }
  223 + } else {
  224 + if (ja != null) {
  225 + ja.put(token instanceof String
  226 + ? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token)
  227 + : token);
  228 + }
  229 + }
  230 + }
  231 + }
  232 +
  233 +
  234 + /**
  235 + * Convert a well-formed (but not necessarily valid) XML string into a
  236 + * JSONArray using the JsonML transform. Each XML tag is represented as
  237 + * a JSONArray in which the first element is the tag name. If the tag has
  238 + * attributes, then the second element will be JSONObject containing the
  239 + * name/value pairs. If the tag contains children, then strings and
  240 + * JSONArrays will represent the child tags.
  241 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  242 + * @param string The source string.
  243 + * @return A JSONArray containing the structured data from the XML string.
  244 + * @throws JSONException Thrown on error converting to a JSONArray
  245 + */
  246 + public static JSONArray toJSONArray(String string) throws JSONException {
  247 + return (JSONArray)parse(new XMLTokener(string), true, null, false);
  248 + }
  249 +
  250 +
  251 + /**
  252 + * Convert a well-formed (but not necessarily valid) XML string into a
  253 + * JSONArray using the JsonML transform. Each XML tag is represented as
  254 + * a JSONArray in which the first element is the tag name. If the tag has
  255 + * attributes, then the second element will be JSONObject containing the
  256 + * name/value pairs. If the tag contains children, then strings and
  257 + * JSONArrays will represent the child tags.
  258 + * As opposed to toJSONArray this method does not attempt to convert
  259 + * any text node or attribute value to any type
  260 + * but just leaves it as a string.
  261 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  262 + * @param string The source string.
  263 + * @param keepStrings If true, then values will not be coerced into boolean
  264 + * or numeric values and will instead be left as strings
  265 + * @return A JSONArray containing the structured data from the XML string.
  266 + * @throws JSONException Thrown on error converting to a JSONArray
  267 + */
  268 + public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
  269 + return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings);
  270 + }
  271 +
  272 +
  273 + /**
  274 + * Convert a well-formed (but not necessarily valid) XML string into a
  275 + * JSONArray using the JsonML transform. Each XML tag is represented as
  276 + * a JSONArray in which the first element is the tag name. If the tag has
  277 + * attributes, then the second element will be JSONObject containing the
  278 + * name/value pairs. If the tag contains children, then strings and
  279 + * JSONArrays will represent the child content and tags.
  280 + * As opposed to toJSONArray this method does not attempt to convert
  281 + * any text node or attribute value to any type
  282 + * but just leaves it as a string.
  283 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  284 + * @param x An XMLTokener.
  285 + * @param keepStrings If true, then values will not be coerced into boolean
  286 + * or numeric values and will instead be left as strings
  287 + * @return A JSONArray containing the structured data from the XML string.
  288 + * @throws JSONException Thrown on error converting to a JSONArray
  289 + */
  290 + public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
  291 + return (JSONArray)parse(x, true, null, keepStrings);
  292 + }
  293 +
  294 +
  295 + /**
  296 + * Convert a well-formed (but not necessarily valid) XML string into a
  297 + * JSONArray using the JsonML transform. Each XML tag is represented as
  298 + * a JSONArray in which the first element is the tag name. If the tag has
  299 + * attributes, then the second element will be JSONObject containing the
  300 + * name/value pairs. If the tag contains children, then strings and
  301 + * JSONArrays will represent the child content and tags.
  302 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  303 + * @param x An XMLTokener.
  304 + * @return A JSONArray containing the structured data from the XML string.
  305 + * @throws JSONException Thrown on error converting to a JSONArray
  306 + */
  307 + public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
  308 + return (JSONArray)parse(x, true, null, false);
  309 + }
  310 +
  311 +
  312 + /**
  313 + * Convert a well-formed (but not necessarily valid) XML string into a
  314 + * JSONObject using the JsonML transform. Each XML tag is represented as
  315 + * a JSONObject with a "tagName" property. If the tag has attributes, then
  316 + * the attributes will be in the JSONObject as properties. If the tag
  317 + * contains children, the object will have a "childNodes" property which
  318 + * will be an array of strings and JsonML JSONObjects.
  319 +
  320 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  321 + * @param string The XML source text.
  322 + * @return A JSONObject containing the structured data from the XML string.
  323 + * @throws JSONException Thrown on error converting to a JSONObject
  324 + */
  325 + public static JSONObject toJSONObject(String string) throws JSONException {
  326 + return (JSONObject)parse(new XMLTokener(string), false, null, false);
  327 + }
  328 +
  329 +
  330 + /**
  331 + * Convert a well-formed (but not necessarily valid) XML string into a
  332 + * JSONObject using the JsonML transform. Each XML tag is represented as
  333 + * a JSONObject with a "tagName" property. If the tag has attributes, then
  334 + * the attributes will be in the JSONObject as properties. If the tag
  335 + * contains children, the object will have a "childNodes" property which
  336 + * will be an array of strings and JsonML JSONObjects.
  337 +
  338 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  339 + * @param string The XML source text.
  340 + * @param keepStrings If true, then values will not be coerced into boolean
  341 + * or numeric values and will instead be left as strings
  342 + * @return A JSONObject containing the structured data from the XML string.
  343 + * @throws JSONException Thrown on error converting to a JSONObject
  344 + */
  345 + public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
  346 + return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings);
  347 + }
  348 +
  349 +
  350 + /**
  351 + * Convert a well-formed (but not necessarily valid) XML string into a
  352 + * JSONObject using the JsonML transform. Each XML tag is represented as
  353 + * a JSONObject with a "tagName" property. If the tag has attributes, then
  354 + * the attributes will be in the JSONObject as properties. If the tag
  355 + * contains children, the object will have a "childNodes" property which
  356 + * will be an array of strings and JsonML JSONObjects.
  357 +
  358 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  359 + * @param x An XMLTokener of the XML source text.
  360 + * @return A JSONObject containing the structured data from the XML string.
  361 + * @throws JSONException Thrown on error converting to a JSONObject
  362 + */
  363 + public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
  364 + return (JSONObject)parse(x, false, null, false);
  365 + }
  366 +
  367 +
  368 + /**
  369 + * Convert a well-formed (but not necessarily valid) XML string into a
  370 + * JSONObject using the JsonML transform. Each XML tag is represented as
  371 + * a JSONObject with a "tagName" property. If the tag has attributes, then
  372 + * the attributes will be in the JSONObject as properties. If the tag
  373 + * contains children, the object will have a "childNodes" property which
  374 + * will be an array of strings and JsonML JSONObjects.
  375 +
  376 + * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
  377 + * @param x An XMLTokener of the XML source text.
  378 + * @param keepStrings If true, then values will not be coerced into boolean
  379 + * or numeric values and will instead be left as strings
  380 + * @return A JSONObject containing the structured data from the XML string.
  381 + * @throws JSONException Thrown on error converting to a JSONObject
  382 + */
  383 + public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
  384 + return (JSONObject)parse(x, false, null, keepStrings);
  385 + }
  386 +
  387 +
  388 + /**
  389 + * Reverse the JSONML transformation, making an XML text from a JSONArray.
  390 + * @param ja A JSONArray.
  391 + * @return An XML string.
  392 + * @throws JSONException Thrown on error converting to a string
  393 + */
  394 + public static String toString(JSONArray ja) throws JSONException {
  395 + int i;
  396 + JSONObject jo;
  397 + int length;
  398 + Object object;
  399 + StringBuilder sb = new StringBuilder();
  400 + String tagName;
  401 +
  402 +// Emit <tagName
  403 +
  404 + tagName = ja.getString(0);
  405 + XML.noSpace(tagName);
  406 + tagName = XML.escape(tagName);
  407 + sb.append('<');
  408 + sb.append(tagName);
  409 +
  410 + object = ja.opt(1);
  411 + if (object instanceof JSONObject) {
  412 + i = 2;
  413 + jo = (JSONObject)object;
  414 +
  415 +// Emit the attributes
  416 +
  417 + // Don't use the new entrySet API to maintain Android support
  418 + for (final String key : jo.keySet()) {
  419 + final Object value = jo.opt(key);
  420 + XML.noSpace(key);
  421 + if (value != null) {
  422 + sb.append(' ');
  423 + sb.append(XML.escape(key));
  424 + sb.append('=');
  425 + sb.append('"');
  426 + sb.append(XML.escape(value.toString()));
  427 + sb.append('"');
  428 + }
  429 + }
  430 + } else {
  431 + i = 1;
  432 + }
  433 +
  434 +// Emit content in body
  435 +
  436 + length = ja.length();
  437 + if (i >= length) {
  438 + sb.append('/');
  439 + sb.append('>');
  440 + } else {
  441 + sb.append('>');
  442 + do {
  443 + object = ja.get(i);
  444 + i += 1;
  445 + if (object != null) {
  446 + if (object instanceof String) {
  447 + sb.append(XML.escape(object.toString()));
  448 + } else if (object instanceof JSONObject) {
  449 + sb.append(toString((JSONObject)object));
  450 + } else if (object instanceof JSONArray) {
  451 + sb.append(toString((JSONArray)object));
  452 + } else {
  453 + sb.append(object.toString());
  454 + }
  455 + }
  456 + } while (i < length);
  457 + sb.append('<');
  458 + sb.append('/');
  459 + sb.append(tagName);
  460 + sb.append('>');
  461 + }
  462 + return sb.toString();
  463 + }
  464 +
  465 + /**
  466 + * Reverse the JSONML transformation, making an XML text from a JSONObject.
  467 + * The JSONObject must contain a "tagName" property. If it has children,
  468 + * then it must have a "childNodes" property containing an array of objects.
  469 + * The other properties are attributes with string values.
  470 + * @param jo A JSONObject.
  471 + * @return An XML string.
  472 + * @throws JSONException Thrown on error converting to a string
  473 + */
  474 + public static String toString(JSONObject jo) throws JSONException {
  475 + StringBuilder sb = new StringBuilder();
  476 + int i;
  477 + JSONArray ja;
  478 + int length;
  479 + Object object;
  480 + String tagName;
  481 + Object value;
  482 +
  483 +//Emit <tagName
  484 +
  485 + tagName = jo.optString("tagName");
  486 + if (tagName == null) {
  487 + return XML.escape(jo.toString());
  488 + }
  489 + XML.noSpace(tagName);
  490 + tagName = XML.escape(tagName);
  491 + sb.append('<');
  492 + sb.append(tagName);
  493 +
  494 +//Emit the attributes
  495 +
  496 + // Don't use the new entrySet API to maintain Android support
  497 + for (final String key : jo.keySet()) {
  498 + if (!"tagName".equals(key) && !"childNodes".equals(key)) {
  499 + XML.noSpace(key);
  500 + value = jo.opt(key);
  501 + if (value != null) {
  502 + sb.append(' ');
  503 + sb.append(XML.escape(key));
  504 + sb.append('=');
  505 + sb.append('"');
  506 + sb.append(XML.escape(value.toString()));
  507 + sb.append('"');
  508 + }
  509 + }
  510 + }
  511 +
  512 +//Emit content in body
  513 +
  514 + ja = jo.optJSONArray("childNodes");
  515 + if (ja == null) {
  516 + sb.append('/');
  517 + sb.append('>');
  518 + } else {
  519 + sb.append('>');
  520 + length = ja.length();
  521 + for (i = 0; i < length; i += 1) {
  522 + object = ja.get(i);
  523 + if (object != null) {
  524 + if (object instanceof String) {
  525 + sb.append(XML.escape(object.toString()));
  526 + } else if (object instanceof JSONObject) {
  527 + sb.append(toString((JSONObject)object));
  528 + } else if (object instanceof JSONArray) {
  529 + sb.append(toString((JSONArray)object));
  530 + } else {
  531 + sb.append(object.toString());
  532 + }
  533 + }
  534 + }
  535 + sb.append('<');
  536 + sb.append('/');
  537 + sb.append(tagName);
  538 + sb.append('>');
  539 + }
  540 + return sb.toString();
  541 + }
  542 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONObject.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +import java.io.Closeable;
  4 +import java.io.IOException;
  5 +import java.io.StringWriter;
  6 +import java.io.Writer;
  7 +import java.lang.reflect.Field;
  8 +import java.lang.reflect.InvocationTargetException;
  9 +import java.lang.reflect.Method;
  10 +import java.lang.reflect.Modifier;
  11 +import java.math.BigDecimal;
  12 +import java.math.BigInteger;
  13 +import java.util.*;
  14 +import java.util.Map.Entry;
  15 +
  16 +/**
  17 + * A JSONObject is an unordered collection of name/value pairs. Its external
  18 + * form is a string wrapped in curly braces with colons between the names and
  19 + * values, and commas between the values and names. The internal form is an
  20 + * object having <code>get</code> and <code>opt</code> methods for accessing
  21 + * the values by name, and <code>put</code> methods for adding or replacing
  22 + * values by name. The values can be any of these types: <code>Boolean</code>,
  23 + * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
  24 + * <code>String</code>, or the <code>JSONObject.NULL</code> object. A
  25 + * JSONObject constructor can be used to convert an external form JSON text
  26 + * into an internal form whose values can be retrieved with the
  27 + * <code>get</code> and <code>opt</code> methods, or to convert values into a
  28 + * JSON text using the <code>put</code> and <code>toString</code> methods. A
  29 + * <code>get</code> method returns a value if one can be found, and throws an
  30 + * exception if one cannot be found. An <code>opt</code> method returns a
  31 + * default value instead of throwing an exception, and so is useful for
  32 + * obtaining optional values.
  33 + * <p>
  34 + * The generic <code>get()</code> and <code>opt()</code> methods return an
  35 + * object, which you can cast or query for type. There are also typed
  36 + * <code>get</code> and <code>opt</code> methods that do type checking and type
  37 + * coercion for you. The opt methods differ from the get methods in that they
  38 + * do not throw. Instead, they return a specified value, such as null.
  39 + * <p>
  40 + * The <code>put</code> methods add or replace values in an object. For
  41 + * example,
  42 + *
  43 + * <pre>
  44 + * myString = new JSONObject()
  45 + * .put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
  46 + * </pre>
  47 + *
  48 + * produces the string <code>{"JSON": "Hello, World"}</code>.
  49 + * <p>
  50 + * The texts produced by the <code>toString</code> methods strictly conform to
  51 + * the JSON syntax rules. The constructors are more forgiving in the texts they
  52 + * will accept:
  53 + * <ul>
  54 + * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
  55 + * before the closing brace.</li>
  56 + * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
  57 + * quote)</small>.</li>
  58 + * <li>Strings do not need to be quoted at all if they do not begin with a
  59 + * quote or single quote, and if they do not contain leading or trailing
  60 + * spaces, and if they do not contain any of these characters:
  61 + * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
  62 + * if they are not the reserved words <code>true</code>, <code>false</code>,
  63 + * or <code>null</code>.</li>
  64 + * </ul>
  65 + *
  66 + * @author JSON.org
  67 + * @version 2016-08-15
  68 + */
  69 +public class JSONObject {
  70 + /**
  71 + * JSONObject.NULL is equivalent to the value that JavaScript calls null,
  72 + * whilst Java's null is equivalent to the value that JavaScript calls
  73 + * undefined.
  74 + */
  75 + private static final class Null {
  76 +
  77 + /**
  78 + * There is only intended to be a single instance of the NULL object,
  79 + * so the clone method returns itself.
  80 + *
  81 + * @return NULL.
  82 + */
  83 + @Override
  84 + protected final Object clone() {
  85 + return this;
  86 + }
  87 +
  88 + /**
  89 + * A Null object is equal to the null value and to itself.
  90 + *
  91 + * @param object
  92 + * An object to test for nullness.
  93 + * @return true if the object parameter is the JSONObject.NULL object or
  94 + * null.
  95 + */
  96 + @Override
  97 + public boolean equals(Object object) {
  98 + return object == null || object == this;
  99 + }
  100 + /**
  101 + * A Null object is equal to the null value and to itself.
  102 + *
  103 + * @return always returns 0.
  104 + */
  105 + @Override
  106 + public int hashCode() {
  107 + return 0;
  108 + }
  109 +
  110 + /**
  111 + * Get the "null" string value.
  112 + *
  113 + * @return The string "null".
  114 + */
  115 + @Override
  116 + public String toString() {
  117 + return "null";
  118 + }
  119 + }
  120 +
  121 + /**
  122 + * The map where the JSONObject's properties are kept.
  123 + */
  124 + private final Map<String, Object> map;
  125 +
  126 + /**
  127 + * It is sometimes more convenient and less ambiguous to have a
  128 + * <code>NULL</code> object than to use Java's <code>null</code> value.
  129 + * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
  130 + * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
  131 + */
  132 + public static final Object NULL = new Null();
  133 +
  134 + /**
  135 + * Construct an empty JSONObject.
  136 + */
  137 + public JSONObject() {
  138 + // HashMap is used on purpose to ensure that elements are unordered by
  139 + // the specification.
  140 + // JSON tends to be a portable transfer format to allows the container
  141 + // implementations to rearrange their items for a faster element
  142 + // retrieval based on associative access.
  143 + // Therefore, an implementation mustn't rely on the order of the item.
  144 + this.map = new HashMap<String, Object>();
  145 + }
  146 +
  147 + /**
  148 + * Construct a JSONObject from a subset of another JSONObject. An array of
  149 + * strings is used to identify the keys that should be copied. Missing keys
  150 + * are ignored.
  151 + *
  152 + * @param jo
  153 + * A JSONObject.
  154 + * @param names
  155 + * An array of strings.
  156 + */
  157 + public JSONObject(JSONObject jo, String[] names) {
  158 + this(names.length);
  159 + for (int i = 0; i < names.length; i += 1) {
  160 + try {
  161 + this.putOnce(names[i], jo.opt(names[i]));
  162 + } catch (Exception ignore) {
  163 + }
  164 + }
  165 + }
  166 +
  167 + /**
  168 + * Construct a JSONObject from a JSONTokener.
  169 + *
  170 + * @param x
  171 + * A JSONTokener object containing the source string.
  172 + * @throws JSONException
  173 + * If there is a syntax error in the source string or a
  174 + * duplicated key.
  175 + */
  176 + public JSONObject(JSONTokener x) throws JSONException {
  177 + this();
  178 + char c;
  179 + String key;
  180 +
  181 + if (x.nextClean() != '{') {
  182 + throw x.syntaxError("A JSONObject text must begin with '{'");
  183 + }
  184 + for (;;) {
  185 + c = x.nextClean();
  186 + switch (c) {
  187 + case 0:
  188 + throw x.syntaxError("A JSONObject text must end with '}'");
  189 + case '}':
  190 + return;
  191 + default:
  192 + x.back();
  193 + key = x.nextValue().toString();
  194 + }
  195 +
  196 + // The key is followed by ':'.
  197 +
  198 + c = x.nextClean();
  199 + if (c != ':') {
  200 + throw x.syntaxError("Expected a ':' after a key");
  201 + }
  202 +
  203 + // Use syntaxError(..) to include error location
  204 +
  205 + if (key != null) {
  206 + // Check if key exists
  207 + if (this.opt(key) != null) {
  208 + // key already exists
  209 + throw x.syntaxError("Duplicate key \"" + key + "\"");
  210 + }
  211 + // Only add value if non-null
  212 + Object value = x.nextValue();
  213 + if (value!=null) {
  214 + this.put(key, value);
  215 + }
  216 + }
  217 +
  218 + // Pairs are separated by ','.
  219 +
  220 + switch (x.nextClean()) {
  221 + case ';':
  222 + case ',':
  223 + if (x.nextClean() == '}') {
  224 + return;
  225 + }
  226 + x.back();
  227 + break;
  228 + case '}':
  229 + return;
  230 + default:
  231 + throw x.syntaxError("Expected a ',' or '}'");
  232 + }
  233 + }
  234 + }
  235 +
  236 + /**
  237 + * Construct a JSONObject from a Map.
  238 + *
  239 + * @param m
  240 + * A map object that can be used to initialize the contents of
  241 + * the JSONObject.
  242 + */
  243 + public JSONObject(Map<?, ?> m) {
  244 + if (m == null) {
  245 + this.map = new HashMap<String, Object>();
  246 + } else {
  247 + this.map = new HashMap<String, Object>(m.size());
  248 + for (final Entry<?, ?> e : m.entrySet()) {
  249 + final Object value = e.getValue();
  250 + if (value != null) {
  251 + this.map.put(String.valueOf(e.getKey()), wrap(value));
  252 + }
  253 + }
  254 + }
  255 + }
  256 +
  257 + /**
  258 + * Construct a JSONObject from an Object using bean getters. It reflects on
  259 + * all of the public methods of the object. For each of the methods with no
  260 + * parameters and a name starting with <code>"get"</code> or
  261 + * <code>"is"</code> followed by an uppercase letter, the method is invoked,
  262 + * and a key and the value returned from the getter method are put into the
  263 + * new JSONObject.
  264 + * <p>
  265 + * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
  266 + * prefix. If the second remaining character is not upper case, then the
  267 + * first character is converted to lower case.
  268 + * <p>
  269 + * For example, if an object has a method named <code>"getName"</code>, and
  270 + * if the result of calling <code>object.getName()</code> is
  271 + * <code>"Larry Fine"</code>, then the JSONObject will contain
  272 + * <code>"name": "Larry Fine"</code>.
  273 + * <p>
  274 + * Methods that return <code>void</code> as well as <code>static</code>
  275 + * methods are ignored.
  276 + *
  277 + * @param bean
  278 + * An object that has getter methods that should be used to make
  279 + * a JSONObject.
  280 + */
  281 + public JSONObject(Object bean) {
  282 + this();
  283 + this.populateMap(bean);
  284 + }
  285 +
  286 + /**
  287 + * Construct a JSONObject from an Object, using reflection to find the
  288 + * public members. The resulting JSONObject's keys will be the strings from
  289 + * the names array, and the values will be the field values associated with
  290 + * those keys in the object. If a key is not found or not visible, then it
  291 + * will not be copied into the new JSONObject.
  292 + *
  293 + * @param object
  294 + * An object that has fields that should be used to make a
  295 + * JSONObject.
  296 + * @param names
  297 + * An array of strings, the names of the fields to be obtained
  298 + * from the object.
  299 + */
  300 + public JSONObject(Object object, String names[]) {
  301 + this(names.length);
  302 + Class<?> c = object.getClass();
  303 + for (int i = 0; i < names.length; i += 1) {
  304 + String name = names[i];
  305 + try {
  306 + this.putOpt(name, c.getField(name).get(object));
  307 + } catch (Exception ignore) {
  308 + }
  309 + }
  310 + }
  311 +
  312 + /**
  313 + * Construct a JSONObject from a source JSON text string. This is the most
  314 + * commonly used JSONObject constructor.
  315 + *
  316 + * @param source
  317 + * A string beginning with <code>{</code>&nbsp;<small>(left
  318 + * brace)</small> and ending with <code>}</code>
  319 + * &nbsp;<small>(right brace)</small>.
  320 + * @exception JSONException
  321 + * If there is a syntax error in the source string or a
  322 + * duplicated key.
  323 + */
  324 + public JSONObject(String source) throws JSONException {
  325 + this(new JSONTokener(source));
  326 + }
  327 +
  328 + /**
  329 + * Construct a JSONObject from a ResourceBundle.
  330 + *
  331 + * @param baseName
  332 + * The ResourceBundle base name.
  333 + * @param locale
  334 + * The Locale to load the ResourceBundle for.
  335 + * @throws JSONException
  336 + * If any JSONExceptions are detected.
  337 + */
  338 + public JSONObject(String baseName, Locale locale) throws JSONException {
  339 + this();
  340 + ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
  341 + Thread.currentThread().getContextClassLoader());
  342 +
  343 +// Iterate through the keys in the bundle.
  344 +
  345 + Enumeration<String> keys = bundle.getKeys();
  346 + while (keys.hasMoreElements()) {
  347 + Object key = keys.nextElement();
  348 + if (key != null) {
  349 +
  350 +// Go through the path, ensuring that there is a nested JSONObject for each
  351 +// segment except the last. Add the value using the last segment's name into
  352 +// the deepest nested JSONObject.
  353 +
  354 + String[] path = ((String) key).split("\\.");
  355 + int last = path.length - 1;
  356 + JSONObject target = this;
  357 + for (int i = 0; i < last; i += 1) {
  358 + String segment = path[i];
  359 + JSONObject nextTarget = target.optJSONObject(segment);
  360 + if (nextTarget == null) {
  361 + nextTarget = new JSONObject();
  362 + target.put(segment, nextTarget);
  363 + }
  364 + target = nextTarget;
  365 + }
  366 + target.put(path[last], bundle.getString((String) key));
  367 + }
  368 + }
  369 + }
  370 +
  371 + /**
  372 + * Constructor to specify an initial capacity of the internal map. Useful for library
  373 + * internal calls where we know, or at least can best guess, how big this JSONObject
  374 + * will be.
  375 + *
  376 + * @param initialCapacity initial capacity of the internal map.
  377 + */
  378 + protected JSONObject(int initialCapacity){
  379 + this.map = new HashMap<String, Object>(initialCapacity);
  380 + }
  381 +
  382 + /**
  383 + * Accumulate values under a key. It is similar to the put method except
  384 + * that if there is already an object stored under the key then a JSONArray
  385 + * is stored under the key to hold all of the accumulated values. If there
  386 + * is already a JSONArray, then the new value is appended to it. In
  387 + * contrast, the put method replaces the previous value.
  388 + *
  389 + * If only one value is accumulated that is not a JSONArray, then the result
  390 + * will be the same as using put. But if multiple values are accumulated,
  391 + * then the result will be like append.
  392 + *
  393 + * @param key
  394 + * A key string.
  395 + * @param value
  396 + * An object to be accumulated under the key.
  397 + * @return this.
  398 + * @throws JSONException
  399 + * If the value is an invalid number or if the key is null.
  400 + */
  401 + public JSONObject accumulate(String key, Object value) throws JSONException {
  402 + testValidity(value);
  403 + Object object = this.opt(key);
  404 + if (object == null) {
  405 + this.put(key,
  406 + value instanceof JSONArray ? new JSONArray().put(value)
  407 + : value);
  408 + } else if (object instanceof JSONArray) {
  409 + ((JSONArray) object).put(value);
  410 + } else {
  411 + this.put(key, new JSONArray().put(object).put(value));
  412 + }
  413 + return this;
  414 + }
  415 +
  416 + /**
  417 + * Append values to the array under a key. If the key does not exist in the
  418 + * JSONObject, then the key is put in the JSONObject with its value being a
  419 + * JSONArray containing the value parameter. If the key was already
  420 + * associated with a JSONArray, then the value parameter is appended to it.
  421 + *
  422 + * @param key
  423 + * A key string.
  424 + * @param value
  425 + * An object to be accumulated under the key.
  426 + * @return this.
  427 + * @throws JSONException
  428 + * If the key is null or if the current value associated with
  429 + * the key is not a JSONArray.
  430 + */
  431 + public JSONObject append(String key, Object value) throws JSONException {
  432 + testValidity(value);
  433 + Object object = this.opt(key);
  434 + if (object == null) {
  435 + this.put(key, new JSONArray().put(value));
  436 + } else if (object instanceof JSONArray) {
  437 + this.put(key, ((JSONArray) object).put(value));
  438 + } else {
  439 + throw new JSONException("JSONObject[" + key
  440 + + "] is not a JSONArray.");
  441 + }
  442 + return this;
  443 + }
  444 +
  445 + /**
  446 + * Produce a string from a double. The string "null" will be returned if the
  447 + * number is not finite.
  448 + *
  449 + * @param d
  450 + * A double.
  451 + * @return A String.
  452 + */
  453 + public static String doubleToString(double d) {
  454 + if (Double.isInfinite(d) || Double.isNaN(d)) {
  455 + return "null";
  456 + }
  457 +
  458 +// Shave off trailing zeros and decimal point, if possible.
  459 +
  460 + String string = Double.toString(d);
  461 + if (string.indexOf('.') > 0 && string.indexOf('e') < 0
  462 + && string.indexOf('E') < 0) {
  463 + while (string.endsWith("0")) {
  464 + string = string.substring(0, string.length() - 1);
  465 + }
  466 + if (string.endsWith(".")) {
  467 + string = string.substring(0, string.length() - 1);
  468 + }
  469 + }
  470 + return string;
  471 + }
  472 +
  473 + /**
  474 + * Get the value object associated with a key.
  475 + *
  476 + * @param key
  477 + * A key string.
  478 + * @return The object associated with the key.
  479 + * @throws JSONException
  480 + * if the key is not found.
  481 + */
  482 + public Object get(String key) throws JSONException {
  483 + if (key == null) {
  484 + throw new JSONException("Null key.");
  485 + }
  486 + Object object = this.opt(key);
  487 + if (object == null) {
  488 + throw new JSONException("JSONObject[" + quote(key) + "] not found.");
  489 + }
  490 + return object;
  491 + }
  492 +
  493 + /**
  494 + * Get the enum value associated with a key.
  495 + *
  496 + * @param clazz
  497 + * The type of enum to retrieve.
  498 + * @param key
  499 + * A key string.
  500 + * @return The enum value associated with the key
  501 + * @throws JSONException
  502 + * if the key is not found or if the value cannot be converted
  503 + * to an enum.
  504 + */
  505 + public <E extends Enum<E>> E getEnum(Class<E> clazz, String key) throws JSONException {
  506 + E val = optEnum(clazz, key);
  507 + if(val==null) {
  508 + // JSONException should really take a throwable argument.
  509 + // If it did, I would re-implement this with the Enum.valueOf
  510 + // method and place any thrown exception in the JSONException
  511 + throw new JSONException("JSONObject[" + quote(key)
  512 + + "] is not an enum of type " + quote(clazz.getSimpleName())
  513 + + ".");
  514 + }
  515 + return val;
  516 + }
  517 +
  518 + /**
  519 + * Get the boolean value associated with a key.
  520 + *
  521 + * @param key
  522 + * A key string.
  523 + * @return The truth.
  524 + * @throws JSONException
  525 + * if the value is not a Boolean or the String "true" or
  526 + * "false".
  527 + */
  528 + public boolean getBoolean(String key) throws JSONException {
  529 + Object object = this.get(key);
  530 + if (object.equals(Boolean.FALSE)
  531 + || (object instanceof String && ((String) object)
  532 + .equalsIgnoreCase("false"))) {
  533 + return false;
  534 + } else if (object.equals(Boolean.TRUE)
  535 + || (object instanceof String && ((String) object)
  536 + .equalsIgnoreCase("true"))) {
  537 + return true;
  538 + }
  539 + throw new JSONException("JSONObject[" + quote(key)
  540 + + "] is not a Boolean.");
  541 + }
  542 +
  543 + /**
  544 + * Get the BigInteger value associated with a key.
  545 + *
  546 + * @param key
  547 + * A key string.
  548 + * @return The numeric value.
  549 + * @throws JSONException
  550 + * if the key is not found or if the value cannot
  551 + * be converted to BigInteger.
  552 + */
  553 + public BigInteger getBigInteger(String key) throws JSONException {
  554 + Object object = this.get(key);
  555 + try {
  556 + return new BigInteger(object.toString());
  557 + } catch (Exception e) {
  558 + throw new JSONException("JSONObject[" + quote(key)
  559 + + "] could not be converted to BigInteger.", e);
  560 + }
  561 + }
  562 +
  563 + /**
  564 + * Get the BigDecimal value associated with a key.
  565 + *
  566 + * @param key
  567 + * A key string.
  568 + * @return The numeric value.
  569 + * @throws JSONException
  570 + * if the key is not found or if the value
  571 + * cannot be converted to BigDecimal.
  572 + */
  573 + public BigDecimal getBigDecimal(String key) throws JSONException {
  574 + Object object = this.get(key);
  575 + if (object instanceof BigDecimal) {
  576 + return (BigDecimal)object;
  577 + }
  578 + try {
  579 + return new BigDecimal(object.toString());
  580 + } catch (Exception e) {
  581 + throw new JSONException("JSONObject[" + quote(key)
  582 + + "] could not be converted to BigDecimal.", e);
  583 + }
  584 + }
  585 +
  586 + /**
  587 + * Get the double value associated with a key.
  588 + *
  589 + * @param key
  590 + * A key string.
  591 + * @return The numeric value.
  592 + * @throws JSONException
  593 + * if the key is not found or if the value is not a Number
  594 + * object and cannot be converted to a number.
  595 + */
  596 + public double getDouble(String key) throws JSONException {
  597 + Object object = this.get(key);
  598 + try {
  599 + return object instanceof Number ? ((Number) object).doubleValue()
  600 + : Double.parseDouble(object.toString());
  601 + } catch (Exception e) {
  602 + throw new JSONException("JSONObject[" + quote(key)
  603 + + "] is not a number.", e);
  604 + }
  605 + }
  606 +
  607 + /**
  608 + * Get the float value associated with a key.
  609 + *
  610 + * @param key
  611 + * A key string.
  612 + * @return The numeric value.
  613 + * @throws JSONException
  614 + * if the key is not found or if the value is not a Number
  615 + * object and cannot be converted to a number.
  616 + */
  617 + public float getFloat(String key) throws JSONException {
  618 + Object object = this.get(key);
  619 + try {
  620 + return object instanceof Number ? ((Number) object).floatValue()
  621 + : Float.parseFloat(object.toString());
  622 + } catch (Exception e) {
  623 + throw new JSONException("JSONObject[" + quote(key)
  624 + + "] is not a number.", e);
  625 + }
  626 + }
  627 +
  628 + /**
  629 + * Get the Number value associated with a key.
  630 + *
  631 + * @param key
  632 + * A key string.
  633 + * @return The numeric value.
  634 + * @throws JSONException
  635 + * if the key is not found or if the value is not a Number
  636 + * object and cannot be converted to a number.
  637 + */
  638 + public Number getNumber(String key) throws JSONException {
  639 + Object object = this.get(key);
  640 + try {
  641 + if (object instanceof Number) {
  642 + return (Number)object;
  643 + }
  644 + return stringToNumber(object.toString());
  645 + } catch (Exception e) {
  646 + throw new JSONException("JSONObject[" + quote(key)
  647 + + "] is not a number.", e);
  648 + }
  649 + }
  650 +
  651 + /**
  652 + * Get the int value associated with a key.
  653 + *
  654 + * @param key
  655 + * A key string.
  656 + * @return The integer value.
  657 + * @throws JSONException
  658 + * if the key is not found or if the value cannot be converted
  659 + * to an integer.
  660 + */
  661 + public int getInt(String key) throws JSONException {
  662 + Object object = this.get(key);
  663 + try {
  664 + return object instanceof Number ? ((Number) object).intValue()
  665 + : Integer.parseInt((String) object);
  666 + } catch (Exception e) {
  667 + throw new JSONException("JSONObject[" + quote(key)
  668 + + "] is not an int.", e);
  669 + }
  670 + }
  671 +
  672 + /**
  673 + * Get the JSONArray value associated with a key.
  674 + *
  675 + * @param key
  676 + * A key string.
  677 + * @return A JSONArray which is the value.
  678 + * @throws JSONException
  679 + * if the key is not found or if the value is not a JSONArray.
  680 + */
  681 + public JSONArray getJSONArray(String key) throws JSONException {
  682 + Object object = this.get(key);
  683 + if (object instanceof JSONArray) {
  684 + return (JSONArray) object;
  685 + }
  686 + throw new JSONException("JSONObject[" + quote(key)
  687 + + "] is not a JSONArray.");
  688 + }
  689 +
  690 + /**
  691 + * Get the JSONObject value associated with a key.
  692 + *
  693 + * @param key
  694 + * A key string.
  695 + * @return A JSONObject which is the value.
  696 + * @throws JSONException
  697 + * if the key is not found or if the value is not a JSONObject.
  698 + */
  699 + public JSONObject getJSONObject(String key) throws JSONException {
  700 + Object object = this.get(key);
  701 + if (object instanceof JSONObject) {
  702 + return (JSONObject) object;
  703 + }
  704 + throw new JSONException("JSONObject[" + quote(key)
  705 + + "] is not a JSONObject.");
  706 + }
  707 +
  708 + /**
  709 + * Get the long value associated with a key.
  710 + *
  711 + * @param key
  712 + * A key string.
  713 + * @return The long value.
  714 + * @throws JSONException
  715 + * if the key is not found or if the value cannot be converted
  716 + * to a long.
  717 + */
  718 + public long getLong(String key) throws JSONException {
  719 + Object object = this.get(key);
  720 + try {
  721 + return object instanceof Number ? ((Number) object).longValue()
  722 + : Long.parseLong((String) object);
  723 + } catch (Exception e) {
  724 + throw new JSONException("JSONObject[" + quote(key)
  725 + + "] is not a long.", e);
  726 + }
  727 + }
  728 +
  729 + /**
  730 + * Get an array of field names from a JSONObject.
  731 + *
  732 + * @return An array of field names, or null if there are no names.
  733 + */
  734 + public static String[] getNames(JSONObject jo) {
  735 + int length = jo.length();
  736 + if (length == 0) {
  737 + return null;
  738 + }
  739 + return jo.keySet().toArray(new String[length]);
  740 + }
  741 +
  742 + /**
  743 + * Get an array of field names from an Object.
  744 + *
  745 + * @return An array of field names, or null if there are no names.
  746 + */
  747 + public static String[] getNames(Object object) {
  748 + if (object == null) {
  749 + return null;
  750 + }
  751 + Class<?> klass = object.getClass();
  752 + Field[] fields = klass.getFields();
  753 + int length = fields.length;
  754 + if (length == 0) {
  755 + return null;
  756 + }
  757 + String[] names = new String[length];
  758 + for (int i = 0; i < length; i += 1) {
  759 + names[i] = fields[i].getName();
  760 + }
  761 + return names;
  762 + }
  763 +
  764 + /**
  765 + * Get the string associated with a key.
  766 + *
  767 + * @param key
  768 + * A key string.
  769 + * @return A string which is the value.
  770 + * @throws JSONException
  771 + * if there is no string value for the key.
  772 + */
  773 + public String getString(String key) throws JSONException {
  774 + Object object = this.get(key);
  775 + if (object instanceof String) {
  776 + return (String) object;
  777 + }
  778 + throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
  779 + }
  780 +
  781 + /**
  782 + * Determine if the JSONObject contains a specific key.
  783 + *
  784 + * @param key
  785 + * A key string.
  786 + * @return true if the key exists in the JSONObject.
  787 + */
  788 + public boolean has(String key) {
  789 + return this.map.containsKey(key);
  790 + }
  791 +
  792 + /**
  793 + * Increment a property of a JSONObject. If there is no such property,
  794 + * create one with a value of 1. If there is such a property, and if it is
  795 + * an Integer, Long, Double, or Float, then add one to it.
  796 + *
  797 + * @param key
  798 + * A key string.
  799 + * @return this.
  800 + * @throws JSONException
  801 + * If there is already a property with this name that is not an
  802 + * Integer, Long, Double, or Float.
  803 + */
  804 + public JSONObject increment(String key) throws JSONException {
  805 + Object value = this.opt(key);
  806 + if (value == null) {
  807 + this.put(key, 1);
  808 + } else if (value instanceof BigInteger) {
  809 + this.put(key, ((BigInteger)value).add(BigInteger.ONE));
  810 + } else if (value instanceof BigDecimal) {
  811 + this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
  812 + } else if (value instanceof Integer) {
  813 + this.put(key, ((Integer) value).intValue() + 1);
  814 + } else if (value instanceof Long) {
  815 + this.put(key, ((Long) value).longValue() + 1L);
  816 + } else if (value instanceof Double) {
  817 + this.put(key, ((Double) value).doubleValue() + 1.0d);
  818 + } else if (value instanceof Float) {
  819 + this.put(key, ((Float) value).floatValue() + 1.0f);
  820 + } else {
  821 + throw new JSONException("Unable to increment [" + quote(key) + "].");
  822 + }
  823 + return this;
  824 + }
  825 +
  826 + /**
  827 + * Determine if the value associated with the key is null or if there is no
  828 + * value.
  829 + *
  830 + * @param key
  831 + * A key string.
  832 + * @return true if there is no value associated with the key or if the value
  833 + * is the JSONObject.NULL object.
  834 + */
  835 + public boolean isNull(String key) {
  836 + return JSONObject.NULL.equals(this.opt(key));
  837 + }
  838 +
  839 + /**
  840 + * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also
  841 + * modify the JSONObject. Use with caution.
  842 + *
  843 + * @see Set#iterator()
  844 + *
  845 + * @return An iterator of the keys.
  846 + */
  847 + public Iterator<String> keys() {
  848 + return this.keySet().iterator();
  849 + }
  850 +
  851 + /**
  852 + * Get a set of keys of the JSONObject. Modifying this key Set will also modify the
  853 + * JSONObject. Use with caution.
  854 + *
  855 + * @see Map#keySet()
  856 + *
  857 + * @return A keySet.
  858 + */
  859 + public Set<String> keySet() {
  860 + return this.map.keySet();
  861 + }
  862 +
  863 + /**
  864 + * Get a set of entries of the JSONObject. These are raw values and may not
  865 + * match what is returned by the JSONObject get* and opt* functions. Modifying
  866 + * the returned EntrySet or the Entry objects contained therein will modify the
  867 + * backing JSONObject. This does not return a clone or a read-only view.
  868 + *
  869 + * Use with caution.
  870 + *
  871 + * @see Map#entrySet()
  872 + *
  873 + * @return An Entry Set
  874 + */
  875 + protected Set<Entry<String, Object>> entrySet() {
  876 + return this.map.entrySet();
  877 + }
  878 +
  879 + /**
  880 + * Get the number of keys stored in the JSONObject.
  881 + *
  882 + * @return The number of keys in the JSONObject.
  883 + */
  884 + public int length() {
  885 + return this.map.size();
  886 + }
  887 +
  888 + /**
  889 + * Produce a JSONArray containing the names of the elements of this
  890 + * JSONObject.
  891 + *
  892 + * @return A JSONArray containing the key strings, or null if the JSONObject
  893 + * is empty.
  894 + */
  895 + public JSONArray names() {
  896 + if(this.map.isEmpty()) {
  897 + return null;
  898 + }
  899 + return new JSONArray(this.map.keySet());
  900 + }
  901 +
  902 + /**
  903 + * Produce a string from a Number.
  904 + *
  905 + * @param number
  906 + * A Number
  907 + * @return A String.
  908 + * @throws JSONException
  909 + * If n is a non-finite number.
  910 + */
  911 + public static String numberToString(Number number) throws JSONException {
  912 + if (number == null) {
  913 + throw new JSONException("Null pointer");
  914 + }
  915 + testValidity(number);
  916 +
  917 + // Shave off trailing zeros and decimal point, if possible.
  918 +
  919 + String string = number.toString();
  920 + if (string.indexOf('.') > 0 && string.indexOf('e') < 0
  921 + && string.indexOf('E') < 0) {
  922 + while (string.endsWith("0")) {
  923 + string = string.substring(0, string.length() - 1);
  924 + }
  925 + if (string.endsWith(".")) {
  926 + string = string.substring(0, string.length() - 1);
  927 + }
  928 + }
  929 + return string;
  930 + }
  931 +
  932 + /**
  933 + * Get an optional value associated with a key.
  934 + *
  935 + * @param key
  936 + * A key string.
  937 + * @return An object which is the value, or null if there is no value.
  938 + */
  939 + public Object opt(String key) {
  940 + return key == null ? null : this.map.get(key);
  941 + }
  942 +
  943 + /**
  944 + * Get the enum value associated with a key.
  945 + *
  946 + * @param clazz
  947 + * The type of enum to retrieve.
  948 + * @param key
  949 + * A key string.
  950 + * @return The enum value associated with the key or null if not found
  951 + */
  952 + public <E extends Enum<E>> E optEnum(Class<E> clazz, String key) {
  953 + return this.optEnum(clazz, key, null);
  954 + }
  955 +
  956 + /**
  957 + * Get the enum value associated with a key.
  958 + *
  959 + * @param clazz
  960 + * The type of enum to retrieve.
  961 + * @param key
  962 + * A key string.
  963 + * @param defaultValue
  964 + * The default in case the value is not found
  965 + * @return The enum value associated with the key or defaultValue
  966 + * if the value is not found or cannot be assigned to <code>clazz</code>
  967 + */
  968 + public <E extends Enum<E>> E optEnum(Class<E> clazz, String key, E defaultValue) {
  969 + try {
  970 + Object val = this.opt(key);
  971 + if (NULL.equals(val)) {
  972 + return defaultValue;
  973 + }
  974 + if (clazz.isAssignableFrom(val.getClass())) {
  975 + // we just checked it!
  976 + @SuppressWarnings("unchecked")
  977 + E myE = (E) val;
  978 + return myE;
  979 + }
  980 + return Enum.valueOf(clazz, val.toString());
  981 + } catch (IllegalArgumentException e) {
  982 + return defaultValue;
  983 + } catch (NullPointerException e) {
  984 + return defaultValue;
  985 + }
  986 + }
  987 +
  988 + /**
  989 + * Get an optional boolean associated with a key. It returns false if there
  990 + * is no such key, or if the value is not Boolean.TRUE or the String "true".
  991 + *
  992 + * @param key
  993 + * A key string.
  994 + * @return The truth.
  995 + */
  996 + public boolean optBoolean(String key) {
  997 + return this.optBoolean(key, false);
  998 + }
  999 +
  1000 + /**
  1001 + * Get an optional boolean associated with a key. It returns the
  1002 + * defaultValue if there is no such key, or if it is not a Boolean or the
  1003 + * String "true" or "false" (case insensitive).
  1004 + *
  1005 + * @param key
  1006 + * A key string.
  1007 + * @param defaultValue
  1008 + * The default.
  1009 + * @return The truth.
  1010 + */
  1011 + public boolean optBoolean(String key, boolean defaultValue) {
  1012 + Object val = this.opt(key);
  1013 + if (NULL.equals(val)) {
  1014 + return defaultValue;
  1015 + }
  1016 + if (val instanceof Boolean){
  1017 + return ((Boolean) val).booleanValue();
  1018 + }
  1019 + try {
  1020 + // we'll use the get anyway because it does string conversion.
  1021 + return this.getBoolean(key);
  1022 + } catch (Exception e) {
  1023 + return defaultValue;
  1024 + }
  1025 + }
  1026 +
  1027 + /**
  1028 + * Get an optional BigDecimal associated with a key, or the defaultValue if
  1029 + * there is no such key or if its value is not a number. If the value is a
  1030 + * string, an attempt will be made to evaluate it as a number.
  1031 + *
  1032 + * @param key
  1033 + * A key string.
  1034 + * @param defaultValue
  1035 + * The default.
  1036 + * @return An object which is the value.
  1037 + */
  1038 + public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
  1039 + Object val = this.opt(key);
  1040 + if (NULL.equals(val)) {
  1041 + return defaultValue;
  1042 + }
  1043 + if (val instanceof BigDecimal){
  1044 + return (BigDecimal) val;
  1045 + }
  1046 + if (val instanceof BigInteger){
  1047 + return new BigDecimal((BigInteger) val);
  1048 + }
  1049 + if (val instanceof Double || val instanceof Float){
  1050 + return new BigDecimal(((Number) val).doubleValue());
  1051 + }
  1052 + if (val instanceof Long || val instanceof Integer
  1053 + || val instanceof Short || val instanceof Byte){
  1054 + return new BigDecimal(((Number) val).longValue());
  1055 + }
  1056 + // don't check if it's a string in case of unchecked Number subclasses
  1057 + try {
  1058 + return new BigDecimal(val.toString());
  1059 + } catch (Exception e) {
  1060 + return defaultValue;
  1061 + }
  1062 + }
  1063 +
  1064 + /**
  1065 + * Get an optional BigInteger associated with a key, or the defaultValue if
  1066 + * there is no such key or if its value is not a number. If the value is a
  1067 + * string, an attempt will be made to evaluate it as a number.
  1068 + *
  1069 + * @param key
  1070 + * A key string.
  1071 + * @param defaultValue
  1072 + * The default.
  1073 + * @return An object which is the value.
  1074 + */
  1075 + public BigInteger optBigInteger(String key, BigInteger defaultValue) {
  1076 + Object val = this.opt(key);
  1077 + if (NULL.equals(val)) {
  1078 + return defaultValue;
  1079 + }
  1080 + if (val instanceof BigInteger){
  1081 + return (BigInteger) val;
  1082 + }
  1083 + if (val instanceof BigDecimal){
  1084 + return ((BigDecimal) val).toBigInteger();
  1085 + }
  1086 + if (val instanceof Double || val instanceof Float){
  1087 + return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
  1088 + }
  1089 + if (val instanceof Long || val instanceof Integer
  1090 + || val instanceof Short || val instanceof Byte){
  1091 + return BigInteger.valueOf(((Number) val).longValue());
  1092 + }
  1093 + // don't check if it's a string in case of unchecked Number subclasses
  1094 + try {
  1095 + // the other opt functions handle implicit conversions, i.e.
  1096 + // jo.put("double",1.1d);
  1097 + // jo.optInt("double"); -- will return 1, not an error
  1098 + // this conversion to BigDecimal then to BigInteger is to maintain
  1099 + // that type cast support that may truncate the decimal.
  1100 + final String valStr = val.toString();
  1101 + if(isDecimalNotation(valStr)) {
  1102 + return new BigDecimal(valStr).toBigInteger();
  1103 + }
  1104 + return new BigInteger(valStr);
  1105 + } catch (Exception e) {
  1106 + return defaultValue;
  1107 + }
  1108 + }
  1109 +
  1110 + /**
  1111 + * Get an optional double associated with a key, or NaN if there is no such
  1112 + * key or if its value is not a number. If the value is a string, an attempt
  1113 + * will be made to evaluate it as a number.
  1114 + *
  1115 + * @param key
  1116 + * A string which is the key.
  1117 + * @return An object which is the value.
  1118 + */
  1119 + public double optDouble(String key) {
  1120 + return this.optDouble(key, Double.NaN);
  1121 + }
  1122 +
  1123 + /**
  1124 + * Get an optional double associated with a key, or the defaultValue if
  1125 + * there is no such key or if its value is not a number. If the value is a
  1126 + * string, an attempt will be made to evaluate it as a number.
  1127 + *
  1128 + * @param key
  1129 + * A key string.
  1130 + * @param defaultValue
  1131 + * The default.
  1132 + * @return An object which is the value.
  1133 + */
  1134 + public double optDouble(String key, double defaultValue) {
  1135 + Object val = this.opt(key);
  1136 + if (NULL.equals(val)) {
  1137 + return defaultValue;
  1138 + }
  1139 + if (val instanceof Number){
  1140 + return ((Number) val).doubleValue();
  1141 + }
  1142 + if (val instanceof String) {
  1143 + try {
  1144 + return Double.parseDouble((String) val);
  1145 + } catch (Exception e) {
  1146 + return defaultValue;
  1147 + }
  1148 + }
  1149 + return defaultValue;
  1150 + }
  1151 +
  1152 + /**
  1153 + * Get the optional double value associated with an index. NaN is returned
  1154 + * if there is no value for the index, or if the value is not a number and
  1155 + * cannot be converted to a number.
  1156 + *
  1157 + * @param key
  1158 + * A key string.
  1159 + * @return The value.
  1160 + */
  1161 + public float optFloat(String key) {
  1162 + return this.optFloat(key, Float.NaN);
  1163 + }
  1164 +
  1165 + /**
  1166 + * Get the optional double value associated with an index. The defaultValue
  1167 + * is returned if there is no value for the index, or if the value is not a
  1168 + * number and cannot be converted to a number.
  1169 + *
  1170 + * @param key
  1171 + * A key string.
  1172 + * @param defaultValue
  1173 + * The default value.
  1174 + * @return The value.
  1175 + */
  1176 + public float optFloat(String key, float defaultValue) {
  1177 + Object val = this.opt(key);
  1178 + if (JSONObject.NULL.equals(val)) {
  1179 + return defaultValue;
  1180 + }
  1181 + if (val instanceof Number){
  1182 + return ((Number) val).floatValue();
  1183 + }
  1184 + if (val instanceof String) {
  1185 + try {
  1186 + return Float.parseFloat((String) val);
  1187 + } catch (Exception e) {
  1188 + return defaultValue;
  1189 + }
  1190 + }
  1191 + return defaultValue;
  1192 + }
  1193 +
  1194 + /**
  1195 + * Get an optional int value associated with a key, or zero if there is no
  1196 + * such key or if the value is not a number. If the value is a string, an
  1197 + * attempt will be made to evaluate it as a number.
  1198 + *
  1199 + * @param key
  1200 + * A key string.
  1201 + * @return An object which is the value.
  1202 + */
  1203 + public int optInt(String key) {
  1204 + return this.optInt(key, 0);
  1205 + }
  1206 +
  1207 + /**
  1208 + * Get an optional int value associated with a key, or the default if there
  1209 + * is no such key or if the value is not a number. If the value is a string,
  1210 + * an attempt will be made to evaluate it as a number.
  1211 + *
  1212 + * @param key
  1213 + * A key string.
  1214 + * @param defaultValue
  1215 + * The default.
  1216 + * @return An object which is the value.
  1217 + */
  1218 + public int optInt(String key, int defaultValue) {
  1219 + Object val = this.opt(key);
  1220 + if (NULL.equals(val)) {
  1221 + return defaultValue;
  1222 + }
  1223 + if (val instanceof Number){
  1224 + return ((Number) val).intValue();
  1225 + }
  1226 +
  1227 + if (val instanceof String) {
  1228 + try {
  1229 + return new BigDecimal((String) val).intValue();
  1230 + } catch (Exception e) {
  1231 + return defaultValue;
  1232 + }
  1233 + }
  1234 + return defaultValue;
  1235 + }
  1236 +
  1237 + /**
  1238 + * Get an optional JSONArray associated with a key. It returns null if there
  1239 + * is no such key, or if its value is not a JSONArray.
  1240 + *
  1241 + * @param key
  1242 + * A key string.
  1243 + * @return A JSONArray which is the value.
  1244 + */
  1245 + public JSONArray optJSONArray(String key) {
  1246 + Object o = this.opt(key);
  1247 + return o instanceof JSONArray ? (JSONArray) o : null;
  1248 + }
  1249 +
  1250 + /**
  1251 + * Get an optional JSONObject associated with a key. It returns null if
  1252 + * there is no such key, or if its value is not a JSONObject.
  1253 + *
  1254 + * @param key
  1255 + * A key string.
  1256 + * @return A JSONObject which is the value.
  1257 + */
  1258 + public JSONObject optJSONObject(String key) {
  1259 + Object object = this.opt(key);
  1260 + return object instanceof JSONObject ? (JSONObject) object : null;
  1261 + }
  1262 +
  1263 + /**
  1264 + * Get an optional long value associated with a key, or zero if there is no
  1265 + * such key or if the value is not a number. If the value is a string, an
  1266 + * attempt will be made to evaluate it as a number.
  1267 + *
  1268 + * @param key
  1269 + * A key string.
  1270 + * @return An object which is the value.
  1271 + */
  1272 + public long optLong(String key) {
  1273 + return this.optLong(key, 0);
  1274 + }
  1275 +
  1276 + /**
  1277 + * Get an optional long value associated with a key, or the default if there
  1278 + * is no such key or if the value is not a number. If the value is a string,
  1279 + * an attempt will be made to evaluate it as a number.
  1280 + *
  1281 + * @param key
  1282 + * A key string.
  1283 + * @param defaultValue
  1284 + * The default.
  1285 + * @return An object which is the value.
  1286 + */
  1287 + public long optLong(String key, long defaultValue) {
  1288 + Object val = this.opt(key);
  1289 + if (NULL.equals(val)) {
  1290 + return defaultValue;
  1291 + }
  1292 + if (val instanceof Number){
  1293 + return ((Number) val).longValue();
  1294 + }
  1295 +
  1296 + if (val instanceof String) {
  1297 + try {
  1298 + return new BigDecimal((String) val).longValue();
  1299 + } catch (Exception e) {
  1300 + return defaultValue;
  1301 + }
  1302 + }
  1303 + return defaultValue;
  1304 + }
  1305 +
  1306 + /**
  1307 + * Get an optional {@link Number} value associated with a key, or <code>null</code>
  1308 + * if there is no such key or if the value is not a number. If the value is a string,
  1309 + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
  1310 + * would be used in cases where type coercion of the number value is unwanted.
  1311 + *
  1312 + * @param key
  1313 + * A key string.
  1314 + * @return An object which is the value.
  1315 + */
  1316 + public Number optNumber(String key) {
  1317 + return this.optNumber(key, null);
  1318 + }
  1319 +
  1320 + /**
  1321 + * Get an optional {@link Number} value associated with a key, or the default if there
  1322 + * is no such key or if the value is not a number. If the value is a string,
  1323 + * an attempt will be made to evaluate it as a number. This method
  1324 + * would be used in cases where type coercion of the number value is unwanted.
  1325 + *
  1326 + * @param key
  1327 + * A key string.
  1328 + * @param defaultValue
  1329 + * The default.
  1330 + * @return An object which is the value.
  1331 + */
  1332 + public Number optNumber(String key, Number defaultValue) {
  1333 + Object val = this.opt(key);
  1334 + if (NULL.equals(val)) {
  1335 + return defaultValue;
  1336 + }
  1337 + if (val instanceof Number){
  1338 + return (Number) val;
  1339 + }
  1340 +
  1341 + if (val instanceof String) {
  1342 + try {
  1343 + return stringToNumber((String) val);
  1344 + } catch (Exception e) {
  1345 + return defaultValue;
  1346 + }
  1347 + }
  1348 + return defaultValue;
  1349 + }
  1350 +
  1351 + /**
  1352 + * Get an optional string associated with a key. It returns an empty string
  1353 + * if there is no such key. If the value is not a string and is not null,
  1354 + * then it is converted to a string.
  1355 + *
  1356 + * @param key
  1357 + * A key string.
  1358 + * @return A string which is the value.
  1359 + */
  1360 + public String optString(String key) {
  1361 + return this.optString(key, "");
  1362 + }
  1363 +
  1364 + /**
  1365 + * Get an optional string associated with a key. It returns the defaultValue
  1366 + * if there is no such key.
  1367 + *
  1368 + * @param key
  1369 + * A key string.
  1370 + * @param defaultValue
  1371 + * The default.
  1372 + * @return A string which is the value.
  1373 + */
  1374 + public String optString(String key, String defaultValue) {
  1375 + Object object = this.opt(key);
  1376 + return NULL.equals(object) ? defaultValue : object.toString();
  1377 + }
  1378 +
  1379 + /**
  1380 + * Populates the internal map of the JSONObject with the bean properties.
  1381 + * The bean can not be recursive.
  1382 + *
  1383 + * @see JSONObject#JSONObject(Object)
  1384 + *
  1385 + * @param bean
  1386 + * the bean
  1387 + */
  1388 + private void populateMap(Object bean) {
  1389 + Class<?> klass = bean.getClass();
  1390 +
  1391 +// If klass is a System class then set includeSuperClass to false.
  1392 +
  1393 + boolean includeSuperClass = klass.getClassLoader() != null;
  1394 +
  1395 + Method[] methods = includeSuperClass ? klass.getMethods() : klass
  1396 + .getDeclaredMethods();
  1397 + for (final Method method : methods) {
  1398 + final int modifiers = method.getModifiers();
  1399 + if (Modifier.isPublic(modifiers)
  1400 + && !Modifier.isStatic(modifiers)
  1401 + && method.getParameterTypes().length == 0
  1402 + && !method.isBridge()
  1403 + && method.getReturnType() != Void.TYPE ) {
  1404 + final String name = method.getName();
  1405 + String key;
  1406 + if (name.startsWith("get")) {
  1407 + if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
  1408 + continue;
  1409 + }
  1410 + key = name.substring(3);
  1411 + } else if (name.startsWith("is")) {
  1412 + key = name.substring(2);
  1413 + } else {
  1414 + continue;
  1415 + }
  1416 + if (key.length() > 0
  1417 + && Character.isUpperCase(key.charAt(0))) {
  1418 + if (key.length() == 1) {
  1419 + key = key.toLowerCase(Locale.ROOT);
  1420 + } else if (!Character.isUpperCase(key.charAt(1))) {
  1421 + key = key.substring(0, 1).toLowerCase(Locale.ROOT)
  1422 + + key.substring(1);
  1423 + }
  1424 +
  1425 + try {
  1426 + final Object result = method.invoke(bean);
  1427 + if (result != null) {
  1428 + this.map.put(key, wrap(result));
  1429 + // we don't use the result anywhere outside of wrap
  1430 + // if it's a resource we should be sure to close it after calling toString
  1431 + if(result instanceof Closeable) {
  1432 + try {
  1433 + ((Closeable)result).close();
  1434 + } catch (IOException ignore) {
  1435 + }
  1436 + }
  1437 + }
  1438 + } catch (IllegalAccessException ignore) {
  1439 + } catch (IllegalArgumentException ignore) {
  1440 + } catch (InvocationTargetException ignore) {
  1441 + }
  1442 + }
  1443 + }
  1444 + }
  1445 + }
  1446 +
  1447 + /**
  1448 + * Put a key/boolean pair in the JSONObject.
  1449 + *
  1450 + * @param key
  1451 + * A key string.
  1452 + * @param value
  1453 + * A boolean which is the value.
  1454 + * @return this.
  1455 + * @throws JSONException
  1456 + * If the key is null.
  1457 + */
  1458 + public JSONObject put(String key, boolean value) throws JSONException {
  1459 + this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
  1460 + return this;
  1461 + }
  1462 +
  1463 + /**
  1464 + * Put a key/value pair in the JSONObject, where the value will be a
  1465 + * JSONArray which is produced from a Collection.
  1466 + *
  1467 + * @param key
  1468 + * A key string.
  1469 + * @param value
  1470 + * A Collection value.
  1471 + * @return this.
  1472 + * @throws JSONException
  1473 + */
  1474 + public JSONObject put(String key, Collection<?> value) throws JSONException {
  1475 + this.put(key, new JSONArray(value));
  1476 + return this;
  1477 + }
  1478 +
  1479 + /**
  1480 + * Put a key/double pair in the JSONObject.
  1481 + *
  1482 + * @param key
  1483 + * A key string.
  1484 + * @param value
  1485 + * A double which is the value.
  1486 + * @return this.
  1487 + * @throws JSONException
  1488 + * If the key is null or if the number is invalid.
  1489 + */
  1490 + public JSONObject put(String key, double value) throws JSONException {
  1491 + this.put(key, Double.valueOf(value));
  1492 + return this;
  1493 + }
  1494 +
  1495 + /**
  1496 + * Put a key/float pair in the JSONObject.
  1497 + *
  1498 + * @param key
  1499 + * A key string.
  1500 + * @param value
  1501 + * A float which is the value.
  1502 + * @return this.
  1503 + * @throws JSONException
  1504 + * If the key is null or if the number is invalid.
  1505 + */
  1506 + public JSONObject put(String key, float value) throws JSONException {
  1507 + this.put(key, Float.valueOf(value));
  1508 + return this;
  1509 + }
  1510 +
  1511 + /**
  1512 + * Put a key/int pair in the JSONObject.
  1513 + *
  1514 + * @param key
  1515 + * A key string.
  1516 + * @param value
  1517 + * An int which is the value.
  1518 + * @return this.
  1519 + * @throws JSONException
  1520 + * If the key is null.
  1521 + */
  1522 + public JSONObject put(String key, int value) throws JSONException {
  1523 + this.put(key, Integer.valueOf(value));
  1524 + return this;
  1525 + }
  1526 +
  1527 + /**
  1528 + * Put a key/long pair in the JSONObject.
  1529 + *
  1530 + * @param key
  1531 + * A key string.
  1532 + * @param value
  1533 + * A long which is the value.
  1534 + * @return this.
  1535 + * @throws JSONException
  1536 + * If the key is null.
  1537 + */
  1538 + public JSONObject put(String key, long value) throws JSONException {
  1539 + this.put(key, Long.valueOf(value));
  1540 + return this;
  1541 + }
  1542 +
  1543 + /**
  1544 + * Put a key/value pair in the JSONObject, where the value will be a
  1545 + * JSONObject which is produced from a Map.
  1546 + *
  1547 + * @param key
  1548 + * A key string.
  1549 + * @param value
  1550 + * A Map value.
  1551 + * @return this.
  1552 + * @throws JSONException
  1553 + */
  1554 + public JSONObject put(String key, Map<?, ?> value) throws JSONException {
  1555 + this.put(key, new JSONObject(value));
  1556 + return this;
  1557 + }
  1558 +
  1559 + /**
  1560 + * Put a key/value pair in the JSONObject. If the value is null, then the
  1561 + * key will be removed from the JSONObject if it is present.
  1562 + *
  1563 + * @param key
  1564 + * A key string.
  1565 + * @param value
  1566 + * An object which is the value. It should be of one of these
  1567 + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
  1568 + * String, or the JSONObject.NULL object.
  1569 + * @return this.
  1570 + * @throws JSONException
  1571 + * If the value is non-finite number or if the key is null.
  1572 + */
  1573 + public JSONObject put(String key, Object value) throws JSONException {
  1574 + if (key == null) {
  1575 + throw new NullPointerException("Null key.");
  1576 + }
  1577 + if (value != null) {
  1578 + testValidity(value);
  1579 + this.map.put(key, value);
  1580 + } else {
  1581 + this.remove(key);
  1582 + }
  1583 + return this;
  1584 + }
  1585 +
  1586 + /**
  1587 + * Put a key/value pair in the JSONObject, but only if the key and the value
  1588 + * are both non-null, and only if there is not already a member with that
  1589 + * name.
  1590 + *
  1591 + * @param key string
  1592 + * @param value object
  1593 + * @return this.
  1594 + * @throws JSONException
  1595 + * if the key is a duplicate
  1596 + */
  1597 + public JSONObject putOnce(String key, Object value) throws JSONException {
  1598 + if (key != null && value != null) {
  1599 + if (this.opt(key) != null) {
  1600 + throw new JSONException("Duplicate key \"" + key + "\"");
  1601 + }
  1602 + this.put(key, value);
  1603 + }
  1604 + return this;
  1605 + }
  1606 +
  1607 + /**
  1608 + * Put a key/value pair in the JSONObject, but only if the key and the value
  1609 + * are both non-null.
  1610 + *
  1611 + * @param key
  1612 + * A key string.
  1613 + * @param value
  1614 + * An object which is the value. It should be of one of these
  1615 + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
  1616 + * String, or the JSONObject.NULL object.
  1617 + * @return this.
  1618 + * @throws JSONException
  1619 + * If the value is a non-finite number.
  1620 + */
  1621 + public JSONObject putOpt(String key, Object value) throws JSONException {
  1622 + if (key != null && value != null) {
  1623 + this.put(key, value);
  1624 + }
  1625 + return this;
  1626 + }
  1627 +
  1628 + /**
  1629 + * Creates a JSONPointer using an initialization string and tries to
  1630 + * match it to an item within this JSONObject. For example, given a
  1631 + * JSONObject initialized with this document:
  1632 + * <pre>
  1633 + * {
  1634 + * "a":{"b":"c"}
  1635 + * }
  1636 + * </pre>
  1637 + * and this JSONPointer string:
  1638 + * <pre>
  1639 + * "/a/b"
  1640 + * </pre>
  1641 + * Then this method will return the String "c".
  1642 + * A JSONPointerException may be thrown from code called by this method.
  1643 + *
  1644 + * @param jsonPointer string that can be used to create a JSONPointer
  1645 + * @return the item matched by the JSONPointer, otherwise null
  1646 + */
  1647 + public Object query(String jsonPointer) {
  1648 + return query(new JSONPointer(jsonPointer));
  1649 + }
  1650 + /**
  1651 + * Uses a user initialized JSONPointer and tries to
  1652 + * match it to an item within this JSONObject. For example, given a
  1653 + * JSONObject initialized with this document:
  1654 + * <pre>
  1655 + * {
  1656 + * "a":{"b":"c"}
  1657 + * }
  1658 + * </pre>
  1659 + * and this JSONPointer:
  1660 + * <pre>
  1661 + * "/a/b"
  1662 + * </pre>
  1663 + * Then this method will return the String "c".
  1664 + * A JSONPointerException may be thrown from code called by this method.
  1665 + *
  1666 + * @param jsonPointer string that can be used to create a JSONPointer
  1667 + * @return the item matched by the JSONPointer, otherwise null
  1668 + */
  1669 + public Object query(JSONPointer jsonPointer) {
  1670 + return jsonPointer.queryFrom(this);
  1671 + }
  1672 +
  1673 + /**
  1674 + * Queries and returns a value from this object using {@code jsonPointer}, or
  1675 + * returns null if the query fails due to a missing key.
  1676 + *
  1677 + * @param jsonPointer the string representation of the JSON pointer
  1678 + * @return the queried value or {@code null}
  1679 + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
  1680 + */
  1681 + public Object optQuery(String jsonPointer) {
  1682 + return optQuery(new JSONPointer(jsonPointer));
  1683 + }
  1684 +
  1685 + /**
  1686 + * Queries and returns a value from this object using {@code jsonPointer}, or
  1687 + * returns null if the query fails due to a missing key.
  1688 + *
  1689 + * @param jsonPointer The JSON pointer
  1690 + * @return the queried value or {@code null}
  1691 + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
  1692 + */
  1693 + public Object optQuery(JSONPointer jsonPointer) {
  1694 + try {
  1695 + return jsonPointer.queryFrom(this);
  1696 + } catch (JSONPointerException e) {
  1697 + return null;
  1698 + }
  1699 + }
  1700 +
  1701 + /**
  1702 + * Produce a string in double quotes with backslash sequences in all the
  1703 + * right places. A backslash will be inserted within </, producing <\/,
  1704 + * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
  1705 + * contain a control character or an unescaped quote or backslash.
  1706 + *
  1707 + * @param string
  1708 + * A String
  1709 + * @return A String correctly formatted for insertion in a JSON text.
  1710 + */
  1711 + public static String quote(String string) {
  1712 + StringWriter sw = new StringWriter();
  1713 + synchronized (sw.getBuffer()) {
  1714 + try {
  1715 + return quote(string, sw).toString();
  1716 + } catch (IOException ignored) {
  1717 + // will never happen - we are writing to a string writer
  1718 + return "";
  1719 + }
  1720 + }
  1721 + }
  1722 +
  1723 + public static Writer quote(String string, Writer w) throws IOException {
  1724 + if (string == null || string.length() == 0) {
  1725 + w.write("\"\"");
  1726 + return w;
  1727 + }
  1728 +
  1729 + char b;
  1730 + char c = 0;
  1731 + String hhhh;
  1732 + int i;
  1733 + int len = string.length();
  1734 +
  1735 + w.write('"');
  1736 + for (i = 0; i < len; i += 1) {
  1737 + b = c;
  1738 + c = string.charAt(i);
  1739 + switch (c) {
  1740 + case '\\':
  1741 + case '"':
  1742 + w.write('\\');
  1743 + w.write(c);
  1744 + break;
  1745 + case '/':
  1746 + if (b == '<') {
  1747 + w.write('\\');
  1748 + }
  1749 + w.write(c);
  1750 + break;
  1751 + case '\b':
  1752 + w.write("\\b");
  1753 + break;
  1754 + case '\t':
  1755 + w.write("\\t");
  1756 + break;
  1757 + case '\n':
  1758 + w.write("\\n");
  1759 + break;
  1760 + case '\f':
  1761 + w.write("\\f");
  1762 + break;
  1763 + case '\r':
  1764 + w.write("\\r");
  1765 + break;
  1766 + default:
  1767 + if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
  1768 + || (c >= '\u2000' && c < '\u2100')) {
  1769 + w.write("\\u");
  1770 + hhhh = Integer.toHexString(c);
  1771 + w.write("0000", 0, 4 - hhhh.length());
  1772 + w.write(hhhh);
  1773 + } else {
  1774 + w.write(c);
  1775 + }
  1776 + }
  1777 + }
  1778 + w.write('"');
  1779 + return w;
  1780 + }
  1781 +
  1782 + /**
  1783 + * Remove a name and its value, if present.
  1784 + *
  1785 + * @param key
  1786 + * The name to be removed.
  1787 + * @return The value that was associated with the name, or null if there was
  1788 + * no value.
  1789 + */
  1790 + public Object remove(String key) {
  1791 + return this.map.remove(key);
  1792 + }
  1793 +
  1794 + /**
  1795 + * Determine if two JSONObjects are similar.
  1796 + * They must contain the same set of names which must be associated with
  1797 + * similar values.
  1798 + *
  1799 + * @param other The other JSONObject
  1800 + * @return true if they are equal
  1801 + */
  1802 + public boolean similar(Object other) {
  1803 + try {
  1804 + if (!(other instanceof JSONObject)) {
  1805 + return false;
  1806 + }
  1807 + if (!this.keySet().equals(((JSONObject)other).keySet())) {
  1808 + return false;
  1809 + }
  1810 + for (final Entry<String,?> entry : this.entrySet()) {
  1811 + String name = entry.getKey();
  1812 + Object valueThis = entry.getValue();
  1813 + Object valueOther = ((JSONObject)other).get(name);
  1814 + if(valueThis == valueOther) {
  1815 + continue;
  1816 + }
  1817 + if(valueThis == null) {
  1818 + return false;
  1819 + }
  1820 + if (valueThis instanceof JSONObject) {
  1821 + if (!((JSONObject)valueThis).similar(valueOther)) {
  1822 + return false;
  1823 + }
  1824 + } else if (valueThis instanceof JSONArray) {
  1825 + if (!((JSONArray)valueThis).similar(valueOther)) {
  1826 + return false;
  1827 + }
  1828 + } else if (!valueThis.equals(valueOther)) {
  1829 + return false;
  1830 + }
  1831 + }
  1832 + return true;
  1833 + } catch (Throwable exception) {
  1834 + return false;
  1835 + }
  1836 + }
  1837 +
  1838 + /**
  1839 + * Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
  1840 + *
  1841 + * @param val value to test
  1842 + * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
  1843 + */
  1844 + protected static boolean isDecimalNotation(final String val) {
  1845 + return val.indexOf('.') > -1 || val.indexOf('e') > -1
  1846 + || val.indexOf('E') > -1 || "-0".equals(val);
  1847 + }
  1848 +
  1849 + /**
  1850 + * Converts a string to a number using the narrowest possible type. Possible
  1851 + * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
  1852 + * When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
  1853 + *
  1854 + * @param val value to convert
  1855 + * @return Number representation of the value.
  1856 + * @throws NumberFormatException thrown if the value is not a valid number. A public
  1857 + * caller should catch this and wrap it in a {@link JSONException} if applicable.
  1858 + */
  1859 + protected static Number stringToNumber(final String val) throws NumberFormatException {
  1860 + char initial = val.charAt(0);
  1861 + if ((initial >= '0' && initial <= '9') || initial == '-') {
  1862 + // decimal representation
  1863 + if (isDecimalNotation(val)) {
  1864 + // quick dirty way to see if we need a BigDecimal instead of a Double
  1865 + // this only handles some cases of overflow or underflow
  1866 + if (val.length()>14) {
  1867 + return new BigDecimal(val);
  1868 + }
  1869 + final Double d = Double.valueOf(val);
  1870 + if (d.isInfinite() || d.isNaN()) {
  1871 + // if we can't parse it as a double, go up to BigDecimal
  1872 + // this is probably due to underflow like 4.32e-678
  1873 + // or overflow like 4.65e5324. The size of the string is small
  1874 + // but can't be held in a Double.
  1875 + return new BigDecimal(val);
  1876 + }
  1877 + return d;
  1878 + }
  1879 + // integer representation.
  1880 + // This will narrow any values to the smallest reasonable Object representation
  1881 + // (Integer, Long, or BigInteger)
  1882 +
  1883 + // string version
  1884 + // The compare string length method reduces GC,
  1885 + // but leads to smaller integers being placed in larger wrappers even though not
  1886 + // needed. i.e. 1,000,000,000 -> Long even though it's an Integer
  1887 + // 1,000,000,000,000,000,000 -> BigInteger even though it's a Long
  1888 + //if(val.length()<=9){
  1889 + // return Integer.valueOf(val);
  1890 + //}
  1891 + //if(val.length()<=18){
  1892 + // return Long.valueOf(val);
  1893 + //}
  1894 + //return new BigInteger(val);
  1895 +
  1896 + // BigInteger version: We use a similar bitLenth compare as
  1897 + // BigInteger#intValueExact uses. Increases GC, but objects hold
  1898 + // only what they need. i.e. Less runtime overhead if the value is
  1899 + // long lived. Which is the better tradeoff? This is closer to what's
  1900 + // in stringToValue.
  1901 + BigInteger bi = new BigInteger(val);
  1902 + if(bi.bitLength()<=31){
  1903 + return Integer.valueOf(bi.intValue());
  1904 + }
  1905 + if(bi.bitLength()<=63){
  1906 + return Long.valueOf(bi.longValue());
  1907 + }
  1908 + return bi;
  1909 + }
  1910 + throw new NumberFormatException("val ["+val+"] is not a valid number.");
  1911 + }
  1912 +
  1913 + /**
  1914 + * Try to convert a string into a number, boolean, or null. If the string
  1915 + * can't be converted, return the string.
  1916 + *
  1917 + * @param string
  1918 + * A String.
  1919 + * @return A simple JSON value.
  1920 + */
  1921 + // Changes to this method must be copied to the corresponding method in
  1922 + // the XML class to keep full support for Android
  1923 + public static Object stringToValue(String string) {
  1924 + if (string.equals("")) {
  1925 + return string;
  1926 + }
  1927 + if (string.equalsIgnoreCase("true")) {
  1928 + return Boolean.TRUE;
  1929 + }
  1930 + if (string.equalsIgnoreCase("false")) {
  1931 + return Boolean.FALSE;
  1932 + }
  1933 + if (string.equalsIgnoreCase("null")) {
  1934 + return JSONObject.NULL;
  1935 + }
  1936 +
  1937 + /*
  1938 + * If it might be a number, try converting it. If a number cannot be
  1939 + * produced, then the value will just be a string.
  1940 + */
  1941 +
  1942 + char initial = string.charAt(0);
  1943 + if ((initial >= '0' && initial <= '9') || initial == '-') {
  1944 + try {
  1945 + // if we want full Big Number support this block can be replaced with:
  1946 + // return stringToNumber(string);
  1947 + if (isDecimalNotation(string)) {
  1948 + Double d = Double.valueOf(string);
  1949 + if (!d.isInfinite() && !d.isNaN()) {
  1950 + return d;
  1951 + }
  1952 + } else {
  1953 + Long myLong = Long.valueOf(string);
  1954 + if (string.equals(myLong.toString())) {
  1955 + if (myLong.longValue() == myLong.intValue()) {
  1956 + return Integer.valueOf(myLong.intValue());
  1957 + }
  1958 + return myLong;
  1959 + }
  1960 + }
  1961 + } catch (Exception ignore) {
  1962 + }
  1963 + }
  1964 + return string;
  1965 + }
  1966 +
  1967 + /**
  1968 + * Throw an exception if the object is a NaN or infinite number.
  1969 + *
  1970 + * @param o
  1971 + * The object to test.
  1972 + * @throws JSONException
  1973 + * If o is a non-finite number.
  1974 + */
  1975 + public static void testValidity(Object o) throws JSONException {
  1976 + if (o != null) {
  1977 + if (o instanceof Double) {
  1978 + if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
  1979 + throw new JSONException(
  1980 + "JSON does not allow non-finite numbers.");
  1981 + }
  1982 + } else if (o instanceof Float) {
  1983 + if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
  1984 + throw new JSONException(
  1985 + "JSON does not allow non-finite numbers.");
  1986 + }
  1987 + }
  1988 + }
  1989 + }
  1990 +
  1991 + /**
  1992 + * Produce a JSONArray containing the values of the members of this
  1993 + * JSONObject.
  1994 + *
  1995 + * @param names
  1996 + * A JSONArray containing a list of key strings. This determines
  1997 + * the sequence of the values in the result.
  1998 + * @return A JSONArray of values.
  1999 + * @throws JSONException
  2000 + * If any of the values are non-finite numbers.
  2001 + */
  2002 + public JSONArray toJSONArray(JSONArray names) throws JSONException {
  2003 + if (names == null || names.length() == 0) {
  2004 + return null;
  2005 + }
  2006 + JSONArray ja = new JSONArray();
  2007 + for (int i = 0; i < names.length(); i += 1) {
  2008 + ja.put(this.opt(names.getString(i)));
  2009 + }
  2010 + return ja;
  2011 + }
  2012 +
  2013 + /**
  2014 + * Make a JSON text of this JSONObject. For compactness, no whitespace is
  2015 + * added. If this would not result in a syntactically correct JSON text,
  2016 + * then null will be returned instead.
  2017 + * <p><b>
  2018 + * Warning: This method assumes that the data structure is acyclical.
  2019 + * </b>
  2020 + *
  2021 + * @return a printable, displayable, portable, transmittable representation
  2022 + * of the object, beginning with <code>{</code>&nbsp;<small>(left
  2023 + * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
  2024 + * brace)</small>.
  2025 + */
  2026 + @Override
  2027 + public String toString() {
  2028 + try {
  2029 + return this.toString(0);
  2030 + } catch (Exception e) {
  2031 + return null;
  2032 + }
  2033 + }
  2034 +
  2035 + /**
  2036 + * Make a pretty-printed JSON text of this JSONObject.
  2037 + *
  2038 + * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
  2039 + * has only one key, then the object will be output on a single line:
  2040 + * <pre>{@code {"key": 1}}</pre>
  2041 + *
  2042 + * <p>If an object has 2 or more keys, then it will be output across
  2043 + * multiple lines: <code><pre>{
  2044 + * "key1": 1,
  2045 + * "key2": "value 2",
  2046 + * "key3": 3
  2047 + * }</pre></code>
  2048 + * <p><b>
  2049 + * Warning: This method assumes that the data structure is acyclical.
  2050 + * </b>
  2051 + *
  2052 + * @param indentFactor
  2053 + * The number of spaces to add to each level of indentation.
  2054 + * @return a printable, displayable, portable, transmittable representation
  2055 + * of the object, beginning with <code>{</code>&nbsp;<small>(left
  2056 + * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
  2057 + * brace)</small>.
  2058 + * @throws JSONException
  2059 + * If the object contains an invalid number.
  2060 + */
  2061 + public String toString(int indentFactor) throws JSONException {
  2062 + StringWriter w = new StringWriter();
  2063 + synchronized (w.getBuffer()) {
  2064 + return this.write(w, indentFactor, 0).toString();
  2065 + }
  2066 + }
  2067 +
  2068 + /**
  2069 + * Make a JSON text of an Object value. If the object has an
  2070 + * value.toJSONString() method, then that method will be used to produce the
  2071 + * JSON text. The method is required to produce a strictly conforming text.
  2072 + * If the object does not contain a toJSONString method (which is the most
  2073 + * common case), then a text will be produced by other means. If the value
  2074 + * is an array or Collection, then a JSONArray will be made from it and its
  2075 + * toJSONString method will be called. If the value is a MAP, then a
  2076 + * JSONObject will be made from it and its toJSONString method will be
  2077 + * called. Otherwise, the value's toString method will be called, and the
  2078 + * result will be quoted.
  2079 + *
  2080 + * <p>
  2081 + * Warning: This method assumes that the data structure is acyclical.
  2082 + *
  2083 + * @param value
  2084 + * The value to be serialized.
  2085 + * @return a printable, displayable, transmittable representation of the
  2086 + * object, beginning with <code>{</code>&nbsp;<small>(left
  2087 + * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
  2088 + * brace)</small>.
  2089 + * @throws JSONException
  2090 + * If the value is or contains an invalid number.
  2091 + */
  2092 + public static String valueToString(Object value) throws JSONException {
  2093 + // moves the implementation to JSONWriter as:
  2094 + // 1. It makes more sense to be part of the writer class
  2095 + // 2. For Android support this method is not available. By implementing it in the Writer
  2096 + // Android users can use the writer with the built in Android JSONObject implementation.
  2097 + return JSONWriter.valueToString(value);
  2098 + }
  2099 +
  2100 + /**
  2101 + * Wrap an object, if necessary. If the object is null, return the NULL
  2102 + * object. If it is an array or collection, wrap it in a JSONArray. If it is
  2103 + * a map, wrap it in a JSONObject. If it is a standard property (Double,
  2104 + * String, et al) then it is already wrapped. Otherwise, if it comes from
  2105 + * one of the java packages, turn it into a string. And if it doesn't, try
  2106 + * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
  2107 + *
  2108 + * @param object
  2109 + * The object to wrap
  2110 + * @return The wrapped value
  2111 + */
  2112 + public static Object wrap(Object object) {
  2113 + try {
  2114 + if (object == null) {
  2115 + return NULL;
  2116 + }
  2117 + if (object instanceof JSONObject || object instanceof JSONArray
  2118 + || NULL.equals(object) || object instanceof JSONString
  2119 + || object instanceof Byte || object instanceof Character
  2120 + || object instanceof Short || object instanceof Integer
  2121 + || object instanceof Long || object instanceof Boolean
  2122 + || object instanceof Float || object instanceof Double
  2123 + || object instanceof String || object instanceof BigInteger
  2124 + || object instanceof BigDecimal || object instanceof Enum) {
  2125 + return object;
  2126 + }
  2127 +
  2128 + if (object instanceof Collection) {
  2129 + Collection<?> coll = (Collection<?>) object;
  2130 + return new JSONArray(coll);
  2131 + }
  2132 + if (object.getClass().isArray()) {
  2133 + return new JSONArray(object);
  2134 + }
  2135 + if (object instanceof Map) {
  2136 + Map<?, ?> map = (Map<?, ?>) object;
  2137 + return new JSONObject(map);
  2138 + }
  2139 + Package objectPackage = object.getClass().getPackage();
  2140 + String objectPackageName = objectPackage != null ? objectPackage
  2141 + .getName() : "";
  2142 + if (objectPackageName.startsWith("java.")
  2143 + || objectPackageName.startsWith("javax.")
  2144 + || object.getClass().getClassLoader() == null) {
  2145 + return object.toString();
  2146 + }
  2147 + return new JSONObject(object);
  2148 + } catch (Exception exception) {
  2149 + return null;
  2150 + }
  2151 + }
  2152 +
  2153 + /**
  2154 + * Write the contents of the JSONObject as JSON text to a writer. For
  2155 + * compactness, no whitespace is added.
  2156 + * <p><b>
  2157 + * Warning: This method assumes that the data structure is acyclical.
  2158 + * </b>
  2159 + *
  2160 + * @return The writer.
  2161 + * @throws JSONException
  2162 + */
  2163 + public Writer write(Writer writer) throws JSONException {
  2164 + return this.write(writer, 0, 0);
  2165 + }
  2166 +
  2167 + static final Writer writeValue(Writer writer, Object value,
  2168 + int indentFactor, int indent) throws JSONException, IOException {
  2169 + if (value == null || value.equals(null)) {
  2170 + writer.write("null");
  2171 + } else if (value instanceof JSONString) {
  2172 + Object o;
  2173 + try {
  2174 + o = ((JSONString) value).toJSONString();
  2175 + } catch (Exception e) {
  2176 + throw new JSONException(e);
  2177 + }
  2178 + writer.write(o != null ? o.toString() : quote(value.toString()));
  2179 + } else if (value instanceof Number) {
  2180 + // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
  2181 + final String numberAsString = numberToString((Number) value);
  2182 + try {
  2183 + // Use the BigDecimal constructor for its parser to validate the format.
  2184 + @SuppressWarnings("unused")
  2185 + BigDecimal testNum = new BigDecimal(numberAsString);
  2186 + // Close enough to a JSON number that we will use it unquoted
  2187 + writer.write(numberAsString);
  2188 + } catch (NumberFormatException ex){
  2189 + // The Number value is not a valid JSON number.
  2190 + // Instead we will quote it as a string
  2191 + quote(numberAsString, writer);
  2192 + }
  2193 + } else if (value instanceof Boolean) {
  2194 + writer.write(value.toString());
  2195 + } else if (value instanceof Enum<?>) {
  2196 + writer.write(quote(((Enum<?>)value).name()));
  2197 + } else if (value instanceof JSONObject) {
  2198 + ((JSONObject) value).write(writer, indentFactor, indent);
  2199 + } else if (value instanceof JSONArray) {
  2200 + ((JSONArray) value).write(writer, indentFactor, indent);
  2201 + } else if (value instanceof Map) {
  2202 + Map<?, ?> map = (Map<?, ?>) value;
  2203 + new JSONObject(map).write(writer, indentFactor, indent);
  2204 + } else if (value instanceof Collection) {
  2205 + Collection<?> coll = (Collection<?>) value;
  2206 + new JSONArray(coll).write(writer, indentFactor, indent);
  2207 + } else if (value.getClass().isArray()) {
  2208 + new JSONArray(value).write(writer, indentFactor, indent);
  2209 + } else {
  2210 + quote(value.toString(), writer);
  2211 + }
  2212 + return writer;
  2213 + }
  2214 +
  2215 + static final void indent(Writer writer, int indent) throws IOException {
  2216 + for (int i = 0; i < indent; i += 1) {
  2217 + writer.write(' ');
  2218 + }
  2219 + }
  2220 +
  2221 + /**
  2222 + * Write the contents of the JSONObject as JSON text to a writer.
  2223 + *
  2224 + * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
  2225 + * has only one key, then the object will be output on a single line:
  2226 + * <pre>{@code {"key": 1}}</pre>
  2227 + *
  2228 + * <p>If an object has 2 or more keys, then it will be output across
  2229 + * multiple lines: <code><pre>{
  2230 + * "key1": 1,
  2231 + * "key2": "value 2",
  2232 + * "key3": 3
  2233 + * }</pre></code>
  2234 + * <p><b>
  2235 + * Warning: This method assumes that the data structure is acyclical.
  2236 + * </b>
  2237 + *
  2238 + * @param writer
  2239 + * Writes the serialized JSON
  2240 + * @param indentFactor
  2241 + * The number of spaces to add to each level of indentation.
  2242 + * @param indent
  2243 + * The indentation of the top level.
  2244 + * @return The writer.
  2245 + * @throws JSONException
  2246 + */
  2247 + public Writer write(Writer writer, int indentFactor, int indent)
  2248 + throws JSONException {
  2249 + try {
  2250 + boolean commanate = false;
  2251 + final int length = this.length();
  2252 + writer.write('{');
  2253 +
  2254 + if (length == 1) {
  2255 + final Entry<String,?> entry = this.entrySet().iterator().next();
  2256 + final String key = entry.getKey();
  2257 + writer.write(quote(key));
  2258 + writer.write(':');
  2259 + if (indentFactor > 0) {
  2260 + writer.write(' ');
  2261 + }
  2262 + try{
  2263 + writeValue(writer, entry.getValue(), indentFactor, indent);
  2264 + } catch (Exception e) {
  2265 + throw new JSONException("Unable to write JSONObject value for key: " + key, e);
  2266 + }
  2267 + } else if (length != 0) {
  2268 + final int newindent = indent + indentFactor;
  2269 + for (final Entry<String,?> entry : this.entrySet()) {
  2270 + if (commanate) {
  2271 + writer.write(',');
  2272 + }
  2273 + if (indentFactor > 0) {
  2274 + writer.write('\n');
  2275 + }
  2276 + indent(writer, newindent);
  2277 + final String key = entry.getKey();
  2278 + writer.write(quote(key));
  2279 + writer.write(':');
  2280 + if (indentFactor > 0) {
  2281 + writer.write(' ');
  2282 + }
  2283 + try {
  2284 + writeValue(writer, entry.getValue(), indentFactor, newindent);
  2285 + } catch (Exception e) {
  2286 + throw new JSONException("Unable to write JSONObject value for key: " + key, e);
  2287 + }
  2288 + commanate = true;
  2289 + }
  2290 + if (indentFactor > 0) {
  2291 + writer.write('\n');
  2292 + }
  2293 + indent(writer, indent);
  2294 + }
  2295 + writer.write('}');
  2296 + return writer;
  2297 + } catch (IOException exception) {
  2298 + throw new JSONException(exception);
  2299 + }
  2300 + }
  2301 +
  2302 + /**
  2303 + * Returns a java.util.Map containing all of the entries in this object.
  2304 + * If an entry in the object is a JSONArray or JSONObject it will also
  2305 + * be converted.
  2306 + * <p>
  2307 + * Warning: This method assumes that the data structure is acyclical.
  2308 + *
  2309 + * @return a java.util.Map containing the entries of this object
  2310 + */
  2311 + public Map<String, Object> toMap() {
  2312 + Map<String, Object> results = new HashMap<String, Object>();
  2313 + for (Entry<String, Object> entry : this.entrySet()) {
  2314 + Object value;
  2315 + if (entry.getValue() == null || NULL.equals(entry.getValue())) {
  2316 + value = null;
  2317 + } else if (entry.getValue() instanceof JSONObject) {
  2318 + value = ((JSONObject) entry.getValue()).toMap();
  2319 + } else if (entry.getValue() instanceof JSONArray) {
  2320 + value = ((JSONArray) entry.getValue()).toList();
  2321 + } else {
  2322 + value = entry.getValue();
  2323 + }
  2324 + results.put(entry.getKey(), value);
  2325 + }
  2326 + return results;
  2327 + }
  2328 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONPointer.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +import java.io.UnsupportedEncodingException;
  4 +import java.net.URLDecoder;
  5 +import java.net.URLEncoder;
  6 +import java.util.ArrayList;
  7 +import java.util.Collections;
  8 +import java.util.List;
  9 +
  10 +import static java.lang.String.format;
  11 +
  12 +/*
  13 +Copyright (c) 2002 JSON.org
  14 +
  15 +Permission is hereby granted, free of charge, to any person obtaining a copy
  16 +of this software and associated documentation files (the "Software"), to deal
  17 +in the Software without restriction, including without limitation the rights
  18 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19 +copies of the Software, and to permit persons to whom the Software is
  20 +furnished to do so, subject to the following conditions:
  21 +
  22 +The above copyright notice and this permission notice shall be included in all
  23 +copies or substantial portions of the Software.
  24 +
  25 +The Software shall be used for Good, not Evil.
  26 +
  27 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  33 +SOFTWARE.
  34 +*/
  35 +
  36 +/**
  37 + * A JSON Pointer is a simple query language defined for JSON documents by
  38 + * <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a>.
  39 + *
  40 + * In a nutshell, JSONPointer allows the user to navigate into a JSON document
  41 + * using strings, and retrieve targeted objects, like a simple form of XPATH.
  42 + * Path segments are separated by the '/' char, which signifies the root of
  43 + * the document when it appears as the first char of the string. Array
  44 + * elements are navigated using ordinals, counting from 0. JSONPointer strings
  45 + * may be extended to any arbitrary number of segments. If the navigation
  46 + * is successful, the matched item is returned. A matched item may be a
  47 + * JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building
  48 + * fails, an appropriate exception is thrown. If the navigation fails to find
  49 + * a match, a JSONPointerException is thrown.
  50 + *
  51 + * @author JSON.org
  52 + * @version 2016-05-14
  53 + */
  54 +public class JSONPointer {
  55 +
  56 + // used for URL encoding and decoding
  57 + private static final String ENCODING = "utf-8";
  58 +
  59 + /**
  60 + * This class allows the user to build a JSONPointer in steps, using
  61 + * exactly one segment in each step.
  62 + */
  63 + public static class Builder {
  64 +
  65 + // Segments for the eventual JSONPointer string
  66 + private final List<String> refTokens = new ArrayList<String>();
  67 +
  68 + /**
  69 + * Creates a {@code JSONPointer} instance using the tokens previously set using the
  70 + * {@link #append(String)} method calls.
  71 + */
  72 + public JSONPointer build() {
  73 + return new JSONPointer(this.refTokens);
  74 + }
  75 +
  76 + /**
  77 + * Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
  78 + *
  79 + * Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
  80 + * argument of this method MUST NOT be escaped. If you want to query the property called
  81 + * {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
  82 + * need to escape it as {@code "a~0b"}.
  83 + *
  84 + * @param token the new token to be appended to the list
  85 + * @return {@code this}
  86 + * @throws NullPointerException if {@code token} is null
  87 + */
  88 + public Builder append(String token) {
  89 + if (token == null) {
  90 + throw new NullPointerException("token cannot be null");
  91 + }
  92 + this.refTokens.add(token);
  93 + return this;
  94 + }
  95 +
  96 + /**
  97 + * Adds an integer to the reference token list. Although not necessarily, mostly this token will
  98 + * denote an array index.
  99 + *
  100 + * @param arrayIndex the array index to be added to the token list
  101 + * @return {@code this}
  102 + */
  103 + public Builder append(int arrayIndex) {
  104 + this.refTokens.add(String.valueOf(arrayIndex));
  105 + return this;
  106 + }
  107 + }
  108 +
  109 + /**
  110 + * Static factory method for {@link Builder}. Example usage:
  111 + *
  112 + * <pre><code>
  113 + * JSONPointer pointer = JSONPointer.builder()
  114 + * .append("obj")
  115 + * .append("other~key").append("another/key")
  116 + * .append("\"")
  117 + * .append(0)
  118 + * .build();
  119 + * </code></pre>
  120 + *
  121 + * @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
  122 + * {@link Builder#append(String)} calls.
  123 + */
  124 + public static Builder builder() {
  125 + return new Builder();
  126 + }
  127 +
  128 + // Segments for the JSONPointer string
  129 + private final List<String> refTokens;
  130 +
  131 + /**
  132 + * Pre-parses and initializes a new {@code JSONPointer} instance. If you want to
  133 + * evaluate the same JSON Pointer on different JSON documents then it is recommended
  134 + * to keep the {@code JSONPointer} instances due to performance considerations.
  135 + *
  136 + * @param pointer the JSON String or URI Fragment representation of the JSON pointer.
  137 + * @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
  138 + */
  139 + public JSONPointer(final String pointer) {
  140 + if (pointer == null) {
  141 + throw new NullPointerException("pointer cannot be null");
  142 + }
  143 + if (pointer.isEmpty() || pointer.equals("#")) {
  144 + this.refTokens = Collections.emptyList();
  145 + return;
  146 + }
  147 + String refs;
  148 + if (pointer.startsWith("#/")) {
  149 + refs = pointer.substring(2);
  150 + try {
  151 + refs = URLDecoder.decode(refs, ENCODING);
  152 + } catch (UnsupportedEncodingException e) {
  153 + throw new RuntimeException(e);
  154 + }
  155 + } else if (pointer.startsWith("/")) {
  156 + refs = pointer.substring(1);
  157 + } else {
  158 + throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
  159 + }
  160 + this.refTokens = new ArrayList<String>();
  161 + for (String token : refs.split("/")) {
  162 + this.refTokens.add(unescape(token));
  163 + }
  164 + }
  165 +
  166 + public JSONPointer(List<String> refTokens) {
  167 + this.refTokens = new ArrayList<String>(refTokens);
  168 + }
  169 +
  170 + private String unescape(String token) {
  171 + return token.replace("~1", "/").replace("~0", "~")
  172 + .replace("\\\"", "\"")
  173 + .replace("\\\\", "\\");
  174 + }
  175 +
  176 + /**
  177 + * Evaluates this JSON Pointer on the given {@code document}. The {@code document}
  178 + * is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty
  179 + * JSON Pointer ({@code ""}) can be evaluated on any JSON values and in such case the
  180 + * returned value will be {@code document} itself.
  181 + *
  182 + * @param document the JSON document which should be the subject of querying.
  183 + * @return the result of the evaluation
  184 + * @throws JSONPointerException if an error occurs during evaluation
  185 + */
  186 + public Object queryFrom(Object document) throws JSONPointerException {
  187 + if (this.refTokens.isEmpty()) {
  188 + return document;
  189 + }
  190 + Object current = document;
  191 + for (String token : this.refTokens) {
  192 + if (current instanceof JSONObject) {
  193 + current = ((JSONObject) current).opt(unescape(token));
  194 + } else if (current instanceof JSONArray) {
  195 + current = readByIndexToken(current, token);
  196 + } else {
  197 + throw new JSONPointerException(format(
  198 + "value [%s] is not an array or object therefore its key %s cannot be resolved", current,
  199 + token));
  200 + }
  201 + }
  202 + return current;
  203 + }
  204 +
  205 + /**
  206 + * Matches a JSONArray element by ordinal position
  207 + * @param current the JSONArray to be evaluated
  208 + * @param indexToken the array index in string form
  209 + * @return the matched object. If no matching item is found a
  210 + * @throws JSONPointerException is thrown if the index is out of bounds
  211 + */
  212 + private Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
  213 + try {
  214 + int index = Integer.parseInt(indexToken);
  215 + JSONArray currentArr = (JSONArray) current;
  216 + if (index >= currentArr.length()) {
  217 + throw new JSONPointerException(format("index %d is out of bounds - the array has %d elements", index,
  218 + currentArr.length()));
  219 + }
  220 + try {
  221 + return currentArr.get(index);
  222 + } catch (JSONException e) {
  223 + throw new JSONPointerException("Error reading value at index position " + index, e);
  224 + }
  225 + } catch (NumberFormatException e) {
  226 + throw new JSONPointerException(format("%s is not an array index", indexToken), e);
  227 + }
  228 + }
  229 +
  230 + /**
  231 + * Returns a string representing the JSONPointer path value using string
  232 + * representation
  233 + */
  234 + @Override
  235 + public String toString() {
  236 + StringBuilder rval = new StringBuilder("");
  237 + for (String token: this.refTokens) {
  238 + rval.append('/').append(escape(token));
  239 + }
  240 + return rval.toString();
  241 + }
  242 +
  243 + /**
  244 + * Escapes path segment values to an unambiguous form.
  245 + * The escape char to be inserted is '~'. The chars to be escaped
  246 + * are ~, which maps to ~0, and /, which maps to ~1. Backslashes
  247 + * and double quote chars are also escaped.
  248 + * @param token the JSONPointer segment value to be escaped
  249 + * @return the escaped value for the token
  250 + */
  251 + private String escape(String token) {
  252 + return token.replace("~", "~0")
  253 + .replace("/", "~1")
  254 + .replace("\\", "\\\\")
  255 + .replace("\"", "\\\"");
  256 + }
  257 +
  258 + /**
  259 + * Returns a string representing the JSONPointer path value using URI
  260 + * fragment identifier representation
  261 + */
  262 + public String toURIFragment() {
  263 + try {
  264 + StringBuilder rval = new StringBuilder("#");
  265 + for (String token : this.refTokens) {
  266 + rval.append('/').append(URLEncoder.encode(token, ENCODING));
  267 + }
  268 + return rval.toString();
  269 + } catch (UnsupportedEncodingException e) {
  270 + throw new RuntimeException(e);
  271 + }
  272 + }
  273 +
  274 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONPointerException.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +/**
  28 + * The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
  29 + * during evaluating a pointer.
  30 + *
  31 + * @author JSON.org
  32 + * @version 2016-05-13
  33 + */
  34 +public class JSONPointerException extends JSONException {
  35 + private static final long serialVersionUID = 8872944667561856751L;
  36 +
  37 + public JSONPointerException(String message) {
  38 + super(message);
  39 + }
  40 +
  41 + public JSONPointerException(String message, Throwable cause) {
  42 + super(message, cause);
  43 + }
  44 +
  45 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONString.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +/**
  3 + * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
  4 + * method so that a class can change the behavior of
  5 + * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
  6 + * and <code>JSONWriter.value(</code>Object<code>)</code>. The
  7 + * <code>toJSONString</code> method will be used instead of the default behavior
  8 + * of using the Object's <code>toString()</code> method and quoting the result.
  9 + */
  10 +public interface JSONString {
  11 + /**
  12 + * The <code>toJSONString</code> method allows a class to produce its own JSON
  13 + * serialization.
  14 + *
  15 + * @return A strictly syntactically correct JSON text.
  16 + */
  17 + public String toJSONString();
  18 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONStringer.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2006 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +import java.io.StringWriter;
  28 +
  29 +/**
  30 + * JSONStringer provides a quick and convenient way of producing JSON text.
  31 + * The texts produced strictly conform to JSON syntax rules. No whitespace is
  32 + * added, so the results are ready for transmission or storage. Each instance of
  33 + * JSONStringer can produce one JSON text.
  34 + * <p>
  35 + * A JSONStringer instance provides a <code>value</code> method for appending
  36 + * values to the
  37 + * text, and a <code>key</code>
  38 + * method for adding keys before values in objects. There are <code>array</code>
  39 + * and <code>endArray</code> methods that make and bound array values, and
  40 + * <code>object</code> and <code>endObject</code> methods which make and bound
  41 + * object values. All of these methods return the JSONWriter instance,
  42 + * permitting cascade style. For example, <pre>
  43 + * myString = new JSONStringer()
  44 + * .object()
  45 + * .key("JSON")
  46 + * .value("Hello, World!")
  47 + * .endObject()
  48 + * .toString();</pre> which produces the string <pre>
  49 + * {"JSON":"Hello, World!"}</pre>
  50 + * <p>
  51 + * The first method called must be <code>array</code> or <code>object</code>.
  52 + * There are no methods for adding commas or colons. JSONStringer adds them for
  53 + * you. Objects and arrays can be nested up to 20 levels deep.
  54 + * <p>
  55 + * This can sometimes be easier than using a JSONObject to build a string.
  56 + * @author JSON.org
  57 + * @version 2015-12-09
  58 + */
  59 +public class JSONStringer extends JSONWriter {
  60 + /**
  61 + * Make a fresh JSONStringer. It can be used to build one JSON text.
  62 + */
  63 + public JSONStringer() {
  64 + super(new StringWriter());
  65 + }
  66 +
  67 + /**
  68 + * Return the JSON text. This method is used to obtain the product of the
  69 + * JSONStringer instance. It will return <code>null</code> if there was a
  70 + * problem in the construction of the JSON text (such as the calls to
  71 + * <code>array</code> were not properly balanced with calls to
  72 + * <code>endArray</code>).
  73 + * @return The JSON text.
  74 + */
  75 + @Override
  76 + public String toString() {
  77 + return this.mode == 'd' ? this.writer.toString() : null;
  78 + }
  79 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONTokener.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +import java.io.*;
  4 +
  5 +/*
  6 +Copyright (c) 2002 JSON.org
  7 +
  8 +Permission is hereby granted, free of charge, to any person obtaining a copy
  9 +of this software and associated documentation files (the "Software"), to deal
  10 +in the Software without restriction, including without limitation the rights
  11 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 +copies of the Software, and to permit persons to whom the Software is
  13 +furnished to do so, subject to the following conditions:
  14 +
  15 +The above copyright notice and this permission notice shall be included in all
  16 +copies or substantial portions of the Software.
  17 +
  18 +The Software shall be used for Good, not Evil.
  19 +
  20 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  26 +SOFTWARE.
  27 + */
  28 +
  29 +/**
  30 + * A JSONTokener takes a source string and extracts characters and tokens from
  31 + * it. It is used by the JSONObject and JSONArray constructors to parse
  32 + * JSON source strings.
  33 + * @author JSON.org
  34 + * @version 2014-05-03
  35 + */
  36 +public class JSONTokener {
  37 + /** current read character position on the current line. */
  38 + private long character;
  39 + /** flag to indicate if the end of the input has been found. */
  40 + private boolean eof;
  41 + /** current read index of the input. */
  42 + private long index;
  43 + /** current line of the input. */
  44 + private long line;
  45 + /** previous character read from the input. */
  46 + private char previous;
  47 + /** Reader for the input. */
  48 + private final Reader reader;
  49 + /** flag to indicate that a previous character was requested. */
  50 + private boolean usePrevious;
  51 + /** the number of characters read in the previous line. */
  52 + private long characterPreviousLine;
  53 +
  54 +
  55 + /**
  56 + * Construct a JSONTokener from a Reader. The caller must close the Reader.
  57 + *
  58 + * @param reader A reader.
  59 + */
  60 + public JSONTokener(Reader reader) {
  61 + this.reader = reader.markSupported()
  62 + ? reader
  63 + : new BufferedReader(reader);
  64 + this.eof = false;
  65 + this.usePrevious = false;
  66 + this.previous = 0;
  67 + this.index = 0;
  68 + this.character = 1;
  69 + this.characterPreviousLine = 0;
  70 + this.line = 1;
  71 + }
  72 +
  73 +
  74 + /**
  75 + * Construct a JSONTokener from an InputStream. The caller must close the input stream.
  76 + * @param inputStream The source.
  77 + */
  78 + public JSONTokener(InputStream inputStream) {
  79 + this(new InputStreamReader(inputStream));
  80 + }
  81 +
  82 +
  83 + /**
  84 + * Construct a JSONTokener from a string.
  85 + *
  86 + * @param s A source string.
  87 + */
  88 + public JSONTokener(String s) {
  89 + this(new StringReader(s));
  90 + }
  91 +
  92 +
  93 + /**
  94 + * Back up one character. This provides a sort of lookahead capability,
  95 + * so that you can test for a digit or letter before attempting to parse
  96 + * the next number or identifier.
  97 + * @throws JSONException Thrown if trying to step back more than 1 step
  98 + * or if already at the start of the string
  99 + */
  100 + public void back() throws JSONException {
  101 + if (this.usePrevious || this.index <= 0) {
  102 + throw new JSONException("Stepping back two steps is not supported");
  103 + }
  104 + this.decrementIndexes();
  105 + this.usePrevious = true;
  106 + this.eof = false;
  107 + }
  108 +
  109 + /**
  110 + * Decrements the indexes for the {@link #back()} method based on the previous character read.
  111 + */
  112 + private void decrementIndexes() {
  113 + this.index--;
  114 + if(this.previous=='\r' || this.previous == '\n') {
  115 + this.line--;
  116 + this.character=this.characterPreviousLine ;
  117 + } else if(this.character > 0){
  118 + this.character--;
  119 + }
  120 + }
  121 +
  122 + /**
  123 + * Get the hex value of a character (base16).
  124 + * @param c A character between '0' and '9' or between 'A' and 'F' or
  125 + * between 'a' and 'f'.
  126 + * @return An int between 0 and 15, or -1 if c was not a hex digit.
  127 + */
  128 + public static int dehexchar(char c) {
  129 + if (c >= '0' && c <= '9') {
  130 + return c - '0';
  131 + }
  132 + if (c >= 'A' && c <= 'F') {
  133 + return c - ('A' - 10);
  134 + }
  135 + if (c >= 'a' && c <= 'f') {
  136 + return c - ('a' - 10);
  137 + }
  138 + return -1;
  139 + }
  140 +
  141 + /**
  142 + * Checks if the end of the input has been reached.
  143 + *
  144 + * @return true if at the end of the file and we didn't step back
  145 + */
  146 + public boolean end() {
  147 + return this.eof && !this.usePrevious;
  148 + }
  149 +
  150 +
  151 + /**
  152 + * Determine if the source string still contains characters that next()
  153 + * can consume.
  154 + * @return true if not yet at the end of the source.
  155 + * @throws JSONException thrown if there is an error stepping forward
  156 + * or backward while checking for more data.
  157 + */
  158 + public boolean more() throws JSONException {
  159 + if(this.usePrevious) {
  160 + return true;
  161 + }
  162 + try {
  163 + this.reader.mark(1);
  164 + } catch (IOException e) {
  165 + throw new JSONException("Unable to preserve stream position", e);
  166 + }
  167 + try {
  168 + // -1 is EOF, but next() can not consume the null character '\0'
  169 + if(this.reader.read() <= 0) {
  170 + this.eof = true;
  171 + return false;
  172 + }
  173 + this.reader.reset();
  174 + } catch (IOException e) {
  175 + throw new JSONException("Unable to read the next character from the stream", e);
  176 + }
  177 + return true;
  178 + }
  179 +
  180 +
  181 + /**
  182 + * Get the next character in the source string.
  183 + *
  184 + * @return The next character, or 0 if past the end of the source string.
  185 + * @throws JSONException Thrown if there is an error reading the source string.
  186 + */
  187 + public char next() throws JSONException {
  188 + int c;
  189 + if (this.usePrevious) {
  190 + this.usePrevious = false;
  191 + c = this.previous;
  192 + } else {
  193 + try {
  194 + c = this.reader.read();
  195 + } catch (IOException exception) {
  196 + throw new JSONException(exception);
  197 + }
  198 + }
  199 + if (c <= 0) { // End of stream
  200 + this.eof = true;
  201 + return 0;
  202 + }
  203 + this.incrementIndexes(c);
  204 + this.previous = (char) c;
  205 + return this.previous;
  206 + }
  207 +
  208 + /**
  209 + * Increments the internal indexes according to the previous character
  210 + * read and the character passed as the current character.
  211 + * @param c the current character read.
  212 + */
  213 + private void incrementIndexes(int c) {
  214 + if(c > 0) {
  215 + this.index++;
  216 + if(c=='\r') {
  217 + this.line++;
  218 + this.characterPreviousLine = this.character;
  219 + this.character=0;
  220 + }else if (c=='\n') {
  221 + if(this.previous != '\r') {
  222 + this.line++;
  223 + this.characterPreviousLine = this.character;
  224 + }
  225 + this.character=0;
  226 + } else {
  227 + this.character++;
  228 + }
  229 + }
  230 + }
  231 +
  232 + /**
  233 + * Consume the next character, and check that it matches a specified
  234 + * character.
  235 + * @param c The character to match.
  236 + * @return The character.
  237 + * @throws JSONException if the character does not match.
  238 + */
  239 + public char next(char c) throws JSONException {
  240 + char n = this.next();
  241 + if (n != c) {
  242 + if(n > 0) {
  243 + throw this.syntaxError("Expected '" + c + "' and instead saw '" +
  244 + n + "'");
  245 + }
  246 + throw this.syntaxError("Expected '" + c + "' and instead saw ''");
  247 + }
  248 + return n;
  249 + }
  250 +
  251 +
  252 + /**
  253 + * Get the next n characters.
  254 + *
  255 + * @param n The number of characters to take.
  256 + * @return A string of n characters.
  257 + * @throws JSONException
  258 + * Substring bounds error if there are not
  259 + * n characters remaining in the source string.
  260 + */
  261 + public String next(int n) throws JSONException {
  262 + if (n == 0) {
  263 + return "";
  264 + }
  265 +
  266 + char[] chars = new char[n];
  267 + int pos = 0;
  268 +
  269 + while (pos < n) {
  270 + chars[pos] = this.next();
  271 + if (this.end()) {
  272 + throw this.syntaxError("Substring bounds error");
  273 + }
  274 + pos += 1;
  275 + }
  276 + return new String(chars);
  277 + }
  278 +
  279 +
  280 + /**
  281 + * Get the next char in the string, skipping whitespace.
  282 + * @throws JSONException Thrown if there is an error reading the source string.
  283 + * @return A character, or 0 if there are no more characters.
  284 + */
  285 + public char nextClean() throws JSONException {
  286 + for (;;) {
  287 + char c = this.next();
  288 + if (c == 0 || c > ' ') {
  289 + return c;
  290 + }
  291 + }
  292 + }
  293 +
  294 +
  295 + /**
  296 + * Return the characters up to the next close quote character.
  297 + * Backslash processing is done. The formal JSON format does not
  298 + * allow strings in single quotes, but an implementation is allowed to
  299 + * accept them.
  300 + * @param quote The quoting character, either
  301 + * <code>"</code>&nbsp;<small>(double quote)</small> or
  302 + * <code>'</code>&nbsp;<small>(single quote)</small>.
  303 + * @return A String.
  304 + * @throws JSONException Unterminated string.
  305 + */
  306 + public String nextString(char quote) throws JSONException {
  307 + char c;
  308 + StringBuilder sb = new StringBuilder();
  309 + for (;;) {
  310 + c = this.next();
  311 + switch (c) {
  312 + case 0:
  313 + case '\n':
  314 + case '\r':
  315 + throw this.syntaxError("Unterminated string");
  316 + case '\\':
  317 + c = this.next();
  318 + switch (c) {
  319 + case 'b':
  320 + sb.append('\b');
  321 + break;
  322 + case 't':
  323 + sb.append('\t');
  324 + break;
  325 + case 'n':
  326 + sb.append('\n');
  327 + break;
  328 + case 'f':
  329 + sb.append('\f');
  330 + break;
  331 + case 'r':
  332 + sb.append('\r');
  333 + break;
  334 + case 'u':
  335 + try {
  336 + sb.append((char)Integer.parseInt(this.next(4), 16));
  337 + } catch (NumberFormatException e) {
  338 + throw this.syntaxError("Illegal escape.", e);
  339 + }
  340 + break;
  341 + case '"':
  342 + case '\'':
  343 + case '\\':
  344 + case '/':
  345 + sb.append(c);
  346 + break;
  347 + default:
  348 + throw this.syntaxError("Illegal escape.");
  349 + }
  350 + break;
  351 + default:
  352 + if (c == quote) {
  353 + return sb.toString();
  354 + }
  355 + sb.append(c);
  356 + }
  357 + }
  358 + }
  359 +
  360 +
  361 + /**
  362 + * Get the text up but not including the specified character or the
  363 + * end of line, whichever comes first.
  364 + * @param delimiter A delimiter character.
  365 + * @return A string.
  366 + * @throws JSONException Thrown if there is an error while searching
  367 + * for the delimiter
  368 + */
  369 + public String nextTo(char delimiter) throws JSONException {
  370 + StringBuilder sb = new StringBuilder();
  371 + for (;;) {
  372 + char c = this.next();
  373 + if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
  374 + if (c != 0) {
  375 + this.back();
  376 + }
  377 + return sb.toString().trim();
  378 + }
  379 + sb.append(c);
  380 + }
  381 + }
  382 +
  383 +
  384 + /**
  385 + * Get the text up but not including one of the specified delimiter
  386 + * characters or the end of line, whichever comes first.
  387 + * @param delimiters A set of delimiter characters.
  388 + * @return A string, trimmed.
  389 + * @throws JSONException Thrown if there is an error while searching
  390 + * for the delimiter
  391 + */
  392 + public String nextTo(String delimiters) throws JSONException {
  393 + char c;
  394 + StringBuilder sb = new StringBuilder();
  395 + for (;;) {
  396 + c = this.next();
  397 + if (delimiters.indexOf(c) >= 0 || c == 0 ||
  398 + c == '\n' || c == '\r') {
  399 + if (c != 0) {
  400 + this.back();
  401 + }
  402 + return sb.toString().trim();
  403 + }
  404 + sb.append(c);
  405 + }
  406 + }
  407 +
  408 +
  409 + /**
  410 + * Get the next value. The value can be a Boolean, Double, Integer,
  411 + * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
  412 + * @throws JSONException If syntax error.
  413 + *
  414 + * @return An object.
  415 + */
  416 + public Object nextValue() throws JSONException {
  417 + char c = this.nextClean();
  418 + String string;
  419 +
  420 + switch (c) {
  421 + case '"':
  422 + case '\'':
  423 + return this.nextString(c);
  424 + case '{':
  425 + this.back();
  426 + return new JSONObject(this);
  427 + case '[':
  428 + this.back();
  429 + return new JSONArray(this);
  430 + }
  431 +
  432 + /*
  433 + * Handle unquoted text. This could be the values true, false, or
  434 + * null, or it can be a number. An implementation (such as this one)
  435 + * is allowed to also accept non-standard forms.
  436 + *
  437 + * Accumulate characters until we reach the end of the text or a
  438 + * formatting character.
  439 + */
  440 +
  441 + StringBuilder sb = new StringBuilder();
  442 + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
  443 + sb.append(c);
  444 + c = this.next();
  445 + }
  446 + this.back();
  447 +
  448 + string = sb.toString().trim();
  449 + if ("".equals(string)) {
  450 + throw this.syntaxError("Missing value");
  451 + }
  452 + return JSONObject.stringToValue(string);
  453 + }
  454 +
  455 +
  456 + /**
  457 + * Skip characters until the next character is the requested character.
  458 + * If the requested character is not found, no characters are skipped.
  459 + * @param to A character to skip to.
  460 + * @return The requested character, or zero if the requested character
  461 + * is not found.
  462 + * @throws JSONException Thrown if there is an error while searching
  463 + * for the to character
  464 + */
  465 + public char skipTo(char to) throws JSONException {
  466 + char c;
  467 + try {
  468 + long startIndex = this.index;
  469 + long startCharacter = this.character;
  470 + long startLine = this.line;
  471 + this.reader.mark(1000000);
  472 + do {
  473 + c = this.next();
  474 + if (c == 0) {
  475 + // in some readers, reset() may throw an exception if
  476 + // the remaining portion of the input is greater than
  477 + // the mark size (1,000,000 above).
  478 + this.reader.reset();
  479 + this.index = startIndex;
  480 + this.character = startCharacter;
  481 + this.line = startLine;
  482 + return 0;
  483 + }
  484 + } while (c != to);
  485 + this.reader.mark(1);
  486 + } catch (IOException exception) {
  487 + throw new JSONException(exception);
  488 + }
  489 + this.back();
  490 + return c;
  491 + }
  492 +
  493 + /**
  494 + * Make a JSONException to signal a syntax error.
  495 + *
  496 + * @param message The error message.
  497 + * @return A JSONException object, suitable for throwing
  498 + */
  499 + public JSONException syntaxError(String message) {
  500 + return new JSONException(message + this.toString());
  501 + }
  502 +
  503 + /**
  504 + * Make a JSONException to signal a syntax error.
  505 + *
  506 + * @param message The error message.
  507 + * @param causedBy The throwable that caused the error.
  508 + * @return A JSONException object, suitable for throwing
  509 + */
  510 + public JSONException syntaxError(String message, Throwable causedBy) {
  511 + return new JSONException(message + this.toString(), causedBy);
  512 + }
  513 +
  514 + /**
  515 + * Make a printable string of this JSONTokener.
  516 + *
  517 + * @return " at {index} [character {character} line {line}]"
  518 + */
  519 + @Override
  520 + public String toString() {
  521 + return " at " + this.index + " [character " + this.character + " line " +
  522 + this.line + "]";
  523 + }
  524 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/JSONWriter.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +import java.io.IOException;
  4 +import java.math.BigDecimal;
  5 +import java.util.Collection;
  6 +import java.util.Map;
  7 +
  8 +/*
  9 +Copyright (c) 2006 JSON.org
  10 +
  11 +Permission is hereby granted, free of charge, to any person obtaining a copy
  12 +of this software and associated documentation files (the "Software"), to deal
  13 +in the Software without restriction, including without limitation the rights
  14 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15 +copies of the Software, and to permit persons to whom the Software is
  16 +furnished to do so, subject to the following conditions:
  17 +
  18 +The above copyright notice and this permission notice shall be included in all
  19 +copies or substantial portions of the Software.
  20 +
  21 +The Software shall be used for Good, not Evil.
  22 +
  23 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  28 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29 +SOFTWARE.
  30 +*/
  31 +
  32 +/**
  33 + * JSONWriter provides a quick and convenient way of producing JSON text.
  34 + * The texts produced strictly conform to JSON syntax rules. No whitespace is
  35 + * added, so the results are ready for transmission or storage. Each instance of
  36 + * JSONWriter can produce one JSON text.
  37 + * <p>
  38 + * A JSONWriter instance provides a <code>value</code> method for appending
  39 + * values to the
  40 + * text, and a <code>key</code>
  41 + * method for adding keys before values in objects. There are <code>array</code>
  42 + * and <code>endArray</code> methods that make and bound array values, and
  43 + * <code>object</code> and <code>endObject</code> methods which make and bound
  44 + * object values. All of these methods return the JSONWriter instance,
  45 + * permitting a cascade style. For example, <pre>
  46 + * new JSONWriter(myWriter)
  47 + * .object()
  48 + * .key("JSON")
  49 + * .value("Hello, World!")
  50 + * .endObject();</pre> which writes <pre>
  51 + * {"JSON":"Hello, World!"}</pre>
  52 + * <p>
  53 + * The first method called must be <code>array</code> or <code>object</code>.
  54 + * There are no methods for adding commas or colons. JSONWriter adds them for
  55 + * you. Objects and arrays can be nested up to 200 levels deep.
  56 + * <p>
  57 + * This can sometimes be easier than using a JSONObject to build a string.
  58 + * @author JSON.org
  59 + * @version 2016-08-08
  60 + */
  61 +public class JSONWriter {
  62 + private static final int maxdepth = 200;
  63 +
  64 + /**
  65 + * The comma flag determines if a comma should be output before the next
  66 + * value.
  67 + */
  68 + private boolean comma;
  69 +
  70 + /**
  71 + * The current mode. Values:
  72 + * 'a' (array),
  73 + * 'd' (done),
  74 + * 'i' (initial),
  75 + * 'k' (key),
  76 + * 'o' (object).
  77 + */
  78 + protected char mode;
  79 +
  80 + /**
  81 + * The object/array stack.
  82 + */
  83 + private final JSONObject stack[];
  84 +
  85 + /**
  86 + * The stack top index. A value of 0 indicates that the stack is empty.
  87 + */
  88 + private int top;
  89 +
  90 + /**
  91 + * The writer that will receive the output.
  92 + */
  93 + protected Appendable writer;
  94 +
  95 + /**
  96 + * Make a fresh JSONWriter. It can be used to build one JSON text.
  97 + */
  98 + public JSONWriter(Appendable w) {
  99 + this.comma = false;
  100 + this.mode = 'i';
  101 + this.stack = new JSONObject[maxdepth];
  102 + this.top = 0;
  103 + this.writer = w;
  104 + }
  105 +
  106 + /**
  107 + * Append a value.
  108 + * @param string A string value.
  109 + * @return this
  110 + * @throws JSONException If the value is out of sequence.
  111 + */
  112 + private JSONWriter append(String string) throws JSONException {
  113 + if (string == null) {
  114 + throw new JSONException("Null pointer");
  115 + }
  116 + if (this.mode == 'o' || this.mode == 'a') {
  117 + try {
  118 + if (this.comma && this.mode == 'a') {
  119 + this.writer.append(',');
  120 + }
  121 + this.writer.append(string);
  122 + } catch (IOException e) {
  123 + // Android as of API 25 does not support this exception constructor
  124 + // however we won't worry about it. If an exception is happening here
  125 + // it will just throw a "Method not found" exception instead.
  126 + throw new JSONException(e);
  127 + }
  128 + if (this.mode == 'o') {
  129 + this.mode = 'k';
  130 + }
  131 + this.comma = true;
  132 + return this;
  133 + }
  134 + throw new JSONException("Value out of sequence.");
  135 + }
  136 +
  137 + /**
  138 + * Begin appending a new array. All values until the balancing
  139 + * <code>endArray</code> will be appended to this array. The
  140 + * <code>endArray</code> method must be called to mark the array's end.
  141 + * @return this
  142 + * @throws JSONException If the nesting is too deep, or if the object is
  143 + * started in the wrong place (for example as a key or after the end of the
  144 + * outermost array or object).
  145 + */
  146 + public JSONWriter array() throws JSONException {
  147 + if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
  148 + this.push(null);
  149 + this.append("[");
  150 + this.comma = false;
  151 + return this;
  152 + }
  153 + throw new JSONException("Misplaced array.");
  154 + }
  155 +
  156 + /**
  157 + * End something.
  158 + * @param m Mode
  159 + * @param c Closing character
  160 + * @return this
  161 + * @throws JSONException If unbalanced.
  162 + */
  163 + private JSONWriter end(char m, char c) throws JSONException {
  164 + if (this.mode != m) {
  165 + throw new JSONException(m == 'a'
  166 + ? "Misplaced endArray."
  167 + : "Misplaced endObject.");
  168 + }
  169 + this.pop(m);
  170 + try {
  171 + this.writer.append(c);
  172 + } catch (IOException e) {
  173 + // Android as of API 25 does not support this exception constructor
  174 + // however we won't worry about it. If an exception is happening here
  175 + // it will just throw a "Method not found" exception instead.
  176 + throw new JSONException(e);
  177 + }
  178 + this.comma = true;
  179 + return this;
  180 + }
  181 +
  182 + /**
  183 + * End an array. This method most be called to balance calls to
  184 + * <code>array</code>.
  185 + * @return this
  186 + * @throws JSONException If incorrectly nested.
  187 + */
  188 + public JSONWriter endArray() throws JSONException {
  189 + return this.end('a', ']');
  190 + }
  191 +
  192 + /**
  193 + * End an object. This method most be called to balance calls to
  194 + * <code>object</code>.
  195 + * @return this
  196 + * @throws JSONException If incorrectly nested.
  197 + */
  198 + public JSONWriter endObject() throws JSONException {
  199 + return this.end('k', '}');
  200 + }
  201 +
  202 + /**
  203 + * Append a key. The key will be associated with the next value. In an
  204 + * object, every value must be preceded by a key.
  205 + * @param string A key string.
  206 + * @return this
  207 + * @throws JSONException If the key is out of place. For example, keys
  208 + * do not belong in arrays or if the key is null.
  209 + */
  210 + public JSONWriter key(String string) throws JSONException {
  211 + if (string == null) {
  212 + throw new JSONException("Null key.");
  213 + }
  214 + if (this.mode == 'k') {
  215 + try {
  216 + JSONObject topObject = this.stack[this.top - 1];
  217 + // don't use the built in putOnce method to maintain Android support
  218 + if(topObject.has(string)) {
  219 + throw new JSONException("Duplicate key \"" + string + "\"");
  220 + }
  221 + topObject.put(string, true);
  222 + if (this.comma) {
  223 + this.writer.append(',');
  224 + }
  225 + this.writer.append(JSONObject.quote(string));
  226 + this.writer.append(':');
  227 + this.comma = false;
  228 + this.mode = 'o';
  229 + return this;
  230 + } catch (IOException e) {
  231 + // Android as of API 25 does not support this exception constructor
  232 + // however we won't worry about it. If an exception is happening here
  233 + // it will just throw a "Method not found" exception instead.
  234 + throw new JSONException(e);
  235 + }
  236 + }
  237 + throw new JSONException("Misplaced key.");
  238 + }
  239 +
  240 +
  241 + /**
  242 + * Begin appending a new object. All keys and values until the balancing
  243 + * <code>endObject</code> will be appended to this object. The
  244 + * <code>endObject</code> method must be called to mark the object's end.
  245 + * @return this
  246 + * @throws JSONException If the nesting is too deep, or if the object is
  247 + * started in the wrong place (for example as a key or after the end of the
  248 + * outermost array or object).
  249 + */
  250 + public JSONWriter object() throws JSONException {
  251 + if (this.mode == 'i') {
  252 + this.mode = 'o';
  253 + }
  254 + if (this.mode == 'o' || this.mode == 'a') {
  255 + this.append("{");
  256 + this.push(new JSONObject());
  257 + this.comma = false;
  258 + return this;
  259 + }
  260 + throw new JSONException("Misplaced object.");
  261 +
  262 + }
  263 +
  264 +
  265 + /**
  266 + * Pop an array or object scope.
  267 + * @param c The scope to close.
  268 + * @throws JSONException If nesting is wrong.
  269 + */
  270 + private void pop(char c) throws JSONException {
  271 + if (this.top <= 0) {
  272 + throw new JSONException("Nesting error.");
  273 + }
  274 + char m = this.stack[this.top - 1] == null ? 'a' : 'k';
  275 + if (m != c) {
  276 + throw new JSONException("Nesting error.");
  277 + }
  278 + this.top -= 1;
  279 + this.mode = this.top == 0
  280 + ? 'd'
  281 + : this.stack[this.top - 1] == null
  282 + ? 'a'
  283 + : 'k';
  284 + }
  285 +
  286 + /**
  287 + * Push an array or object scope.
  288 + * @param jo The scope to open.
  289 + * @throws JSONException If nesting is too deep.
  290 + */
  291 + private void push(JSONObject jo) throws JSONException {
  292 + if (this.top >= maxdepth) {
  293 + throw new JSONException("Nesting too deep.");
  294 + }
  295 + this.stack[this.top] = jo;
  296 + this.mode = jo == null ? 'a' : 'k';
  297 + this.top += 1;
  298 + }
  299 +
  300 + /**
  301 + * Make a JSON text of an Object value. If the object has an
  302 + * value.toJSONString() method, then that method will be used to produce the
  303 + * JSON text. The method is required to produce a strictly conforming text.
  304 + * If the object does not contain a toJSONString method (which is the most
  305 + * common case), then a text will be produced by other means. If the value
  306 + * is an array or Collection, then a JSONArray will be made from it and its
  307 + * toJSONString method will be called. If the value is a MAP, then a
  308 + * JSONObject will be made from it and its toJSONString method will be
  309 + * called. Otherwise, the value's toString method will be called, and the
  310 + * result will be quoted.
  311 + *
  312 + * <p>
  313 + * Warning: This method assumes that the data structure is acyclical.
  314 + *
  315 + * @param value
  316 + * The value to be serialized.
  317 + * @return a printable, displayable, transmittable representation of the
  318 + * object, beginning with <code>{</code>&nbsp;<small>(left
  319 + * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
  320 + * brace)</small>.
  321 + * @throws JSONException
  322 + * If the value is or contains an invalid number.
  323 + */
  324 + public static String valueToString(Object value) throws JSONException {
  325 + if (value == null || value.equals(null)) {
  326 + return "null";
  327 + }
  328 + if (value instanceof JSONString) {
  329 + Object object;
  330 + try {
  331 + object = ((JSONString) value).toJSONString();
  332 + } catch (Exception e) {
  333 + throw new JSONException(e);
  334 + }
  335 + if (object instanceof String) {
  336 + return (String) object;
  337 + }
  338 + throw new JSONException("Bad value from toJSONString: " + object);
  339 + }
  340 + if (value instanceof Number) {
  341 + // not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
  342 + final String numberAsString = JSONObject.numberToString((Number) value);
  343 + try {
  344 + // Use the BigDecimal constructor for it's parser to validate the format.
  345 + @SuppressWarnings("unused")
  346 + BigDecimal unused = new BigDecimal(numberAsString);
  347 + // Close enough to a JSON number that we will return it unquoted
  348 + return numberAsString;
  349 + } catch (NumberFormatException ex){
  350 + // The Number value is not a valid JSON number.
  351 + // Instead we will quote it as a string
  352 + return JSONObject.quote(numberAsString);
  353 + }
  354 + }
  355 + if (value instanceof Boolean || value instanceof JSONObject
  356 + || value instanceof JSONArray) {
  357 + return value.toString();
  358 + }
  359 + if (value instanceof Map) {
  360 + Map<?, ?> map = (Map<?, ?>) value;
  361 + return new JSONObject(map).toString();
  362 + }
  363 + if (value instanceof Collection) {
  364 + Collection<?> coll = (Collection<?>) value;
  365 + return new JSONArray(coll).toString();
  366 + }
  367 + if (value.getClass().isArray()) {
  368 + return new JSONArray(value).toString();
  369 + }
  370 + if(value instanceof Enum<?>){
  371 + return JSONObject.quote(((Enum<?>)value).name());
  372 + }
  373 + return JSONObject.quote(value.toString());
  374 + }
  375 +
  376 + /**
  377 + * Append either the value <code>true</code> or the value
  378 + * <code>false</code>.
  379 + * @param b A boolean.
  380 + * @return this
  381 + * @throws JSONException
  382 + */
  383 + public JSONWriter value(boolean b) throws JSONException {
  384 + return this.append(b ? "true" : "false");
  385 + }
  386 +
  387 + /**
  388 + * Append a double value.
  389 + * @param d A double.
  390 + * @return this
  391 + * @throws JSONException If the number is not finite.
  392 + */
  393 + public JSONWriter value(double d) throws JSONException {
  394 + return this.value(new Double(d));
  395 + }
  396 +
  397 + /**
  398 + * Append a long value.
  399 + * @param l A long.
  400 + * @return this
  401 + * @throws JSONException
  402 + */
  403 + public JSONWriter value(long l) throws JSONException {
  404 + return this.append(Long.toString(l));
  405 + }
  406 +
  407 +
  408 + /**
  409 + * Append an object value.
  410 + * @param object The object to append. It can be null, or a Boolean, Number,
  411 + * String, JSONObject, or JSONArray, or an object that implements JSONString.
  412 + * @return this
  413 + * @throws JSONException If the value is out of sequence.
  414 + */
  415 + public JSONWriter value(Object object) throws JSONException {
  416 + return this.append(valueToString(object));
  417 + }
  418 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/LICENSE 0 → 100644
  1 +============================================================================
  2 +
  3 +Copyright (c) 2002 JSON.org
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +The Software shall be used for Good, not Evil.
  16 +
  17 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23 +SOFTWARE.
src/main/java/com/bsth/data/zndd/baidu/org/json/Property.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +import java.util.Enumeration;
  28 +import java.util.Properties;
  29 +
  30 +/**
  31 + * Converts a Property file data into JSONObject and back.
  32 + * @author JSON.org
  33 + * @version 2015-05-05
  34 + */
  35 +public class Property {
  36 + /**
  37 + * Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
  38 + * @param properties java.util.Properties
  39 + * @return JSONObject
  40 + * @throws JSONException
  41 + */
  42 + public static JSONObject toJSONObject(Properties properties) throws JSONException {
  43 + // can't use the new constructor for Android support
  44 + // JSONObject jo = new JSONObject(properties == null ? 0 : properties.size());
  45 + JSONObject jo = new JSONObject();
  46 + if (properties != null && !properties.isEmpty()) {
  47 + Enumeration<?> enumProperties = properties.propertyNames();
  48 + while(enumProperties.hasMoreElements()) {
  49 + String name = (String)enumProperties.nextElement();
  50 + jo.put(name, properties.getProperty(name));
  51 + }
  52 + }
  53 + return jo;
  54 + }
  55 +
  56 + /**
  57 + * Converts the JSONObject into a property file object.
  58 + * @param jo JSONObject
  59 + * @return java.util.Properties
  60 + * @throws JSONException
  61 + */
  62 + public static Properties toProperties(JSONObject jo) throws JSONException {
  63 + Properties properties = new Properties();
  64 + if (jo != null) {
  65 + // Don't use the new entrySet API to maintain Android support
  66 + for (final String key : jo.keySet()) {
  67 + Object value = jo.opt(key);
  68 + if (!JSONObject.NULL.equals(value)) {
  69 + properties.put(key, value.toString());
  70 + }
  71 + }
  72 + }
  73 + return properties;
  74 + }
  75 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/README.md 0 → 100644
  1 +JSON in Java [package org.json]
  2 +===============================
  3 +
  4 +[![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json)
  5 +
  6 +JSON is a light-weight, language independent, data interchange format.
  7 +See http://www.JSON.org/
  8 +
  9 +The files in this package implement JSON encoders/decoders in Java.
  10 +It also includes the capability to convert between JSON and XML, HTTP
  11 +headers, Cookies, and CDL.
  12 +
  13 +This is a reference implementation. There is a large number of JSON packages
  14 +in Java. Perhaps someday the Java community will standardize on one. Until
  15 +then, choose carefully.
  16 +
  17 +The license includes this restriction: "The software shall be used for good,
  18 +not evil." If your conscience cannot live with that, then choose a different
  19 +package.
  20 +
  21 +The package compiles on Java 1.6-1.8.
  22 +
  23 +
  24 +**JSONObject.java**: The `JSONObject` can parse text from a `String` or a `JSONTokener`
  25 +to produce a map-like object. The object provides methods for manipulating its
  26 +contents, and for producing a JSON compliant object serialization.
  27 +
  28 +**JSONArray.java**: The `JSONArray` can parse text from a String or a `JSONTokener`
  29 +to produce a vector-like object. The object provides methods for manipulating
  30 +its contents, and for producing a JSON compliant array serialization.
  31 +
  32 +**JSONTokener.java**: The `JSONTokener` breaks a text into a sequence of individual
  33 +tokens. It can be constructed from a `String`, `Reader`, or `InputStream`.
  34 +
  35 +**JSONException.java**: The `JSONException` is the standard exception type thrown
  36 +by this package.
  37 +
  38 +**JSONPointer.java**: Implementation of
  39 +[JSON Pointer (RFC 6901)](https://tools.ietf.org/html/rfc6901). Supports
  40 +JSON Pointers both in the form of string representation and URI fragment
  41 +representation.
  42 +
  43 +**JSONString.java**: The `JSONString` interface requires a `toJSONString` method,
  44 +allowing an object to provide its own serialization.
  45 +
  46 +**JSONStringer.java**: The `JSONStringer` provides a convenient facility for
  47 +building JSON strings.
  48 +
  49 +**JSONWriter.java**: The `JSONWriter` provides a convenient facility for building
  50 +JSON text through a writer.
  51 +
  52 +
  53 +**CDL.java**: `CDL` provides support for converting between JSON and comma
  54 +delimited lists.
  55 +
  56 +**Cookie.java**: `Cookie` provides support for converting between JSON and cookies.
  57 +
  58 +**CookieList.java**: `CookieList` provides support for converting between JSON and
  59 +cookie lists.
  60 +
  61 +**HTTP.java**: `HTTP` provides support for converting between JSON and HTTP headers.
  62 +
  63 +**HTTPTokener.java**: `HTTPTokener` extends `JSONTokener` for parsing HTTP headers.
  64 +
  65 +**XML.java**: `XML` provides support for converting between JSON and XML.
  66 +
  67 +**JSONML.java**: `JSONML` provides support for converting between JSONML and XML.
  68 +
  69 +**XMLTokener.java**: `XMLTokener` extends `JSONTokener` for parsing XML text.
  70 +
  71 +Unit tests are maintained in a separate project. Contributing developers can test
  72 +JSON-java pull requests with the code in this project:
  73 +https://github.com/stleary/JSON-Java-unit-test
  74 +
  75 +Numeric types in this package comply with
  76 +[ECMA-404: The JSON Data Interchange Format](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) and
  77 +[RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159#section-6).
  78 +This package fully supports `Integer`, `Long`, and `Double` Java types. Partial support
  79 +for `BigInteger` and `BigDecimal` values in `JSONObject` and `JSONArray` objects is provided
  80 +in the form of `get()`, `opt()`, and `put()` API methods.
  81 +
  82 +Although 1.6 compatibility is currently supported, it is not a project goal and may be
  83 +removed in some future release.
  84 +
  85 +In compliance with RFC7159 page 10 section 9, the parser is more lax with what is valid
  86 +JSON than the Generator. For Example, the tab character (U+0009) is allowed when reading
  87 +JSON Text strings, but when output by the Generator, tab is properly converted to \t in
  88 +the string. Other instances may occur where reading invalid JSON text does not cause an
  89 +error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
  90 +invalid number formats (1.2e6.3) will cause errors as such documents can not be read
  91 + reliably.
  92 +
  93 +Release history:
  94 +
  95 +~~~
  96 +20180130 Recent commits
  97 +
  98 +20171018 Checkpoint for recent commits.
  99 +
  100 +20170516 Roll up recent commits.
  101 +
  102 +20160810 Revert code that was breaking opt*() methods.
  103 +
  104 +20160807 This release contains a bug in the JSONObject.opt*() and JSONArray.opt*() methods,
  105 +it is not recommended for use.
  106 +Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
  107 +RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
  108 +Contains the latest code as of 7 Aug, 2016
  109 +
  110 +20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb, 2016.
  111 +
  112 +20151123 JSONObject and JSONArray initialization with generics. Contains the
  113 +latest code as of 23 Nov, 2015.
  114 +
  115 +20150729 Checkpoint for Maven central repository release. Contains the latest code
  116 +as of 29 July, 2015.
  117 +~~~
  118 +
  119 +
  120 +JSON-java releases can be found by searching the Maven repository for groupId "org.json"
  121 +and artifactId "json". For example:
  122 +https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22
src/main/java/com/bsth/data/zndd/baidu/org/json/XML.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2015 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +import java.util.Iterator;
  28 +
  29 +/**
  30 + * This provides static methods to convert an XML text into a JSONObject, and to
  31 + * covert a JSONObject into an XML text.
  32 + *
  33 + * @author JSON.org
  34 + * @version 2016-08-10
  35 + */
  36 +@SuppressWarnings("boxing")
  37 +public class XML {
  38 + /** The Character '&amp;'. */
  39 + public static final Character AMP = '&';
  40 +
  41 + /** The Character '''. */
  42 + public static final Character APOS = '\'';
  43 +
  44 + /** The Character '!'. */
  45 + public static final Character BANG = '!';
  46 +
  47 + /** The Character '='. */
  48 + public static final Character EQ = '=';
  49 +
  50 + /** The Character '>'. */
  51 + public static final Character GT = '>';
  52 +
  53 + /** The Character '&lt;'. */
  54 + public static final Character LT = '<';
  55 +
  56 + /** The Character '?'. */
  57 + public static final Character QUEST = '?';
  58 +
  59 + /** The Character '"'. */
  60 + public static final Character QUOT = '"';
  61 +
  62 + /** The Character '/'. */
  63 + public static final Character SLASH = '/';
  64 +
  65 + /**
  66 + * Creates an iterator for navigating Code Points in a string instead of
  67 + * characters. Once Java7 support is dropped, this can be replaced with
  68 + * <code>
  69 + * string.codePoints()
  70 + * </code>
  71 + * which is available in Java8 and above.
  72 + *
  73 + * @see <a href=
  74 + * "http://stackoverflow.com/a/21791059/6030888">http://stackoverflow.com/a/21791059/6030888</a>
  75 + */
  76 + private static Iterable<Integer> codePointIterator(final String string) {
  77 + return new Iterable<Integer>() {
  78 + @Override
  79 + public Iterator<Integer> iterator() {
  80 + return new Iterator<Integer>() {
  81 + private int nextIndex = 0;
  82 + private int length = string.length();
  83 +
  84 + @Override
  85 + public boolean hasNext() {
  86 + return this.nextIndex < this.length;
  87 + }
  88 +
  89 + @Override
  90 + public Integer next() {
  91 + int result = string.codePointAt(this.nextIndex);
  92 + this.nextIndex += Character.charCount(result);
  93 + return result;
  94 + }
  95 +
  96 + @Override
  97 + public void remove() {
  98 + throw new UnsupportedOperationException();
  99 + }
  100 + };
  101 + }
  102 + };
  103 + }
  104 +
  105 + /**
  106 + * Replace special characters with XML escapes:
  107 + *
  108 + * <pre>
  109 + * &amp; <small>(ampersand)</small> is replaced by &amp;amp;
  110 + * &lt; <small>(less than)</small> is replaced by &amp;lt;
  111 + * &gt; <small>(greater than)</small> is replaced by &amp;gt;
  112 + * &quot; <small>(double quote)</small> is replaced by &amp;quot;
  113 + * &apos; <small>(single quote / apostrophe)</small> is replaced by &amp;apos;
  114 + * </pre>
  115 + *
  116 + * @param string
  117 + * The string to be escaped.
  118 + * @return The escaped string.
  119 + */
  120 + public static String escape(String string) {
  121 + StringBuilder sb = new StringBuilder(string.length());
  122 + for (final int cp : codePointIterator(string)) {
  123 + switch (cp) {
  124 + case '&':
  125 + sb.append("&amp;");
  126 + break;
  127 + case '<':
  128 + sb.append("&lt;");
  129 + break;
  130 + case '>':
  131 + sb.append("&gt;");
  132 + break;
  133 + case '"':
  134 + sb.append("&quot;");
  135 + break;
  136 + case '\'':
  137 + sb.append("&apos;");
  138 + break;
  139 + default:
  140 + if (mustEscape(cp)) {
  141 + sb.append("&#x");
  142 + sb.append(Integer.toHexString(cp));
  143 + sb.append(';');
  144 + } else {
  145 + sb.appendCodePoint(cp);
  146 + }
  147 + }
  148 + }
  149 + return sb.toString();
  150 + }
  151 +
  152 + /**
  153 + * @param cp code point to test
  154 + * @return true if the code point is not valid for an XML
  155 + */
  156 + private static boolean mustEscape(int cp) {
  157 + /* Valid range from https://www.w3.org/TR/REC-xml/#charsets
  158 + *
  159 + * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
  160 + *
  161 + * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
  162 + */
  163 + // isISOControl is true when (cp >= 0 && cp <= 0x1F) || (cp >= 0x7F && cp <= 0x9F)
  164 + // all ISO control characters are out of range except tabs and new lines
  165 + return (Character.isISOControl(cp)
  166 + && cp != 0x9
  167 + && cp != 0xA
  168 + && cp != 0xD
  169 + ) || !(
  170 + // valid the range of acceptable characters that aren't control
  171 + (cp >= 0x20 && cp <= 0xD7FF)
  172 + || (cp >= 0xE000 && cp <= 0xFFFD)
  173 + || (cp >= 0x10000 && cp <= 0x10FFFF)
  174 + )
  175 + ;
  176 + }
  177 +
  178 + /**
  179 + * Removes XML escapes from the string.
  180 + *
  181 + * @param string
  182 + * string to remove escapes from
  183 + * @return string with converted entities
  184 + */
  185 + public static String unescape(String string) {
  186 + StringBuilder sb = new StringBuilder(string.length());
  187 + for (int i = 0, length = string.length(); i < length; i++) {
  188 + char c = string.charAt(i);
  189 + if (c == '&') {
  190 + final int semic = string.indexOf(';', i);
  191 + if (semic > i) {
  192 + final String entity = string.substring(i + 1, semic);
  193 + sb.append(XMLTokener.unescapeEntity(entity));
  194 + // skip past the entity we just parsed.
  195 + i += entity.length() + 1;
  196 + } else {
  197 + // this shouldn't happen in most cases since the parser
  198 + // errors on unclosed entries.
  199 + sb.append(c);
  200 + }
  201 + } else {
  202 + // not part of an entity
  203 + sb.append(c);
  204 + }
  205 + }
  206 + return sb.toString();
  207 + }
  208 +
  209 + /**
  210 + * Throw an exception if the string contains whitespace. Whitespace is not
  211 + * allowed in tagNames and attributes.
  212 + *
  213 + * @param string
  214 + * A string.
  215 + * @throws JSONException Thrown if the string contains whitespace or is empty.
  216 + */
  217 + public static void noSpace(String string) throws JSONException {
  218 + int i, length = string.length();
  219 + if (length == 0) {
  220 + throw new JSONException("Empty string.");
  221 + }
  222 + for (i = 0; i < length; i += 1) {
  223 + if (Character.isWhitespace(string.charAt(i))) {
  224 + throw new JSONException("'" + string
  225 + + "' contains a space character.");
  226 + }
  227 + }
  228 + }
  229 +
  230 + /**
  231 + * Scan the content following the named tag, attaching it to the context.
  232 + *
  233 + * @param x
  234 + * The XMLTokener containing the source string.
  235 + * @param context
  236 + * The JSONObject that will include the new material.
  237 + * @param name
  238 + * The tag name.
  239 + * @return true if the close tag is processed.
  240 + * @throws JSONException
  241 + */
  242 + private static boolean parse(XMLTokener x, JSONObject context, String name, boolean keepStrings)
  243 + throws JSONException {
  244 + char c;
  245 + int i;
  246 + JSONObject jsonobject = null;
  247 + String string;
  248 + String tagName;
  249 + Object token;
  250 +
  251 + // Test for and skip past these forms:
  252 + // <!-- ... -->
  253 + // <! ... >
  254 + // <![ ... ]]>
  255 + // <? ... ?>
  256 + // Report errors for these forms:
  257 + // <>
  258 + // <=
  259 + // <<
  260 +
  261 + token = x.nextToken();
  262 +
  263 + // <!
  264 +
  265 + if (token == BANG) {
  266 + c = x.next();
  267 + if (c == '-') {
  268 + if (x.next() == '-') {
  269 + x.skipPast("-->");
  270 + return false;
  271 + }
  272 + x.back();
  273 + } else if (c == '[') {
  274 + token = x.nextToken();
  275 + if ("CDATA".equals(token)) {
  276 + if (x.next() == '[') {
  277 + string = x.nextCDATA();
  278 + if (string.length() > 0) {
  279 + context.accumulate("content", string);
  280 + }
  281 + return false;
  282 + }
  283 + }
  284 + throw x.syntaxError("Expected 'CDATA['");
  285 + }
  286 + i = 1;
  287 + do {
  288 + token = x.nextMeta();
  289 + if (token == null) {
  290 + throw x.syntaxError("Missing '>' after '<!'.");
  291 + } else if (token == LT) {
  292 + i += 1;
  293 + } else if (token == GT) {
  294 + i -= 1;
  295 + }
  296 + } while (i > 0);
  297 + return false;
  298 + } else if (token == QUEST) {
  299 +
  300 + // <?
  301 + x.skipPast("?>");
  302 + return false;
  303 + } else if (token == SLASH) {
  304 +
  305 + // Close tag </
  306 +
  307 + token = x.nextToken();
  308 + if (name == null) {
  309 + throw x.syntaxError("Mismatched close tag " + token);
  310 + }
  311 + if (!token.equals(name)) {
  312 + throw x.syntaxError("Mismatched " + name + " and " + token);
  313 + }
  314 + if (x.nextToken() != GT) {
  315 + throw x.syntaxError("Misshaped close tag");
  316 + }
  317 + return true;
  318 +
  319 + } else if (token instanceof Character) {
  320 + throw x.syntaxError("Misshaped tag");
  321 +
  322 + // Open tag <
  323 +
  324 + } else {
  325 + tagName = (String) token;
  326 + token = null;
  327 + jsonobject = new JSONObject();
  328 + for (;;) {
  329 + if (token == null) {
  330 + token = x.nextToken();
  331 + }
  332 + // attribute = value
  333 + if (token instanceof String) {
  334 + string = (String) token;
  335 + token = x.nextToken();
  336 + if (token == EQ) {
  337 + token = x.nextToken();
  338 + if (!(token instanceof String)) {
  339 + throw x.syntaxError("Missing value");
  340 + }
  341 + jsonobject.accumulate(string,
  342 + keepStrings ? ((String)token) : stringToValue((String) token));
  343 + token = null;
  344 + } else {
  345 + jsonobject.accumulate(string, "");
  346 + }
  347 +
  348 +
  349 + } else if (token == SLASH) {
  350 + // Empty tag <.../>
  351 + if (x.nextToken() != GT) {
  352 + throw x.syntaxError("Misshaped tag");
  353 + }
  354 + if (jsonobject.length() > 0) {
  355 + context.accumulate(tagName, jsonobject);
  356 + } else {
  357 + context.accumulate(tagName, "");
  358 + }
  359 + return false;
  360 +
  361 + } else if (token == GT) {
  362 + // Content, between <...> and </...>
  363 + for (;;) {
  364 + token = x.nextContent();
  365 + if (token == null) {
  366 + if (tagName != null) {
  367 + throw x.syntaxError("Unclosed tag " + tagName);
  368 + }
  369 + return false;
  370 + } else if (token instanceof String) {
  371 + string = (String) token;
  372 + if (string.length() > 0) {
  373 + jsonobject.accumulate("content",
  374 + keepStrings ? string : stringToValue(string));
  375 + }
  376 +
  377 + } else if (token == LT) {
  378 + // Nested element
  379 + if (parse(x, jsonobject, tagName,keepStrings)) {
  380 + if (jsonobject.length() == 0) {
  381 + context.accumulate(tagName, "");
  382 + } else if (jsonobject.length() == 1
  383 + && jsonobject.opt("content") != null) {
  384 + context.accumulate(tagName,
  385 + jsonobject.opt("content"));
  386 + } else {
  387 + context.accumulate(tagName, jsonobject);
  388 + }
  389 + return false;
  390 + }
  391 + }
  392 + }
  393 + } else {
  394 + throw x.syntaxError("Misshaped tag");
  395 + }
  396 + }
  397 + }
  398 + }
  399 +
  400 + /**
  401 + * This method is the same as {@link JSONObject#stringToValue(String)}.
  402 + *
  403 + * @param string String to convert
  404 + * @return JSON value of this string or the string
  405 + */
  406 + // To maintain compatibility with the Android API, this method is a direct copy of
  407 + // the one in JSONObject. Changes made here should be reflected there.
  408 + public static Object stringToValue(String string) {
  409 + if (string.equals("")) {
  410 + return string;
  411 + }
  412 + if (string.equalsIgnoreCase("true")) {
  413 + return Boolean.TRUE;
  414 + }
  415 + if (string.equalsIgnoreCase("false")) {
  416 + return Boolean.FALSE;
  417 + }
  418 + if (string.equalsIgnoreCase("null")) {
  419 + return JSONObject.NULL;
  420 + }
  421 +
  422 + /*
  423 + * If it might be a number, try converting it. If a number cannot be
  424 + * produced, then the value will just be a string.
  425 + */
  426 +
  427 + char initial = string.charAt(0);
  428 + if ((initial >= '0' && initial <= '9') || initial == '-') {
  429 + try {
  430 + // if we want full Big Number support this block can be replaced with:
  431 + // return stringToNumber(string);
  432 + if (string.indexOf('.') > -1 || string.indexOf('e') > -1
  433 + || string.indexOf('E') > -1 || "-0".equals(string)) {
  434 + Double d = Double.valueOf(string);
  435 + if (!d.isInfinite() && !d.isNaN()) {
  436 + return d;
  437 + }
  438 + } else {
  439 + Long myLong = Long.valueOf(string);
  440 + if (string.equals(myLong.toString())) {
  441 + if (myLong.longValue() == myLong.intValue()) {
  442 + return Integer.valueOf(myLong.intValue());
  443 + }
  444 + return myLong;
  445 + }
  446 + }
  447 + } catch (Exception ignore) {
  448 + }
  449 + }
  450 + return string;
  451 + }
  452 +
  453 + /**
  454 + * Convert a well-formed (but not necessarily valid) XML string into a
  455 + * JSONObject. Some information may be lost in this transformation because
  456 + * JSON is a data format and XML is a document format. XML uses elements,
  457 + * attributes, and content text, while JSON uses unordered collections of
  458 + * name/value pairs and arrays of values. JSON does not does not like to
  459 + * distinguish between elements and attributes. Sequences of similar
  460 + * elements are represented as JSONArrays. Content text may be placed in a
  461 + * "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code>
  462 + * are ignored.
  463 + *
  464 + * @param string
  465 + * The source string.
  466 + * @return A JSONObject containing the structured data from the XML string.
  467 + * @throws JSONException Thrown if there is an errors while parsing the string
  468 + */
  469 + public static JSONObject toJSONObject(String string) throws JSONException {
  470 + return toJSONObject(string, false);
  471 + }
  472 +
  473 +
  474 + /**
  475 + * Convert a well-formed (but not necessarily valid) XML string into a
  476 + * JSONObject. Some information may be lost in this transformation because
  477 + * JSON is a data format and XML is a document format. XML uses elements,
  478 + * attributes, and content text, while JSON uses unordered collections of
  479 + * name/value pairs and arrays of values. JSON does not does not like to
  480 + * distinguish between elements and attributes. Sequences of similar
  481 + * elements are represented as JSONArrays. Content text may be placed in a
  482 + * "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code>
  483 + * are ignored.
  484 + *
  485 + * All values are converted as strings, for 1, 01, 29.0 will not be coerced to
  486 + * numbers but will instead be the exact value as seen in the XML document.
  487 + *
  488 + * @param string
  489 + * The source string.
  490 + * @param keepStrings If true, then values will not be coerced into boolean
  491 + * or numeric values and will instead be left as strings
  492 + * @return A JSONObject containing the structured data from the XML string.
  493 + * @throws JSONException Thrown if there is an errors while parsing the string
  494 + */
  495 + public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
  496 + JSONObject jo = new JSONObject();
  497 + XMLTokener x = new XMLTokener(string);
  498 + while (x.more()) {
  499 + x.skipPast("<");
  500 + if(x.more()) {
  501 + parse(x, jo, null, keepStrings);
  502 + }
  503 + }
  504 + return jo;
  505 + }
  506 + /**
  507 + * Convert a JSONObject into a well-formed, element-normal XML string.
  508 + *
  509 + * @param object
  510 + * A JSONObject.
  511 + * @return A string.
  512 + * @throws JSONException Thrown if there is an error parsing the string
  513 + */
  514 + public static String toString(Object object) throws JSONException {
  515 + return toString(object, null);
  516 + }
  517 +
  518 + /**
  519 + * Convert a JSONObject into a well-formed, element-normal XML string.
  520 + *
  521 + * @param object
  522 + * A JSONObject.
  523 + * @param tagName
  524 + * The optional name of the enclosing tag.
  525 + * @return A string.
  526 + * @throws JSONException Thrown if there is an error parsing the string
  527 + */
  528 + public static String toString(final Object object, final String tagName)
  529 + throws JSONException {
  530 + StringBuilder sb = new StringBuilder();
  531 + JSONArray ja;
  532 + JSONObject jo;
  533 + String string;
  534 +
  535 + if (object instanceof JSONObject) {
  536 +
  537 + // Emit <tagName>
  538 + if (tagName != null) {
  539 + sb.append('<');
  540 + sb.append(tagName);
  541 + sb.append('>');
  542 + }
  543 +
  544 + // Loop thru the keys.
  545 + // don't use the new entrySet accessor to maintain Android Support
  546 + jo = (JSONObject) object;
  547 + for (final String key : jo.keySet()) {
  548 + Object value = jo.opt(key);
  549 + if (value == null) {
  550 + value = "";
  551 + } else if (value.getClass().isArray()) {
  552 + value = new JSONArray(value);
  553 + }
  554 +
  555 + // Emit content in body
  556 + if ("content".equals(key)) {
  557 + if (value instanceof JSONArray) {
  558 + ja = (JSONArray) value;
  559 + int jaLength = ja.length();
  560 + // don't use the new iterator API to maintain support for Android
  561 + for (int i = 0; i < jaLength; i++) {
  562 + if (i > 0) {
  563 + sb.append('\n');
  564 + }
  565 + Object val = ja.opt(i);
  566 + sb.append(escape(val.toString()));
  567 + }
  568 + } else {
  569 + sb.append(escape(value.toString()));
  570 + }
  571 +
  572 + // Emit an array of similar keys
  573 +
  574 + } else if (value instanceof JSONArray) {
  575 + ja = (JSONArray) value;
  576 + int jaLength = ja.length();
  577 + // don't use the new iterator API to maintain support for Android
  578 + for (int i = 0; i < jaLength; i++) {
  579 + Object val = ja.opt(i);
  580 + if (val instanceof JSONArray) {
  581 + sb.append('<');
  582 + sb.append(key);
  583 + sb.append('>');
  584 + sb.append(toString(val));
  585 + sb.append("</");
  586 + sb.append(key);
  587 + sb.append('>');
  588 + } else {
  589 + sb.append(toString(val, key));
  590 + }
  591 + }
  592 + } else if ("".equals(value)) {
  593 + sb.append('<');
  594 + sb.append(key);
  595 + sb.append("/>");
  596 +
  597 + // Emit a new tag <k>
  598 +
  599 + } else {
  600 + sb.append(toString(value, key));
  601 + }
  602 + }
  603 + if (tagName != null) {
  604 +
  605 + // Emit the </tagname> close tag
  606 + sb.append("</");
  607 + sb.append(tagName);
  608 + sb.append('>');
  609 + }
  610 + return sb.toString();
  611 +
  612 + }
  613 +
  614 + if (object != null && (object instanceof JSONArray || object.getClass().isArray())) {
  615 + if(object.getClass().isArray()) {
  616 + ja = new JSONArray(object);
  617 + } else {
  618 + ja = (JSONArray) object;
  619 + }
  620 + int jaLength = ja.length();
  621 + // don't use the new iterator API to maintain support for Android
  622 + for (int i = 0; i < jaLength; i++) {
  623 + Object val = ja.opt(i);
  624 + // XML does not have good support for arrays. If an array
  625 + // appears in a place where XML is lacking, synthesize an
  626 + // <array> element.
  627 + sb.append(toString(val, tagName == null ? "array" : tagName));
  628 + }
  629 + return sb.toString();
  630 + }
  631 +
  632 + string = (object == null) ? "null" : escape(object.toString());
  633 + return (tagName == null) ? "\"" + string + "\""
  634 + : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName
  635 + + ">" + string + "</" + tagName + ">";
  636 +
  637 + }
  638 +}
src/main/java/com/bsth/data/zndd/baidu/org/json/XMLTokener.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.org.json;
  2 +
  3 +/*
  4 +Copyright (c) 2002 JSON.org
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +of this software and associated documentation files (the "Software"), to deal
  8 +in the Software without restriction, including without limitation the rights
  9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +copies of the Software, and to permit persons to whom the Software is
  11 +furnished to do so, subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +The Software shall be used for Good, not Evil.
  17 +
  18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24 +SOFTWARE.
  25 +*/
  26 +
  27 +/**
  28 + * The XMLTokener extends the JSONTokener to provide additional methods
  29 + * for the parsing of XML texts.
  30 + * @author JSON.org
  31 + * @version 2015-12-09
  32 + */
  33 +public class XMLTokener extends JSONTokener {
  34 +
  35 +
  36 + /** The table of entity values. It initially contains Character values for
  37 + * amp, apos, gt, lt, quot.
  38 + */
  39 + public static final java.util.HashMap<String, Character> entity;
  40 +
  41 + static {
  42 + entity = new java.util.HashMap<String, Character>(8);
  43 + entity.put("amp", XML.AMP);
  44 + entity.put("apos", XML.APOS);
  45 + entity.put("gt", XML.GT);
  46 + entity.put("lt", XML.LT);
  47 + entity.put("quot", XML.QUOT);
  48 + }
  49 +
  50 + /**
  51 + * Construct an XMLTokener from a string.
  52 + * @param s A source string.
  53 + */
  54 + public XMLTokener(String s) {
  55 + super(s);
  56 + }
  57 +
  58 + /**
  59 + * Get the text in the CDATA block.
  60 + * @return The string up to the <code>]]&gt;</code>.
  61 + * @throws JSONException If the <code>]]&gt;</code> is not found.
  62 + */
  63 + public String nextCDATA() throws JSONException {
  64 + char c;
  65 + int i;
  66 + StringBuilder sb = new StringBuilder();
  67 + while (more()) {
  68 + c = next();
  69 + sb.append(c);
  70 + i = sb.length() - 3;
  71 + if (i >= 0 && sb.charAt(i) == ']' &&
  72 + sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
  73 + sb.setLength(i);
  74 + return sb.toString();
  75 + }
  76 + }
  77 + throw syntaxError("Unclosed CDATA");
  78 + }
  79 +
  80 +
  81 + /**
  82 + * Get the next XML outer token, trimming whitespace. There are two kinds
  83 + * of tokens: the '<' character which begins a markup tag, and the content
  84 + * text between markup tags.
  85 + *
  86 + * @return A string, or a '<' Character, or null if there is no more
  87 + * source text.
  88 + * @throws JSONException
  89 + */
  90 + public Object nextContent() throws JSONException {
  91 + char c;
  92 + StringBuilder sb;
  93 + do {
  94 + c = next();
  95 + } while (Character.isWhitespace(c));
  96 + if (c == 0) {
  97 + return null;
  98 + }
  99 + if (c == '<') {
  100 + return XML.LT;
  101 + }
  102 + sb = new StringBuilder();
  103 + for (;;) {
  104 + if (c == 0) {
  105 + return sb.toString().trim();
  106 + }
  107 + if (c == '<') {
  108 + back();
  109 + return sb.toString().trim();
  110 + }
  111 + if (c == '&') {
  112 + sb.append(nextEntity(c));
  113 + } else {
  114 + sb.append(c);
  115 + }
  116 + c = next();
  117 + }
  118 + }
  119 +
  120 +
  121 + /**
  122 + * Return the next entity. These entities are translated to Characters:
  123 + * <code>&amp; &apos; &gt; &lt; &quot;</code>.
  124 + * @param ampersand An ampersand character.
  125 + * @return A Character or an entity String if the entity is not recognized.
  126 + * @throws JSONException If missing ';' in XML entity.
  127 + */
  128 + public Object nextEntity(char ampersand) throws JSONException {
  129 + StringBuilder sb = new StringBuilder();
  130 + for (;;) {
  131 + char c = next();
  132 + if (Character.isLetterOrDigit(c) || c == '#') {
  133 + sb.append(Character.toLowerCase(c));
  134 + } else if (c == ';') {
  135 + break;
  136 + } else {
  137 + throw syntaxError("Missing ';' in XML entity: &" + sb);
  138 + }
  139 + }
  140 + String string = sb.toString();
  141 + return unescapeEntity(string);
  142 + }
  143 +
  144 + /**
  145 + * Unescapes an XML entity encoding;
  146 + * @param e entity (only the actual entity value, not the preceding & or ending ;
  147 + * @return
  148 + */
  149 + static String unescapeEntity(String e) {
  150 + // validate
  151 + if (e == null || e.isEmpty()) {
  152 + return "";
  153 + }
  154 + // if our entity is an encoded unicode point, parse it.
  155 + if (e.charAt(0) == '#') {
  156 + int cp;
  157 + if (e.charAt(1) == 'x') {
  158 + // hex encoded unicode
  159 + cp = Integer.parseInt(e.substring(2), 16);
  160 + } else {
  161 + // decimal encoded unicode
  162 + cp = Integer.parseInt(e.substring(1));
  163 + }
  164 + return new String(new int[] {cp},0,1);
  165 + }
  166 + Character knownEntity = entity.get(e);
  167 + if(knownEntity==null) {
  168 + // we don't know the entity so keep it encoded
  169 + return '&' + e + ';';
  170 + }
  171 + return knownEntity.toString();
  172 + }
  173 +
  174 +
  175 + /**
  176 + * Returns the next XML meta token. This is used for skipping over <!...>
  177 + * and <?...?> structures.
  178 + * @return Syntax characters (<code>< > / = ! ?</code>) are returned as
  179 + * Character, and strings and names are returned as Boolean. We don't care
  180 + * what the values actually are.
  181 + * @throws JSONException If a string is not properly closed or if the XML
  182 + * is badly structured.
  183 + */
  184 + public Object nextMeta() throws JSONException {
  185 + char c;
  186 + char q;
  187 + do {
  188 + c = next();
  189 + } while (Character.isWhitespace(c));
  190 + switch (c) {
  191 + case 0:
  192 + throw syntaxError("Misshaped meta tag");
  193 + case '<':
  194 + return XML.LT;
  195 + case '>':
  196 + return XML.GT;
  197 + case '/':
  198 + return XML.SLASH;
  199 + case '=':
  200 + return XML.EQ;
  201 + case '!':
  202 + return XML.BANG;
  203 + case '?':
  204 + return XML.QUEST;
  205 + case '"':
  206 + case '\'':
  207 + q = c;
  208 + for (;;) {
  209 + c = next();
  210 + if (c == 0) {
  211 + throw syntaxError("Unterminated string");
  212 + }
  213 + if (c == q) {
  214 + return Boolean.TRUE;
  215 + }
  216 + }
  217 + default:
  218 + for (;;) {
  219 + c = next();
  220 + if (Character.isWhitespace(c)) {
  221 + return Boolean.TRUE;
  222 + }
  223 + switch (c) {
  224 + case 0:
  225 + case '<':
  226 + case '>':
  227 + case '/':
  228 + case '=':
  229 + case '!':
  230 + case '?':
  231 + case '"':
  232 + case '\'':
  233 + back();
  234 + return Boolean.TRUE;
  235 + }
  236 + }
  237 + }
  238 + }
  239 +
  240 +
  241 + /**
  242 + * Get the next XML TokenHolder. These tokens are found inside of angle
  243 + * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it
  244 + * may be a string wrapped in single quotes or double quotes, or it may be a
  245 + * name.
  246 + * @return a String or a Character.
  247 + * @throws JSONException If the XML is not well formed.
  248 + */
  249 + public Object nextToken() throws JSONException {
  250 + char c;
  251 + char q;
  252 + StringBuilder sb;
  253 + do {
  254 + c = next();
  255 + } while (Character.isWhitespace(c));
  256 + switch (c) {
  257 + case 0:
  258 + throw syntaxError("Misshaped element");
  259 + case '<':
  260 + throw syntaxError("Misplaced '<'");
  261 + case '>':
  262 + return XML.GT;
  263 + case '/':
  264 + return XML.SLASH;
  265 + case '=':
  266 + return XML.EQ;
  267 + case '!':
  268 + return XML.BANG;
  269 + case '?':
  270 + return XML.QUEST;
  271 +
  272 +// Quoted string
  273 +
  274 + case '"':
  275 + case '\'':
  276 + q = c;
  277 + sb = new StringBuilder();
  278 + for (;;) {
  279 + c = next();
  280 + if (c == 0) {
  281 + throw syntaxError("Unterminated string");
  282 + }
  283 + if (c == q) {
  284 + return sb.toString();
  285 + }
  286 + if (c == '&') {
  287 + sb.append(nextEntity(c));
  288 + } else {
  289 + sb.append(c);
  290 + }
  291 + }
  292 + default:
  293 +
  294 +// Name
  295 +
  296 + sb = new StringBuilder();
  297 + for (;;) {
  298 + sb.append(c);
  299 + c = next();
  300 + if (Character.isWhitespace(c)) {
  301 + return sb.toString();
  302 + }
  303 + switch (c) {
  304 + case 0:
  305 + return sb.toString();
  306 + case '>':
  307 + case '/':
  308 + case '=':
  309 + case '!':
  310 + case '?':
  311 + case '[':
  312 + case ']':
  313 + back();
  314 + return sb.toString();
  315 + case '<':
  316 + case '"':
  317 + case '\'':
  318 + throw syntaxError("Bad character in a name");
  319 + }
  320 + }
  321 + }
  322 + }
  323 +
  324 +
  325 + /**
  326 + * Skip characters until past the requested string.
  327 + * If it is not found, we are left at the end of the source with a result of false.
  328 + * @param to A string to skip past.
  329 + */
  330 + // The Android implementation of JSONTokener has a public method of public void skipPast(String to)
  331 + // even though ours does not have that method, to have API compatibility, our method in the subclass
  332 + // should match.
  333 + public void skipPast(String to) {
  334 + boolean b;
  335 + char c;
  336 + int i;
  337 + int j;
  338 + int offset = 0;
  339 + int length = to.length();
  340 + char[] circle = new char[length];
  341 +
  342 + /*
  343 + * First fill the circle buffer with as many characters as are in the
  344 + * to string. If we reach an early end, bail.
  345 + */
  346 +
  347 + for (i = 0; i < length; i += 1) {
  348 + c = next();
  349 + if (c == 0) {
  350 + return;
  351 + }
  352 + circle[i] = c;
  353 + }
  354 +
  355 + /* We will loop, possibly for all of the remaining characters. */
  356 +
  357 + for (;;) {
  358 + j = offset;
  359 + b = true;
  360 +
  361 + /* Compare the circle buffer with the to string. */
  362 +
  363 + for (i = 0; i < length; i += 1) {
  364 + if (circle[j] != to.charAt(i)) {
  365 + b = false;
  366 + break;
  367 + }
  368 + j += 1;
  369 + if (j >= length) {
  370 + j -= length;
  371 + }
  372 + }
  373 +
  374 + /* If we exit the loop with b intact, then victory is ours. */
  375 +
  376 + if (b) {
  377 + return;
  378 + }
  379 +
  380 + /* Get the next character. If there isn't one, then defeat is ours. */
  381 +
  382 + c = next();
  383 + if (c == 0) {
  384 + return;
  385 + }
  386 + /*
  387 + * Shove the character in the circle buffer and advance the
  388 + * circle offset. The offset is mod n.
  389 + */
  390 + circle[offset] = c;
  391 + offset += 1;
  392 + if (offset >= length) {
  393 + offset -= length;
  394 + }
  395 + }
  396 + }
  397 +}
src/main/java/com/bsth/data/zndd/baidu/speech/restapi/asrdemo/AsrMain.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.speech.restapi.asrdemo;
  2 +
  3 +import com.bsth.data.zndd.baidu.org.json.JSONObject;
  4 +import com.bsth.data.zndd.baidu.speech.restapi.common.ConnUtil;
  5 +import com.bsth.data.zndd.baidu.speech.restapi.common.DemoException;
  6 +import com.bsth.data.zndd.baidu.speech.restapi.common.TokenHolder;
  7 +import com.bsth.entity.sys.SysUser;
  8 +import com.bsth.security.util.SecurityUtils;
  9 +
  10 +import java.io.File;
  11 +import java.io.FileInputStream;
  12 +import java.io.IOException;
  13 +import java.net.HttpURLConnection;
  14 +import java.net.URL;
  15 +import java.util.Base64;
  16 +
  17 +public class AsrMain {
  18 +
  19 + private final boolean METHOD_RAW = false; // 默认以json方式上传音频文件
  20 +
  21 + // 填写网页上申请的appkey 如 $apiKey="g8eBUMSokVB1BHGmgxxxxxx"
  22 + private final String APP_KEY = "Oigm0L3Y8j78pDx6T5hFAmpD";
  23 +
  24 + // 填写网页上申请的APP SECRET 如 $SECRET_KEY="94dc99566550d87f8fa8ece112xxxxx"
  25 + private final String SECRET_KEY = "v7OFLoPOqZBHn21VUHgTRUhFkFcXBxib";
  26 +
  27 + //情感分析的
  28 + private final String App_ID = "28015871";
  29 + private final String API_Key = "FxxqPgNKzGoEA8NwR0jIuuoS";
  30 + private final String Secret_Key = "ljnHGV5UyOcIO5UYKrCgGHPaxLDBh5El";
  31 +
  32 +
  33 +
  34 +
  35 +
  36 +
  37 + private String CUID = "1234567JAVA";
  38 +
  39 + // 采样率固定值
  40 + private final int RATE = 16000;
  41 +
  42 + private String URL;
  43 +
  44 + private int DEV_PID;
  45 +
  46 + //private int LM_ID;//测试自训练平台需要打开此注释
  47 +
  48 + private String SCOPE;
  49 +
  50 + // 普通版 参数
  51 + {
  52 + URL = "http://vop.baidu.com/server_api"; // 可以改为https
  53 + // 1537 表示识别普通话,使用输入法模型。 其它语种参见文档
  54 + DEV_PID = 1537;
  55 + SCOPE = "audio_voice_assistant_get";
  56 + }
  57 +
  58 + // 自训练平台 参数
  59 + /*{
  60 + //自训练平台模型上线后,您会看见 第二步:“”获取专属模型参数pid:8001,modelid:1234”,按照这个信息获取 dev_pid=8001,lm_id=1234
  61 + DEV_PID = 8001;
  62 + LM_ID = 1234;
  63 + }*/
  64 +
  65 + /* 极速版 参数
  66 + {
  67 + URL = "http://vop.baidu.com/pro_api"; // 可以改为https
  68 + DEV_PID = 80001;
  69 + SCOPE = "brain_enhanced_asr";
  70 + }
  71 + */
  72 +
  73 + /* 忽略scope检查,非常旧的应用可能没有
  74 + {
  75 + SCOPE = null;
  76 + }
  77 + */
  78 +
  79 + /*public static void main(String[] args) throws IOException, DemoException {
  80 + AsrMain demo = new AsrMain();
  81 + // 填写下面信息
  82 + String result = demo.run();
  83 + System.out.println("识别结束:结果是:");
  84 +
  85 +
  86 + System.out.println(result);
  87 + // 如果显示乱码,请打开result.txt查看
  88 + File file = new File("result.txt");
  89 + FileWriter fo = new FileWriter(file);
  90 + fo.write(result);
  91 + fo.close();
  92 + System.out.println("Result also wrote into " + file.getAbsolutePath());
  93 + }*/
  94 +
  95 +
  96 + public String run() throws IOException, DemoException {
  97 + TokenHolder holder = new TokenHolder(APP_KEY, SECRET_KEY, SCOPE);
  98 + holder.resfresh();
  99 + String token = holder.getToken();
  100 + String result = null;
  101 + if (METHOD_RAW) {
  102 + result = runRawPostMethod(token);
  103 + } else {
  104 + result = runJsonPostMethod(token);
  105 + }
  106 + return result;
  107 + }
  108 +
  109 +
  110 +
  111 + private String runRawPostMethod(String token) throws IOException, DemoException {
  112 + SysUser user = SecurityUtils.getCurrentUser();
  113 + // 需要识别的文件
  114 + String FILENAME = "/pcm/test_"+user.getUserName()+".wav";
  115 + // 文件格式, 支持pcm/wav/amr 格式,极速版额外支持m4a 格式
  116 + String FORMAT = FILENAME.substring(FILENAME.length() - 3);
  117 + String url2 = URL + "?cuid=" + ConnUtil.urlEncode(CUID) + "&dev_pid=" + DEV_PID + "&token=" + token;
  118 + //测试自训练平台需要打开以下信息
  119 + //String url2 = URL + "?cuid=" + ConnUtil.urlEncode(CUID) + "&dev_pid=" + DEV_PID + "&lm_id="+ LM_ID + "&token=" + token;
  120 + String contentTypeStr = "audio/" + FORMAT + "; rate=" + RATE;
  121 + //System.out.println(url2);
  122 + byte[] content = getFileContent(FILENAME);
  123 + HttpURLConnection conn = (HttpURLConnection) new URL(url2).openConnection();
  124 + conn.setConnectTimeout(5000);
  125 + conn.setRequestProperty("Content-Type", contentTypeStr);
  126 + conn.setRequestMethod("POST");
  127 + conn.setDoOutput(true);
  128 + conn.getOutputStream().write(content);
  129 + conn.getOutputStream().close();
  130 + //System.out.println("url is " + url2);
  131 + //System.out.println("header is " + "Content-Type :" + contentTypeStr);
  132 + String result = ConnUtil.getResponseString(conn);
  133 + return result;
  134 + }
  135 +
  136 + public String runJsonPostMethod(String token) throws DemoException, IOException {
  137 + SysUser user = SecurityUtils.getCurrentUser();
  138 + // 需要识别的文件
  139 + String FILENAME = "/pcm/test_"+user.getUserName()+".wav";
  140 + // 文件格式, 支持pcm/wav/amr 格式,极速版额外支持m4a 格式
  141 + String FORMAT = FILENAME.substring(FILENAME.length() - 3);
  142 + byte[] content = getFileContent(FILENAME);
  143 + String speech = base64Encode(content);
  144 +
  145 + JSONObject params = new JSONObject();
  146 + params.put("dev_pid", DEV_PID);
  147 + //params.put("lm_id",LM_ID);//测试自训练平台需要打开注释
  148 + params.put("format", FORMAT);
  149 + params.put("rate", RATE);
  150 + params.put("token", token);
  151 + params.put("cuid", CUID);
  152 + params.put("channel", "1");
  153 + params.put("len", content.length);
  154 + params.put("speech", speech);
  155 +
  156 + // System.out.println(params.toString());
  157 + HttpURLConnection conn = (HttpURLConnection) new URL(URL).openConnection();
  158 + conn.setConnectTimeout(5000);
  159 + conn.setRequestMethod("POST");
  160 + conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
  161 + conn.setDoOutput(true);
  162 + conn.getOutputStream().write(params.toString().getBytes());
  163 + conn.getOutputStream().close();
  164 + String result = ConnUtil.getResponseString(conn);
  165 +
  166 +
  167 + params.put("speech", "base64Encode(getFileContent(FILENAME))");
  168 + //System.out.println("url is : " + URL);
  169 + //System.out.println("params is :" + params.toString());
  170 +
  171 +
  172 + return result;
  173 + }
  174 +
  175 + private byte[] getFileContent(String filename) throws DemoException, IOException {
  176 + File file = new File(filename);
  177 + if (!file.canRead()) {
  178 + System.err.println("文件不存在或者不可读: " + file.getAbsolutePath());
  179 + throw new DemoException("file cannot read: " + file.getAbsolutePath());
  180 + }
  181 + FileInputStream is = null;
  182 + try {
  183 + is = new FileInputStream(file);
  184 + return ConnUtil.getInputStreamContent(is);
  185 + } finally {
  186 + if (is != null) {
  187 + try {
  188 + is.close();
  189 + } catch (IOException e) {
  190 + e.printStackTrace();
  191 + }
  192 + }
  193 + }
  194 +
  195 + }
  196 +
  197 + private String base64Encode(byte[] content) {
  198 +
  199 + Base64.Encoder encoder = Base64.getEncoder(); // JDK 1.8 推荐方法
  200 + String str = encoder.encodeToString(content);
  201 +
  202 +
  203 + /* char[] chars = Base64Util.encode(content); // 1.7 及以下,不推荐,请自行跟换相关库
  204 + String str = new String(chars);
  205 +*/
  206 + return str;
  207 + }
  208 +
  209 +}
src/main/java/com/bsth/data/zndd/baidu/speech/restapi/asrdemo/Base64Util.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.speech.restapi.asrdemo;
  2 +
  3 +import java.io.*;
  4 +
  5 +/**
  6 + * Base64 编码和解码。
  7 + *
  8 + * @author jiangshuai
  9 + * @date 2016年10月03日
  10 + */
  11 +public class Base64Util {
  12 +
  13 + public Base64Util() {
  14 + }
  15 +
  16 + /**
  17 + * 功能:编码字符串
  18 + *
  19 + * @author jiangshuai
  20 + * @date 2016年10月03日
  21 + * @param data
  22 + * 源字符串
  23 + * @return String
  24 + */
  25 + public static String encode(String data) {
  26 + return new String(encode(data.getBytes()));
  27 + }
  28 +
  29 + /**
  30 + * 功能:解码字符串
  31 + *
  32 + * @author jiangshuai
  33 + * @date 2016年10月03日
  34 + * @param data
  35 + * 源字符串
  36 + * @return String
  37 + */
  38 + public static String decode(String data) {
  39 + return new String(decode(data.toCharArray()));
  40 + }
  41 +
  42 + /**
  43 + * 功能:编码byte[]
  44 + *
  45 + * @author jiangshuai
  46 + * @date 2016年10月03日
  47 + * @param data
  48 + * 源
  49 + * @return char[]
  50 + */
  51 + public static char[] encode(byte[] data) {
  52 + char[] out = new char[((data.length + 2) / 3) * 4];
  53 + for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
  54 + boolean quad = false;
  55 + boolean trip = false;
  56 +
  57 + int val = (0xFF & (int) data[i]);
  58 + val <<= 8;
  59 + if ((i + 1) < data.length) {
  60 + val |= (0xFF & (int) data[i + 1]);
  61 + trip = true;
  62 + }
  63 + val <<= 8;
  64 + if ((i + 2) < data.length) {
  65 + val |= (0xFF & (int) data[i + 2]);
  66 + quad = true;
  67 + }
  68 + out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
  69 + val >>= 6;
  70 + out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
  71 + val >>= 6;
  72 + out[index + 1] = alphabet[val & 0x3F];
  73 + val >>= 6;
  74 + out[index + 0] = alphabet[val & 0x3F];
  75 + }
  76 + return out;
  77 + }
  78 +
  79 + /**
  80 + * 功能:解码
  81 + *
  82 + * @author jiangshuai
  83 + * @date 2016年10月03日
  84 + * @param data
  85 + * 编码后的字符数组
  86 + * @return byte[]
  87 + */
  88 + public static byte[] decode(char[] data) {
  89 +
  90 + int tempLen = data.length;
  91 + for (int ix = 0; ix < data.length; ix++) {
  92 + if ((data[ix] > 255) || codes[data[ix]] < 0) {
  93 + --tempLen; // ignore non-valid chars and padding
  94 + }
  95 + }
  96 + // calculate required length:
  97 + // -- 3 bytes for every 4 valid base64 chars
  98 + // -- plus 2 bytes if there are 3 extra base64 chars,
  99 + // or plus 1 byte if there are 2 extra.
  100 +
  101 + int len = (tempLen / 4) * 3;
  102 + if ((tempLen % 4) == 3) {
  103 + len += 2;
  104 + }
  105 + if ((tempLen % 4) == 2) {
  106 + len += 1;
  107 +
  108 + }
  109 + byte[] out = new byte[len];
  110 +
  111 + int shift = 0; // # of excess bits stored in accum
  112 + int accum = 0; // excess bits
  113 + int index = 0;
  114 +
  115 + // we now go through the entire array (NOT using the 'tempLen' value)
  116 + for (int ix = 0; ix < data.length; ix++) {
  117 + int value = (data[ix] > 255) ? -1 : codes[data[ix]];
  118 +
  119 + if (value >= 0) { // skip over non-code
  120 + accum <<= 6; // bits shift up by 6 each time thru
  121 + shift += 6; // loop, with new bits being put in
  122 + accum |= value; // at the bottom.
  123 + if (shift >= 8) { // whenever there are 8 or more shifted in,
  124 + shift -= 8; // write them out (from the top, leaving any
  125 + out[index++] = // excess at the bottom for next iteration.
  126 + (byte) ((accum >> shift) & 0xff);
  127 + }
  128 + }
  129 + }
  130 +
  131 + // if there is STILL something wrong we just have to throw up now!
  132 + if (index != out.length) {
  133 + throw new Error("Miscalculated data length (wrote " + index
  134 + + " instead of " + out.length + ")");
  135 + }
  136 +
  137 + return out;
  138 + }
  139 +
  140 + /**
  141 + * 功能:编码文件
  142 + *
  143 + * @author jiangshuai
  144 + * @date 2016年10月03日
  145 + * @param file
  146 + * 源文件
  147 + */
  148 + public static void encode(File file) throws IOException {
  149 + if (!file.exists()) {
  150 + System.exit(0);
  151 + }
  152 +
  153 + else {
  154 + byte[] decoded = readBytes(file);
  155 + char[] encoded = encode(decoded);
  156 + writeChars(file, encoded);
  157 + }
  158 + file = null;
  159 + }
  160 +
  161 + /**
  162 + * 功能:解码文件。
  163 + *
  164 + * @author jiangshuai
  165 + * @date 2016年10月03日
  166 + * @param file
  167 + * 源文件
  168 + * @throws IOException
  169 + */
  170 + public static void decode(File file) throws IOException {
  171 + if (!file.exists()) {
  172 + System.exit(0);
  173 + } else {
  174 + char[] encoded = readChars(file);
  175 + byte[] decoded = decode(encoded);
  176 + writeBytes(file, decoded);
  177 + }
  178 + file = null;
  179 + }
  180 +
  181 + //
  182 + // code characters for values 0..63
  183 + //
  184 + private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  185 + .toCharArray();
  186 +
  187 + //
  188 + // lookup table for converting base64 characters to value in range 0..63
  189 + //
  190 + private static byte[] codes = new byte[256];
  191 + static {
  192 + for (int i = 0; i < 256; i++) {
  193 + codes[i] = -1;
  194 + // LoggerUtil.debug(i + "&" + codes[i] + " ");
  195 + }
  196 + for (int i = 'A'; i <= 'Z'; i++) {
  197 + codes[i] = (byte) (i - 'A');
  198 + // LoggerUtil.debug(i + "&" + codes[i] + " ");
  199 + }
  200 +
  201 + for (int i = 'a'; i <= 'z'; i++) {
  202 + codes[i] = (byte) (26 + i - 'a');
  203 + // LoggerUtil.debug(i + "&" + codes[i] + " ");
  204 + }
  205 + for (int i = '0'; i <= '9'; i++) {
  206 + codes[i] = (byte) (52 + i - '0');
  207 + // LoggerUtil.debug(i + "&" + codes[i] + " ");
  208 + }
  209 + codes['+'] = 62;
  210 + codes['/'] = 63;
  211 + }
  212 +
  213 + private static byte[] readBytes(File file) throws IOException {
  214 + ByteArrayOutputStream baos = new ByteArrayOutputStream();
  215 + byte[] b = null;
  216 + InputStream fis = null;
  217 + InputStream is = null;
  218 + try {
  219 + fis = new FileInputStream(file);
  220 + is = new BufferedInputStream(fis);
  221 + int count = 0;
  222 + byte[] buf = new byte[16384];
  223 + while ((count = is.read(buf)) != -1) {
  224 + if (count > 0) {
  225 + baos.write(buf, 0, count);
  226 + }
  227 + }
  228 + b = baos.toByteArray();
  229 +
  230 + } finally {
  231 + try {
  232 + if (fis != null)
  233 + fis.close();
  234 + if (is != null)
  235 + is.close();
  236 + if (baos != null)
  237 + baos.close();
  238 + } catch (Exception e) {
  239 + System.out.println(e);
  240 + }
  241 + }
  242 +
  243 + return b;
  244 + }
  245 +
  246 + private static char[] readChars(File file) throws IOException {
  247 + CharArrayWriter caw = new CharArrayWriter();
  248 + Reader fr = null;
  249 + Reader in = null;
  250 + try {
  251 + fr = new FileReader(file);
  252 + in = new BufferedReader(fr);
  253 + int count = 0;
  254 + char[] buf = new char[16384];
  255 + while ((count = in.read(buf)) != -1) {
  256 + if (count > 0) {
  257 + caw.write(buf, 0, count);
  258 + }
  259 + }
  260 +
  261 + } finally {
  262 + try {
  263 + if (caw != null)
  264 + caw.close();
  265 + if (in != null)
  266 + in.close();
  267 + if (fr != null)
  268 + fr.close();
  269 + } catch (Exception e) {
  270 + System.out.println(e);
  271 + }
  272 + }
  273 +
  274 + return caw.toCharArray();
  275 + }
  276 +
  277 + private static void writeBytes(File file, byte[] data) throws IOException {
  278 + OutputStream fos = null;
  279 + OutputStream os = null;
  280 + try {
  281 + fos = new FileOutputStream(file);
  282 + os = new BufferedOutputStream(fos);
  283 + os.write(data);
  284 +
  285 + } finally {
  286 + try {
  287 + if (os != null)
  288 + os.close();
  289 + if (fos != null)
  290 + fos.close();
  291 + } catch (Exception e) {
  292 + System.out.println(e);
  293 + }
  294 + }
  295 + }
  296 +
  297 + private static void writeChars(File file, char[] data) throws IOException {
  298 + Writer fos = null;
  299 + Writer os = null;
  300 + try {
  301 + fos = new FileWriter(file);
  302 + os = new BufferedWriter(fos);
  303 + os.write(data);
  304 +
  305 + } finally {
  306 + try {
  307 + if (os != null)
  308 + os.close();
  309 + if (fos != null)
  310 + fos.close();
  311 + } catch (Exception e) {
  312 + e.printStackTrace();
  313 + }
  314 + }
  315 + }
  316 +
  317 + // /////////////////////////////////////////////////
  318 + // end of test code.
  319 + // /////////////////////////////////////////////////
  320 +
  321 +}
0 \ No newline at end of file 322 \ No newline at end of file
src/main/java/com/bsth/data/zndd/baidu/speech/restapi/common/ConnUtil.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.speech.restapi.common;
  2 +
  3 +import java.io.ByteArrayOutputStream;
  4 +import java.io.IOException;
  5 +import java.io.InputStream;
  6 +import java.io.UnsupportedEncodingException;
  7 +import java.net.HttpURLConnection;
  8 +import java.net.URLEncoder;
  9 +
  10 +/**
  11 + * 与连接相关的Util类
  12 + */
  13 +public class ConnUtil {
  14 +
  15 + /**
  16 + * UrlEncode, UTF-8 编码
  17 + *
  18 + * @param str 原始字符串
  19 + * @return
  20 + */
  21 + public static String urlEncode(String str) {
  22 + String result = null;
  23 + try {
  24 + result = URLEncoder.encode(str, "UTF-8");
  25 + } catch (UnsupportedEncodingException e) {
  26 + e.printStackTrace();
  27 + }
  28 + return result;
  29 + }
  30 +
  31 + /**
  32 + * 从HttpURLConnection 获取返回的字符串
  33 + *
  34 + * @param conn
  35 + * @return
  36 + * @throws IOException
  37 + * @throws DemoException
  38 + */
  39 + public static String getResponseString(HttpURLConnection conn) throws IOException, DemoException {
  40 + return new String(getResponseBytes(conn));
  41 + }
  42 +
  43 + /**
  44 + * 从HttpURLConnection 获取返回的bytes
  45 + * 注意 HttpURLConnection自身问题, 400类错误,会直接抛出异常。不能获取conn.getInputStream();
  46 + *
  47 + * @param conn
  48 + * @return
  49 + * @throws IOException http请求错误
  50 + * @throws DemoException http 的状态码不是 200
  51 + */
  52 + public static byte[] getResponseBytes(HttpURLConnection conn) throws IOException, DemoException {
  53 + int responseCode = conn.getResponseCode();
  54 + InputStream inputStream = conn.getInputStream();
  55 + if (responseCode != 200) {
  56 + System.err.println("http 请求返回的状态码错误,期望200, 当前是 " + responseCode);
  57 + if (responseCode == 401) {
  58 + System.err.println("可能是appkey appSecret 填错");
  59 + }
  60 + System.err.println("response headers" + conn.getHeaderFields());
  61 + if (inputStream == null) {
  62 + inputStream = conn.getErrorStream();
  63 + }
  64 + byte[] result = getInputStreamContent(inputStream);
  65 + System.err.println(new String(result));
  66 +
  67 + throw new DemoException("http response code is" + responseCode);
  68 + }
  69 +
  70 + byte[] result = getInputStreamContent(inputStream);
  71 + return result;
  72 + }
  73 +
  74 + /**
  75 + * 将InputStream内的内容全部读取,作为bytes返回
  76 + *
  77 + * @param is
  78 + * @return
  79 + * @throws IOException @see InputStream.read()
  80 + */
  81 + public static byte[] getInputStreamContent(InputStream is) throws IOException {
  82 + byte[] b = new byte[1024];
  83 + // 定义一个输出流存储接收到的数据
  84 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  85 + // 开始接收数据
  86 + int len = 0;
  87 + while (true) {
  88 + len = is.read(b);
  89 + if (len == -1) {
  90 + // 数据读完
  91 + break;
  92 + }
  93 + byteArrayOutputStream.write(b, 0, len);
  94 + }
  95 + return byteArrayOutputStream.toByteArray();
  96 + }
  97 +}
src/main/java/com/bsth/data/zndd/baidu/speech/restapi/common/DemoException.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.speech.restapi.common;
  2 +
  3 +public class DemoException extends Exception {
  4 + public DemoException(String message) {
  5 + super(message);
  6 + }
  7 +}
src/main/java/com/bsth/data/zndd/baidu/speech/restapi/common/TokenHolder.java 0 → 100644
  1 +package com.bsth.data.zndd.baidu.speech.restapi.common;
  2 +
  3 +import com.bsth.data.zndd.baidu.org.json.JSONObject;
  4 +
  5 +import java.io.IOException;
  6 +import java.net.HttpURLConnection;
  7 +import java.net.URL;
  8 +
  9 +/**
  10 + * token的获取类
  11 + * 将apiKey和secretKey换取token,注意有效期保存在expiresAt
  12 + */
  13 +public class TokenHolder {
  14 +
  15 +
  16 + public static final String TTS_SCOPE = "audio_tts_post";
  17 +
  18 + /**
  19 + * url , Token的url,http可以改为https
  20 + */
  21 + private static final String url = "http://aip.baidubce.com/oauth/2.0/token";
  22 +
  23 + /**
  24 + * asr的权限 scope 是 "audio_voice_assistant_get"
  25 + * tts 的权限 scope 是 "audio_tts_post"
  26 + */
  27 + private String scope;
  28 +
  29 + /**
  30 + * 网页上申请语音识别应用获取的apiKey
  31 + */
  32 + private String apiKey;
  33 +
  34 + /**
  35 + * 网页上申请语音识别应用获取的secretKey
  36 + */
  37 + private String secretKey;
  38 +
  39 + /**
  40 + * 保存访问接口获取的token
  41 + */
  42 + private String token;
  43 +
  44 + /**
  45 + * 当前的时间戳,毫秒
  46 + */
  47 + private long expiresAt;
  48 +
  49 + /**
  50 + * @param apiKey 网页上申请语音识别应用获取的apiKey
  51 + * @param secretKey 网页上申请语音识别应用获取的secretKey
  52 + */
  53 + public TokenHolder(String apiKey, String secretKey, String scope) {
  54 + this.apiKey = apiKey;
  55 + this.secretKey = secretKey;
  56 + this.scope = scope;
  57 + }
  58 +
  59 +
  60 + /**
  61 + * 获取token,refresh 方法后调用有效
  62 + *
  63 + * @return
  64 + */
  65 + public String getToken() {
  66 + return token;
  67 + }
  68 +
  69 + /**
  70 + * 获取过期时间,refresh 方法后调用有效
  71 + *
  72 + * @return
  73 + */
  74 + public long getExpiresAt() {
  75 + return expiresAt;
  76 + }
  77 +
  78 +
  79 +
  80 +
  81 + /**
  82 + * 获取token
  83 + *
  84 + * @return
  85 + * @throws IOException http请求错误
  86 + * @throws DemoException http接口返回不是 200, access_token未获取
  87 + */
  88 + public void resfresh() throws IOException, DemoException {
  89 + String getTokenURL = url + "?grant_type=client_credentials"
  90 + + "&client_id=" + ConnUtil.urlEncode(apiKey) + "&client_secret=" + ConnUtil.urlEncode(secretKey);
  91 +
  92 + // 打印的url出来放到浏览器内可以复现
  93 + System.out.println("token url:" + getTokenURL);
  94 +
  95 + URL url = new URL(getTokenURL);
  96 + HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  97 + conn.setConnectTimeout(5000);
  98 + String result = ConnUtil.getResponseString(conn);
  99 + System.out.println("Token result json:" + result);
  100 + parseJson(result);
  101 + }
  102 +
  103 + /**
  104 + * @param result token接口获得的result
  105 + * @throws DemoException
  106 + */
  107 + private void parseJson(String result) throws DemoException {
  108 + JSONObject json = new JSONObject(result);
  109 + if (!json.has("access_token")) {
  110 + // 返回没有access_token字段
  111 + throw new DemoException("access_token not obtained, " + result);
  112 + }
  113 + if (!json.has("scope")) {
  114 + // 返回没有scope字段
  115 + throw new DemoException("scopenot obtained, " + result);
  116 + }
  117 + token = json.getString("access_token");
  118 + expiresAt = System.currentTimeMillis() + json.getLong("expires_in") * 1000;
  119 + }
  120 +}
src/main/java/com/bsth/data/zndd/voice/UploadVideoServlet.java 0 → 100644
  1 +package com.bsth.data.zndd.voice;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.bsth.data.BasicData;
  5 +import com.bsth.data.zndd.baidu.speech.restapi.asrdemo.AsrMain;
  6 +import com.bsth.entity.StationRoute;
  7 +import com.bsth.entity.sys.SysUser;
  8 +import com.bsth.security.util.SecurityUtils;
  9 +import com.bsth.service.StationRouteService;
  10 +import net.sourceforge.pinyin4j.PinyinHelper;
  11 +import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
  12 +import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
  13 +import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
  14 +import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
  15 +import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  16 +import org.apache.commons.fileupload.servlet.ServletFileUpload;
  17 +import org.springframework.beans.factory.annotation.Autowired;
  18 +import org.springframework.stereotype.Service;
  19 +import org.springframework.web.multipart.MultipartFile;
  20 +import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
  21 +
  22 +import javax.servlet.ServletException;
  23 +import javax.servlet.http.HttpServlet;
  24 +import javax.servlet.http.HttpServletRequest;
  25 +import javax.servlet.http.HttpServletResponse;
  26 +import java.io.*;
  27 +import java.util.*;
  28 +import java.util.regex.Matcher;
  29 +import java.util.regex.Pattern;
  30 +
  31 +
  32 +@Service
  33 +public class UploadVideoServlet extends HttpServlet {
  34 +
  35 + @Autowired
  36 + StationRouteService stationRouteService;
  37 +
  38 + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  39 + System.out.println("1");
  40 +
  41 + }
  42 +
  43 + //如果出现多线程的情况下 识别文件名称可以加上专属账号的属性
  44 + public void doPost(String line,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  45 + // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
  46 + String savePath = "/pcm";
  47 +
  48 + File file = new File(savePath);
  49 + // 判断上传文件的保存目录是否存在
  50 + if (!file.exists() && !file.isDirectory()) {
  51 + System.out.println(savePath + "目录不存在,需要创建");
  52 + // 创建目录
  53 + file.mkdir();
  54 + }
  55 + // 消息提示
  56 + String message = "";
  57 + try {
  58 + String filename = null;
  59 + // 使用Apache文件上传组件处理文件上传步骤:
  60 + // 1、创建一个DiskFileItemFactory工厂
  61 + DiskFileItemFactory factory = new DiskFileItemFactory();
  62 + // 2、创建一个文件上传解析器
  63 + ServletFileUpload upload = new ServletFileUpload(factory);
  64 + // 解决上传文件名的中文乱码
  65 + upload.setHeaderEncoding("UTF-8");
  66 + // 3、判断提交上来的数据是否是上传表单的数据
  67 + if (!ServletFileUpload.isMultipartContent(request)) {
  68 + // 按照传统方式获取数据
  69 + return;
  70 + }
  71 + StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request;
  72 + Iterator<String> iterator = req.getFileNames();
  73 +
  74 + String[] value = new String[5];
  75 + int i = 0;
  76 + while (iterator.hasNext()) {
  77 + MultipartFile item = req.getFile(iterator.next());
  78 + SysUser user = SecurityUtils.getCurrentUser();
  79 + // 如果fileitem中封装的是上传文件
  80 + // 得到上传的文件名称,
  81 + filename = "test_"+user.getUserName()+".wav";
  82 + //item.getName();
  83 + //System.out.println(filename);
  84 +
  85 + // 获取item中的上传文件的输入流
  86 + InputStream in = item.getInputStream();
  87 + // 创建一个文件输出流
  88 + FileOutputStream out = new FileOutputStream(savePath + "/" + filename);
  89 + // 创建一个缓冲区
  90 + byte buffer[] = new byte[1024];
  91 + // 判断输入流中的数据是否已经读完的标识
  92 + int len = 0;
  93 + // 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
  94 + while ((len = in.read(buffer)) > 0) {
  95 + // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
  96 + // + filename)当中
  97 + out.write(buffer, 0, len);
  98 + }
  99 + // 关闭输入流
  100 + in.close();
  101 + // 关闭输出流
  102 + out.close();
  103 + // 删除处理文件上传时生成的临时文件
  104 + //item.delete();
  105 + message = "文件上传成功!";
  106 + //System.out.println(message);
  107 + /*VoiceUtil voiceUtil= new VoiceUtil();
  108 + String str = voiceUtil.getWord(savePath + "/" + filename);
  109 + str = str.replace(" ","");*/
  110 + //语音转文字
  111 + AsrMain demo = new AsrMain();
  112 + // 填写下面信息
  113 + String result = demo.run();
  114 + JSONObject json = JSONObject.parseObject(result);
  115 + List textList = ( List)json.get("result");
  116 + String str = textList.get(0).toString().replace("。","");
  117 +
  118 +
  119 +
  120 + System.out.println("语音解析:"+str);
  121 + //定义输出类型
  122 + response.setHeader("Content-type", "text/html;charset=UTF-8");
  123 + PrintWriter writer = response.getWriter();
  124 + List<retun> list1 = new ArrayList<>();
  125 + String text = textList.get(0).toString();
  126 +
  127 +
  128 + //帮我添加一个夏硕路林兰路到鸿音路云端路的班次
  129 + String fcsj = null;//线路名,上下行,发车时间
  130 + String[] ks = text.replace(",","").split("到");
  131 + String Station1= ks[0].split("个")[1];
  132 + String Station2= ks[1].split("的")[0];
  133 + //发车时间
  134 + fcsj = extractTimes(text);
  135 + //线路名称 - 线路编码和名称对照
  136 +
  137 + Map<String, Object> param = new HashMap<>();
  138 + param.put("lineCode_eq", line);
  139 + param.put("directions_eq", 0);
  140 + param.put("destroy_eq", 0);
  141 + List<StationRoute> stationup = ((List<StationRoute>) stationRouteService.list(param));
  142 + //上行匹配
  143 + Map m = pyPp(stationup,Station1,Station2);
  144 + if (m.get("stationcode1") == null || m.get("stationcode2") == null){
  145 + param.put("directions_eq",1);
  146 + List<StationRoute> stationdown = ((List<StationRoute>) stationRouteService.list(param));
  147 + //下行匹配
  148 + Map smap = pyPp(stationdown,Station1,Station2);
  149 + if (smap.get("stationcode1") == null || smap.get("stationcode2") == null){
  150 + writer.write(text +","+"99999");
  151 + return;
  152 + }
  153 +
  154 + writer.write(text +","+smap.get("stationcode1")+","+smap.get("stationcode2")+","+1);
  155 + return;
  156 + }
  157 +
  158 + writer.write(text +","+m.get("stationcode1")+","+m.get("stationcode2")+","+0);
  159 + return;
  160 +
  161 + //打开0 关闭1 临加2 999异常
  162 + }
  163 +
  164 + } catch (Exception e) {
  165 + message = "文件上传失败!";
  166 + System.out.println(message);
  167 + e.printStackTrace();
  168 + }
  169 +
  170 + }
  171 +
  172 + public static Map pyPp(List<StationRoute> stationss,String Station1,String Station2){
  173 +
  174 + Double sity1 = 0D,sity2 = 0D; //拼音匹配百分比
  175 + Map m = new HashMap();
  176 + String stationcode1 = null,stationcode2 = null;//匹配的站点
  177 + Boolean st2 = false;
  178 + for (StationRoute st : stationss){
  179 + sity1 = calculateSimilarity(st.getStationName(), Station1);
  180 + if (sity1 >= 0.75 && !st2){
  181 + stationcode1 = st.getStationCode();
  182 + st2 =true;
  183 + }
  184 +
  185 + if (st2){
  186 + sity2 = calculateSimilarity(st.getStationName(), Station2);
  187 + if(sity2 >= 0.75){
  188 + stationcode2 = st.getStationCode();
  189 + }
  190 + }
  191 +
  192 + }
  193 + m.put("stationcode1",stationcode1);
  194 + m.put("stationcode2",stationcode2);
  195 +
  196 + return m;
  197 + }
  198 +
  199 +
  200 + private static final Pattern TIME_PATTERN =
  201 + Pattern.compile("([0-5][0-9]:[0-5][0-9])");
  202 + //获取添加班次时间
  203 + public static String extractTimes(String text) {
  204 + Matcher matcher = TIME_PATTERN.matcher(text);
  205 + while (matcher.find()) {
  206 + return matcher.group();
  207 + }
  208 + return "";
  209 + }
  210 +
  211 +
  212 + class retun {
  213 + private String tite;
  214 + private String txt;
  215 +
  216 +
  217 + public String getTite() {
  218 + return tite;
  219 + }
  220 +
  221 + public void setTite(String tite) {
  222 + this.tite = tite;
  223 + }
  224 +
  225 + public String getTxt() {
  226 + return txt;
  227 + }
  228 +
  229 + public void setTxt(String txt) {
  230 + this.txt = txt;
  231 + }
  232 + }
  233 +
  234 +
  235 +
  236 + public static String getPinyin(String chinese) {
  237 + HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
  238 + format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
  239 + format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
  240 +
  241 + StringBuilder pinyinBuilder = new StringBuilder();
  242 + char[] charArray = chinese.toCharArray();
  243 + for (char c : charArray) {
  244 + String[] pinyinArray = null;
  245 + try {
  246 + pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
  247 + } catch (BadHanyuPinyinOutputFormatCombination e) {
  248 + e.printStackTrace();
  249 + }
  250 + if (pinyinArray != null) {
  251 + pinyinBuilder.append(pinyinArray[0]);
  252 + } else {
  253 + pinyinBuilder.append(c);
  254 + }
  255 + }
  256 + return pinyinBuilder.toString();
  257 + }
  258 +
  259 + public static Double calculateSimilarity(String str1, String str2) {
  260 + String pinyinStr1 = getPinyin(str1);
  261 + String pinyinStr2 = getPinyin(str2);
  262 +
  263 + int len1 = pinyinStr1.length();
  264 + int len2 = pinyinStr2.length();
  265 + int[][] dp = new int[len1 + 1][len2 + 1];
  266 +
  267 + for (int i = 0; i <= len1; i++) {
  268 + dp[i][0] = 0;
  269 + }
  270 + for (int j = 0; j <= len2; j++) {
  271 + dp[0][j] = 0;
  272 + }
  273 +
  274 + for (int i = 1; i <= len1; i++) {
  275 + for (int j = 1; j <= len2; j++) {
  276 + if (pinyinStr1.charAt(i - 1) == pinyinStr2.charAt(j - 1)) {
  277 + dp[i][j] = dp[i - 1][j - 1] + 1;
  278 + } else {
  279 + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
  280 + }
  281 + }
  282 + }
  283 + return Double.valueOf(dp[len1][len2]) / len1;
  284 + }
  285 +
  286 +
  287 +
  288 +
  289 +
  290 +
  291 +}
0 \ No newline at end of file 292 \ No newline at end of file
src/main/java/com/bsth/data/zndd/voice/VoiceUtil.java 0 → 100644
  1 +package com.bsth.data.zndd.voice;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.sun.media.sound.WaveFileReader;
  6 +import com.sun.media.sound.WaveFileWriter;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.util.Assert;
  10 +import org.springframework.util.StringUtils;
  11 +import org.vosk.LibVosk;
  12 +import org.vosk.LogLevel;
  13 +import org.vosk.Model;
  14 +import org.vosk.Recognizer;
  15 +
  16 +import javax.sound.sampled.*;
  17 +import java.io.*;
  18 +import java.nio.file.Files;
  19 +import java.nio.file.Paths;
  20 +
  21 +public class VoiceUtil {
  22 + /* @Value("${leenleda.vosk.model}")
  23 + private String VOSKMODELPATH;*/
  24 +
  25 + Logger log = LoggerFactory.getLogger(this.getClass());
  26 + public String getWord(String filePath) throws IOException, UnsupportedAudioFileException {
  27 + Assert.isTrue(StringUtils.hasLength("D:\\pcm\\vosk-model-small-cn-0.22"), "无效的VOS模块!");
  28 + byte[] bytes = Files.readAllBytes(Paths.get(filePath));
  29 + // 转换为16KHZ
  30 + reSamplingAndSave(bytes, filePath);
  31 + File f = new File(filePath);
  32 + RandomAccessFile rdf = null;
  33 + rdf = new RandomAccessFile(f, "r");
  34 + log.info("声音尺寸:{}", toInt(read(rdf, 4, 4)));
  35 + log.info("音频格式:{}", toShort(read(rdf, 20, 2)));
  36 + short track = toShort(read(rdf, 22, 2));
  37 + log.info("1 单声道 2 双声道: {}", track);
  38 + log.info("采样率、音频采样级别 16000 = 16KHz: {}", toInt(read(rdf, 24, 4)));
  39 + log.info("每秒波形的数据量:{}", toShort(read(rdf, 22, 2)));
  40 + log.info("采样帧的大小:{}", toShort(read(rdf, 32, 2)));
  41 + log.info("采样位数:{}", toShort(read(rdf, 34, 2)));
  42 + rdf.close();
  43 + LibVosk.setLogLevel(LogLevel.WARNINGS);
  44 + try (
  45 + Model model = new Model("D:\\pcm\\vosk-model-small-cn-0.22");
  46 + InputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(filePath)));
  47 + // 采样率为音频采样率的声道倍数
  48 + Recognizer recognizer = new Recognizer(model, 16000 * track)) {
  49 +
  50 + recognizer.setWords(true);
  51 +
  52 + String result = recognizer.getFinalResult();
  53 + log.info("识别结果:{}", result);
  54 + if (StringUtils.hasLength(result)) {
  55 + JSONObject jsonObject = JSON.parseObject(result);
  56 + return jsonObject.getString("text").replace(" ", "");
  57 + }
  58 + return "";
  59 + }
  60 +
  61 +
  62 +
  63 + }
  64 +
  65 + public static int toInt(byte[] b) {
  66 + return (((b[3] & 0xff) << 24) + ((b[2] & 0xff) << 16) + ((b[1] & 0xff) << 8) + ((b[0] & 0xff) << 0));
  67 + }
  68 +
  69 + public static short toShort(byte[] b) {
  70 + return (short) ((b[1] << 8) + (b[0] << 0));
  71 + }
  72 +
  73 + public static byte[] read(RandomAccessFile rdf, int pos, int length) throws IOException {
  74 + rdf.seek(pos);
  75 + byte result[] = new byte[length];
  76 + for (int i = 0; i < length; i++) {
  77 + result[i] = rdf.readByte();
  78 + }
  79 + return result;
  80 + }
  81 +
  82 + public static void reSamplingAndSave(byte[] data, String path) throws IOException, UnsupportedAudioFileException {
  83 + WaveFileReader reader = new WaveFileReader();
  84 + AudioInputStream audioIn = reader.getAudioInputStream(new ByteArrayInputStream(data));
  85 + AudioFormat srcFormat = audioIn.getFormat();
  86 + int targetSampleRate = 16000;
  87 + AudioFormat dstFormat = new AudioFormat(srcFormat.getEncoding(),
  88 + targetSampleRate,
  89 + srcFormat.getSampleSizeInBits(),
  90 + srcFormat.getChannels(),
  91 + srcFormat.getFrameSize(),
  92 + srcFormat.getFrameRate(),
  93 + srcFormat.isBigEndian());
  94 + AudioInputStream convertedIn = AudioSystem.getAudioInputStream(dstFormat, audioIn);
  95 + File file = new File(path);
  96 + WaveFileWriter writer = new WaveFileWriter();
  97 + writer.write(convertedIn, AudioFileFormat.Type.WAVE, file);
  98 + }
  99 +}
0 \ No newline at end of file 100 \ No newline at end of file
src/main/java/com/bsth/service/zndd/LoggerZnddService.java
1 package com.bsth.service.zndd; 1 package com.bsth.service.zndd;
2 2
  3 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
3 import com.bsth.entity.zndd.LoggerZndd; 4 import com.bsth.entity.zndd.LoggerZndd;
4 import com.bsth.service.BaseService; 5 import com.bsth.service.BaseService;
5 6
@@ -10,4 +11,6 @@ public interface LoggerZnddService extends BaseService&lt;LoggerZndd, Integer&gt; { @@ -10,4 +11,6 @@ public interface LoggerZnddService extends BaseService&lt;LoggerZndd, Integer&gt; {
10 11
11 12
12 List<Map<String, Object>> listAll(Map<String, Object> map); 13 List<Map<String, Object>> listAll(Map<String, Object> map);
  14 +
  15 + public ScheduleRealInfo schlist(String lineCode,Integer dir);
13 } 16 }
src/main/java/com/bsth/service/zndd/impl/LoggerZnddServiceImpl.java
1 package com.bsth.service.zndd.impl; 1 package com.bsth.service.zndd.impl;
2 2
  3 +import com.bsth.data.schedule.DayOfSchedule;
  4 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
3 import com.bsth.entity.search.CustomerSpecs; 5 import com.bsth.entity.search.CustomerSpecs;
4 import com.bsth.entity.zndd.LoggerZndd; 6 import com.bsth.entity.zndd.LoggerZndd;
5 import com.bsth.repository.zndd.LoggerZnddRepository; 7 import com.bsth.repository.zndd.LoggerZnddRepository;
@@ -20,9 +22,25 @@ public class LoggerZnddServiceImpl extends BaseServiceImpl&lt;LoggerZndd, Integer&gt; @@ -20,9 +22,25 @@ public class LoggerZnddServiceImpl extends BaseServiceImpl&lt;LoggerZndd, Integer&gt;
20 22
21 @Autowired 23 @Autowired
22 LoggerZnddRepository loggerZnddRepository; 24 LoggerZnddRepository loggerZnddRepository;
  25 + @Autowired
  26 + DayOfSchedule dayOfSchedule;
23 public List<Map<String, Object>> listAll(Map<String, Object> map){ 27 public List<Map<String, Object>> listAll(Map<String, Object> map){
24 loggerZnddRepository.findAll((Sort) map); 28 loggerZnddRepository.findAll((Sort) map);
25 29
26 return null; 30 return null;
27 } 31 }
  32 +
  33 +
  34 + @Override
  35 + public ScheduleRealInfo schlist(String lineCode,Integer dir){
  36 + List<ScheduleRealInfo> list = dayOfSchedule.findByLineAndUpDown(lineCode,dir);
  37 + if (!list.isEmpty() ){
  38 + for (ScheduleRealInfo sr : list){
  39 + if(sr.getBcType().equals("normal")){
  40 + return sr;
  41 + }
  42 + }
  43 + }
  44 + return null;
  45 + };
28 } 46 }
src/main/resources/fatso/package.json
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 "cheerio": "^0.20.0", 12 "cheerio": "^0.20.0",
13 "clean-css": "^4.0.12", 13 "clean-css": "^4.0.12",
14 "colors": "^1.3.3", 14 "colors": "^1.3.3",
15 - "eventproxy": "^0.3.4", 15 + "eventproxy": "^0.3.5",
16 "uglify-js": "^2.6.2" 16 "uglify-js": "^2.6.2"
17 } 17 }
18 } 18 }
src/main/resources/static/real_control_v2/css/main.css
@@ -2243,4 +2243,15 @@ g.gps-wrap rect.twinkle[updown=&quot;1&quot;] { @@ -2243,4 +2243,15 @@ g.gps-wrap rect.twinkle[updown=&quot;1&quot;] {
2243 color: white; 2243 color: white;
2244 text-align: center; 2244 text-align: center;
2245 margin-top: 5px; 2245 margin-top: 5px;
  2246 +}
  2247 +#recidress{
  2248 + position: absolute;
  2249 + box-sizing: border-box;
  2250 + margin: 50px auto;
  2251 + padding: 20px;
  2252 + width: 280px;
  2253 + z-index: 9999;
  2254 + left: 40%;
  2255 + top: 20%;
  2256 + background: rgba(255, 255, 255, 0.5);
2246 } 2257 }
2247 \ No newline at end of file 2258 \ No newline at end of file
src/main/resources/static/real_control_v2/css/microphone.css 0 → 100644
  1 +.voluemImg {
  2 + background: url(microphone.png) no-repeat center center;
  3 +}
0 \ No newline at end of file 4 \ No newline at end of file
src/main/resources/static/real_control_v2/css/microphone.png 0 → 100644

2.02 KB

src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch/add_normal.html
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 <div class="uk-form-row"> 15 <div class="uk-form-row">
16 <label class="uk-form-label">上下行</label> 16 <label class="uk-form-label">上下行</label>
17 <div class="uk-form-controls"> 17 <div class="uk-form-controls">
18 - <select name="xlDir"> 18 + <select name="xlDir" id="xlDir">
19 <option value="0">上行</option> 19 <option value="0">上行</option>
20 <option value="1">下行</option> 20 <option value="1">下行</option>
21 </select> 21 </select>
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 <div class="uk-form-row"> 28 <div class="uk-form-row">
29 <label class="uk-form-label">起点站</label> 29 <label class="uk-form-label">起点站</label>
30 <div class="uk-form-controls"> 30 <div class="uk-form-controls">
31 - <select name="qdzCode"> 31 + <select name="qdzCode" id="qdzCode">
32 </select> 32 </select>
33 </div> 33 </div>
34 </div> 34 </div>
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 <div class="uk-form-row"> 37 <div class="uk-form-row">
38 <label class="uk-form-label">终点站</label> 38 <label class="uk-form-label">终点站</label>
39 <div class="uk-form-controls"> 39 <div class="uk-form-controls">
40 - <select name="zdzCode"> 40 + <select name="zdzCode" id="zdzCode">
41 </select> 41 </select>
42 </div> 42 </div>
43 </div> 43 </div>
@@ -166,11 +166,16 @@ @@ -166,11 +166,16 @@
166 //字典转换 166 //字典转换
167 dictionaryUtils.transformDom($('.nt-dictionary', f)); 167 dictionaryUtils.transformDom($('.nt-dictionary', f));
168 //validation 168 //validation
  169 +
169 f.formValidation({framework: 'uikit', locale: 'zh_CN'}); 170 f.formValidation({framework: 'uikit', locale: 'zh_CN'});
170 //autocomp 171 //autocomp
171 f.trigger('init-autoCom'); 172 f.trigger('init-autoCom');
172 173
  174 + $("#xlDir").val(sch.xlDir);
173 $f('bcType', f).trigger('change'); 175 $f('bcType', f).trigger('change');
  176 + $("#qdzCode").val(sch.qdzCode);
  177 + $("#zdzCode").val(sch.zdzCode);
  178 + $f('zdzCode', f).trigger('change');
174 return f; 179 return f;
175 } 180 }
176 181
src/main/resources/static/real_control_v2/js/data/json/north_toolbar.json
@@ -128,6 +128,12 @@ @@ -128,6 +128,12 @@
128 "text": "维修上报记录", 128 "text": "维修上报记录",
129 "event": "form_repairReport", 129 "event": "form_repairReport",
130 "icon": "uk-icon-table" 130 "icon": "uk-icon-table"
  131 + },
  132 + {
  133 + "id": 2.7,
  134 + "text": "智能调度执行记录",
  135 + "event": "form_loggerr_zndd",
  136 + "icon": "uk-icon-table"
131 } 137 }
132 ] 138 ]
133 }, 139 },
src/main/resources/static/real_control_v2/js/line_schedule/sch_table.js
1 /** schedule table */ 1 /** schedule table */
2 2
3 var gb_schedule_table = (function () { 3 var gb_schedule_table = (function () {
4 - 4 + var TablelineCode;
5 var temps; 5 var temps;
6 //线路分组的班次数据 6 //线路分组的班次数据
7 var line2Schedule = {}; 7 var line2Schedule = {};
@@ -65,6 +65,7 @@ var gb_schedule_table = (function () { @@ -65,6 +65,7 @@ var gb_schedule_table = (function () {
65 var lineCode, dirData, htmlStr; 65 var lineCode, dirData, htmlStr;
66 $('#main-tab-content .line_schedule').each(function () { 66 $('#main-tab-content .line_schedule').each(function () {
67 lineCode = $(this).data('id'); 67 lineCode = $(this).data('id');
  68 + TablelineCode = lineCode;
68 if (arrayIsNull(data[lineCode])) 69 if (arrayIsNull(data[lineCode]))
69 return true; 70 return true;
70 dirData = gb_common.groupBy(data[lineCode], 'xlDir'); 71 dirData = gb_common.groupBy(data[lineCode], 'xlDir');
@@ -937,6 +938,7 @@ var gb_schedule_table = (function () { @@ -937,6 +938,7 @@ var gb_schedule_table = (function () {
937 renderCarRemark: renderCarRemark, 938 renderCarRemark: renderCarRemark,
938 putSCodeErrorInfo: putSCodeErrorInfo, 939 putSCodeErrorInfo: putSCodeErrorInfo,
939 findSCodeErrorInfo: findSCodeErrorInfo, 940 findSCodeErrorInfo: findSCodeErrorInfo,
940 - refreshRfid: refreshRfid 941 + refreshRfid: refreshRfid,
  942 + TablelineCode : TablelineCode
941 }; 943 };
942 })(); 944 })();
src/main/resources/static/real_control_v2/js/main.js
1 /* main js */ 1 /* main js */
2 var gb_main_ep = new EventProxy(), 2 var gb_main_ep = new EventProxy(),
3 res_load_ep = EventProxy.create('load_data_basic', 'load_tab', 'load_home_layout', 'load_home_line_panel', function () { 3 res_load_ep = EventProxy.create('load_data_basic', 'load_tab', 'load_home_layout', 'load_home_line_panel', function () {
  4 +
  5 +
  6 + var recorder;
  7 + var fired = true;
  8 + document.onkeypress =function(e) { //对整个页面监听
  9 + var keyNum = window.event ? e.keyCode : e.which; //获取被按下的键值
  10 + //判断如果用户按下了回车键(keycody=13)
  11 + if (keyNum == 13) {
  12 + var id = document.getElementById("len");
  13 + if(fired)
  14 + fired = false;
  15 + else
  16 + return
  17 +
  18 + document.getElementById("recidress").style.display = "";
  19 + HZRecorder.get(function (rec) {
  20 + recorder = rec;
  21 + recorder.start();
  22 + });
  23 +
  24 +
  25 + }
  26 + }
  27 +
  28 + document.onkeyup =function(e) { //对整个页面监听
  29 + var keyNum = window.event ? e.keyCode : e.which; //获取被按下的键值
  30 + //判断如果用户按下了回车键(keycody=13)
  31 + if (keyNum == 13) {
  32 + fired = true;
  33 + debugger
  34 + let lineCode = gb_schedule_table.TablelineCode;
  35 + document.getElementById("recidress").style.display = 'none';
  36 + recorder.upload("zndd/do/"+lineCode, function (state, e) {
  37 + switch (state) {
  38 + case 'uploading':
  39 + //var `percentComplete` = Math.round(e.loaded * 100 / e.total) + '%';
  40 + break;
  41 + case 'ok':
  42 + // alert("识别成功");
  43 + break;
  44 + case 'error':
  45 + alert("识别失败");
  46 + break;
  47 + case 'cancel':
  48 + alert("识别被取消");
  49 + break;
  50 + }
  51 + });
  52 + }
  53 + };
  54 +
4 var eq = gb_main_ep; 55 var eq = gb_main_ep;
5 // basic data end 56 // basic data end
6 eq.once('data-basic', g_emit('tab')); 57 eq.once('data-basic', g_emit('tab'));
src/main/resources/static/real_control_v2/js/north/tabs.js
@@ -56,6 +56,7 @@ var gb_tabs = (function() { @@ -56,6 +56,7 @@ var gb_tabs = (function() {
56 else if(area.attr('id')=='north_tabs_map_btn'){ 56 else if(area.attr('id')=='north_tabs_map_btn'){
57 gb_map_overlay_mge.reload_gps(); 57 gb_map_overlay_mge.reload_gps();
58 }*/ 58 }*/
  59 + gb_schedule_table.TablelineCode = area[0].dataset.code;
59 if(area.attr('id')=='north_tabs_map_btn'){ 60 if(area.attr('id')=='north_tabs_map_btn'){
60 gb_map_overlay_mge.reload_gps();//刷新地图 61 gb_map_overlay_mge.reload_gps();//刷新地图
61 } 62 }
src/main/resources/static/real_control_v2/js/zndd/data_zndd.js
@@ -16,7 +16,7 @@ var gb_dataZndd = (function (){ @@ -16,7 +16,7 @@ var gb_dataZndd = (function (){
16 16
17 var timelist = [],interval; 17 var timelist = [],interval;
18 var dataMap = new Map(); 18 var dataMap = new Map();
19 - var leftTime = 1000 * 20;//剩余的毫秒数 19 + var leftTime = 1000 * 10;//剩余的毫秒数
20 var sop = function (data) { 20 var sop = function (data) {
21 21
22 //时间格式化 22 //时间格式化
src/main/resources/static/real_control_v2/js/zndd/recorder/microphone.js 0 → 100644
  1 +var microphone = (function() {
  2 + function isIE() {
  3 + return !!window.ActiveXObject || 'ActiveXObject' in window ? true : false
  4 + }
  5 + var _volume = function(id, vol) {
  6 + var volID = document.getElementById(id);
  7 + volID.innerHTML = '<div style="width: 120px;height: 120px;border-radius: 60px;background: #fff;border:#daf3fc 1px solid;position: relative;">' +
  8 + '<span style="display: block;width: 30px;height: 65px;position: absolute;left: 9px;top:26px;">' +
  9 + '<span style="display: block;position:relative;width: 30px;height: 32px;margin-bottom: 1px;">' +
  10 + '<i style="display: block;position: absolute;left: 0;bottom: 0;width: 2px;background: #c5f0ff;height:' + 11 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.4) + '"></i>' +
  11 + '<i style="display: block;position: absolute;left: 4px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 14 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.2) + '"></i>' +
  12 + '<i style="display: block;position: absolute;left: 8px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 17 * vol / 100 + 'px;opacity:' + (vol / 100 + 0) + '"></i>' +
  13 + '<i style="display: block;position: absolute;left: 12px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 20 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.2) + '"></i>' +
  14 + '<i style="display: block;position: absolute;left: 16px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 23 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.4) + '"></i>' +
  15 + '<i style="display: block;position: absolute;left: 20px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 26 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.6) + '"></i>' +
  16 + '<i style="display: block;position: absolute;left: 24px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 29 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.8) + '"></i>' +
  17 + '<i style="display: block;position: absolute;left: 28px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 32 * vol / 100 + 'px;opacity:' + (vol / 100 + 1) + '"></i>' +
  18 + '</span>' +
  19 + '<span style="display: block;position:relative;width: 30px;height: 32px;">' +
  20 + '<i style="display: block;position: absolute;left: 0;top: 0;width: 2px;background: #c5f0ff;height:' + 11 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.4) + '"></i>' +
  21 + '<i style="display: block;position: absolute;left: 4px;top: 0;width: 2px;background: #c5f0ff;height:' + 14 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.2) + '"></i>' +
  22 + '<i style="display: block;position: absolute;left: 8px;top: 0;width: 2px;background: #c5f0ff;height:' + 17 * vol / 100 + 'px;opacity:' + (vol / 100 + 0) + '"></i>' +
  23 + '<i style="display: block;position: absolute;left: 12px;top: 0;width: 2px;background: #c5f0ff;height:' + 20 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.2) + '"></i>' +
  24 + '<i style="display: block;position: absolute;left: 16px;top: 0;width: 2px;background: #c5f0ff;height:' + 23 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.4) + '"></i>' +
  25 + '<i style="display: block;position: absolute;left: 20px;top: 0;width: 2px;background: #c5f0ff;height:' + 26 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.6) + '"></i>' +
  26 + '<i style="display: block;position: absolute;left: 24px;top: 0;width: 2px;background: #c5f0ff;height:' + 29 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.8) + '"></i>' +
  27 + '<i style="display: block;position: absolute;left: 28px;top: 0;width: 2px;background: #c5f0ff;height:' + 32 * vol / 100 + 'px;opacity:' + (vol / 100 + 1) + '"></i>' +
  28 + '</span>' +
  29 + '</span>' +
  30 + '<span style="display:block;margin:31px auto;width: 36px;height: 58px;" class="voluemImg"></span>' +
  31 + '<span style="display: block;width: 30px;height: 65px;position: absolute;right: 9px;top:26px;">' +
  32 + '<span style="display: block;position:relative;width: 30px;height: 32px;margin-bottom: 1px;">' +
  33 + '<i style="display: block;position: absolute;left: 0;bottom: 0;width: 2px;background: #c5f0ff;height:' + 32 * vol / 100 + 'px;opacity:' + (vol / 100 + 1) + '"></i>' +
  34 + '<i style="display: block;position: absolute;left: 4px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 29 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.8) + '"></i>' +
  35 + '<i style="display: block;position: absolute;left: 8px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 26 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.6) + '"></i>' +
  36 + '<i style="display: block;position: absolute;left: 12px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 23 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.4) + '"></i>' +
  37 + '<i style="display: block;position: absolute;left: 16px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 20 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.2) + '"></i>' +
  38 + '<i style="display: block;position: absolute;left: 20px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 17 * vol / 100 + 'px;opacity:' + (vol / 100 + 0) + '"></i>' +
  39 + '<i style="display: block;position: absolute;left: 24px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 14 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.2) + '"></i>' +
  40 + '<i style="display: block;position: absolute;left: 28px;bottom: 0;width: 2px;background: #c5f0ff;height:' + 11 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.4) + '"></i>' +
  41 + '</span>' +
  42 + '<span style="display: block;position:relative;width: 30px;height: 32px;">' +
  43 + '<i style="display: block;position: absolute;left: 0;top: 0;width: 2px;background: #c5f0ff;height:' + 32 * vol / 100 + 'px;opacity:' + (vol / 100 + 1) + '"></i>' +
  44 + '<i style="display: block;position: absolute;left: 4px;top: 0;width: 2px;background: #c5f0ff;height:' + 29 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.8) + '"></i>' +
  45 + '<i style="display: block;position: absolute;left: 8px;top: 0;width: 2px;background: #c5f0ff;height:' + 26 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.6) + '"></i>' +
  46 + '<i style="display: block;position: absolute;left: 12px;top: 0;width: 2px;background: #c5f0ff;height:' + 23 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.4) + '"></i>' +
  47 + '<i style="display: block;position: absolute;left: 16px;top: 0;width: 2px;background: #c5f0ff;height:' + 20 * vol / 100 + 'px;opacity:' + (vol / 100 + 0.2) + '"></i>' +
  48 + '<i style="display: block;position: absolute;left: 20px;top: 0;width: 2px;background: #c5f0ff;height:' + 17 * vol / 100 + 'px;opacity:' + (vol / 100 + 0) + '"></i>' +
  49 + '<i style="display: block;position: absolute;left: 24px;top: 0;width: 2px;background: #c5f0ff;height:' + 14 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.2) + '"></i>' +
  50 + '<i style="display: block;position: absolute;left: 28px;top: 0;width: 2px;background: #c5f0ff;height:' + 11 * vol / 100 + 'px;opacity:' + (vol / 100 - 0.4) + '"></i>' +
  51 + '</span>' +
  52 + '</span>' +
  53 + '</div>';
  54 + }
  55 + return {
  56 + volume: _volume
  57 + };
  58 +})();
0 \ No newline at end of file 59 \ No newline at end of file
src/main/resources/static/real_control_v2/js/zndd/recorder/recorder.js
@@ -187,76 +187,40 @@ @@ -187,76 +187,40 @@
187 //notify_succ("您说的是:"+responseText[0]); 187 //notify_succ("您说的是:"+responseText[0]);
188 188
189 console.log(responseText); // 这里会输出 "Hello, World!" 189 console.log(responseText); // 这里会输出 "Hello, World!"
190 - let switchs = responseText[1];  
191 - let storage = window.localStorage;  
192 - if (switchs == 0){  
193 - storage.setItem("switchType", 1); //1开启  
194 - succll(responseText[0],zzdopen);  
195 - } else if (switchs == 1){  
196 - storage.setItem("switchType", 0); //0关闭  
197 - succll(responseText[0],zzdclone);  
198 -  
199 - } else if (switchs == 2){ //临加班次  
200 - let lineCode = gb_schedule_table.TablelineCode;  
201 - //打开临加班次  
202 - var folder = '/real_control_v2/fragments/line_schedule/context_menu';  
203 - var modal_opts = {  
204 - center: false,  
205 - bgclose: false  
206 - };  
207 -  
208 - debugger  
209 -  
210 - /*$.post('/znddLogger/schlist/'+lineCode,function(sch) {  
211 - sch.dir = responseText[3] == null ? sch.dir : responseText[3]  
212 - sch.fcsj = responseText[4] == null ? sch.fcsj : responseText[4]  
213 - if (sch != null && sch != "") {  
214 - open_modal(folder + '/temp_sch/main.html', {  
215 - sch: sch  
216 - }, modal_opts);  
217 - }else {  
218 - errll(nosche);  
219 - }  
220 - });*/  
221 - } else if (switchs == 3){ //撤销实发  
222 - let lineCode = gb_schedule_table.TablelineCode;  
223 - var content = '<h3>确定要对<span>' +lineCode +'</span>'+撤销+  
224 - '<span style="color:red;margin: 0 5px;">'+ responseText[4]+ '</span>的实发时间?</h3>'  
225 - alt_confirm(content, function () {  
226 - gb_common.$post('/realSchedule/revokeRealOutgo', {  
227 - id: that.data('id')  
228 - }, function (rs) {  
229 - gb_schedule_table.updateSchedule(rs.ts);  
230 - notify_succ('撤销实发操作成功!');  
231 - //calc 应发未发  
232 - gb_schedule_table.calc_yfwf_num(sch.xlBm);  
233 -  
234 - cb && cb();  
235 - $(this).parent().remove();  
236 - });  
237 - }, '确认撤销实发');  
238 - } else if (switchs == 4){ //撤销班次  
239 - lineCode = responseText[2] == null ? lineCode : responseText[2]  
240 - var content = '<h3>确定要对<span>' +lineCode +'</span>'+取消+  
241 - '<span style="color:red;margin: 0 5px;">'+ responseText[4]+ '</span>的班次?</h3>'  
242 - alt_confirm(content, function () {  
243 - gb_common.$post('/realSchedule/deleteRealSchedule', {  
244 - id: that.data('id')  
245 - }, function (rs) {  
246 - gb_schedule_table.updateSchedule(rs.ts);  
247 - notify_succ('撤销实发操作成功!');  
248 - //calc 应发未发  
249 - gb_schedule_table.calc_yfwf_num(sch.xlBm);  
250 -  
251 - cb && cb();  
252 - $(this).parent().remove();  
253 - });  
254 - }, '确认撤销实发');  
255 - }else{  
256 -  
257 - errll(responseText[0],error); 190 +
  191 + debugger
  192 + let lineCode = gb_schedule_table.TablelineCode;
  193 + //打开临加班次
  194 + var folder = '/real_control_v2/fragments/line_schedule/context_menu';
  195 + var modal_opts = {
  196 + center: false,
  197 + bgclose: false
  198 + };
  199 + /*var sch ={
  200 + xlBm : lineCode,
  201 + qdzCode : responseText[1],
  202 + zdzCode : responseText[2],
  203 + dir : responseText[3],
  204 + yuyin:111,
  205 + };*/
  206 + let date = {
  207 + lineCode :lineCode,
  208 + dir:responseText[3],
258 } 209 }
259 - 210 + $.post('/logZndd/schlist',date,function(sch) {
  211 + debugger
  212 + sch.qdzCode = responseText[1];
  213 + sch.zdzCode = responseText[2];
  214 + sch.xlDir = responseText[3];
  215 + sch.zdsjActual = moment(new Date()).format("HH:mm")
  216 +
  217 + open_modal(folder + '/temp_sch/main.html', {
  218 + sch: sch
  219 + }, modal_opts);
  220 + });
  221 +
  222 +
  223 +
260 } 224 }
261 }; 225 };
262 226
src/main/resources/static/real_control_v2/main.html
@@ -47,6 +47,11 @@ @@ -47,6 +47,11 @@
47 <!-- flatpickr --> 47 <!-- flatpickr -->
48 <link rel="stylesheet" href="/real_control_v2/assets/plugins/flatpickr/flatpickr.min.css" merge="plugins"> 48 <link rel="stylesheet" href="/real_control_v2/assets/plugins/flatpickr/flatpickr.min.css" merge="plugins">
49 <link rel="stylesheet" href="/real_control_v2/assets/plugins/flatpickr/themes/airbnb.css" merge="plugins"> 49 <link rel="stylesheet" href="/real_control_v2/assets/plugins/flatpickr/themes/airbnb.css" merge="plugins">
  50 +
  51 +
  52 + <!-- main style -->
  53 + <link rel="stylesheet" href="/real_control_v2/css/microphone.css" />
  54 +
50 </head> 55 </head>
51 56
52 <body> 57 <body>
@@ -322,6 +327,10 @@ @@ -322,6 +327,10 @@
322 <script src="/real_control_v2/js/stationcf/stationcf.js" merge="custom_js"></script> 327 <script src="/real_control_v2/js/stationcf/stationcf.js" merge="custom_js"></script>
323 <!--智能调度--> 328 <!--智能调度-->
324 <script src="/real_control_v2/js/zndd/data_zndd.js" merge="custom_js"></script> 329 <script src="/real_control_v2/js/zndd/data_zndd.js" merge="custom_js"></script>
  330 +
  331 +<!--语音图标-->
  332 +<script src="/real_control_v2/js/zndd//recorder/microphone.js"></script>
  333 +
325 <!--recorder--> 334 <!--recorder-->
326 <script src="/real_control_v2/js/zndd/recorder/recorder.js"></script> 335 <script src="/real_control_v2/js/zndd/recorder/recorder.js"></script>
327 <script src="/real_control_v2/js/zndd/recorder/recorders.js"></script> 336 <script src="/real_control_v2/js/zndd/recorder/recorders.js"></script>