You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by lo...@apache.org on 2013/06/19 20:32:00 UTC
[28/37] [CB-3401] renamed blackberry root folder to bbos
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/http/FileUploader.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/http/FileUploader.java b/bbos/framework/ext/src/org/apache/cordova/http/FileUploader.java
new file mode 100644
index 0000000..75645c7
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/http/FileUploader.java
@@ -0,0 +1,280 @@
+/*
+ * 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.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import javax.microedition.io.Connector;
+import javax.microedition.io.HttpConnection;
+import javax.microedition.io.file.FileConnection;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.json4j.JSONException;
+import org.apache.cordova.json4j.JSONObject;
+import org.apache.cordova.util.Logger;
+
+import net.rim.device.api.io.FileNotFoundException;
+import net.rim.device.api.io.IOUtilities;
+import net.rim.device.api.io.MIMETypeAssociations;
+import net.rim.device.api.io.http.HttpProtocolConstants;
+import net.rim.device.api.ui.UiApplication;
+
+/**
+ * The FileUploader uses an HTTP multipart request to upload files on the
+ * device to a remote server. It currently supports a single file per HTTP
+ * request.
+ */
+public class FileUploader {
+
+ /**
+ * Constants
+ */
+ private static final String BOUNDARY = "----0x2fc1b3ef7cecbf14L";
+ private static final String LINE_END = "\r\n";
+ private static final String TD = "--";
+
+ private Integer responseCode = null;
+
+ /**
+ * Uploads the specified file to the server URL provided using an HTTP
+ * multipart request.
+ * @param filePath Full path of the file on the file system
+ * @param server URL of the server to receive the file
+ * @param fileKey Name of file request parameter
+ * @param fileName File name to be used on server
+ * @param mimeType Describes file content type
+ * @param params key:value pairs of user-defined parameters
+ * @return FileUploadResult containing result of upload request
+ */
+ public FileUploadResult upload(String filePath, String server, String fileKey,
+ String fileName, String mimeType, JSONObject params, JSONObject headers)
+ throws FileNotFoundException, IllegalArgumentException, IOException {
+
+ Logger.log(this.getClass().getName() + ": uploading " + filePath + " to " + server);
+ FileUploadResult result = new FileUploadResult();
+
+ InputStream in = null;
+ OutputStream out = null;
+ FileConnection fconn = null;
+ HttpConnection httpConn = null;
+ try {
+ // open connection to the file
+ try {
+ fconn = (FileConnection)Connector.open(filePath, Connector.READ);
+ } catch (ClassCastException e) {
+ // in case something really funky gets passed in
+ throw new IllegalArgumentException("Invalid file path");
+ } catch (IOException e) {
+ throw new FileNotFoundException("Failed to open source file: " + filePath);
+ }
+ if (!fconn.exists()) {
+ throw new FileNotFoundException(filePath + " not found");
+ }
+
+ // determine mime type by
+ // 1) user-provided type
+ // 2) retrieve from file system
+ // 3) default to JPEG
+ if (mimeType == null) {
+ mimeType = MIMETypeAssociations.getMIMEType(filePath);
+ if (mimeType == null) {
+ mimeType = HttpProtocolConstants.CONTENT_TYPE_IMAGE_JPEG;
+ }
+ }
+
+ // boundary messages
+ String boundaryMsg = getBoundaryMessage(fileKey, fileName, mimeType);
+ String lastBoundary = getEndBoundary();
+
+ // user-defined request parameters
+ String customParams = (params != null) ? getParameterContent(params) : "";
+ Logger.log(this.getClass().getName() + ": params=" + customParams);
+
+ // determine content length
+ long fileSize = fconn.fileSize();
+ Logger.log(this.getClass().getName() + ": " + filePath + " size=" + fileSize + " bytes");
+ long contentLength = fileSize +
+ (long)boundaryMsg.length() +
+ (long)lastBoundary.length() +
+ (long)customParams.length();
+
+ // get HttpConnection
+ httpConn = HttpUtils.getHttpConnection(server);
+ if (httpConn == null) {
+ throw new IOException("Failed to connect to " + server);
+ }
+ Logger.log(this.getClass().getName() + ": server URL=" + httpConn.getURL());
+
+ // set request headers
+ httpConn.setRequestMethod(HttpConnection.POST);
+ httpConn.setRequestProperty(
+ HttpProtocolConstants.HEADER_USER_AGENT,
+ System.getProperty("browser.useragent"));
+ httpConn.setRequestProperty(
+ HttpProtocolConstants.HEADER_KEEP_ALIVE, "300");
+ httpConn.setRequestProperty(
+ HttpProtocolConstants.HEADER_CONNECTION, "keep-alive");
+ httpConn.setRequestProperty(
+ HttpProtocolConstants.HEADER_CONTENT_TYPE,
+ HttpProtocolConstants.CONTENT_TYPE_MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
+ httpConn.setRequestProperty(
+ HttpProtocolConstants.HEADER_CONTENT_LENGTH,
+ Long.toString(contentLength));
+
+ if(headers != null){
+ for(Enumeration e = headers.keys(); e.hasMoreElements();){
+ String key = e.nextElement().toString();
+ String value = headers.optString(key);
+ Logger.log(this.getClass().getName() + ": key=" + key + " value=" + value);
+ httpConn.setRequestProperty(key, value);
+ }
+ }
+
+ // set cookie
+ String cookie = HttpUtils.getCookie(server);
+ if (cookie != null) {
+ httpConn.setRequestProperty(HttpProtocolConstants.HEADER_COOKIE, cookie);
+ Logger.log(this.getClass().getName() + ": cookie=" + cookie);
+ }
+
+ // write...
+ out = httpConn.openDataOutputStream();
+
+ // parameters
+ out.write(customParams.getBytes());
+
+ // boundary
+ out.write(boundaryMsg.getBytes());
+
+ // file data
+ in = fconn.openInputStream();
+ byte[] data = IOUtilities.streamToBytes(in);
+ out.write(data);
+ in.close();
+
+ // end boundary
+ out.write(lastBoundary.getBytes());
+
+ // send request and get response
+ in = httpConn.openDataInputStream();
+ //int rc = httpConn.getResponseCode();
+ result.setResponse(new String(IOUtilities.streamToBytes(in)));
+ //result.setResponseCode(rc);
+ result.setBytesSent(contentLength);
+ Logger.log(this.getClass().getName() + ": sent " + contentLength + " bytes");
+ }
+ finally {
+
+ if (httpConn != null) {
+ result.setResponseCode(httpConn.getResponseCode());
+ responseCode = new Integer(httpConn.getResponseCode());
+ }
+
+ try {
+ if (fconn != null) fconn.close();
+ if (in != null) in.close();
+ if (out != null) out.close();
+ if (httpConn != null) httpConn.close();
+ }
+ catch (IOException e) {
+ Logger.log(this.getClass().getName() + ": " + e);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Sends an upload progress notification back to JavaScript engine.
+ * @param result FileUploadResult containing bytes sent of total
+ * @param callbackId identifier of callback function to invoke
+ */
+ protected void sendProgress(FileUploadResult result, final String callbackId) {
+ JSONObject o = null;
+ try {
+ o = result.toJSONObject();
+ }
+ catch (JSONException e) {
+ Logger.log(this.getClass().getName() + ": " + e);
+ return;
+ }
+
+ // send a progress result
+ final PluginResult r = new PluginResult(PluginResult.Status.OK, o);
+ r.setKeepCallback(true);
+ UiApplication.getUiApplication().invokeAndWait(
+ new Runnable() {
+ public void run() {
+ CordovaExtension.invokeSuccessCallback(callbackId, r);
+ }
+ }
+ );
+ }
+
+ /**
+ * Returns the boundary string that represents the beginning of a file
+ * in a multipart HTTP request.
+ * @param fileKey Name of file request parameter
+ * @param fileName File name to be used on server
+ * @param mimeType Describes file content type
+ * @return string representing the boundary message in a multipart HTTP request
+ */
+ protected String getBoundaryMessage(String fileKey, String fileName, String mimeType) {
+ return (new StringBuffer())
+ .append(TD).append(BOUNDARY).append(LINE_END)
+ .append("Content-Disposition: form-data; name=\"").append(fileKey)
+ .append("\"; filename=\"").append(fileName).append("\"").append(LINE_END)
+ .append("Content-Type: ").append(mimeType).append(LINE_END)
+ .append(LINE_END)
+ .toString();
+ }
+
+ /**
+ * Returns the boundary string that represents the end of a file in a
+ * multipart HTTP request.
+ * @return string representing the end boundary message in a multipart HTTP request
+ */
+ protected String getEndBoundary() {
+ return LINE_END + TD + BOUNDARY + TD + LINE_END;
+ }
+
+ /**
+ * Returns HTTP form content containing specified parameters.
+ */
+ protected String getParameterContent(JSONObject params) {
+ StringBuffer buf = new StringBuffer();
+ for (Enumeration e = params.keys(); e.hasMoreElements();) {
+ String key = e.nextElement().toString();
+ String value = params.optString(key);
+ buf.append(TD).append(BOUNDARY).append(LINE_END)
+ .append("Content-Disposition: form-data; name=\"").append(key).append("\"")
+ .append(LINE_END).append(LINE_END)
+ .append(value).append(LINE_END);
+ }
+ return buf.toString();
+ }
+
+ Integer getResponseCode() {
+ return responseCode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/http/HttpUtils.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/http/HttpUtils.java b/bbos/framework/ext/src/org/apache/cordova/http/HttpUtils.java
new file mode 100644
index 0000000..af6ada6
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/http/HttpUtils.java
@@ -0,0 +1,66 @@
+/*
+ * 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.http;
+
+import javax.microedition.io.HttpConnection;
+
+import org.apache.cordova.CordovaExtension;
+
+import net.rim.device.api.io.transport.ConnectionDescriptor;
+import net.rim.device.api.io.transport.ConnectionFactory;
+
+/**
+ * BlackBerry devices can connect to the network using a variety of transport
+ * types, such as: WI-FI, BES/MDS, BIS, WAP (cellular). A connection URL must
+ * have the appropriate suffix to match the transport type. This class contains
+ * utility methods to retrieve the correct URL for the appropriate transport.
+ */
+public class HttpUtils
+{
+ /**
+ * This method will open an HTTP connection over the best available transport type.
+ * @param url Connection URL
+ */
+ public static HttpConnection getHttpConnection(String url)
+ {
+ HttpConnection httpConn = null;
+
+ // Create ConnectionFactory
+ ConnectionFactory factory = new ConnectionFactory();
+
+ // use the factory to get a connection
+ ConnectionDescriptor conDescriptor = factory.getConnection(url);
+
+ if (conDescriptor != null) {
+ // using the connection
+ httpConn = (HttpConnection) conDescriptor.getConnection();
+ }
+
+ return httpConn;
+ }
+
+ /**
+ * Retrieves the cookie from the application browser instance for the specified URL.
+ * @param url Connection URL
+ */
+ public static String getCookie(String url)
+ {
+ return CordovaExtension.getBrowserField().getCookieManager().getCookie(url);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/json4j/JSON.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/json4j/JSON.java b/bbos/framework/ext/src/org/apache/cordova/json4j/JSON.java
new file mode 100644
index 0000000..adbe514
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/json4j/JSON.java
@@ -0,0 +1,208 @@
+/*
+ * 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.Reader;
+
+import org.apache.cordova.json4j.internal.JSON4JPBackReader;
+
+/**
+ * Helper class that does generic parsing of a JSON stream and returns the appropriate
+ * JSON structure (JSONArray or JSONObject). Note that it is slightly more efficient to directly
+ * parse with the appropriate object than to use this class to do a generalized parse.
+ */
+public class JSON {
+
+ /**
+ * A constant for representing null.
+ * In this case, it is just null.
+ */
+ public static final Object NULL = null;
+
+ /**
+ * Parse a Reader of JSON text into a JSONArtifact.
+ * @param reader The character reader to read the JSON data from.
+ * @param order Boolean flag indicating if the order of the JSON data should be preserved. This parameter only has an effect if the stream is JSON Object { ... } formatted data.
+ * Note: The provided reader is not closed on completion of read; that is left to the caller.
+ * Note: This is the same as calling parse(reader, order, false);
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject, OrderedJSONObject, or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(Reader reader, boolean order) throws JSONException, NullPointerException {
+ return parse(reader,order,false);
+ }
+
+ /**
+ * Parse a Reader of JSON text into a JSONArtifact.
+ * @param reader The character reader to read the JSON data from.
+ * @param order Boolean flag indicating if the order of the JSON data should be preserved. This parameter only has an effect if the stream is JSON Object { ... } formatted data.
+ * @param strict Boolean flag to indicate if the content should be parsed in strict mode or not, meaning comments and unquoted strings are not allowed.
+ * Note: The provided reader is not closed on completion of read; that is left to the caller.
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject, OrderedJSONObject, or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(Reader reader, boolean order, boolean strict) throws JSONException, NullPointerException {
+
+ try {
+ if (reader != null) {
+
+ JSON4JPBackReader pReader = null;
+
+ //Determine if we should buffer-wrap the reader before passing it on
+ //to the appropriate parser.
+ //boolean bufferIt = false;
+
+ Class readerClass = reader.getClass();
+
+ /* if (!StringReader.class.isAssignableFrom(readerClass) &&
+ !CharArrayReader.class.isAssignableFrom(readerClass) &&
+ !PushbackReader.class.isAssignableFrom(readerClass) &&
+ !BufferedReader.class.isAssignableFrom(readerClass)) {
+ bufferIt = true;
+ } */
+
+ //MSN IMPLEMENT PUSHBACKREADER!!
+ if (JSON4JPBackReader.class.isAssignableFrom(readerClass)) {
+ pReader = (JSON4JPBackReader) reader;
+ } else {
+ pReader = new JSON4JPBackReader(reader);
+ }
+
+ Reader rdr = pReader;
+ int ch = pReader.read();
+ while (ch != -1) {
+ switch (ch) {
+ case '{':
+ pReader.unread(ch);
+ /* if (bufferIt) {
+ rdr = new BufferedReader(pReader);
+ } */
+ return new JSONObject(rdr,strict);
+ case '[':
+ pReader.unread(ch);
+ /*if (bufferIt) {
+ rdr = new BufferedReader(pReader);
+ } */
+ return new JSONArray(rdr, strict);
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\r':
+ case '\n':
+ case '\b':
+ ch = pReader.read();
+ break;
+ default:
+ throw new JSONException("Unexpected character: [" + (char)ch + "] while scanning JSON String for JSON type. Invalid JSON.");
+ }
+ }
+ throw new JSONException("Encountered end of stream before JSON data was read. Invalid JSON");
+ } else {
+ throw new NullPointerException("reader cannot be null.");
+ }
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ }
+
+ /**
+ * Parse a Reader of JSON text into a JSONArtifact.
+ * This call is the same as JSON.parse(reader, false, false).
+ * Note that the provided reader is not closed on completion of read; that is left to the caller.
+ * @param reader The character reader to read the JSON data from.
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject, OrderedJSONObject, or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(Reader reader) throws JSONException, NullPointerException {
+ return parse(reader,false, false);
+ }
+
+ /**
+ * Parse a InputStream of JSON text into a JSONArtifact.
+ * Note: The provided InputStream is not closed on completion of read; that is left to the caller.
+ * @param is The input stream to read from. The content is assumed to be UTF-8 encoded and handled as such.
+ * @param order Boolean flag indicating if the order of the JSON data should be preserved. This parameter only has an effect if the stream is JSON Object { ... } formatted data.
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(InputStream is, boolean order) throws JSONException, NullPointerException {
+ return parse(is,order, false);
+ }
+
+ /**
+ * Parse a InputStream of JSON text into a JSONArtifact.
+ * Note that the provided InputStream is not closed on completion of read; that is left to the caller.
+ * @param is The input stream to read from. The content is assumed to be UTF-8 encoded and handled as such.
+ * @param order Boolean flag indicating if the order of the JSON data should be preserved. This parameter only has an effect if the stream is JSON Object { ... } formatted data.
+ * @param strict Boolean flag to indicate if the content should be parsed in strict mode or not, meaning comments and unquoted strings are not allowed.
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(InputStream is, boolean order, boolean strict) throws JSONException, NullPointerException {
+ if (is != null) {
+ //BufferedReader reader = null;
+ InputStreamReader reader = null;
+ try {
+ reader = new InputStreamReader(is, "UTF-8");
+ } catch (Exception ex) {
+ JSONException iox = new JSONException("Could not construct UTF-8 character reader for the InputStream");
+ iox.setCause(ex);
+ throw iox;
+ }
+ return parse(reader,order);
+ } else {
+ throw new NullPointerException("is cannot be null");
+ }
+ }
+
+ /**
+ * Parse an InputStream of JSON text into a JSONArtifact.
+ * This call is the same as JSON.parse(is, false, false).
+ * Note that the provided InputStream is not closed on completion of read; that is left to the caller.
+ * @param is The input stream to read from. The content is assumed to be UTF-8 encoded and handled as such.
+ *
+ * @return Returns an instance of JSONArtifact (JSONObject, OrderedJSONObject, or JSONArray), corrisponding to if the input stream was Object or Array notation.
+ *
+ * @throws JSONException Thrown on errors during parse.
+ * @throws NullPointerException Thrown if reader is null
+ */
+ public static JSONArtifact parse(InputStream is) throws JSONException, NullPointerException {
+ return parse(is,false, false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArray.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArray.java b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArray.java
new file mode 100644
index 0000000..87362c8
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArray.java
@@ -0,0 +1,1123 @@
+/*
+ * 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.Vector;
+
+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;
+
+/**
+ * Extension of ArrayList that only allows values which are JSON-able.
+ * See JSONObject for a list of valid values.
+ *
+ * Instances of this class are not thread-safe.
+ */
+public class JSONArray extends Vector implements JSONArtifact {
+
+ /**
+ * Serial UID for serialization checking.
+ */
+ private static final long serialVersionUID = 9076798781015779954L;
+
+ /**
+ * Create a new instance of this class.
+ */
+ public JSONArray() {
+ super();
+ }
+
+ /**
+ * Create a new instance of this class with the specified initial capacity.
+ * @param initialCapacity The initial size to define the array as.
+ */
+ public JSONArray(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Create a new instance of this class based off the contents of the passed object array.
+ * @param elems The strings to add to a new JSONArray
+ * @throws JSONException Thrown when objects in the array are not JSONable.
+ */
+ public JSONArray(Object[] elems) throws JSONException {
+ if(elems != null){
+ for(int i = 0; i < elems.length; i++){
+ this.add(elems[i]);
+ }
+ }
+ }
+
+ /**
+ * Create a new instance of this class based off the contents of the passed object array.
+ * @param elems The strings to add to a new JSONArray
+ * @param includeSuperclass For JavaBeans, include all superclass info.
+ * @throws JSONException Thrown when objects in the array are not JSONable.
+ */
+ public JSONArray(Object[] elems, boolean includeSuperclass) throws JSONException {
+ if(elems != null){
+ for(int i = 0; i < elems.length; i++){
+ this.add(elems[i]);
+ }
+ }
+ }
+
+ /**
+ * Create a new instance of this class from the provided JSON object string.
+ * Note: This is the same as calling new JSONArray(str, false); Parsing in non-strict mode.
+ * @param str The JSON array string to parse.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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 array string to parse.
+ * @param strict Boolean denoting if the JSON should be parsed n strict mode, meaning unquoted strings and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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 array string.
+ * Note: The reader will not be closed, that is left to the caller.
+ * Note: This is the same as calling new JSONArray(rdr, false); Parsing in non-strict mode.
+ * @param rdr The Reader from which to read the JSON array string to parse.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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 array string.
+ * Note: The reader will not be closed, that is left to the caller.
+ * @param rdr The Reader from which to read the JSON array string to parse.
+ * @param strict Boolean denoting if the JSON should be parsed n strict mode, meaning unquoted strings and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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 array 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 array string to parse.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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 array 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 array string to parse.
+ * @param strict Boolean denoting if the JSON should be parsed n strict mode, meaning unquoted strings and comments are not allowed.
+ * @throws JSONException Thrown when the string passed is null, or malformed JSON..
+ */
+ public JSONArray(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);
+ }
+
+ /**
+ * Function to get a JSONArray entry at a specified index.
+ * @param index The position in the rray to fetch the object from
+ * @throws JSONException Thrown if the index is outside the array bounds.
+ */
+ public Object getIndex(int index) throws JSONException {
+ try{
+ return super.elementAt(index);
+ }catch (Exception ex) {
+ JSONException jex = new JSONException("Error occurred trying to access element at: " + index);
+ jex.setCause(ex);
+ throw jex;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.ArrayList#add(int, java.lang.Object)
+ */
+ public void add(int index, Object element) {
+ if(index > this.size() - 1){
+ expandArray(index);
+ }
+ if (!JSONObject.isValidObject(element)) {
+ throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
+ }
+ super.insertElementAt(element, index);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.ArrayList#add(java.lang.Object)
+ */
+ public boolean add(Object element, boolean includeSuperclass) {
+ if (!JSONObject.isValidObject(element)) {
+ throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
+ }
+ super.addElement(element);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.ArrayList#add(java.lang.Object)
+ */
+ public boolean add(Object element) {
+ return this.add(element, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.ArrayList#set(int, java.lang.Object)
+ */
+ public Object set(int index, Object element) {
+ if(index > this.size() - 1){
+ expandArray(index);
+ }
+ if (!JSONObject.isValidObject(element)) {
+ throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
+ }
+ Object obj = super.elementAt(index);
+ super.setElementAt(element, index);
+ return obj;
+ }
+
+ /**
+ * Internal function to pad-out the array list
+ * Added to mimic expansion behavior of other JSON models.
+ * @param toIndex Increase the array so that it has up to 'toIndex' as indexable slots.
+ */
+ private void expandArray(int toIndex){
+ int maxIndex = this.size();
+ toIndex = toIndex - maxIndex;
+ if(toIndex > 0){
+ for(int i = 0; i < toIndex; i++){
+ super.addElement(null);
+ }
+ }
+ }
+
+ /**************************************************************/
+ /* Maps of add to put, for API compatibility to other parsers.*/
+ /**************************************************************/
+
+ /**
+ * Map of java.util.ArrayList.add(int, java.lang.Object), for compatibility to other JSON parsers.
+ * @see java.util.ArrayList#add(int, java.lang.Object)
+ * @throws JSONException in the case of index out of bounds, etc.
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, Object element) throws JSONException {
+ if (!JSONObject.isValidObject(element)) {
+ throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
+ }
+ try {
+ super.insertElementAt(element, index);
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Exception occurred while placing element.");
+ jex.setCause(ex);
+ throw jex;
+ }
+ return this;
+ }
+
+ /**
+ * Map of java.util.ArrayList.add(java.lang.Object), for compatibility to other JSON parsers.
+ * @see java.util.ArrayList#add(java.lang.Object)
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(Object element) throws JSONException {
+ return put(element, true);
+ }
+
+ /**
+ * Map of java.util.ArrayList.add(java.lang.Object), for compatibility to other JSON parsers.
+ * @see java.util.ArrayList#add(java.lang.Object)
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(Object element, boolean includeSuperclass) throws JSONException {
+ if (!JSONObject.isValidObject(element)) {
+ throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
+
+ }
+ try {
+ super.addElement(element);
+ } catch (Exception ex) {
+ JSONException jex = new JSONException("Exception occurred while placing element.");
+ jex.setCause(ex);
+ throw jex;
+ }
+ return this;
+ }
+
+ /**
+ * Method to place a long into the array.
+ * @param value A long
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(long value) {
+ this.add(new Long(value));
+ return this;
+ }
+
+ /**
+ * Method to place a long into the array.
+ * @param index The position in the array to place the long.
+ * @param value A long
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, long value) {
+ this.add(index, new Long(value));
+ return this;
+ }
+
+ /**
+ * Method to place a int into the array.
+ * @param value An int
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int value) {
+ this.add(new Integer(value));
+ return this;
+ }
+
+ /**
+ * Method to place an int into the array.
+ * @param index The position in the array to place the int.
+ * @param value An int
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, int value) {
+ this.add(index, new Integer(value));
+ return this;
+ }
+
+ /**
+ * Method to place a short into the array.
+ * @param value A short
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(short value) {
+ this.add(new Short(value));
+ return this;
+ }
+
+ /**
+ * Method to place a short into the array.
+ * @param index The position in the array to place the short.
+ * @param value A short
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, short value) {
+ this.add(index, new Short(value));
+ return this;
+ }
+
+ /**
+ * Method to place a double into the array.
+ * @param value A double
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(double value) {
+ this.add(new Double(value));
+ return this;
+ }
+
+ /**
+ * Method to place a double into the array.
+ * @param index The position in the array to place the double.
+ * @param value A double
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, double value) {
+ this.add(index, new Double(value));
+ return this;
+ }
+
+ /**
+ * Method to place a int into the array.
+ * @param value A boolean
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(boolean value) {
+ this.add(new Boolean(value));
+ return this;
+ }
+
+ /**
+ * Method to place a boolean into the array.
+ * @param index The position in the array to place the int.
+ * @param value A boolean
+ * @return A reference to this array instance.
+ */
+ public JSONArray put(int index, boolean value) {
+ this.add(index, new Boolean(value));
+ return this;
+ }
+
+ /*****************/
+ /* End of mapping*/
+ /*****************/
+
+ /********************/
+ /* Utility functions*/
+ /********************/
+
+ /**
+ * Function to obtain a value at the specified index as a boolean.
+ * @param index The index of the item to retrieve.
+ * @return boolean value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not Boolean or a string of 'true' or 'false'
+ */
+ public boolean getBoolean(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (Boolean.class.isAssignableFrom(val.getClass())) {
+ return((Boolean)val).booleanValue();
+ } else if (NumberUtil.isNumber(val.getClass())) {
+ throw new JSONException("Value at index: [" + index + "] 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("Value at index: [" + index + "] was not a boolean or string value of 'true' or 'false'.");
+ }
+ }
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was null");
+ }
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ return false;
+ }
+
+ /**
+ * Function to obtain a value at the specified index as a double.
+ * @param index The index of the item to retrieve.
+ * @return double value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not Number.
+ */
+ public double getDouble(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getDouble(val);
+ }
+ else {
+ throw new JSONException("Value at index: [" + index + "] was not a number.");
+ }
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was null");
+ }
+
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Function to obtain a value at the specified index as a long.
+ * @param index The index of the item to retrieve.
+ * @return long value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not Number.
+ */
+ public long getLong(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getLong(val);
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was not a number.");
+ }
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was null");
+ }
+
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Function to obtain a value at the specified index as an int.
+ * @param index The index of the item to retrieve.
+ * @return int value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not Number.
+ */
+ public int getInt(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getInt(val);
+ }else {
+ throw new JSONException("Value at index: [" + index + "] was not a number.");
+ }
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was null");
+ }
+
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Function to obtain a value at the specified index as a short.
+ * @param index The index of the item to retrieve.
+ * @return short value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not Number.
+ */
+ public short getShort(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (NumberUtil.isNumber(val.getClass())) {
+ return NumberUtil.getShort(val);
+ }
+ else {
+ throw new JSONException("Value at index: [" + index + "] was not a number.");
+ }
+ } else {
+ throw new JSONException("Value at index: [" + index + "] was null");
+ }
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Function to obtain a value at the specified index as a string.
+ * @param index The index of the item to retrieve.
+ * @return string value.
+ * @throws JSONException if the index is outside the range or if the type at the position was not an object with a toString() function..
+ */
+ public String getString(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ return val.toString();
+ } else {
+ throw new JSONException("The value at index: [" + index + "] was null.");
+ }
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * 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.
+ * @param index The index 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(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (JSONObject.class.isAssignableFrom(val.getClass())) {
+ return(JSONObject)val;
+ } else {
+ throw new JSONException("The value for index: [" + index + "] was not a JSONObject");
+ }
+ } else {
+ throw new JSONException("The value for index: [" + index + "] was null. Object required.");
+ }
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Utility method to obtain the specified index as a JSONArray
+ * Only values that are instances of JSONArray will be returned. A null will generate an exception.
+ * @param index The index 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(int index) throws JSONException {
+ try {
+ Object val = this.elementAt(index);
+ if (val != null) {
+ if (JSONArray.class.isAssignableFrom(val.getClass())) {
+ return(JSONArray)val;
+ } else {
+ throw new JSONException("The value index key: [" + index + "] was not a JSONObject");
+ }
+ } else {
+ throw new JSONException("The value for index: [" + index + "] was null. Object required.");
+ }
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ JSONException jex = new JSONException("The specified index was outside of the array boundries");
+ jex.setCause(iobe);
+ throw jex;
+ }
+ }
+
+ /**
+ * Utility function for testing if an element at index 'idx' is null or not.
+ * @return boolean indicating if an index is null or not. Will also return true for indexes outside the size of the array.
+ */
+ public boolean isNull(int index) {
+ try {
+ Object obj = this.elementAt(index);
+ return JSONObject.NULL.equals(obj);
+ } catch (java.lang.IndexOutOfBoundsException iobe) {
+ return true;
+ }
+ }
+
+ /**
+ * Utility function that maps ArrayList.size() to length, for compatibility to other JSON parsers.
+ * @return The number of elements in this JSONArray.
+ */
+ public int length() {
+ return this.size();
+ }
+
+ /***************************/
+ /* End of Utility functions*/
+ /***************************/
+
+ /**
+ * Convert this object into a stream of JSON text. Same as calling write(os,false);
+ * @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);
+ * @param os The output stream to write data to. Output stream characters will be serialized as UTF-8.
+ * @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 reimplement BUFFERED
+ writer = new OutputStreamWriter(os, "UTF-8");
+ } catch (UnsupportedEncodingException uex) {
+ JSONException jex = new JSONException(uex.toString());
+ jex.setCause(uex);
+ throw jex;
+ }
+ write(writer, verbose);
+ return os;
+ }
+
+ /**
+ * Convert this object into a String of JSON text, specifying how many spaces should
+ * be used for each indent level. Output stream characters will be serialized as UTF-8.
+ * @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 reimplement BUFFERED
+ writer = new OutputStreamWriter(os, "UTF-8");
+ } catch (UnsupportedEncodingException uex) {
+ JSONException jex = new JSONException(uex.toString());
+ jex.setCause(uex);
+ throw jex;
+ }
+ write(writer, indentDepth);
+ return os;
+ }
+
+ /**
+ * Convert this object into a stream of 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;
+ }
+
+ /**
+ * Convert this object into a stream of JSON text, specifying verbosity.
+ * @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;
+
+ //MSN reimplement BUFFERED
+ /*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.writeArray(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 array into a stream of JSON text, specifying verbosity.
+ * @param writer The writer which to write the JSON text to.
+ * @param indentDepth How many spaces to use for each indent level. Should be one to eight.
+ *
+ * @throws JSONException Thrown on IO errors during serialization.
+ */
+ 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.
+ //MSN reimplement BUFFERED
+// Class writerClass = writer.getClass();
+// if (!StringWriter.class.isAssignableFrom(writerClass) &&
+// !CharArrayWriter.class.isAssignableFrom(writerClass) &&
+// !BufferedWriter.class.isAssignableFrom(writerClass)) {
+// writer = new BufferedWriter(writer);
+// }
+
+ if (indentDepth > 0) {
+ serializer = new SerializerVerbose(writer, indentDepth);
+ } else {
+ serializer = new Serializer(writer);
+ }
+ try {
+ serializer.writeArray(this);
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ return writer;
+ }
+
+ /**
+ * Convert this object into a String of JSON text, specifying verbosity.
+ * @param verbose Whether or not to write in compressed for formatted Strings.
+ *
+ * @throws JSONException Thrown on IO 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.writeArray(this).flush();
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ jex.setCause(iox);
+ throw jex;
+ }
+ return writer.toString();
+ }
+
+ /**
+ * Convert this array into a String of JSON text, specifying verbosity.
+ * @param indentDepth How many spaces to use for each indent level. Should be one to eight.
+ *
+ * @throws JSONException Thrown on IO 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.writeArray(this).flush();
+ } catch (IOException iox) {
+ JSONException jex = new JSONException("Error occurred during input read.");
+ 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);
+ }
+
+ /**
+ * 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>]
+ */
+ public String toString() {
+ String str = null;
+ try {
+ str = write(false);
+ } 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, the return will be of format: JSON Generation Error: [<some error>]
+ * @throws JSONException Thrown if an error occurs during JSON generation.
+ */
+ public String toString(int indentDepth) throws JSONException {
+ return write(indentDepth);
+ }
+
+ /**
+ * Method to mimic the behavior of the JavaScript array join function
+ * @param str The string delimiter to place between joined array elements in the output string.
+ * @return A string of all the elements joined together.
+ */
+ public String join(String str) {
+ if (str == null) {
+ str = "";
+ }
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < this.size(); i++) {
+ if (i > 0) {
+ buf.append(str);
+ }
+ Object obj = this.elementAt(i);
+ if (obj == null) {
+ buf.append("null");
+ } else {
+ buf.append(obj.toString());
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Methods added for compatibility to other models.
+ */
+
+ /**
+ * Method to get the object at that position, or null if outside the array range.
+ * @param index the array index to get
+ * @return - value or null
+ */
+ public Object opt(int index) {
+ try{
+ return elementAt(index);
+ } catch (Throwable th){
+ return null;
+ }
+ }
+
+ /**
+ * Method to get the object at that position, or null if outside the array range.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or defaultValue
+ */
+ public Object opt(int index, Object defaultValue) {
+ try{
+ return elementAt(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as an boolean, or 'false' if outside the array.
+ * @param index the array index to get
+ * @return - value or false
+ */
+ public boolean optBoolean(int index) {
+ try{
+ return getBoolean(index);
+ } catch (Throwable th){
+ return false;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as an boolean, or 'defaultValue' if outside the array.
+ * @param index The array index to get.
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or false
+ */
+ public boolean optBoolean(int index, boolean defaultValue) {
+ try{
+ return getBoolean(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as an int, or '0' if outside the array.
+ * @param index the array index to get
+ * @return - value or 0
+ */
+ public int optInt(int index) {
+ try{
+ return getInt(index);
+ } catch (Throwable th){
+ return 0;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as an int, or defaultValue if outside the array.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or 0
+ */
+ public int optInt(int index, int defaultValue) {
+ try{
+ return getInt(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a long, or '0' if outside the array.
+ * @param index the array index to get
+ * @return - value or 0
+ */
+ public long optLong(int index) {
+ try{
+ return getLong(index);
+ } catch (Throwable th){
+ return (long)0;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a long, or defaultValue if outside the array.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ v* @return - value or defaultValue
+ */
+ public long optLong(int index, long defaultValue) {
+ try{
+ return getLong(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a short, or '0' if outside the array.
+ * @param index the array index to get
+ * @return - value or 0
+ */
+ public short optShort(int index) {
+ try{
+ return getShort(index);
+ } catch (Throwable th){
+ return (short)0;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a short, or '0' if outside the array.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or defaultValue
+ */
+ public short optShort(int index, short defaultValue) {
+ try{
+ return getShort(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a double, or Double.NaN if outside the array.
+ * @param index the array index to get
+ * @return - value or Double.NaN
+ */
+ public double optDouble(int index) {
+ try{
+ return getDouble(index);
+ } catch (Throwable th){
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a double, or Double.NaN if outside the array.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or defaultValue
+ */
+ public double optDouble(int index, double defaultValue) {
+ try{
+ return getDouble(index);
+ } catch (Throwable th){
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a String, or null if outside the array.
+ * @param index the array index to get
+ * @return - value or null
+ */
+ public String optString(int index) {
+ try{
+ return getString(index);
+ } catch (Exception th){
+ return null;
+ }
+ }
+
+ /**
+ * Method to obtain the value at index as a String, or defaultValue if outside the array.
+ * @param index the array index to get
+ * @param defaultValue the value to return if index is outside the array.
+ * @return - value or defaultValue
+ */
+ public String optString(int index, String defaultValue) {
+ try{
+ return getString(index);
+ } catch (Throwable th){
+ return defaultValue;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArtifact.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArtifact.java b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArtifact.java
new file mode 100644
index 0000000..4e8ff0c
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONArtifact.java
@@ -0,0 +1,118 @@
+/*
+ * 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.OutputStream;
+import java.io.Writer;
+
+/**
+ * Interface class to define a set of generic APIs both JSONObject and JSONArray implement.
+ * This is namely so that functions such as write, which are common between the two, can be easily
+ * invoked without knowing the object type.
+ */
+public interface JSONArtifact
+{
+ /**
+ * 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.
+ * @return The passed in OutputStream.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public OutputStream write(OutputStream os) throws JSONException;
+
+ /**
+ * Write this object to the stream as JSON text in UTF-8 encoding, specifying whether to use verbose (tab-indented) output or not.
+ * 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. If true, will indent via tab.
+ * @return The passed in OutputStream.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public OutputStream write(OutputStream os, boolean verbose) throws JSONException;
+
+ /**
+ * Write this object to the stream as JSON text in UTF-8 encoding, 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.
+ * @return The passed in OutputStream.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public OutputStream write(OutputStream os, int indentDepth) throws JSONException;
+
+ /**
+ * 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.
+ * @return The passed in writer.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public Writer write(Writer writer) throws JSONException;
+
+ /**
+ * Writer this object to the writer as JSON text, specifying whether to use verbose (tab-indented) output or not.
+ * 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.
+ * @return The passed in writer.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public Writer write(Writer writer, boolean verbose) throws JSONException;
+
+ /**
+ * 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.
+ * @return The passed in writer.
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public Writer write(Writer writer, int indentDepth) throws JSONException;
+
+ /**
+ * 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.
+ * 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(boolean verbose) throws JSONException;
+
+ /**
+ * 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;
+
+ /**
+ * Convert this object into a String of JSON text. Same as write(false);
+ *
+ * @throws JSONException Thrown on errors during serialization.
+ */
+ public String write() throws JSONException;
+}
http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/b66b2ef1/bbos/framework/ext/src/org/apache/cordova/json4j/JSONException.java
----------------------------------------------------------------------
diff --git a/bbos/framework/ext/src/org/apache/cordova/json4j/JSONException.java b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONException.java
new file mode 100644
index 0000000..d79f419
--- /dev/null
+++ b/bbos/framework/ext/src/org/apache/cordova/json4j/JSONException.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+/**
+ * Class that implements an exception type thrown by all JSON classes
+ * as a common exception when JSON handling errors occur.
+ */
+public class JSONException extends Exception {
+
+ private Throwable cause;
+
+ /**
+ * Constructor for JSON Exception
+ * @param message The error that generated the exception.
+ */
+ public JSONException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor for JSON Exception
+ * @param t The exception that generated this exception.
+ */
+ public JSONException(Throwable t) {
+ cause = t;
+ }
+
+ public void setCause(Throwable t) {
+ cause = t;
+ }
+
+ /**
+ * Method to get the underlying cause of the JSONException
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+}