You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/01/22 02:57:59 UTC
[21/52] [partial] support for 2.4.0rc1. "vendored" the platform libs
in. added Gord and Braden as contributors. removed dependency on unzip and
axed the old download-cordova code.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONObject.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONObject.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONObject.java
new file mode 100644
index 0000000..28c6216
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONObject.java
@@ -0,0 +1,1367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.cordova.json4j.internal.JSON4JStringReader;
+import org.apache.cordova.json4j.internal.JSON4JStringWriter;
+import org.apache.cordova.json4j.internal.NumberUtil;
+import org.apache.cordova.json4j.internal.Parser;
+import org.apache.cordova.json4j.internal.Serializer;
+import org.apache.cordova.json4j.internal.SerializerVerbose;
+
+/**
+ * Models a JSON Object.
+ *
+ * Extension of Hashtable that only allows String keys, and values which are JSON-able (such as a Java Bean).
+ * <BR><BR>
+ * JSON-able values are: null, and instances of String, Boolean, Number, JSONObject and JSONArray.
+ * <BR><BR>
+ * Instances of this class are not thread-safe.
+ */
+public class JSONObject extends Hashtable implements JSONArtifact {
+
+ private static final long serialVersionUID = -3269263069889337298L;
+
+ /**
+ * A constant definition reference to Java null.
+ * Provided for API compatibility with other JSON parsers.
+ */
+ public static final Object NULL = new Null();
+
+ /**
+ * Return whether the object is a valid value for a property.
+ * @param object The object to check for validity as a JSON property value.
+ * @return boolean indicating if the provided object is directly convertable to JSON.
+ */
+ public static boolean isValidObject(Object object) {
+ if (null == object) return true;
+ return isValidType(object.getClass());
+ }
+
+ /**
+ * Return whether the class is a valid type of value for a property.
+ * @param clazz The class type to check for validity as a JSON object type.
+ * @return boolean indicating if the provided class is directly convertable to JSON.
+ */
+ public static boolean isValidType(Class clazz) {
+ if (null == clazz) throw new IllegalArgumentException();
+
+ if (String.class == clazz) return true;
+ if (Boolean.class == clazz) return true;
+ if (JSONObject.class.isAssignableFrom(clazz)) return true;
+ if (JSONArray.class == clazz) return true;
+ if (NumberUtil.isNumber(clazz)) return true;
+ if (JSONObject.NULL == clazz) return true;
+ if (JSONString.class.isAssignableFrom(clazz)) return true;
+
+ return false;
+ }
+
+ /**
+ * Create a new instance of this class.
+ */
+ public JSONObject() {
+ super();
+ }
+
+ /**
+ * Create a new instance of this class taking selected values from the underlying one.
+ * @param obj The JSONObject to extract values from.
+ * @param keys The keys to take from the JSONObject and apply to this instance.
+ * @throws JSONException Thrown if a key is duplicated in the string[] keys
+ */
+ public JSONObject(JSONObject obj, String[] keys) throws JSONException{
+ super();
+ if (keys != null && keys.length > 0) {
+ for (int i = 0; i < keys.length; i++) {
+ if (this.containsKey(keys[i])) {
+ throw new JSONException("Duplicate key: " + keys[i]);
+ }
+ try {
+ this.put(keys[i], obj.get(keys[i]));
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Error occurred during JSONObject creation");
+ jex.setCause(ex);
+ throw jex;
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a new instance of this class from the provided JSON object string.
+ * Note: This is the same as new JSONObject(str, false); Parsing in non-strict mode.
+ * @param str The JSON string to parse.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject(String str) throws JSONException {
+ super();
+ JSON4JStringReader reader = new JSON4JStringReader(str);
+ (new Parser(reader)).parse(this);
+ }
+
+ /**
+ * Create a new instance of this class from the provided JSON object string.
+ * @param str The JSON string to parse.
+ * @param strict Whether or not to parse in 'strict' mode, meaning all strings must be quoted (including identifiers), and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject(String str, boolean strict) throws JSONException {
+ super();
+ JSON4JStringReader reader = new JSON4JStringReader(str);
+ (new Parser(reader, strict)).parse(this);
+ }
+
+ /**
+ * Create a new instance of this class from the data provided from the reader. The reader content must be a JSON object string.
+ * Note: The reader will not be closed, that is left to the caller.
+ * Note: This is the same as new JSONObject(rdr, false); Parsing in non-strict mode.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject(Reader rdr) throws JSONException {
+ (new Parser(rdr)).parse(this);
+ }
+
+ /**
+ * Create a new instance of this class from the data provided from the reader. The reader content must be a JSON object string.
+ * Note: The reader will not be closed, that is left to the caller.
+ * @param rdr The reader from which to read the JSON.
+ * @param strict Whether or not to parse in 'strict' mode, meaning all strings must be quoted (including identifiers), and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject(Reader rdr, boolean strict) throws JSONException {
+ (new Parser(rdr, strict)).parse(this);
+ }
+
+ /**
+ * Create a new instance of this class from the data provided from the input stream. The stream content must be a JSON object string.
+ * Note: The input stream content is assumed to be UTF-8 encoded.
+ * Note: The InputStream will not be closed, that is left to the caller.
+ * Note: This is the same as new JSONObject(is, false); Parsing in non-strict mode.
+ * @param is The InputStream from which to read the JSON.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject (InputStream is) throws JSONException {
+ InputStreamReader isr = null;
+ if (is != null) {
+ try {
+ isr = new InputStreamReader(is, "UTF-8");
+ } catch (Exception ex) {
+ isr = new InputStreamReader(is);
+ }
+ } else {
+ throw new JSONException("InputStream cannot be null");
+ }
+ (new Parser(isr)).parse(true, this);
+ }
+
+ /**
+ * Create a new instance of this class from the data provided from the input stream. The stream content must be a JSON object string.
+ * Note: The input stream content is assumed to be UTF-8 encoded.
+ * Note: The InputStream will not be closed, that is left to the caller.
+ * @param is The InputStream from which to read the JSON.
+ * @param strict Whether or not to parse in 'strict' mode, meaning all strings must be quoted (including identifiers), and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONObject (InputStream is, boolean strict) throws JSONException {
+ InputStreamReader isr = null;
+ if (is != null) {
+ try {
+ isr = new InputStreamReader(is, "UTF-8");
+ } catch (Exception ex) {
+ isr = new InputStreamReader(is);
+ }
+ } else {
+ throw new JSONException("InputStream cannot be null");
+ }
+ (new Parser(isr, strict)).parse(true, this);
+ }
+
+ /**
+ * Write this object to the stream as JSON text in UTF-8 encoding. Same as calling write(os,false);
+ * Note that encoding is always written as UTF-8, as per JSON spec.
+ * @param os The output stream to write data to.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public OutputStream write(OutputStream os) throws JSONException {
+ write(os,false);
+ return os;
+ }
+
+ /**
+ * Convert this object into a stream of JSON text. Same as calling write(writer,false);
+ * Note that encoding is always written as UTF-8, as per JSON spec.
+ * @param os The output stream to write data to.
+ * @param verbose Whether or not to write the JSON text in a verbose format.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public OutputStream write(OutputStream os, boolean verbose) throws JSONException {
+ Writer writer = null;
+ try {
+ //MSN BUFFERED
+ writer = new OutputStreamWriter(os, "UTF-8");
+ } catch (UnsupportedEncodingException uex) {
+ JSONException jex = new JSONException(uex.toString());
+ jex.setCause(uex);
+ throw jex;
+ }
+ write(writer, verbose);
+ try {
+ writer.flush();
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Error during buffer flush");
+ jex.setCause(ex);
+ throw jex;
+ }
+ return os;
+ }
+
+ /**
+ * Write this object to the stream as JSON text in UTF-8 encoding, specifying how many spaces should be used for each indent.
+ * @param indentDepth How many spaces to use for each indent level. Should be one to eight.
+ * Less than one means no intending, greater than 8 and it will just use tab.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public OutputStream write(OutputStream os, int indentDepth) throws JSONException {
+ Writer writer = null;
+ try {
+ //MSN BUFFERED
+ writer = new OutputStreamWriter(os, "UTF-8");
+ } catch (UnsupportedEncodingException uex) {
+ JSONException jex = new JSONException(uex.toString());
+ jex.setCause(uex);
+ throw jex;
+ }
+ write(writer, indentDepth);
+ try {
+ writer.flush();
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Error during buffer flush");
+ jex.setCause(ex);
+ throw jex;
+ }
+ return os;
+ }
+
+ /**
+ * Write this object to the writer as JSON text. Same as calling write(writer,false);
+ * @param writer The writer which to write the JSON text to.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public Writer write(Writer writer) throws JSONException {
+ write(writer, false);
+ return writer;
+ }
+
+ /**
+ * Write this object to the writer as JSON text in UTF-8 encoding, specifying whether to use verbose (tab-indented) output or not.
+ * @param writer The writer which to write the JSON text to.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public Writer write(Writer writer, boolean verbose) throws JSONException {
+ Serializer serializer;
+
+ //Try to avoid double-buffering or buffering in-memory
+ //writers.
+// Class writerClass = writer.getClass();
+ boolean flushIt = false;
+// if (!StringWriter.class.isAssignableFrom(writerClass) &&
+// !CharArrayWriter.class.isAssignableFrom(writerClass) &&
+// !BufferedWriter.class.isAssignableFrom(writerClass)) {
+// writer = new BufferedWriter(writer);
+// flushIt = true;
+// }
+
+ if (verbose) {
+ serializer = new SerializerVerbose(writer);
+ } else {
+ serializer = new Serializer(writer);
+ }
+
+ try {
+ serializer.writeObject(this);
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ if (flushIt) {
+ try {
+ writer.flush();
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Error during buffer flush");
+ jex.setCause(ex);
+ throw jex;
+ }
+ }
+ return writer;
+ }
+
+ /**
+ * Write this object to the writer as JSON text, specifying how many spaces should be used for each indent.
+ * This is an alternate indent style to using tabs.
+ * @param writer The writer which to write the JSON text to.
+ * @param indentDepth How many spaces to use for each indent. The value should be between one to eight.
+ */
+ public Writer write(Writer writer, int indentDepth) throws JSONException {
+ Serializer serializer;
+
+ if (indentDepth < 1) {
+ indentDepth = 0;
+ } else if (indentDepth > 8) {
+ indentDepth = 9;
+ }
+
+ //Try to avoid double-buffering or buffering in-memory
+ //writers.
+// Class writerClass = writer.getClass();
+ boolean flushIt = false;
+// if (!StringWriter.class.isAssignableFrom(writerClass) &&
+// !CharArrayWriter.class.isAssignableFrom(writerClass) &&
+// !BufferedWriter.class.isAssignableFrom(writerClass)) {
+// writer = new BufferedWriter(writer);
+// flushIt = true;
+// }
+
+ if (indentDepth > 0) {
+ serializer = new SerializerVerbose(writer, indentDepth);
+ } else {
+ serializer = new Serializer(writer);
+ }
+ try {
+ serializer.writeObject(this);
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ if (flushIt) {
+ try {
+ writer.flush();
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Error during buffer flush");
+ jex.setCause(ex);
+ throw jex;
+ }
+ }
+ return writer;
+ }
+
+ /**
+ * Convert this object into a String of JSON text, specifying how many spaces should be used for each indent.
+ * This is an alternate indent style to using tabs.
+ * @param indentDepth How many spaces to use for each indent. The value should be between one to eight.
+ * Less than one means no indenting, greater than 8 and it will just use tab.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public String write(int indentDepth) throws JSONException {
+ Serializer serializer;
+ JSON4JStringWriter writer = new JSON4JStringWriter();
+
+ if (indentDepth < 1) {
+ indentDepth = 0;
+ } else if (indentDepth > 8) {
+ indentDepth = 9;
+ }
+
+ if (indentDepth > 0) {
+ serializer = new SerializerVerbose(writer, indentDepth);
+ } else {
+ serializer = new Serializer(writer);
+ }
+ try {
+ serializer.writeObject(this).flush();
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during write.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ return writer.toString();
+ }
+
+ /**
+ * Convert this object into a String of JSON text, specifying whether to use verbose (tab-indented) output or not.
+ * @param verbose Whether or not to write in compressed format.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public String write(boolean verbose) throws JSONException {
+ Serializer serializer;
+ JSON4JStringWriter writer = new JSON4JStringWriter();
+
+ if (verbose) {
+ serializer = new SerializerVerbose(writer);
+ } else {
+ serializer = new Serializer(writer);
+ }
+ try {
+ serializer.writeObject(this).flush();
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during write.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ return writer.toString();
+ }
+
+ /**
+ * Convert this object into a String of JSON text. Same as write(false);
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ public String write() throws JSONException {
+ return write(false);
+ }
+
+ /**
+ * Method to obtain the object value for a key.
+ * This string-based method is provided for API compatibility to other JSON models.
+ * @param key The key (attribute) name to obtain the value for.
+ * @throws JSONException Thrown if the noted key is not in the map of key/value pairs.
+ */
+ public Object get(String key) throws JSONException {
+ Object val = this.get((Object)key);
+ if (val == null) {
+ if (!this.containsKey(key)) {
+ throw new JSONException("The key [" + key + "] was not in the map");
+ }
+ }
+ return val;
+ }
+
+ /**
+ * Method to obtain the object value for a key. If the key is not in the map, null is returned.
+ * This string-based method is provided for API compatibility to other JSON models.
+ * @param key The key (attribute) name to obtain the value for.
+ */
+ public Object opt(String key) {
+ return this.get((Object)key);
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ * @param key The key to put in the JSONObject
+ * @param value The value to put in the JSONObject
+ * @param includeSuperclass Boolean indicating that if the object is a JavaBean, include superclass getter properties.
+ * @throws JSONException. Thrown if key is null, not a string, or the value could not be converted.
+ */
+ public Object put(Object key, Object value, boolean includeSuperclass) throws JSONException{
+ if (null == key) throw new JSONException("key must not be null");
+ if (!(key instanceof String)) throw new JSONException("key must be a String");
+ if (!isValidObject(value)) {
+ throw new JSONException("Invalid type of value. Could not convert type: [" + value.getClass().getName() + "]");
+ }
+ if (null == value) {
+ value = NULL;
+ }
+ return super.put(key, value);
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ * This is the same as calling put(key, value, true);
+ */
+ public Object put(Object key, Object value) {
+ try {
+ return put(key, value, true);
+ } catch (Exception e) {
+ IllegalArgumentException iae = new IllegalArgumentException("Error occurred during JSON conversion");
+ //MSN iae.setCause(e);
+ throw iae;
+ }
+ }
+
+ /**
+ * Convenience functions, to help map from other JSON parsers.
+ */
+
+ /**
+ * Similar to default HashMap put, except it returns JSONObject instead of Object.
+ * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ * @return A reference to this object instance.
+ * @throws JSONException. Thrown if key is null, not a string, or the value could not be converted to JSON.
+ */
+ public JSONObject put(String key, Object value) throws JSONException{
+ this.put((Object)key, value);
+ return this;
+ }
+
+ /**
+ * Method to add an atomic boolean to the JSONObject.
+ * param key The key/attribute name to set the boolean at.
+ * @param value The boolean value.
+ * @throws JSONException. Thrown if key is null or not a string.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, boolean value) throws JSONException{
+ this.put(key,new Boolean(value));
+ return this;
+ }
+
+ /**
+ * Method to add an atomic double to the JSONObject.
+ * param key The key/attribute name to set the double at.
+ * @param value The double value.
+ * @throws JSONException. Thrown if key is null or not a string.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, double value) throws JSONException{
+ this.put(key, new Double(value));
+ return this;
+ }
+
+ /**
+ * Method to add an atomic integer to the JSONObject.
+ * param key The key/attribute name to set the integer at.
+ * @param value The integer value.
+ * @throws JSONException. Thrown if key is null or not a string.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, int value) throws JSONException{
+ this.put(key, new Integer(value));
+ return this;
+ }
+
+ /**
+ * Method to add an atomic short to the JSONObject.
+ * param key The key/attribute name to set the integer at.
+ * @param value The integer value.
+ * @throws JSONException. Thrown if key is null or not a string.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, short value) throws JSONException{
+ this.put(key, new Short(value));
+ return this;
+ }
+
+ /**
+ * Method to add an atomic long to the JSONObject.
+ * @param key The key/attribute name to set the long to.
+ * @param value The long value.
+ * @throws JSONException. Thrown if key is null or not a string.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, long value) throws JSONException{
+ this.put(key, new Long(value));
+ return this;
+ }
+
+ /**
+ * Method to add an Object array as a new JSONArray contained in this JSONObject
+ * @param key The key/attribute name to set the collection to.
+ * @param value The Object array to convert to a JSONArray and store.
+ * @throws JSONException Thrown when contents in the Collection cannot be converted to something JSONable.
+ * @return A reference to this object instance.
+ */
+ public JSONObject put(String key, Object[] value) throws JSONException {
+ return put (key, new JSONArray(value));
+ }
+
+ /**
+ * Method to add an Object array as a new JSONArray contained in this JSONObject
+ * @param key The key/attribute name to set the collection to.
+ * @param value The Object array to convert to a JSONArray and store.
+ * @param includeSuperclass For values of the Object array which are JavaBeans and are converted, include superclass getter properties.
+ * @throws JSONException Thrown when contents in the Collection cannot be converted to something JSONable.
+ * @return A reference to this object instance.
+ *
+ public JSONObject put(String key, Object[] value, boolean includeSuperclass) throws JSONException {
+ return put (key, new JSONArray(value), includeSuperclass);
+ } */
+
+ /**
+ * Utility method to obtain the specified key as a 'boolean' value
+ * Only boolean true, false, and the String true and false will return. In this case null, the number 0, and empty string should be treated as false.
+ * everything else is true.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a boolean instance, or the strings 'true' or 'false'.
+ * @return A boolean value (true or false), if the value stored for key is a Boolean, or the strings 'true' or 'false'.
+ */
+ public boolean getBoolean(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (val instanceof Boolean) {
+ return((Boolean)val).booleanValue();
+ } else if (NumberUtil.isNumber(val.getClass())) {
+ throw new JSONException("Value at key: [" + key + "] was not a boolean or string value of 'true' or 'false'.");
+ } else if (String.class.isAssignableFrom(val.getClass())) {
+ String str = (String)val;
+ if (str.equals("true")) {
+ return true;
+ } else if (str.equals("false")) {
+ return false;
+ } else {
+ throw new JSONException("The value for key: [" + key + "]: [" + str + "] was not 'true' or 'false'");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a type that can be converted to boolean");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'boolean' value
+ * Only returns true if the value is boolean true or the string 'true'. All other values return false.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A boolean value (true or false), if the value stored for key is a Boolean, or the strings 'true' or 'false'.
+ */
+ public boolean optBoolean(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (val instanceof Boolean) {
+ return((Boolean)val).booleanValue();
+ } else if (NumberUtil.isNumber(val.getClass())) {
+ return false;
+ } else if (String.class.isAssignableFrom(val.getClass())) {
+ String str = (String)val;
+ if (str.equals("true")) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'boolean' value
+ * Only returns true if the value is boolean true or the string 'true'. All other values return false.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default value to return.
+ * @return A boolean value (true or false), if the value stored for key is a Boolean, or the strings 'true' or 'false'.
+ */
+ public boolean optBoolean(String key, boolean defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (val instanceof Boolean) {
+ return((Boolean)val).booleanValue();
+ } else if (NumberUtil.isNumber(val.getClass())) {
+ return false;
+ } else if (String.class.isAssignableFrom(val.getClass())) {
+ String str = (String)val;
+ if (str.equals("true")) {
+ return true;
+ } else if (str.equals("false")) {
+ return false;
+ } else {
+ return defaultValue;
+ }
+ } else {
+ return defaultValue;
+ }
+ } else {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'double' value
+ * Only values of Number will be converted to double, all other types will generate an exception
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a Double instance, or cannot be converted to a double.
+ * @return A double value if the value stored for key is an instance of Number.
+ */
+ public double getDouble(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getDouble(val);
+ }
+ else {
+ throw new JSONException("The value for key: [" + key + "] was not a type that can be converted to double");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Number required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'double' value
+ * Only values of Number will be converted to double. all other values will return Double.NaN.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A double value if the value stored for key is an instance of Number.
+ */
+ public double optDouble(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getDouble(val);
+ }
+ }
+ return Double.NaN;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'double' value
+ * Only values of Number will be converted to double. all other values will return Double.NaN.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default double value to return in case of NaN/null values in map.
+ * @return A double value if the value stored for key is an instance of Number.
+ */
+ public double optDouble(String key, double defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getDouble(val);
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'short' value
+ * Only values of Number will be converted to short, all other types will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a Short instance, or cannot be converted to a short.
+ * @return A short value if the value stored for key is an instance of Number.
+ */
+ public short getShort(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getShort(val);
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a type that can be converted to short");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Number required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'short' value
+ * Only values of Number will be converted to short. All other types return 0.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A short value if the value stored for key is an instance of Number. 0 otherwise.
+ */
+ public short optShort(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getShort(val);
+ }
+ }
+ return(short)0;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'short' value
+ * Only values of Number will be converted to short.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default value to return in the case of null/nonNumber values in the map.
+ * @return A short value if the value stored for key is an instance of Number. 0 otherwise.
+ */
+ public short optShort(String key, short defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getShort(val);
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'int' value
+ * Only values of Number will be converted to integer, all other types will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a Double instance, or cannot be converted to a double.
+ * @return A int value if the value stored for key is an instance of Number.
+ */
+ public int getInt(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getInt(val);
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a type that can be converted to integer");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Number required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'int' value
+ * Provided for compatibility to other JSON models.
+ * Only values of Number will be converted to integer, all other types will return 0.
+ * @param key The key to look up.
+ * @return A int value if the value stored for key is an instance of Number. 0 otherwise.
+ */
+ public int optInt(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getInt(val);
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'int' value
+ * Provided for compatibility to other JSON models.
+ * Only values of Number will be converted to integer
+ * @param key The key to look up.
+ * @param defaultValue The default int value to return in case of null/non-number values in the map.
+ * @return A int value if the value stored for key is an instance of Number.
+ */
+ public int optInt(String key, int defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getInt(val);
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'long' value
+ * Only values of Number will be converted to long, all other types will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a Long instance, or cannot be converted to a long..
+ * @return A long value if the value stored for key is an instance of Number.
+ */
+ public long getLong(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getLong(val);
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a type that can be converted to long");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Number required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'long' value
+ * Only values of Number will be converted to long. all other types return 0.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A long value if the value stored for key is an instance of Number, 0 otherwise.
+ */
+ public long optLong(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getLong(val);
+ }
+ }
+ return(long)0;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'long' value
+ * Only values of Number will be converted to long. all other types return 0.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default long value to return in case of null/non Number values in the map.
+ * @return A long value if the value stored for key is an instance of Number, defaultValue otherwise.
+ */
+ public long optLong(String key, long defaultValue) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getLong(val);
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'string' value
+ * Only values that can be easily converted to string will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is null.
+ * @return A string value if the value if the value stored for key is not null.
+ */
+ public String getString(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ return val.toString();
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Object required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'string' value
+ * Only values that can be easily converted to string will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is null.
+ * @return A string value if the value if the value stored for key is not null.
+ */
+ public String optString(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ return val.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a 'string' value
+ * Only values that can be easily converted to string will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default String value to return in the case of null values in the map.
+ * @return A string value if the value if the value stored for key is not null, defaultValue otherwise.
+ */
+ public String optString(String key, String defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ return val.toString();
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONObject
+ * Only values that are instances of JSONObject will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a JSONObject instance.
+ * @return A JSONObject value if the value stored for key is an instance or subclass of JSONObject.
+ */
+ public JSONObject getJSONObject(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONObject.class.isAssignableFrom(val.getClass())) {
+ return(JSONObject)val;
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a JSONObject");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Object required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONObject
+ * Only values that are instances of JSONObject will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A JSONObject value if the value stored for key is an instance or subclass of JSONObject, null otherwise.
+ */
+ public JSONObject optJSONObject(String key) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONObject.class.isAssignableFrom(val.getClass())) {
+ return(JSONObject)val;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONObject
+ * Only values that are instances of JSONObject will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default JSONObject to return in the case of null/non JSONObject values in the map.
+ * @return A JSONObject value if the value stored for key is an instance or subclass of JSONObject, defaultValue otherwise.
+ */
+ public JSONObject optJSONObject(String key, JSONObject defaultValue) {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONObject.class.isAssignableFrom(val.getClass())) {
+ return(JSONObject)val;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONArray
+ * Only values that are instances of JSONArray will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * throws JSONException Thrown when the type returned by get(key) is not a Long instance, or cannot be converted to a long..
+ * @return A JSONArray value if the value stored for key is an instance or subclass of JSONArray.
+ */
+ public JSONArray getJSONArray(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONArray.class.isAssignableFrom(val.getClass())) {
+ return(JSONArray)val;
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was not a JSONObject");
+ }
+ } else {
+ throw new JSONException("The value for key: [" + key + "] was null. Object required.");
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONArray
+ * Only values that are instances of JSONArray will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @return A JSONArray value if the value stored for key is an instance or subclass of JSONArray, null otherwise.
+ */
+ public JSONArray optJSONArray(String key) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONArray.class.isAssignableFrom(val.getClass())) {
+ return(JSONArray)val;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to obtain the specified key as a JSONArray
+ * Only values that are instances of JSONArray will be returned. A null will generate an exception.
+ * Provided for compatibility to other JSON models.
+ * @param key The key to look up.
+ * @param defaultValue The default value to return if the value in the map is null/not a JSONArray.
+ * @return A JSONArray value if the value stored for key is an instance or subclass of JSONArray, defaultValue otherwise.
+ */
+ public JSONArray optJSONArray(String key, JSONArray defaultValue) throws JSONException {
+ Object val = this.opt(key);
+ if (val != null) {
+ if (JSONArray.class.isAssignableFrom(val.getClass())) {
+ return(JSONArray)val;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Put a key/value pair into the JSONObject, but only if key/value are both not null, and only if the key is not present already.
+ * Provided for compatibility to existing models.
+ * @param key The ket to place in the array
+ * @param value The value to place in the array
+ * @return Reference to the current JSONObject.
+ * @throws JSONException - Thrown if the key already exists or if key or value is null
+ */
+ public JSONObject putOnce(String key, Object value) throws JSONException {
+ if (key == null) {
+ throw new JSONException("Key cannot be null");
+ }
+ if (value == null) {
+ throw new JSONException("Value cannot be null");
+ }
+ if (this.containsKey(key)) {
+ throw new JSONException("Key [" + key + "] already exists in the map");
+ }
+ this.put(key,value);
+ return this;
+ }
+
+ /**
+ * Put a key/value pair into the JSONObject, but only if the key and value are non-null.
+ * @param key The keey (attribute) name to assign to the value.
+ * @param value The value to put into the JSONObject.
+ * @return Reference to the current JSONObject.
+ * @throws JSONException - if the value is a non-finite number
+ */
+ public JSONObject putOpt(String key, Object value) throws JSONException {
+ if (key == null) {
+ throw new JSONException("Key cannot be null");
+ }
+ if (value == null) {
+ throw new JSONException("Value cannot be null");
+ }
+ this.put(key,value);
+ return this;
+ }
+
+ /**
+ * Method to return the number of keys in this JSONObject.
+ * This function merely maps to HashMap.size(). Provided for API compatibility.
+ * @return returns the number of keys in the JSONObject.
+ */
+ public int length() {
+ return this.size();
+ }
+
+ /**
+ * Method to append the 'value' object to the element at entry 'key'.
+ * If JSONObject.has(key) returns false, a new array is created and the value is appended to it.
+ * If the object as position key is not an array, then a new JSONArray is created
+ * and both current and new values are appended to it, then the value of the attribute is set to the new
+ * array. If the current value is already an array, then 'value' is added to it.
+ *
+ * @param key The key/attribute name to append to.
+ * @param value The value to append to it.
+ *
+ * @throws JSONException Thrown if the value to append is not JSONAble.
+ * @return A reference to this object instance.
+ */
+ public JSONObject append(String key, Object value) throws JSONException {
+ JSONArray array = null;
+ if (!this.has(key)) {
+ array = new JSONArray();
+ }
+ else {
+ Object oldVal = this.get(key);
+ array = new JSONArray();
+ if (oldVal == null) {
+ // Add a null if the key was actually there, but just
+ // had value of null.
+ array.add(null);
+ }
+ else if (JSONArray.class.isAssignableFrom(oldVal.getClass())) {
+ array = (JSONArray)oldVal;
+ } else {
+ array = new JSONArray();
+ array.add(oldVal);
+ }
+ }
+ array.add(value);
+ return put(key,array);
+ }
+
+ /**
+ * Produce a JSONArray containing the values of the members of this JSONObject
+ * @param names - A JSONArray containing the a list of key strings. This determines the sequence of values in the result.
+ * @return A JSONArray of the values found for the names provided.
+ * @throws JSONException - if errors occur during storing the values in a JSONArray
+ */
+ public JSONArray toJSONArray(JSONArray names) throws JSONException {
+ Enumeration itr = names.elements();
+ JSONArray array = new JSONArray();
+ //MSN WAS IF, SHOULD BE WHILE?
+ while (itr != null && itr.hasMoreElements()) {
+ array.put(this.get(itr.nextElement()));
+ }
+ return array;
+ }
+
+
+ /**
+ * Method to test if a key exists in the JSONObject.
+ * @param key The key to test.
+ * @return true if the key is defined in the JSONObject (regardless of value), or false if the key is not in the JSONObject
+ */
+ public boolean has(String key) {
+ if (key != null) {
+ return this.containsKey(key);
+ }
+ return false;
+ }
+
+ /**
+ * Method to test if a key is mapped to null. This method will also return
+ * true if the key has not been put in the JSONObject yet,
+ *
+ * @param key The key to test for null.
+ * @return true if the key is not in the map or if the value referenced by the
+ * key is null, or if the value is the JSONObject.NULL object.
+ */
+ public boolean isNull(String key) {
+ Object obj = this.opt(key);
+ return JSONObject.NULL.equals(obj);
+ }
+
+ /**
+ * Utility function that returns an iterator of all the keys (attributes) of this JSONObject
+ * @return An iterator of all keys in the object.
+ *
+ public Enumeration keys() {
+ return this.keys();
+
+ } */
+
+ /**
+ * Utility function that returns a JSONArray of all the names of the keys (attributes) of this JSONObject
+ * @return All the keys in the JSONObject as a JSONArray.
+ */
+ public JSONArray names() {
+ Enumeration itr = this.keys();
+ if (itr != null) {
+ JSONArray array = new JSONArray();
+ while (itr.hasMoreElements()) {
+ array.add(itr.nextElement());
+ }
+ return array;
+ }
+ return null;
+ }
+
+ /**
+ * Utility function that returns a String[] of all the names of the keys (attributes) of this JSONObject
+ * @return All the keys in the JSONObject as a String[].
+ */
+ public static String[] getNames(JSONObject obj) {
+ String[] array = null;
+ if (obj != null) {
+ if (obj.size() > 0) {
+ array = new String[obj.size()];
+ int pos = 0;
+ Enumeration itr = obj.keys();
+ if (itr != null) {
+ while (itr.hasMoreElements()) {
+ array[pos] = (String)itr.nextElement();
+ pos++;
+ }
+ }
+ }
+ }
+ return array;
+ }
+
+// /**
+// * Utility function that returns an iterator of all the keys (attributes) of this JSONObject sorted in lexicographic manner (String.compareTo).
+// * @return An iterator of all keys in the object in lexicographic (character code) sorted order.
+// */
+// public Enumeration sortedKeys() {
+// Enumeration itr = this.keys();
+// if (itr != null && itr.hasMoreElements()) {
+// Vector vect = new Vector();
+// while (itr.hasMoreElements()) {
+// vect.addElement(itr.nextElement());
+// }
+// String[] strs = new String[vect.size()];
+// vect.copyInto(strs);
+// // java.util.Arrays.sort(strs);
+// vect.clear();
+// for (int i = 0; i < strs.length; i++) {
+// vect.add(strs[i]);
+// }
+// return vect.iterator();
+// }
+// return null;
+// }
+
+ /**
+ * End of convenience methods.
+ */
+
+ /**
+ * Over-ridden toString() method. Returns the same value as write(), which is a compact JSON String.
+ * If an error occurs in the serialization, the return will be of format: JSON Generation Error: [<some error>]
+ * @return A string of JSON text, if possible.
+ */
+ public String toString() {
+ return toString(false);
+ }
+
+ /**
+ * Verbose capable toString method.
+ * If an error occurs in the serialization, the return will be of format: JSON Generation Error: [<some error>]
+ * @param verbose Whether or not to tab-indent the output.
+ * @return A string of JSON text, if possible.
+ */
+ public String toString(boolean verbose) {
+ String str = null;
+ try {
+ str = write(verbose);
+ } catch (JSONException jex) {
+ str = "JSON Generation Error: [" + jex.toString() + "]";
+ }
+ return str;
+ }
+
+ /**
+ * Function to return a string of JSON text with specified indention. Returns the same value as write(indentDepth).
+ * If an error occurs in the serialization, a JSONException is thrown.
+ * @return A string of JSON text, if possible.
+ */
+ public String toString(int indentDepth) throws JSONException {
+ return write(indentDepth);
+ }
+
+ public static String quote(String string) {
+ return Serializer.quote(string);
+ }
+
+ /**
+ * An simple class provided for API compatibility to other JSON models that 'represents'
+ * 'null' in an actual object.
+ */
+ private static class Null implements JSONString {
+
+ /**
+ * Equals function that returns true for comparisons to null.
+ */
+ public boolean equals(Object obj) {
+ if (obj == null || obj == this) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Ensure only one Null object.
+ */
+ protected Object clone() {
+ return this;
+ }
+
+ /**
+ * toString method that just returns 'null' as the string.
+ */
+ public String toString() {
+ return "null";
+ }
+
+ /**
+ * Method to return a JSON compliant representation of this object.
+ * @return a JSON formatted string.
+ */
+ public String toJSONString() {
+ return this.toString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONString.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONString.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONString.java
new file mode 100644
index 0000000..b887adb
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONString.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j;
+
+/**
+ * An interface that can be implemented to make a
+ * particular object have an easy to use JSON representation. Objects that implement this
+ * can be inserted into JSONObject and JSONArray and serialized.
+ */
+public interface JSONString {
+ /**
+ * Method to return a JSON compliant representation of this object.
+ * @return a JSON formatted string.
+ */
+ public String toJSONString();
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONStringer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONStringer.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONStringer.java
new file mode 100644
index 0000000..10fb7a8
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONStringer.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j;
+
+import java.io.IOException;
+
+import org.apache.cordova.json4j.internal.JSON4JStringWriter;
+
+/**
+ * This class implements a JSONSringer, a basic convenience subclass of JSONWriter to allow for
+ * generating JSON strings quickly. This class exists for API compatibility to other popular
+ * JSON parsers.
+ */
+public class JSONStringer extends JSONWriter {
+
+ public JSONStringer() {
+ super(new JSON4JStringWriter());
+ }
+
+ /**
+ * Return a string of the stringer contents. This also terminates the
+ * Stringer and it cannot be used again. If any errors occur while trying to generate the JSON
+ * it returns an empty string.
+ */
+ public String toString() {
+ try {
+ super.flush();
+ super.close();
+ return ((JSON4JStringWriter)writer).toString();
+ } catch (Exception ex) {
+ /* Squelch */
+ return "";
+ }
+ }
+
+ /**
+ * Over-ride to do nothing for the stringer. Only toString() terminates the stringer object.
+ */
+ public void close() throws IOException, IllegalStateException {
+ // Do nothing.
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONWriter.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONWriter.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONWriter.java
new file mode 100644
index 0000000..1914f58
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/JSONWriter.java
@@ -0,0 +1,586 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Stack;
+
+import org.apache.cordova.json4j.internal.NumberUtil;
+
+/**
+ * This class implements a JSONWrier, a convenience function for writing out JSON
+ * to a writer or underlying stream.
+ */
+public class JSONWriter {
+
+ /**
+ * The writer to use to output JSON in a semi-streaming fashion.
+ */
+ protected Writer writer = null;
+
+ /**
+ * Flag to denote that the writer is in an object.
+ */
+ private boolean inObject = false;
+
+ /**
+ * Flag to denote that the writer is in an array.
+ */
+ private boolean inArray = false;
+
+ /**
+ * Flag for state checking that a key was placed (if inside an object)
+ * Required to be true for a value to be placed in that situation
+ */
+ private boolean keyPlaced = false;
+
+ /**
+ * Flag denoting if in an array or object, if the first entry has been placed or not.
+ */
+ private boolean firstEntry = false;
+
+ /**
+ * A stack to keep track of all the closures.
+ */
+ private Stack closures = null;
+
+ /**
+ * Flag used to check the state of this writer, if it has been closed, all
+ * operations will throw an IllegalStateException.
+ */
+ private boolean closed = false;
+
+ /**
+ * Constructor.
+ * @param writer The writer to use to do 'streaming' JSON writing.
+ * @throws NullPointerException Thrown if writer is null.
+ */
+ public JSONWriter(Writer writer) throws NullPointerException {
+ //Try to avoid double-buffering or buffering in-memory writers.
+// Class writerClass = writer.getClass();
+// if (!StringWriter.class.isAssignableFrom(writerClass) &&
+// !CharArrayWriter.class.isAssignableFrom(writerClass) &&
+// !BufferedWriter.class.isAssignableFrom(writerClass)) {
+// writer = new BufferedWriter(writer);
+// }
+ this.writer = writer;
+ this.closures = new Stack();
+ }
+
+ /**
+ * Open a new JSON Array in the output stream.
+ * @throws IOException Thrown if an error occurs on the underlying writer.
+ * @throws IllegalstateException Thrown if the current writer position does not permit an array.
+ * @return A reference to this writer.
+ */
+ public JSONWriter array() throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inObject) {
+ if (!keyPlaced) {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified to contain a new array");
+ }
+ } else if (inArray) {
+ if (!firstEntry) {
+ writer.write(",");
+ }
+ }
+ writer.write("[");
+ inArray = true;
+ inObject = false;
+ keyPlaced = false;
+ firstEntry = true;
+ closures.push("]");
+ return this;
+ }
+
+ /**
+ * Method to close the current JSON Array in the stream.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the writer position is not inside an array.
+ * @return A reference to this writer.
+ */
+ public JSONWriter endArray() throws IOException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (!inArray) {
+ throw new IllegalStateException("Current writer position is not within a JSON array");
+ } else {
+ writer.write(((String)closures.pop()));
+ // Set our current positional/control state.
+ if (!closures.isEmpty()) {
+ String nextClosure = (String)closures.peek();
+ if (nextClosure.equals("}")) {
+ inObject = true;
+ inArray = false;
+ } else {
+ inObject = false;
+ inArray = true;
+ }
+ firstEntry = false;
+ } else {
+ inArray = false;
+ inObject = false;
+ firstEntry = true;
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Method to close a current JSON object in the stream.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the writer position is not inside an object, or if the object has a key placed, but no value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter endObject() throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (!inObject) {
+ throw new IllegalStateException("Current writer position is not within a JSON object");
+ } else {
+ if (keyPlaced) {
+ throw new IllegalStateException("Current writer position in an object and has a key placed, but no value has been assigned to the key. Cannot end.");
+ } else {
+ writer.write((String)closures.pop());
+ // Set our current positional/control state.
+ if (!closures.isEmpty()) {
+ String nextClosure = (String)closures.peek();
+ if (nextClosure.equals("}")) {
+ inObject = true;
+ inArray = false;
+ } else {
+ inObject = false;
+ inArray = true;
+ }
+ firstEntry = false;
+ } else {
+ inArray = false;
+ inObject = false;
+ firstEntry = true;
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Place a key in the current JSON Object.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position is not within an object.
+ * @return A reference to this writer.
+ */
+ public JSONWriter key(String s) throws IOException, IllegalStateException, NullPointerException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (s == null) {
+ throw new NullPointerException("Key cannot be null");
+ } else {
+ if (!inObject) {
+ throw new IllegalStateException("Current writer position is not inside a JSON Object, a key cannot be placed.");
+ } else {
+ if (!keyPlaced) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ keyPlaced = true;
+ writeString(s);
+ writer.write(":");
+ } else {
+ throw new IllegalStateException("Current writer position is inside a JSON Object an with an open key waiting for a value. Another key cannot be placed.");
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Open a new JSON Object in the output stream.
+ * @throws IllegalStateException Thrown if an object cannot currently be created in the stream.
+ * @throws IOException Thrown if an IO error occurs in the underlying writer.
+ * @return A reference to this writer.
+ */
+ public JSONWriter object() throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inObject) {
+ if (!keyPlaced) {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified to contain a new object");
+ }
+ } else if (inArray) {
+ if (!firstEntry) {
+ writer.write(",");
+ }
+ }
+ writer.write("{");
+ inObject = true;
+ inArray = false;
+ keyPlaced = false;
+ firstEntry = true;
+ closures.push("}");
+ return this;
+ }
+
+ /**
+ * Method to write a boolean to the current writer position.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position will not accept a boolean value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(boolean b) throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ if (b)
+ writer.write("true");
+ else
+ writer.write("false");
+
+ } else if (inObject) {
+ if (keyPlaced) {
+ if (b)
+ writer.write("true");
+ else
+ writer.write("false");
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the boolean value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to write a double to the current writer position.
+ * @param d The Double to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position will not accept a double value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(double d) throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ writer.write(Double.toString(d));
+ } else if (inObject) {
+ if (keyPlaced) {
+ writer.write(Double.toString(d));
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the double value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to write a double to the current writer position.
+ * @param l The long to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position will not accept a double value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(long l) throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ writer.write(Long.toString(l));
+ } else if (inObject) {
+ if (keyPlaced) {
+ writer.write(Long.toString(l));
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the long value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to write an int to the current writer position.
+ * @param i The int to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position will not accept a double value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(int i) throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ writer.write(Integer.toString(i));
+ } else if (inObject) {
+ if (keyPlaced) {
+ writer.write(Integer.toString(i));
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the int value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to write a short to the current writer position.
+ * @param s The short to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the current writer position will not accept a double value.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(short s) throws IOException, IllegalStateException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ writer.write(Integer.toString(s));
+ } else if (inObject) {
+ if (keyPlaced) {
+ writer.write(Integer.toString(s));
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the short value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to write an Object to the current writer position.
+ * @param o The object to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws JSONException Thrown if the object is not JSONAble.
+ * @return A reference to this writer.
+ */
+ public JSONWriter value(Object o) throws IOException, IllegalStateException, JSONException {
+ if (closed) {
+ throw new IllegalStateException("The writer has been closed. No further operations allowed.");
+ }
+ if (inArray) {
+ if (firstEntry) {
+ firstEntry = false;
+ } else {
+ writer.write(",");
+ }
+ writeObject(o);
+ } else if (inObject) {
+ if (keyPlaced) {
+ writeObject(o);
+ keyPlaced = false;
+ } else {
+ throw new IllegalStateException("Current containment is a JSONObject, but a key has not been specified for the boolean value.");
+ }
+ } else {
+ throw new IllegalStateException("Writer is currently not in an array or object, cannot write value");
+ }
+ return this;
+ }
+
+ /**
+ * Method to close the JSON Writer. All current object depths will be closed out and the writer closed.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws IllegalStateException Thrown if the writer position is in an object and a key has been placed, but a value has not been assigned or if the writer was already closed.
+ */
+ public void close() throws IOException, IllegalStateException {
+ if (!closed) {
+ if (inObject && keyPlaced) {
+ throw new IllegalStateException("Object has key without value. Cannot close.");
+ } else {
+ while (!closures.isEmpty()) {
+ writer.write((String)closures.pop());
+ }
+ writer.flush();
+ writer.close();
+ closed = true;
+ }
+ }
+ }
+
+ /**
+ * Method to flush the underlying writer so that all buffered content, if any, is written out.
+ * @return A reference to this writer.
+ */
+ public JSONWriter flush() throws IOException {
+ writer.flush();
+ return this;
+ }
+
+ /**
+ * Method to write a String out to the writer, encoding special characters and unicode characters properly.
+ * @param value The string to write out.
+ * @throws IOException Thrown if an error occurs during write.
+ */
+ private void writeString(String value) throws IOException {
+ writer.write('"');
+ char[] chars = value.toCharArray();
+ for (int i=0; i<chars.length; i++) {
+ char c = chars[i];
+ switch (c) {
+ case '"': writer.write("\\\""); break;
+ case '\\': writer.write("\\\\"); break;
+ case 0: writer.write("\\0"); break;
+ case '\b': writer.write("\\b"); break;
+ case '\t': writer.write("\\t"); break;
+ case '\n': writer.write("\\n"); break;
+ case '\f': writer.write("\\f"); break;
+ case '\r': writer.write("\\r"); break;
+ case '/': writer.write("\\/"); break;
+ default:
+ if ((c >= 32) && (c <= 126)) {
+ writer.write(c);
+ } else {
+ writer.write("\\u");
+ writer.write(rightAlignedZero(Integer.toHexString(c),4));
+ }
+ }
+ }
+ writer.write('"');
+ }
+
+ /**
+ * Method to generate a string with a particular width. Alignment is done using zeroes if it does not meet the width requirements.
+ * @param s The string to write
+ * @param len The minimum length it should be, and to align with zeroes if length is smaller.
+ * @return A string properly aligned/correct width.
+ */
+ private String rightAlignedZero(String s, int len) {
+ if (len == s.length()) return s;
+ StringBuffer sb = new StringBuffer(s);
+ while (sb.length() < len) {
+ sb.insert(0, '0');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Method to write a number to the current writer.
+ * @param value The number to write to the JSON output string.
+ * @throws IOException Thrown if an error occurs during write.
+ */
+ private void writeNumber(Object value) throws IOException {
+ if (null == value) {
+ writeNull();
+ }
+ if (value instanceof Float) {
+ if (((Float)value).isNaN()) {
+ writeNull();
+ }
+ if (Float.NEGATIVE_INFINITY == ((Float)value).floatValue()) {
+ writeNull();
+ }
+ if (Float.POSITIVE_INFINITY == ((Float)value).floatValue()) {
+ writeNull();
+ }
+ }
+ if (value instanceof Double) {
+ if (((Double)value).isNaN()) {
+ writeNull();
+ }
+ if (Double.NEGATIVE_INFINITY == ((Double)value).doubleValue()) {
+ writeNull();
+ }
+ if (Double.POSITIVE_INFINITY == ((Double)value).doubleValue()) {
+ writeNull();
+ }
+ }
+ writer.write(value.toString());
+ }
+
+ /**
+ * Method to write an object to the current writer.
+ * @param o The object to write.
+ * @throws IOException Thrown if an IO error occurs on the underlying writer.
+ * @throws JSONException Thrown if the specified object is not JSONAble.
+ */
+ private void writeObject(Object o) throws IOException, JSONException {
+ // Handle the object!
+ if (o == null) {
+ writeNull();
+ } else {
+ Class clazz = o.getClass();
+ if (JSONArtifact.class.isAssignableFrom(clazz)) {
+ writer.write(((JSONArtifact)o).toString());
+ } else if (NumberUtil.isNumber(clazz)) {
+ writeNumber(o);
+ } else if (Boolean.class.isAssignableFrom(clazz)) {
+ writer.write(((Boolean)o).toString());
+ } else if (String.class.isAssignableFrom(clazz)) {
+ writeString((String)o);
+ } else if (JSONString.class.isAssignableFrom(clazz)) {
+ writer.write(((JSONString)o).toJSONString());
+ }// else {
+ // // Unknown type, we'll just try to serialize it like a Java Bean.
+ // writer.write(BeanSerializer.toJson(o, true).write());
+ // }
+ }
+ }
+
+ /**
+ * Method to write the text string 'null' to the output stream (null JSON object).
+ * @throws IOException Thrown if an error occurs during write.
+ */
+ private void writeNull() throws IOException {
+ writer.write("null");
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JNumber.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JNumber.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JNumber.java
new file mode 100644
index 0000000..99d244c
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JNumber.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j.internal;
+
+public class JSON4JNumber {
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JPBackReader.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JPBackReader.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JPBackReader.java
new file mode 100644
index 0000000..a2ed87b
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/json4j/internal/JSON4JPBackReader.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.json4j.internal;
+
+import java.io.IOException;
+import java.io.Reader;
+
+public class JSON4JPBackReader extends Reader {
+
+ private Reader _reader = null;
+
+ private int _lastChar = 0;
+
+ public JSON4JPBackReader(Reader reader) {
+ _reader = reader;
+ }
+
+ public void close() throws IOException {
+ _reader.close();
+ }
+
+ public void unread(int c) {
+ }
+
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ cbuf[off] = (char)_lastChar;
+ _reader.read(cbuf, off + 1, len -1);
+ _lastChar = cbuf[off + len];
+ return 0;
+ }
+}