From 4dc0b14e4d0377f7adde39eb7a028486d1bcde79 Mon Sep 17 00:00:00 2001
From: fiqare-emergya-dev
<47174790+fiqare-emergya-dev@users.noreply.github.com>
Date: Tue, 4 Feb 2020 08:55:22 +0100
Subject: [PATCH] FIX software quality improvement based on ISO25010
recommendations
---
.gitignore | 1 -
.travis.yml | 2 +-
CHANGES_NEXT_RELEASE | 1 +
README.md | 6 +-
documentation/architecture.md | 6 +-
documentation/deployment.md | 14 +-
documentation/images/architecture.dot | 10 +-
documentation/logs.md | 2 +-
perseo-main/pom.xml | 10 +
.../telefonica/iot/perseo/Configuration.java | 11 +-
.../com/telefonica/iot/perseo/Constants.java | 2 +-
.../telefonica/iot/perseo/EventsServlet.java | 29 +-
.../iot/perseo/GenericListener.java | 13 +-
.../iot/perseo/LogLevelServlet.java | 49 +-
.../com/telefonica/iot/perseo/Result.java | 1 -
.../telefonica/iot/perseo/RulesManager.java | 95 +-
.../telefonica/iot/perseo/RulesServlet.java | 111 +-
.../telefonica/iot/perseo/TimeRulesStore.java | 10 +-
.../java/com/telefonica/iot/perseo/Utils.java | 15 +-
.../com/telefonica/iot/perseo/Version.java | 1 -
perseo-main/src/main/java/org/json/CDL.java | 279 ---
.../src/main/java/org/json/Cookie.java | 169 --
.../src/main/java/org/json/CookieList.java | 89 -
perseo-main/src/main/java/org/json/HTTP.java | 163 --
.../src/main/java/org/json/HTTPTokener.java | 77 -
.../src/main/java/org/json/JSONArray.java | 977 ----------
.../src/main/java/org/json/JSONException.java | 43 -
.../src/main/java/org/json/JSONML.java | 467 -----
.../src/main/java/org/json/JSONObject.java | 1683 -----------------
.../src/main/java/org/json/JSONString.java | 18 -
.../src/main/java/org/json/JSONStringer.java | 78 -
.../src/main/java/org/json/JSONTokener.java | 446 -----
.../src/main/java/org/json/JSONWriter.java | 327 ----
perseo-main/src/main/java/org/json/Kim.java | 372 ----
.../src/main/java/org/json/Property.java | 72 -
perseo-main/src/main/java/org/json/README | 68 -
perseo-main/src/main/java/org/json/XML.java | 490 -----
.../src/main/java/org/json/XMLTokener.java | 365 ----
.../src/main/resources/perseo-core.properties | 1 -
.../iot/perseo/EventsServletTest.java | 13 +-
.../iot/perseo/GenericListenerTest.java | 8 +-
.../iot/perseo/LogLevelServletTest.java | 19 +-
.../iot/perseo/RulesManagerTest.java | 24 +-
.../iot/perseo/RulesServletTest.java | 39 +-
.../iot/perseo/TimeRulesStoreTest.java | 13 +-
.../com/telefonica/iot/perseo/UtilsTest.java | 29 +-
.../iot/perseo/test/EventBeanMock.java | 2 +-
.../com/telefonica/iot/perseo/test/Help.java | 87 +-
.../iot/perseo/test/ServletContextMock.java | 12 +-
.../iot/perseo/utils/DateTimeUtils.java | 67 +-
pom.xml | 2 +-
51 files changed, 402 insertions(+), 6486 deletions(-)
delete mode 100644 perseo-main/src/main/java/org/json/CDL.java
delete mode 100644 perseo-main/src/main/java/org/json/Cookie.java
delete mode 100644 perseo-main/src/main/java/org/json/CookieList.java
delete mode 100644 perseo-main/src/main/java/org/json/HTTP.java
delete mode 100644 perseo-main/src/main/java/org/json/HTTPTokener.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONArray.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONException.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONML.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONObject.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONString.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONStringer.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONTokener.java
delete mode 100644 perseo-main/src/main/java/org/json/JSONWriter.java
delete mode 100644 perseo-main/src/main/java/org/json/Kim.java
delete mode 100644 perseo-main/src/main/java/org/json/Property.java
delete mode 100644 perseo-main/src/main/java/org/json/README
delete mode 100644 perseo-main/src/main/java/org/json/XML.java
delete mode 100644 perseo-main/src/main/java/org/json/XMLTokener.java
diff --git a/.gitignore b/.gitignore
index ea3d611..05d31dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,3 @@ hs_err_pid*
target
nb-configuration.xml
nbactions.xml
-
diff --git a/.travis.yml b/.travis.yml
index 168e7d0..97c2b0a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,4 +36,4 @@ install:
- mvn test -B
before_install:
- - mvn clean
+ - mvn clean
\ No newline at end of file
diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE
index e69de29..7a9422e 100644
--- a/CHANGES_NEXT_RELEASE
+++ b/CHANGES_NEXT_RELEASE
@@ -0,0 +1 @@
+ - Hardening: software quality improvement based on ISO25010 recommendations
\ No newline at end of file
diff --git a/README.md b/README.md
index 3920316..2793183 100644
--- a/README.md
+++ b/README.md
@@ -13,9 +13,9 @@ This is the code repository for the EPL-server, named perseo-core.
* [Architecture](documentation/architecture.md)
* [Logs & Alarms](documentation/logs.md)
* O&M
- * [Deployment](documentation/deployment.md)
- * [Configuration](documentation/config.md)
- * [Administration](documentation/admin.md)
+ * [Deployment](documentation/deployment.md)
+ * [Configuration](documentation/config.md)
+ * [Administration](documentation/admin.md)
* [API](documentation/api.md)
* [License](#licence)
diff --git a/documentation/architecture.md b/documentation/architecture.md
index 816c814..21e73d0 100644
--- a/documentation/architecture.md
+++ b/documentation/architecture.md
@@ -19,11 +19,11 @@ Being this rule working
@Audit
select *,"blood_1_action" as iotcepaction,
ev.BloodPressure? as Pression,
- ev.id? as Meter
+ ev.id? as Meter
from pattern [
every ev=iotEvent(cast(cast(BloodPressure?,String),float)>1.5
- and type="BloodMeter")
- ]
+ and type="BloodMeter")
+ ]
```
and sending an event
```JSON
diff --git a/documentation/deployment.md b/documentation/deployment.md
index 5b56280..8b9d6b5 100644
--- a/documentation/deployment.md
+++ b/documentation/deployment.md
@@ -10,7 +10,7 @@ The only dependecy for perseo-core is the servlet engine container for its WAR f
You only need to do this once in your system:
- docker build -t perseo .
+ docker build -t perseo .
The parameter `-t perseo` gives the image a name. This name could be anything, or even include an organization like
`-t org/fiware-perseo`. This name is later used to run the container based on the image.
@@ -22,12 +22,12 @@ If you want to know more about images and the building process you can find it i
The following line will run the container, using a manually built image (see above),
exposing port `8080`, give it a name -in this case `perseo1`, and present a bash prompt:
- docker run -d --name perseo1 -p 8080:8080 perseo
+ docker run -d --name perseo1 -p 8080:8080 perseo
As a result of this command, there is a PERSEO listening on port 8080 on localhost. Try to see if it works now with
- curl localhost:8080/perseo-core/version
-
+ curl localhost:8080/perseo-core/version
+
To get access to the log file of Perseo Core you can run:
```
@@ -40,7 +40,7 @@ The following line will run the container, from Dockerhub, exposing port `8080`,
and binding it to a [Perseo Front-End](https://github.com/telefonicaid/perseo-fe)
instance (hostname `perseo-frontend`) listening on port 9090.
- docker run -d --name perseo_core -h perseocore -p 8080:8080 telefonicaiot/perseo-core:master -perseo_fe_url perseo-frontend:9090
+ docker run -d --name perseo_core -h perseocore -p 8080:8080 telefonicaiot/perseo-core:master -perseo_fe_url perseo-frontend:9090
A few points to consider:
@@ -121,5 +121,5 @@ Independently of how the service is installed, the log files will need an extern
Logrotate is installed as RPM dependency along with perseo. The system is configured to rotate every day and whenever the log file size is greater than 100MB (checked very 30 minutes by default):
* For daily rotation: /etc/logrotate.d/logrotate-perseo-daily: which enables daily log rotation
* For size-based rotation:
- * /etc/sysconfig/logrotate-perseo-size: in addition to the previous rotation, this file ensures log rotation if the log file grows beyond a given threshold (100 MB by default)
- * /etc/cron.d/cron-logrotate-perseo-size: which ensures the execution of etc/sysconfig/logrotate-perseo-size at a regular frecuency (default is 30 minutes)
+ * /etc/sysconfig/logrotate-perseo-size: in addition to the previous rotation, this file ensures log rotation if the log file grows beyond a given threshold (100 MB by default)
+ * /etc/cron.d/cron-logrotate-perseo-size: which ensures the execution of etc/sysconfig/logrotate-perseo-size at a regular frecuency (default is 30 minutes)
diff --git a/documentation/images/architecture.dot b/documentation/images/architecture.dot
index 3b5b46a..3e8b9bf 100644
--- a/documentation/images/architecture.dot
+++ b/documentation/images/architecture.dot
@@ -1,11 +1,11 @@
digraph perseocore {
- rankdir=LR
+ rankdir=LR
node [fontname = "arial"];
perseo[shape=circle, style=dashed];
- core[label=" core ", shape=circle];
+ core[label=" core ", shape=circle];
- perseo->core[label="rule"]
- perseo->core[label="event"]
- core->perseo[label="action"]
+ perseo->core[label="rule"]
+ perseo->core[label="event"]
+ core->perseo[label="action"]
}
diff --git a/documentation/logs.md b/documentation/logs.md
index ac8640e..8640faa 100644
--- a/documentation/logs.md
+++ b/documentation/logs.md
@@ -3,7 +3,7 @@
Logs have levels `FATAL`, `ERROR`, `INFO` and `DEBUG`. The log level must be set in the configuration file `log4j.xml`
```xml
-
+
```
Each log line contains several fields of the form *name*`=` *value*, separated by `|`
diff --git a/perseo-main/pom.xml b/perseo-main/pom.xml
index 50ed89e..a4bd2a5 100644
--- a/perseo-main/pom.xml
+++ b/perseo-main/pom.xml
@@ -78,6 +78,16 @@
com.telefonica.iot1.5.0-SNAPSHOT
+
+ org.json
+ json
+ 20180813
+
+
+ org.owasp.encoder
+ encoder
+ 1.2.2
+
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/Configuration.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/Configuration.java
index 90ba385..dffb2dd 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/Configuration.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/Configuration.java
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,7 +54,7 @@ private Configuration() {
private static long maxAge;
static {
- LOGGER.debug("Configuration init: " + reload());
+ LOGGER.debug(String.format("Configuration init: %s",reload()));
}
/**
@@ -95,10 +96,10 @@ public static synchronized boolean reload() {
// Add actions/do path if perseoFeURLEnv not contains it yet
actionRule = perseoFeURLEnv.contains(actionPath) ? perseoFeURLEnv : perseoFeURLEnv + actionPath;
} else {
- LOGGER.error("Invalid value for " + PERSEO_FE_URL_ENV + ": " + perseoFeURLEnv);
+ LOGGER.error(String.format("Invalid value for %s: %s",PERSEO_FE_URL_ENV, perseoFeURLEnv));
return false;
}
- LOGGER.info("actionRule configuration is: " + actionRule);
+ LOGGER.info(String.format("actionRule configuration is: %s",actionRule));
// Get MAX_AGE from env var if exist, else default
String maxAgeEnv = System.getenv(PERSEO_MAX_AGE_ENV);
@@ -106,10 +107,10 @@ public static synchronized boolean reload() {
try {
maxAge = maxAgeEnv != null ? Long.parseLong(maxAgeEnv) : Long.parseLong(defaultMaxAge);
} catch (NumberFormatException nfe) {
- LOGGER.error("Invalid value for " + PERSEO_MAX_AGE_ENV + ": " + nfe);
+ LOGGER.error(String.format("Invalid value for %s: %s",PERSEO_MAX_AGE_ENV,nfe));
return false;
}
- LOGGER.info("maxAge configuration is: " + maxAge);
+ LOGGER.info(String.format("maxAge configuration is: %s",maxAge));
return true;
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/Constants.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/Constants.java
index 2c76a2b..ee1f6eb 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/Constants.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/Constants.java
@@ -24,7 +24,7 @@
* @author brox
*/
public final class Constants {
- private Constants() { };
+ private Constants() {}
public static final String SERVICE_FIELD = "service";
public static final String SUBSERVICE_FIELD = "subservice";
public static final String CORRELATOR_HEADER = "fiware-correlator";
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/EventsServlet.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/EventsServlet.java
index b7aeb31..4c7ede8 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/EventsServlet.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/EventsServlet.java
@@ -33,6 +33,7 @@
import org.apache.log4j.MDC;
import org.json.JSONException;
import org.json.JSONObject;
+import org.owasp.encoder.Encode;
/**
*
@@ -42,7 +43,7 @@
public class EventsServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(EventsServlet.class);
- EPServiceProvider epService;
+ private static EPServiceProvider epService;
@Override
public void init() {
@@ -76,25 +77,25 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
Utils.putCorrelatorAndTrans(request);
logger.debug("events doPost");
response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
+ response.setContentType("application/json;charset=UTF-8");
try {
- StringBuilder sb = new StringBuilder();
String eventText = Utils.getBodyAsString(request);
- logger.info("incoming event:" + eventText);
+ logger.info(String.format("incoming event: %s", eventText));
org.json.JSONObject jo = new JSONObject(eventText);
- logger.debug("event as JSONObject: " + jo);
+ logger.debug(String.format("event as JSONObject: %s", jo));
Map eventMap = Utils.JSONObject2Map(jo);
- logger.debug("event as map: " + eventMap);
+ logger.debug(String.format("event as map: %s" , eventMap));
epService.getEPRuntime().sendEvent(eventMap, Constants.IOT_EVENT);
- logger.debug("event was sent: " + eventMap);
- } catch (JSONException je) {
- logger.error("error: " + je);
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- out.printf("{\"error\":\"%s\"}\n", je.getMessage());
- } finally {
- out.close();
+ logger.debug(String.format("event was sent: %s", eventMap));
+ } catch (Exception je) {
+ try {
+ logger.error(String.format("error: %s" ,je));
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ response.getOutputStream().print(String.format("{\"error\":\"%s\"}%n", Encode.forHtmlContent(je.getMessage())));
+ } catch (IOException exception) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
}
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/GenericListener.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/GenericListener.java
index c9bf114..ba42a83 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/GenericListener.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/GenericListener.java
@@ -49,8 +49,7 @@ public class GenericListener implements UpdateListener {
*/
@Override
public void update(EventBean[] newEvents, EventBean[] oldEvents) {
- try {
- HashMap rules = TimeRulesStore.getInstance().getAllRulesInfo();
+ try {
for (EventBean event : newEvents) {
JSONObject jo = Utils.Event2JSONObject(event);
@@ -64,15 +63,15 @@ public void update(EventBean[] newEvents, EventBean[] oldEvents) {
// Is a timed Rule. Set special headers using rule saved information
Utils.setTimerRuleHeaders(rule);
- LOGGER.info("Firing temporal rule: " + event);
+ LOGGER.info(String.format("Firing temporal rule: %s",event));
} else {
- LOGGER.info("Firing Rule: " + event);
+ LOGGER.info(String.format("Firing Rule: %s",event));
}
- LOGGER.debug("result errors: " + jo.optJSONObject("errors"));
- LOGGER.debug("result json: " + jo);
+ LOGGER.debug(String.format("result errors: %s",jo.optJSONObject("errors")));
+ LOGGER.debug(String.format("result json: %s", jo));
boolean ok = Utils.DoHTTPPost(Configuration.getActionURL(), jo.toString());
if (!ok) {
@@ -80,7 +79,7 @@ public void update(EventBean[] newEvents, EventBean[] oldEvents) {
}
}
} catch (PropertyAccessException pae) {
- LOGGER.error("doing action " + pae);
+ LOGGER.error(String.format("doing action %s",pae));
}
}
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/LogLevelServlet.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/LogLevelServlet.java
index dec916e..1f8c8ef 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/LogLevelServlet.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/LogLevelServlet.java
@@ -30,6 +30,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
+import org.owasp.encoder.Encode;
/**
@@ -65,21 +66,28 @@ public class LogLevelServlet extends HttpServlet {
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- String levelName = request.getParameter("level");
- logger.info("changing log level to " + levelName);
- Level level = levels.get(levelName);
- if (level == null) {
- logger.error("invalid log level: " + levelName);
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json");
+ try {
+ String levelName = request.getParameter("level");
+ logger.info(String.format("changing log level to %s",levelName));
+ Level level = levels.get(levelName);
+ if (level == null) {
+ logger.error(String.format("invalid log level: %s",levelName));
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json");
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ response.getOutputStream().print("{\"errorMessage\":\"invalid log level\"}");
+ return;
+ }
+ synchronized (mutex) {
+ LogManager.getRootLogger().setLevel(level);
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ } catch (IOException e) {
+ logger.error("IOException in log level");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- response.getOutputStream().print("{\"errorMessage\":\"invalid log level\"}");
return;
}
- synchronized (mutex) {
- LogManager.getRootLogger().setLevel(level);
- }
- response.setStatus(HttpServletResponse.SC_OK);
+
}
/**
@@ -95,11 +103,18 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.debug("getting log level");
synchronized (mutex) {
- String currentLevel = LogManager.getRootLogger().getLevel().toString();
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_OK);
- response.getOutputStream().print("{\"level\":\""+ currentLevel +"\"}");
+ try {
+ String currentLevel = LogManager.getRootLogger().getLevel().toString();
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json");
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.getOutputStream().print(String.format("{\"level\":\"%s\"}",Encode.forHtmlContent(currentLevel)));
+ } catch (IOException e) {
+ logger.error("IOException in log level");
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
}
}
/**
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/Result.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/Result.java
index 2dc9909..f909697 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/Result.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/Result.java
@@ -41,7 +41,6 @@ public class Result {
Result(int code, String msg) {
this.statusCode = code;
this.message = msg;
-
}
/**
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesManager.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesManager.java
index df53475..95622fe 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesManager.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesManager.java
@@ -41,7 +41,7 @@
*/
public class RulesManager {
- private static final Logger logger = LoggerFactory.getLogger(RulesServlet.class);
+ private static final Logger logger = LoggerFactory.getLogger(RulesManager.class);
/**
* Get a rule by name
@@ -52,9 +52,8 @@ public class RulesManager {
* @return Result object with a code and a JSON response
*/
public static synchronized Result get(EPServiceProvider epService, String ruleName) {
- try {
-
- logger.debug("rule asked for: " + ruleName);
+ try {
+ logger.debug(String.format("rule asked for: %s", ruleName));
ruleName = ruleName == null ? "" : ruleName;
EPAdministrator epa = epService.getEPAdministrator();
@@ -62,7 +61,7 @@ public static synchronized Result get(EPServiceProvider epService, String ruleNa
EPStatement st = epa.getStatement(ruleName);
if (st == null) {
return new Result(HttpServletResponse.SC_NOT_FOUND,
- String.format("{\"error\":\"%s not found\"}\n",
+ String.format("{\"error\":\"%s not found\"}%n",
ruleName));
} else {
return new Result(HttpServletResponse.SC_OK,
@@ -72,7 +71,7 @@ public static synchronized Result get(EPServiceProvider epService, String ruleNa
String[] sttmntNames = epa.getStatementNames();
JSONArray ja = new JSONArray();
for (String name : sttmntNames) {
- logger.debug("getting rule " + name);
+ logger.debug(String.format("getting rule %s", name));
EPStatement st = epa.getStatement(name);
ja.put(Utils.Statement2JSONObject(st));
}
@@ -80,9 +79,9 @@ public static synchronized Result get(EPServiceProvider epService, String ruleNa
}
} catch (EPException epe) {
- logger.error("getting statement" + epe);
+ logger.error(String.format("getting statement %s", epe));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(epe.getMessage())));
}
}
@@ -98,13 +97,12 @@ public static synchronized Result get(EPServiceProvider epService, String ruleNa
*/
public static synchronized Result make(EPServiceProvider epService, String text) {
try {
-
- logger.debug("rule text: " + text);
+ logger.debug(String.format("rule text: %s", text));
org.json.JSONObject jo = new JSONObject(text);
- logger.debug("rule as JSONObject: " + jo);
+ logger.debug(String.format("rule as JSONObject: %s", jo));
String name = jo.optString("name", "");
- logger.info("post rule: " + name);
+ logger.info(String.format("post rule: %s",name));
if ("".equals(name.trim())) {
return new Result(HttpServletResponse.SC_BAD_REQUEST,
"{\"error\":\"missing name\"}");
@@ -114,44 +112,44 @@ public static synchronized Result make(EPServiceProvider epService, String text)
return new Result(HttpServletResponse.SC_BAD_REQUEST,
"{\"error\":\"missing text\"}");
}
- logger.debug("statement name: " + name);
- logger.debug("statement text: " + newEpl);
+ logger.debug(String.format("statement name: %s",name));
+ logger.debug(String.format("statement text: %s",newEpl));
EPStatement statement;
EPStatement prevStmnt = epService.getEPAdministrator().getStatement(name);
if (prevStmnt == null) {
- logger.debug("found new statement: " + name);
+ logger.debug(String.format("found new statement: %s",name));
statement = epService.getEPAdministrator().createEPL(newEpl, name);
- logger.debug("statement json: " + Utils.Statement2JSONObject(statement));
+ logger.debug(String.format("statement json: %s", Utils.Statement2JSONObject(statement)));
statement.addListener(new GenericListener());
} else {
String oldEpl = prevStmnt.getText();
- logger.debug("old epl: " + oldEpl);
+ logger.debug(String.format("old epl: %s", oldEpl));
if (!newEpl.equals(oldEpl)) {
- logger.debug("found changed statement: " + name);
+ logger.debug(String.format("found changed statement: %s",name));
prevStmnt.destroy();
- logger.debug("deleted statement: " + name);
+ logger.debug(String.format("deleted statement: %s",name));
statement = epService.getEPAdministrator().createEPL(newEpl, name);
- logger.debug("re-created statement: " + name);
- logger.debug("statement json: " + Utils.Statement2JSONObject(statement));
+ logger.debug(String.format("re-created statement: %s", name));
+ logger.debug(String.format("statement json: %s", Utils.Statement2JSONObject(statement)));
statement.addListener(new GenericListener());
} else {
- logger.debug("found repeated statement: " + name);
+ logger.debug(String.format("found repeated statement: %s", name));
statement = prevStmnt;
}
}
return new Result(HttpServletResponse.SC_OK,
Utils.Statement2JSONObject(statement).toString());
} catch (EPException epe) {
- logger.error("creating statement " + epe);
+ logger.error(String.format("creating statement %s", epe));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(epe.getMessage())));
} catch (JSONException je) {
- logger.error("creating statement " + je);
+ logger.error(String.format("creating statement %s",je));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(je.getMessage())));
}
}
@@ -170,10 +168,10 @@ public static synchronized Result make(EPServiceProvider epService, String text)
public static synchronized Result updateAll(EPServiceProvider epService, String text) {
try {
long maxAge = Configuration.getMaxAge();
- logger.debug("rule block text: " + text);
+ logger.debug(String.format("rule block text: %s",text));
org.json.JSONArray ja = new JSONArray(text);
- logger.debug("rules as JSONArray: " + ja);
- logger.info("put rules+contexts: " + ja.length());
+ logger.debug(String.format("rules as JSONArray: %s", ja));
+ logger.info(String.format("put rules+contexts: %s", ja.length()));
Map newOnes = new LinkedHashMap();
Set oldOnesNames = new HashSet();
@@ -198,23 +196,23 @@ public static synchronized Result updateAll(EPServiceProvider epService, String
for (String n : newOnes.keySet()) {
String newEpl = newOnes.get(n);
if (!oldOnesNames.contains(n)) {
- logger.debug("found new statement: " + n);
+ logger.debug(String.format("found new statement: %s", n));
EPStatement statement = epService.getEPAdministrator().createEPL(newEpl, n);
- logger.debug("statement json: " + Utils.Statement2JSONObject(statement));
+ logger.debug(String.format("statement json: %s", Utils.Statement2JSONObject(statement)));
statement.addListener(new GenericListener());
} else {
EPStatement prevStmnt = epService.getEPAdministrator().getStatement(n);
String oldEPL = prevStmnt.getText();
if (!oldEPL.equals(newOnes.get(n))) {
- logger.debug("found changed statement: " + n);
+ logger.debug(String.format("found changed statement: %s", n));
prevStmnt.destroy();
- logger.debug("deleted statement: " + n);
+ logger.debug(String.format("deleted statement: %s", n));
EPStatement statement = epService.getEPAdministrator().createEPL(newEpl, n);
- logger.debug("re-created statement: " + n);
- logger.debug("statement json: " + Utils.Statement2JSONObject(statement));
+ logger.debug(String.format("re-created statement: %s" ,n));
+ logger.debug(String.format("statement json: %s", Utils.Statement2JSONObject(statement)));
statement.addListener(new GenericListener());
} else {
- logger.debug("identical statement: " + n);
+ logger.debug(String.format("identical statement: %s", n));
}
oldOnesNames.remove(n);
}
@@ -222,23 +220,23 @@ public static synchronized Result updateAll(EPServiceProvider epService, String
//Delete oldOnes if they are old enough
for (String o : oldOnesNames) {
EPStatement prevStmnt = epService.getEPAdministrator().getStatement(o);
- logger.debug("unexpected statement: " + o);
+ logger.debug(String.format("unexpected statement: %s" ,o));
if (prevStmnt.getTimeLastStateChange() < now - maxAge) {
- logger.debug("unexpected statement, too old: " + o);
+ logger.debug(String.format("unexpected statement, too old: %s", o));
prevStmnt.destroy();
- logger.debug("deleted garbage statement: " + o);
+ logger.debug(String.format("deleted garbage statement: %s", o));
}
}
return new Result(HttpServletResponse.SC_OK, "{}");
} catch (EPException epe) {
- logger.error("creating statement " + epe);
+ logger.error(String.format("creating statement %s", epe));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(epe.getMessage())));
} catch (JSONException je) {
- logger.error("creating statement " + je);
+ logger.error(String.format("creating statement %s", je));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(je.getMessage())));
}
}
@@ -254,21 +252,20 @@ public static synchronized Result updateAll(EPServiceProvider epService, String
*/
public static synchronized Result delete(EPServiceProvider epService, String ruleName) {
try {
-
ruleName = ruleName == null ? "" : ruleName;
- logger.debug("delete rule: " + ruleName);
+ logger.debug(String.format("delete rule: %s" ,ruleName));
EPAdministrator epa = epService.getEPAdministrator();
if (ruleName.length() != 0) {
EPStatement st = epa.getStatement(ruleName);
//Allow to delete inexistent rule
if (st != null) {
- logger.debug("deleted statement: " + ruleName);
+ logger.debug(String.format("deleted statement: %s", ruleName));
st.destroy();
return new Result(HttpServletResponse.SC_OK,
Utils.Statement2JSONObject(st).toString());
} else {
- logger.debug("asked for deleting inexistent statement: " + ruleName);
+ logger.debug(String.format("asked for deleting inexistent statement: %s",ruleName));
return new Result(HttpServletResponse.SC_OK, "{}");
}
@@ -277,9 +274,9 @@ public static synchronized Result delete(EPServiceProvider epService, String rul
}
} catch (EPException epe) {
- logger.error("deleting statement " + epe);
+ logger.error(String.format("deleting statement %s", epe));
return new Result(HttpServletResponse.SC_BAD_REQUEST,
- String.format("{\"error\":%s}\n",
+ String.format("{\"error\":%s}%n",
JSONObject.valueToString(epe.getMessage())));
}
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesServlet.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesServlet.java
index 90bdc9c..9c40a54 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesServlet.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/RulesServlet.java
@@ -31,6 +31,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.MDC;
+import org.owasp.encoder.Encode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +43,7 @@
public class RulesServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(RulesServlet.class);
- EPServiceProvider epService;
+ private static EPServiceProvider epService;
@Override
public void init() throws ServletException {
@@ -81,17 +82,20 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)
Utils.putCorrelatorAndTrans(request);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- logger.info("get rule " + request.getPathInfo());
- String ruleName = request.getPathInfo();
- //request.getPathInfo() returns null or the extra path information
- //that follows the servlet path but precedes the query string and will
- //start with a "/" character. So, we remove it with .substring(1)
- ruleName = ruleName == null ? "/" : ruleName;
- Result r = RulesManager.get(epService, ruleName.substring(1));
- response.setStatus(r.getStatusCode());
- out.println(r.getMessage());
- out.close();
+ try {
+ logger.info(String.format("get rule %s", request.getPathInfo()));
+ String ruleName = request.getPathInfo();
+ //request.getPathInfo() returns null or the extra path information
+ //that follows the servlet path but precedes the query string and will
+ //start with a "/" character. So, we remove it with .substring(1)
+ ruleName = ruleName == null ? "/" : ruleName;
+ Result r = RulesManager.get(epService, ruleName.substring(1));
+ response.setStatus(r.getStatusCode());
+ response.getOutputStream().print(Encode.forHtmlContent(r.getMessage()));
+ } catch (Exception je) {
+ logger.error(String.format("error: %s" ,je));
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
}
@@ -108,16 +112,21 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
Utils.putCorrelatorAndTrans(request);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- String body = Utils.getBodyAsString(request);
- // Save temporary rules, not triggered by events external to the core
- TimeRulesStore.getInstance().saveTimeRules(body);
+ try {
+ String body = Utils.getBodyAsString(request);
+
+ // Save temporary rules, not triggered by events external to the core
+ TimeRulesStore.getInstance().saveTimeRules(body);
+
+ Result r = RulesManager.make(epService, body);
+ response.setStatus(r.getStatusCode());
+ response.getOutputStream().print(Encode.forHtmlContent(r.getMessage()));
+ } catch (Exception je) {
+ logger.error(String.format("error: %s" ,je));
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
- Result r = RulesManager.make(epService, body);
- response.setStatus(r.getStatusCode());
- out.println(r.getMessage());
- out.close();
}
/**
@@ -134,16 +143,19 @@ protected void doPut(HttpServletRequest request, HttpServletResponse response)
Utils.putCorrelatorAndTrans(request);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- String body = Utils.getBodyAsString(request);
-
- // Save timed rules, which are not activated by events external to the core
- TimeRulesStore.getInstance().saveTimeRules(body);
-
- Result r = RulesManager.updateAll(epService, body);
- response.setStatus(r.getStatusCode());
- out.println(r.getMessage());
- out.close();
+ try {
+ String body = Utils.getBodyAsString(request);
+
+ // Save timed rules, which are not activated by events external to the core
+ TimeRulesStore.getInstance().saveTimeRules(body);
+
+ Result r = RulesManager.updateAll(epService, body);
+ response.setStatus(r.getStatusCode());
+ response.getOutputStream().print(Encode.forHtmlContent(r.getMessage()));
+ } catch (Exception je) {
+ logger.error(String.format("error: %s" ,je));
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
}
/**
@@ -160,26 +172,29 @@ protected void doDelete(HttpServletRequest request, HttpServletResponse response
Utils.putCorrelatorAndTrans(request);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- logger.info("delete rule " + request.getPathInfo());
- //request.getPathInfo() returns null or the extra path information
- //that follows the servlet path but precedes the query string and will
- //start with a "/" character. So, we remove it with .substring(1)
- String ruleName = request.getPathInfo();
- if (ruleName == null) {
- response.setStatus(400);
- out.println("Deleting a rule require valid ruleName parameter");
- out.close();
- return;
+ try {
+ logger.info(String.format("delete rule %s", request.getPathInfo()));
+ //request.getPathInfo() returns null or the extra path information
+ //that follows the servlet path but precedes the query string and will
+ //start with a "/" character. So, we remove it with .substring(1)
+ String ruleName = request.getPathInfo();
+ if (ruleName == null) {
+ response.setStatus(400);
+ response.getOutputStream().print("Deleting a rule require valid ruleName parameter");
+ return;
+ }
+ Result r = RulesManager.delete(epService, ruleName.substring(1));
+
+ // Delete timed rule if necessary
+ TimeRulesStore.getInstance().removeTimeRule(ruleName.substring(1));
+
+ response.setStatus(r.getStatusCode());
+ response.getOutputStream().print(r.getMessage());
+ } catch (Exception je) {
+ logger.error(String.format("error: %s" ,je));
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
- Result r = RulesManager.delete(epService, ruleName.substring(1));
-
- // Delete timed rule if necessary
- TimeRulesStore.getInstance().removeTimeRule(ruleName.substring(1));
- response.setStatus(r.getStatusCode());
- out.println(r.getMessage());
- out.close();
}
/**
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/TimeRulesStore.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/TimeRulesStore.java
index a1e7e67..8f07f35 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/TimeRulesStore.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/TimeRulesStore.java
@@ -57,7 +57,7 @@ public static TimeRulesStore getInstance() {
* @param body POST or PUT body with rules data
*/
public void saveTimeRules(String body) {
- LOGGER.debug("Saving timerules from body: " + body);
+ LOGGER.debug(String.format("Saving timerules from body: %s", body));
if (body.equals("")) {
return;
} else {
@@ -81,10 +81,10 @@ public void saveTimeRules(String body) {
ruleText = (String) jo.getJSONObject(i).get("text");
} catch (JSONException e) {
// Invalid Rule
- LOGGER.error("invalid rule " + i + " by: " + e.getMessage());
+ LOGGER.error(String.format("invalid rule %s by %s", i,e.getMessage()));
continue;
}
- LOGGER.debug("Checking rule " + i + ": " + strName);
+ LOGGER.debug(String.format("Checking rule %s: %s",i, strName));
// Only "Timed Rules"
if (!strName.startsWith("ctxt$") && isTimeRule(ruleText)) {
@@ -95,7 +95,7 @@ public void saveTimeRules(String body) {
context.remove(0);
jo.getJSONObject(i).put("subservice", "/" + String.join("/", context));
rulesInfo.put(ruleName.get(0), jo.getJSONObject(i));
- LOGGER.info("Time rule " + i + " " + ruleName + " added");
+ LOGGER.info(String.format("Time rule %s %s added",i, ruleName));
}
}
}
@@ -146,7 +146,7 @@ public JSONObject getRuleInfo(String ruleName) {
* @param ruleName The rule name. Can include optionally '@context...' in the name
*/
public void removeTimeRule(String ruleName) {
- LOGGER.info("Removing timerule: " + ruleName);
+ LOGGER.info(String.format("Removing timerule: %s",ruleName));
if (ruleName != null) {
rulesInfo.remove(ruleName.split("@")[0]);
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/Utils.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/Utils.java
index cbdd4b4..a1bfc52 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/Utils.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/Utils.java
@@ -81,7 +81,6 @@ public static synchronized EPServiceProvider initEPService(ServletContext sc) {
// Add Single row function for perseo-utils functions
try {
-
cfg.addPlugInSingleRowFunction("getNextSunrise",
"com.telefonica.iot.perseo.utils.DateTimeUtils",
"getNextSunrise", ConfigurationPlugInSingleRowFunction.ValueCache.DISABLED);
@@ -223,31 +222,31 @@ public static boolean DoHTTPPost(String urlStr, String content) {
int code = urlConn.getResponseCode();
String message = urlConn.getResponseMessage();
- logger.debug("action http response " + code + " " + message);
+ logger.debug(String.format("action http response %s %s",code,message));
if (code / 100 == 2) {
InputStream input = urlConn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
for (String line; (line = reader.readLine()) != null;) {
- logger.info("action response body: " + line);
+ logger.info(String.format("action response body: %s", line));
}
input.close();
return true;
} else {
- logger.error("action response is not OK: " + code + " " + message);
+ logger.error(String.format("action response is not OK: %s %s",code,message));
InputStream error = urlConn.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(error));
for (String line; (line = reader.readLine()) != null;) {
- logger.error("action error response body: " + line);
+ logger.error(String.format("action error response body: %s", line));
}
error.close();
return false;
}
} catch (MalformedURLException me) {
- logger.error("exception MalformedURLException: " + me);
+ logger.error(String.format("exception MalformedURLException: %s",me));
return false;
} catch (IOException ioe) {
- logger.error("exception IOException: " + ioe);
+ logger.error(String.format("exception IOException: %s",ioe));
return false;
}
}
@@ -296,7 +295,7 @@ public static void putCorrelatorAndTrans(HttpServletRequest req) {
*
*/
public static String getBodyAsString(HttpServletRequest request) throws IOException {
- logger.debug("request.getCharacterEncoding() " + request.getCharacterEncoding());
+ logger.debug(String.format("request.getCharacterEncoding() %s", request.getCharacterEncoding()));
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
diff --git a/perseo-main/src/main/java/com/telefonica/iot/perseo/Version.java b/perseo-main/src/main/java/com/telefonica/iot/perseo/Version.java
index 45fb315..526bfec 100644
--- a/perseo-main/src/main/java/com/telefonica/iot/perseo/Version.java
+++ b/perseo-main/src/main/java/com/telefonica/iot/perseo/Version.java
@@ -46,7 +46,6 @@ private Version() {
LOGGER.error(ioe.getMessage());
POM.setProperty("version", "UNKNOWN");
}
-
}
/**
diff --git a/perseo-main/src/main/java/org/json/CDL.java b/perseo-main/src/main/java/org/json/CDL.java
deleted file mode 100644
index 995b1d4..0000000
--- a/perseo-main/src/main/java/org/json/CDL.java
+++ /dev/null
@@ -1,279 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * This provides static methods to convert comma delimited text into a
- * JSONArray, and to covert a JSONArray into comma delimited text. Comma
- * delimited text is a very popular format for data interchange. It is
- * understood by most database, spreadsheet, and organizer programs.
- *
- * Each row of text represents a row in a table or a data record. Each row
- * ends with a NEWLINE character. Each row contains one or more values.
- * Values are separated by commas. A value can contain any character except
- * for comma, unless is is wrapped in single quotes or double quotes.
- *
- * The first row usually contains the names of the columns.
- *
- * A comma delimited list can be converted into a JSONArray of JSONObjects.
- * The names for the elements in the JSONObjects can be taken from the names
- * in the first row.
- * @author JSON.org
- * @version 2014-05-03
- */
-public class CDL {
-
- /**
- * Get the next value. The value can be wrapped in quotes. The value can
- * be empty.
- * @param x A JSONTokener of the source text.
- * @return The value string, or null if empty.
- * @throws JSONException if the quoted string is badly formed.
- */
- private static String getValue(JSONTokener x) throws JSONException {
- char c;
- char q;
- StringBuffer sb;
- do {
- c = x.next();
- } while (c == ' ' || c == '\t');
- switch (c) {
- case 0:
- return null;
- case '"':
- case '\'':
- q = c;
- sb = new StringBuffer();
- for (;;) {
- c = x.next();
- if (c == q) {
- break;
- }
- if (c == 0 || c == '\n' || c == '\r') {
- throw x.syntaxError("Missing close quote '" + q + "'.");
- }
- sb.append(c);
- }
- return sb.toString();
- case ',':
- x.back();
- return "";
- default:
- x.back();
- return x.nextTo(',');
- }
- }
-
- /**
- * Produce a JSONArray of strings from a row of comma delimited values.
- * @param x A JSONTokener of the source text.
- * @return A JSONArray of strings.
- * @throws JSONException
- */
- public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
- JSONArray ja = new JSONArray();
- for (;;) {
- String value = getValue(x);
- char c = x.next();
- if (value == null ||
- (ja.length() == 0 && value.length() == 0 && c != ',')) {
- return null;
- }
- ja.put(value);
- for (;;) {
- if (c == ',') {
- break;
- }
- if (c != ' ') {
- if (c == '\n' || c == '\r' || c == 0) {
- return ja;
- }
- throw x.syntaxError("Bad character '" + c + "' (" +
- (int)c + ").");
- }
- c = x.next();
- }
- }
- }
-
- /**
- * Produce a JSONObject from a row of comma delimited text, using a
- * parallel JSONArray of strings to provides the names of the elements.
- * @param names A JSONArray of names. This is commonly obtained from the
- * first row of a comma delimited text file using the rowToJSONArray
- * method.
- * @param x A JSONTokener of the source text.
- * @return A JSONObject combining the names and values.
- * @throws JSONException
- */
- public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
- throws JSONException {
- JSONArray ja = rowToJSONArray(x);
- return ja != null ? ja.toJSONObject(names) : null;
- }
-
- /**
- * Produce a comma delimited text row from a JSONArray. Values containing
- * the comma character will be quoted. Troublesome characters may be
- * removed.
- * @param ja A JSONArray of strings.
- * @return A string ending in NEWLINE.
- */
- public static String rowToString(JSONArray ja) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < ja.length(); i += 1) {
- if (i > 0) {
- sb.append(',');
- }
- Object object = ja.opt(i);
- if (object != null) {
- String string = object.toString();
- if (string.length() > 0 && (string.indexOf(',') >= 0 ||
- string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
- string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
- sb.append('"');
- int length = string.length();
- for (int j = 0; j < length; j += 1) {
- char c = string.charAt(j);
- if (c >= ' ' && c != '"') {
- sb.append(c);
- }
- }
- sb.append('"');
- } else {
- sb.append(string);
- }
- }
- }
- sb.append('\n');
- return sb.toString();
- }
-
- /**
- * Produce a JSONArray of JSONObjects from a comma delimited text string,
- * using the first row as a source of names.
- * @param string The comma delimited text.
- * @return A JSONArray of JSONObjects.
- * @throws JSONException
- */
- public static JSONArray toJSONArray(String string) throws JSONException {
- return toJSONArray(new JSONTokener(string));
- }
-
- /**
- * Produce a JSONArray of JSONObjects from a comma delimited text string,
- * using the first row as a source of names.
- * @param x The JSONTokener containing the comma delimited text.
- * @return A JSONArray of JSONObjects.
- * @throws JSONException
- */
- public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
- return toJSONArray(rowToJSONArray(x), x);
- }
-
- /**
- * Produce a JSONArray of JSONObjects from a comma delimited text string
- * using a supplied JSONArray as the source of element names.
- * @param names A JSONArray of strings.
- * @param string The comma delimited text.
- * @return A JSONArray of JSONObjects.
- * @throws JSONException
- */
- public static JSONArray toJSONArray(JSONArray names, String string)
- throws JSONException {
- return toJSONArray(names, new JSONTokener(string));
- }
-
- /**
- * Produce a JSONArray of JSONObjects from a comma delimited text string
- * using a supplied JSONArray as the source of element names.
- * @param names A JSONArray of strings.
- * @param x A JSONTokener of the source text.
- * @return A JSONArray of JSONObjects.
- * @throws JSONException
- */
- public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
- throws JSONException {
- if (names == null || names.length() == 0) {
- return null;
- }
- JSONArray ja = new JSONArray();
- for (;;) {
- JSONObject jo = rowToJSONObject(names, x);
- if (jo == null) {
- break;
- }
- ja.put(jo);
- }
- if (ja.length() == 0) {
- return null;
- }
- return ja;
- }
-
-
- /**
- * Produce a comma delimited text from a JSONArray of JSONObjects. The
- * first row will be a list of names obtained by inspecting the first
- * JSONObject.
- * @param ja A JSONArray of JSONObjects.
- * @return A comma delimited text.
- * @throws JSONException
- */
- public static String toString(JSONArray ja) throws JSONException {
- JSONObject jo = ja.optJSONObject(0);
- if (jo != null) {
- JSONArray names = jo.names();
- if (names != null) {
- return rowToString(names) + toString(names, ja);
- }
- }
- return null;
- }
-
- /**
- * Produce a comma delimited text from a JSONArray of JSONObjects using
- * a provided list of names. The list of names is not included in the
- * output.
- * @param names A JSONArray of strings.
- * @param ja A JSONArray of JSONObjects.
- * @return A comma delimited text.
- * @throws JSONException
- */
- public static String toString(JSONArray names, JSONArray ja)
- throws JSONException {
- if (names == null || names.length() == 0) {
- return null;
- }
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < ja.length(); i += 1) {
- JSONObject jo = ja.optJSONObject(i);
- if (jo != null) {
- sb.append(rowToString(jo.toJSONArray(names)));
- }
- }
- return sb.toString();
- }
-}
diff --git a/perseo-main/src/main/java/org/json/Cookie.java b/perseo-main/src/main/java/org/json/Cookie.java
deleted file mode 100644
index 1867dbd..0000000
--- a/perseo-main/src/main/java/org/json/Cookie.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * Convert a web browser cookie specification to a JSONObject and back.
- * JSON and Cookies are both notations for name/value pairs.
- * @author JSON.org
- * @version 2014-05-03
- */
-public class Cookie {
-
- /**
- * Produce a copy of a string in which the characters '+', '%', '=', ';'
- * and control characters are replaced with "%hh". This is a gentle form
- * of URL encoding, attempting to cause as little distortion to the
- * string as possible. The characters '=' and ';' are meta characters in
- * cookies. By convention, they are escaped using the URL-encoding. This is
- * only a convention, not a standard. Often, cookies are expected to have
- * encoded values. We encode '=' and ';' because we must. We encode '%' and
- * '+' because they are meta characters in URL encoding.
- * @param string The source string.
- * @return The escaped result.
- */
- public static String escape(String string) {
- char c;
- String s = string.trim();
- int length = s.length();
- StringBuilder sb = new StringBuilder(length);
- for (int i = 0; i < length; i += 1) {
- c = s.charAt(i);
- if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
- sb.append('%');
- sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
- sb.append(Character.forDigit((char)(c & 0x0f), 16));
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
-
- /**
- * Convert a cookie specification string into a JSONObject. The string
- * will contain a name value pair separated by '='. The name and the value
- * will be unescaped, possibly converting '+' and '%' sequences. The
- * cookie properties may follow, separated by ';', also represented as
- * name=value (except the secure property, which does not have a value).
- * The name will be stored under the key "name", and the value will be
- * stored under the key "value". This method does not do checking or
- * validation of the parameters. It only converts the cookie string into
- * a JSONObject.
- * @param string The cookie specification string.
- * @return A JSONObject containing "name", "value", and possibly other
- * members.
- * @throws JSONException
- */
- public static JSONObject toJSONObject(String string) throws JSONException {
- String name;
- JSONObject jo = new JSONObject();
- Object value;
- JSONTokener x = new JSONTokener(string);
- jo.put("name", x.nextTo('='));
- x.next('=');
- jo.put("value", x.nextTo(';'));
- x.next();
- while (x.more()) {
- name = unescape(x.nextTo("=;"));
- if (x.next() != '=') {
- if (name.equals("secure")) {
- value = Boolean.TRUE;
- } else {
- throw x.syntaxError("Missing '=' in cookie parameter.");
- }
- } else {
- value = unescape(x.nextTo(';'));
- x.next();
- }
- jo.put(name, value);
- }
- return jo;
- }
-
-
- /**
- * Convert a JSONObject into a cookie specification string. The JSONObject
- * must contain "name" and "value" members.
- * If the JSONObject contains "expires", "domain", "path", or "secure"
- * members, they will be appended to the cookie specification string.
- * All other members are ignored.
- * @param jo A JSONObject
- * @return A cookie specification string
- * @throws JSONException
- */
- public static String toString(JSONObject jo) throws JSONException {
- StringBuilder sb = new StringBuilder();
-
- sb.append(escape(jo.getString("name")));
- sb.append("=");
- sb.append(escape(jo.getString("value")));
- if (jo.has("expires")) {
- sb.append(";expires=");
- sb.append(jo.getString("expires"));
- }
- if (jo.has("domain")) {
- sb.append(";domain=");
- sb.append(escape(jo.getString("domain")));
- }
- if (jo.has("path")) {
- sb.append(";path=");
- sb.append(escape(jo.getString("path")));
- }
- if (jo.optBoolean("secure")) {
- sb.append(";secure");
- }
- return sb.toString();
- }
-
- /**
- * Convert %hh sequences to single characters, and
- * convert plus to space.
- * @param string A string that may contain
- * + (plus) and
- * %hh sequences.
- * @return The unescaped string.
- */
- public static String unescape(String string) {
- int length = string.length();
- StringBuilder sb = new StringBuilder(length);
- for (int i = 0; i < length; ++i) {
- char c = string.charAt(i);
- if (c == '+') {
- c = ' ';
- } else if (c == '%' && i + 2 < length) {
- int d = JSONTokener.dehexchar(string.charAt(i + 1));
- int e = JSONTokener.dehexchar(string.charAt(i + 2));
- if (d >= 0 && e >= 0) {
- c = (char)(d * 16 + e);
- i += 2;
- }
- }
- sb.append(c);
- }
- return sb.toString();
- }
-}
diff --git a/perseo-main/src/main/java/org/json/CookieList.java b/perseo-main/src/main/java/org/json/CookieList.java
deleted file mode 100644
index b716fd7..0000000
--- a/perseo-main/src/main/java/org/json/CookieList.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-/**
- * Convert a web browser cookie list string to a JSONObject and back.
- * @author JSON.org
- * @version 2014-05-03
- */
-public class CookieList {
-
- /**
- * Convert a cookie list into a JSONObject. A cookie list is a sequence
- * of name/value pairs. The names are separated from the values by '='.
- * The pairs are separated by ';'. The names and the values
- * will be unescaped, possibly converting '+' and '%' sequences.
- *
- * To add a cookie to a cooklist,
- * cookielistJSONObject.put(cookieJSONObject.getString("name"),
- * cookieJSONObject.getString("value"));
- * @param string A cookie list string
- * @return A JSONObject
- * @throws JSONException
- */
- public static JSONObject toJSONObject(String string) throws JSONException {
- JSONObject jo = new JSONObject();
- JSONTokener x = new JSONTokener(string);
- while (x.more()) {
- String name = Cookie.unescape(x.nextTo('='));
- x.next('=');
- jo.put(name, Cookie.unescape(x.nextTo(';')));
- x.next();
- }
- return jo;
- }
-
- /**
- * Convert a JSONObject into a cookie list. A cookie list is a sequence
- * of name/value pairs. The names are separated from the values by '='.
- * The pairs are separated by ';'. The characters '%', '+', '=', and ';'
- * in the names and values are replaced by "%hh".
- * @param jo A JSONObject
- * @return A cookie list string
- * @throws JSONException
- */
- public static String toString(JSONObject jo) throws JSONException {
- boolean b = false;
- Iterator keys = jo.keys();
- String string;
- StringBuilder sb = new StringBuilder();
- while (keys.hasNext()) {
- string = keys.next();
- if (!jo.isNull(string)) {
- if (b) {
- sb.append(';');
- }
- sb.append(Cookie.escape(string));
- sb.append("=");
- sb.append(Cookie.escape(jo.getString(string)));
- b = true;
- }
- }
- return sb.toString();
- }
-}
diff --git a/perseo-main/src/main/java/org/json/HTTP.java b/perseo-main/src/main/java/org/json/HTTP.java
deleted file mode 100644
index 648f4da..0000000
--- a/perseo-main/src/main/java/org/json/HTTP.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-/**
- * Convert an HTTP header to a JSONObject and back.
- * @author JSON.org
- * @version 2014-05-03
- */
-public class HTTP {
-
- /** Carriage return/line feed. */
- public static final String CRLF = "\r\n";
-
- /**
- * Convert an HTTP header string into a JSONObject. It can be a request
- * header or a response header. A request header will contain
- *
- * It does no further checking or conversion. It does not parse dates.
- * It does not do '%' transforms on URLs.
- * @param string An HTTP header string.
- * @return A JSONObject containing the elements and attributes
- * of the XML string.
- * @throws JSONException
- */
- public static JSONObject toJSONObject(String string) throws JSONException {
- JSONObject jo = new JSONObject();
- HTTPTokener x = new HTTPTokener(string);
- String token;
-
- token = x.nextToken();
- if (token.toUpperCase().startsWith("HTTP")) {
-
-// Response
-
- jo.put("HTTP-Version", token);
- jo.put("Status-Code", x.nextToken());
- jo.put("Reason-Phrase", x.nextTo('\0'));
- x.next();
-
- } else {
-
-// Request
-
- jo.put("Method", token);
- jo.put("Request-URI", x.nextToken());
- jo.put("HTTP-Version", x.nextToken());
- }
-
-// Fields
-
- while (x.more()) {
- String name = x.nextTo(':');
- x.next(':');
- jo.put(name, x.nextTo('\0'));
- x.next();
- }
- return jo;
- }
-
-
- /**
- * Convert a JSONObject into an HTTP header. A request header must contain
- *
- * Any other members of the JSONObject will be output as HTTP fields.
- * The result will end with two CRLF pairs.
- * @param jo A JSONObject
- * @return An HTTP header string.
- * @throws JSONException if the object does not contain enough
- * information.
- */
- public static String toString(JSONObject jo) throws JSONException {
- Iterator keys = jo.keys();
- String string;
- StringBuilder sb = new StringBuilder();
- if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
- sb.append(jo.getString("HTTP-Version"));
- sb.append(' ');
- sb.append(jo.getString("Status-Code"));
- sb.append(' ');
- sb.append(jo.getString("Reason-Phrase"));
- } else if (jo.has("Method") && jo.has("Request-URI")) {
- sb.append(jo.getString("Method"));
- sb.append(' ');
- sb.append('"');
- sb.append(jo.getString("Request-URI"));
- sb.append('"');
- sb.append(' ');
- sb.append(jo.getString("HTTP-Version"));
- } else {
- throw new JSONException("Not enough material for an HTTP header.");
- }
- sb.append(CRLF);
- while (keys.hasNext()) {
- string = keys.next();
- if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
- !"Reason-Phrase".equals(string) && !"Method".equals(string) &&
- !"Request-URI".equals(string) && !jo.isNull(string)) {
- sb.append(string);
- sb.append(": ");
- sb.append(jo.getString(string));
- sb.append(CRLF);
- }
- }
- sb.append(CRLF);
- return sb.toString();
- }
-}
diff --git a/perseo-main/src/main/java/org/json/HTTPTokener.java b/perseo-main/src/main/java/org/json/HTTPTokener.java
deleted file mode 100644
index b2489b6..0000000
--- a/perseo-main/src/main/java/org/json/HTTPTokener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * The HTTPTokener extends the JSONTokener to provide additional methods
- * for the parsing of HTTP headers.
- * @author JSON.org
- * @version 2014-05-03
- */
-public class HTTPTokener extends JSONTokener {
-
- /**
- * Construct an HTTPTokener from a string.
- * @param string A source string.
- */
- public HTTPTokener(String string) {
- super(string);
- }
-
-
- /**
- * Get the next token or string. This is used in parsing HTTP headers.
- * @throws JSONException
- * @return A String.
- */
- public String nextToken() throws JSONException {
- char c;
- char q;
- StringBuilder sb = new StringBuilder();
- do {
- c = next();
- } while (Character.isWhitespace(c));
- if (c == '"' || c == '\'') {
- q = c;
- for (;;) {
- c = next();
- if (c < ' ') {
- throw syntaxError("Unterminated string.");
- }
- if (c == q) {
- return sb.toString();
- }
- sb.append(c);
- }
- }
- for (;;) {
- if (c == 0 || Character.isWhitespace(c)) {
- return sb.toString();
- }
- sb.append(c);
- c = next();
- }
- }
-}
diff --git a/perseo-main/src/main/java/org/json/JSONArray.java b/perseo-main/src/main/java/org/json/JSONArray.java
deleted file mode 100644
index 3f05548..0000000
--- a/perseo-main/src/main/java/org/json/JSONArray.java
+++ /dev/null
@@ -1,977 +0,0 @@
-package org.json;
-
-/*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * A JSONArray is an ordered sequence of values. Its external text form is a
- * string wrapped in square brackets with commas separating the values. The
- * internal form is an object having get and opt
- * methods for accessing the values by index, and put methods for
- * adding or replacing values. The values can be any of these types:
- * Boolean, JSONArray, JSONObject,
- * Number, String, or the
- * JSONObject.NULL object.
- *
- * The constructor can convert a JSON text into a Java object. The
- * toString method converts to JSON text.
- *
- * A get method returns a value if one can be found, and throws an
- * exception if one cannot be found. An opt method returns a
- * default value instead of throwing an exception, and so is useful for
- * obtaining optional values.
- *
- * The generic get() and opt() methods return an
- * object which you can cast or query for type. There are also typed
- * get and opt methods that do type checking and type
- * coercion for you.
- *
- * The texts produced by the toString methods strictly conform to
- * JSON syntax rules. The constructors are more forgiving in the texts they will
- * accept:
- *
- *
An extra , (comma) may appear just
- * before the closing bracket.
- *
The null value will be inserted when there is ,
- * (comma) elision.
- *
Strings may be quoted with ' (single
- * quote).
- *
Strings do not need to be quoted at all if they do not begin with a quote
- * or single quote, and if they do not contain leading or trailing spaces, and
- * if they do not contain any of these characters:
- * { } [ ] / \ : , # and if they do not look like numbers and
- * if they are not the reserved words true, false, or
- * null.
- *
- *
- * @author JSON.org
- * @version 2014-05-03
- */
-public class JSONArray {
-
- /**
- * The arrayList where the JSONArray's properties are kept.
- */
- private final ArrayList