All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wink.json4j.JSONArray Maven / Gradle / Ivy

The newest version!
/*
 * 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.wink.json4j;

import java.io.BufferedWriter;
import java.io.CharArrayWriter;
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.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.apache.wink.json4j.internal.BeanSerializer;
import org.apache.wink.json4j.internal.Parser;
import org.apache.wink.json4j.internal.Serializer;
import org.apache.wink.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 ArrayList 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 in collection
     * @param col The Collection of objects to add into this array.
     * @throws JSONException Thrown when objects in the collection are not JSONable.
     * @throws NullPointerException Thrown if col is null.
     */
    public JSONArray(Collection col) throws JSONException {
        super(col.size());
        Iterator itr = col.iterator();
        if (itr != null) {
            while (itr.hasNext()) {
                this.add(itr.next());
            }
        }
    }

    /**
     * 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 based off the contents of the passed
     * in collection
     * @param col The Collection of objects to add into this array.
     * @param includeSuperclass For JavaBeans, include all superclass info.
     * @throws JSONException Thrown when objects in the collection are not JSONable.
     * &throws NullPointerException Thrown if col is null.
     */
    public JSONArray(Collection col, boolean includeSuperclass) throws JSONException {
        super(col.size());
        Iterator itr = col.iterator();
        if (itr != null) {
            while (itr.hasNext()) {
                this.add(itr.next(), true);
            }
        }
    }

    /**
     * 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();
        StringReader reader = new StringReader(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();
        StringReader reader = new StringReader(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.get(index);
        }catch (Exception ex) {
            JSONException jex = new JSONException("Error occurred trying to access element at: " + index);
            jex.initCause(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)) {
            try {
                element = BeanSerializer.toJson(element, true);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
            }
        }
        super.add(index, element);
    }

    /*
     * (non-Javadoc)
     * @see java.util.ArrayList#add(java.lang.Object)
     */
    public boolean add(Object element, boolean includeSuperclass) {
        if (!JSONObject.isValidObject(element)) {
            try {
                element = BeanSerializer.toJson(element, includeSuperclass);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
            }
        }
        return super.add(element);
    }


    /*
     * (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#addAll(java.util.Collection)
     */
    public boolean addAll(Collection collection) {
        for (Iterator iter = collection.iterator(); iter.hasNext(); ) {
            Object obj = iter.next();
            if (!JSONObject.isValidObject(obj)) {
                try {
                    obj = BeanSerializer.toJson(obj, true);
                } catch (Exception ex) {
                    throw new IllegalArgumentException("Object of type: [" + obj.getClass().getName() + "] could not be converted to a JSON representation.");
                }
            }
            super.add(obj);
        }
        return true;
    }

    /*
     * (non-Javadoc)
     * @see java.util.ArrayList#addAll(int, java.util.Collection)
     */
    public boolean addAll(int index, Collection collection) {
        if(index > this.size() - 1){
            expandArray(index);
        }
        for (Iterator iter = collection.iterator(); iter.hasNext(); ) {
            Object obj = iter.next();
            if (!JSONObject.isValidObject(obj)) {
                try {
                    obj = BeanSerializer.toJson(obj, true);
                } catch (Exception ex) {
                    throw new IllegalArgumentException("Object of type: [" + obj.getClass().getName() + "] could not be converted to a JSON representation.");
                }
            }
            super.add(index, obj);
            index++;
        }
        return 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)) {
            try {
                element = BeanSerializer.toJson(element, true);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
            }
        }
        return super.set(index, element);
    }

    /**
     * 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.add(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)) {
            try {
                element = BeanSerializer.toJson(element, true);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
            }
        }
        try {
            super.add(index, element);
        } catch (Exception ex) {
            JSONException jex = new JSONException("Exception occurred while placing element.");
            jex.initCause(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)) {
            try {
                element = BeanSerializer.toJson(element, includeSuperclass);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Object of type: [" + element.getClass().getName() + "] could not be converted to a JSON representation.");
            }
        }
        try {
            super.add(element);            
        } catch (Exception ex) {
            JSONException jex = new JSONException("Exception occurred while placing element.");
            jex.initCause(ex);
            throw jex;
        }
        return this;
    }

    /**
     * Method to place a java.util.Map instance in the array.  It will convert the map to a JSONObject if necessary.
     * @param index The position in the array to place the Map (or coverted map).
     * @param value An instance of a java.util.Map to insert into the array.  Will convert to JSONObject if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the map cannot be converted to something JSONAble or the index is out of bounds.
     */
    public JSONArray put(int index, Map value) throws JSONException {
        return this.put(index,value,true);
    }

    /**
     * Method to place a java.util.Map instance in the array.  It will convert the map to a JSONObject if necessary.
     * @param index The position in the array to place the Map (or coverted map).
     * @param value An instance of a java.util.Map to insert into the array.  Will convert to JSONObject if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the map cannot be converted to something JSONAble or the index is out of bounds.
     */
    public JSONArray put(int index, Map value, boolean includeSuperclass) throws JSONException{
        if (value == null) {
            this.add((Object)null);
        } else {
            if (JSONObject.class.isAssignableFrom(value.getClass())) {
                this.add(index, (Object)value);
            } else {
                this.add(index, new JSONObject(value, includeSuperclass));
            }
        }
        return this;
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONObject if necessary.
     * @param value An instance of a java.util.Map to insert into the array.  Will convert to JSONObject if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the map cannot be converted to something JSONAble.
     */
    public JSONArray put(Map value) throws JSONException {
        return this.put(value, true);
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONObject if necessary.
     * @param value An instance of a java.util.Map to insert into the array.  Will convert to JSONObject if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the map cannot be converted to something JSONAble.
     */
    public JSONArray put(Map value, boolean includeSuperclass) throws JSONException {
        if (value == null) {
            this.add((Object)null);
        } else {
            if (JSONObject.class.isAssignableFrom(value.getClass())) {
                this.add((Object)value);
            } else {
                this.add(new JSONObject(value, includeSuperclass));
            }
        }
        return this;
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONArray if necessary.
     * @param index The position in the array to place the Collection.
     * @param value An instance of a java.util.Collection to insert into the array.  Will convert to JSONArray if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the collection cannot be converted to something JSONAble or the index is out of bounds.
     */
    public JSONArray put(int index, Collection value) throws JSONException {
        return this.put(index,value,true);
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONArray if necessary.
     * @param index The position in the array to place the Collection.
     * @param value An instance of a java.util.Collection to insert into the array.  Will convert to JSONArray if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the collection cannot be converted to something JSONAble or the index is out of bounds.
     */
    public JSONArray put(int index, Collection value, boolean includeSuperclass) throws JSONException {
        if (value == null) {
            this.add((Object)null);
        } else {
            if (JSONArray.class.isAssignableFrom(value.getClass())) {
                this.add(index, (Object)value);
            } else {
                this.add(index, new JSONArray(value, includeSuperclass));
            }
        }
        return this;
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONArray if necessary.
     * @param value An instance of a java.util.Collection to insert into the array.  Will convert to JSONArray if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the collection cannot be converted to something JSONAble.
     */
    public JSONArray put(Collection value) throws JSONException {
        return this.put(value,true);
    }

    /**
     * Method to place a map into the array.  It will convert the map to a JSONArray if necessary.
     * @param value An instance of a java.util.Collection to insert into the array.  Will convert to JSONArray if necessary.
     * @return A reference to this array instance.
     * @throws JSONException Thrown if the collection cannot be converted to something JSONAble.
     */
    public JSONArray put(Collection value, boolean includeSuperclass) throws JSONException {
        if (value == null) {
            this.add((Object)null);
        } else {
            if (JSONArray.class.isAssignableFrom(value.getClass())) {
                this.add((Object)value);
            } else {
                this.add(new JSONArray(value, includeSuperclass));
            }
        }
        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.get(index);
            if (val != null) {
                if (Boolean.class.isAssignableFrom(val.getClass())) {
                    return((Boolean)val).booleanValue();
                } else if (Number.class.isAssignableFrom(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.initCause(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.get(index);
            if (val != null) {
                if (Number.class.isAssignableFrom(val.getClass())) {
                    return((Number)val).doubleValue();
                } 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.initCause(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.get(index);
            if (val != null) {
                if (Number.class.isAssignableFrom(val.getClass())) {
                    return((Number)val).longValue();
                } 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.initCause(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.get(index);
            if (val != null) {
                if (Number.class.isAssignableFrom(val.getClass())) {
                    return((Number)val).intValue();
                } 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.initCause(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.get(index);
            if (val != null) {
                if (Number.class.isAssignableFrom(val.getClass())) {
                    return((Number)val).shortValue();
                } 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.initCause(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.get(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.initCause(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.get(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.initCause(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.get(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.initCause(iobe);
            throw jex;
        }
    }

    /**
     * Utility functions
     */

    /**
     * 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.get(index);
            if (obj != null) {
                return false;
            } else {
                return true;
            }
        } 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 {
            writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
        } catch (UnsupportedEncodingException uex) {
            JSONException jex = new JSONException(uex.toString());
            jex.initCause(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 {
            writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
        } catch (UnsupportedEncodingException uex) {
            JSONException jex = new JSONException(uex.toString());
            jex.initCause(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;
        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.initCause(iox);
            throw jex;
        }
        if (flushIt) {
            try {
                writer.flush();
            } catch (Exception ex) { 
                JSONException jex = new JSONException("Error during buffer flush");
                jex.initCause(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.
        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.initCause(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;
        StringWriter writer = new StringWriter();

        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.initCause(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;
        StringWriter writer = new StringWriter();

        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.initCause(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: []
     */
    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: []
     * @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.get(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 get(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 get(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 (Throwable 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;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy