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

net.pwall.json.JSONArray Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/*
 * @(#) JSONArray.java
 *
 * jsonutil JSON Utility Library
 * Copyright (c) 2014, 2015 Peter Wall
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package net.pwall.json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * A JSON array.
 *
 * @author Peter Wall
 */
public class JSONArray extends ArrayList implements JSONComposite {

    private static final long serialVersionUID = -6963671812529472759L;

    /**
     * Construct an empty JSON array.
     */
    public JSONArray() {
    }

    /**
     * Construct a JSON array by copying another JSON array.
     *
     * @param   array   the source {@code JSONArray}
     * @throws  NullPointerException if the collection is {@code null}
     */
    public JSONArray(JSONValue[] array) {
        for (JSONValue item : requireNonNull(array))
            add(item);
    }

    /**
     * Construct a JSON array from a {@link Collection} of JSON values.
     *
     * @param   collection  the source {@link Collection}
     * @throws  NullPointerException if the collection is {@code null}
     */
    public JSONArray(Collection collection) {
        super(collection);
    }

    /**
     * Add a {@link JSONString} to the JSON array representing the supplied {@link CharSequence}
     * ({@link String}, {@link StringBuilder} etc.).
     *
     * @param   cs      the {@link CharSequence}
     * @return          {@code this} (for chaining)
     * @throws  NullPointerException if the value is {@code null}
     */
    public JSONArray addValue(CharSequence cs) {
        add(new JSONString(cs));
        return this;
    }

    /**
     * Add a {@link JSONInteger} to the JSON array representing the supplied {@code int}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     */
    public JSONArray addValue(int value) {
        add(JSONInteger.valueOf(value));
        return this;
    }

    /**
     * Add a {@link JSONLong} to the JSON array representing the supplied {@code long}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     */
    public JSONArray addValue(long value) {
        add(JSONLong.valueOf(value));
        return this;
    }

    /**
     * Add a {@link JSONFloat} to the JSON array representing the supplied {@code float}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     */
    public JSONArray addValue(float value) {
        add(JSONFloat.valueOf(value));
        return this;
    }

    /**
     * Add a {@link JSONDouble} to the JSON array representing the supplied {@code double}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     */
    public JSONArray addValue(double value) {
        add(JSONDouble.valueOf(value));
        return this;
    }

    /**
     * Add a {@link JSONBoolean} to the JSON array representing the supplied {@code boolean}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     */
    public JSONArray addValue(boolean value) {
        add(JSONBoolean.valueOf(value));
        return this;
    }

    /**
     * Add a {@link JSONBoolean} to the JSON array representing the supplied {@link Boolean}.
     *
     * @param   value   the value
     * @return          {@code this} (for chaining)
     * @throws  NullPointerException if the value is {@code null}
     */
    public JSONArray addValue(Boolean value) {
        add(JSONBoolean.valueOf(requireNonNull(value).booleanValue()));
        return this;
    }

    public  JSONArray addValues(Collection collection) {
        for (CharSequence value : collection)
            addValue(value);
        return this;
    }

    public  JSONArray addValues(T[] array) {
        for (int i = 0, n = array.length; i < n; i++)
            addValue(array[i]);
        return this;
    }

    public JSONArray addValues(int[] array) {
        for (int i = 0, n = array.length; i < n; i++)
            addValue(array[i]);
        return this;
    }

    public JSONArray addValues(long[] array) {
        for (int i = 0, n = array.length; i < n; i++)
            addValue(array[i]);
        return this;
    }

    public JSONArray addValues(float[] array) {
        for (int i = 0, n = array.length; i < n; i++)
            addValue(array[i]);
        return this;
    }

    public JSONArray addValues(double[] array) {
        for (int i = 0, n = array.length; i < n; i++)
            addValue(array[i]);
        return this;
    }

    /**
     * Add a {@code null} value to the JSON array.
     *
     * @return          {@code this} (for chaining)
     */
    public JSONArray addNull() {
        add(null);
        return this;
    }

    /**
     * Add a {@link JSONValue} to the {@code JSONArray}.  This method duplicates the
     * {@link ArrayList#add(Object) add(JSONValue)} method inherited from the {@link ArrayList}
     * class, but it returns {@code this} to allow for chaining.
     *
     * @param   json    the {@link JSONValue}
     * @return          {@code this} (for chaining)
     */
    public JSONArray addJSON(JSONValue json) {
        add(json);
        return this;
    }

    /**
     * Get a {@link String} value from the array.  If the array entry is {@code null} return
     * {@code null}.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link JSONString}
     */
    public String getString(int index) {
        return JSON.getString(get(index));
    }

    /**
     * Get an {@code int} value from the array.  If the array entry is {@code null} return 0.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link Number}
     */
    public int getInt(int index) {
        return JSON.getInt(get(index));
    }

    /**
     * Get a {@code long} value from the array.  If the array entry is {@code null} return 0.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link Number}
     */
    public long getLong(int index) {
        return JSON.getLong(get(index));
    }

    /**
     * Get a {@code float} value from the array.  If the array entry is {@code null} return 0.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link Number}
     */
    public float getFloat(int index) {
        return JSON.getFloat(get(index));
    }

    /**
     * Get a {@code double} value from the array.  If the array entry is {@code null} return 0.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link Number}
     */
    public double getDouble(int index) {
        return JSON.getDouble(get(index));
    }

    /**
     * Get a {@code boolean} value from the array.  If the array entry is {@code null} return
     * {@code false}.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link JSONBoolean}
     */
    public boolean getBoolean(int index) {
        return JSON.getBoolean(get(index));
    }

    /**
     * Get a {@link JSONArray} value from the array.  If the array entry is {@code null} return
     * {@code null}.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link JSONArray}
     */
    public JSONArray getArray(int index) {
        return JSON.getArray(get(index));
    }

    /**
     * Get a {@link JSONObject} value from the array.  If the array entry is {@code null} return
     * {@code null}.
     *
     * @param   index   the index of the value
     * @return  the value
     * @throws  JSONException if the array entry is not a {@link JSONArray}
     */
    public JSONObject getObject(int index) {
        return JSON.getObject(get(index));
    }

    /**
     * Get an {@link Iterable} of {@link String} from this array.  Supports the idiom:
     * 
     *     for (String item : jsonArray.strings()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link String} or {@code null}. * * @return an {@link Iterable} of {@link String} */ public Iterable strings() { return new Iterable() { @Override public Iterator iterator() { return new StringIterator(); } }; } /** * Get an {@link Iterable} of {@link Integer} from this array. Supports the idiom: *
     *     for (Integer item : jsonArray.ints()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link Integer} or {@code null}. * * @return an {@link Iterable} of {@link Integer} */ public Iterable ints() { return new Iterable() { @Override public Iterator iterator() { return new IntegerIterator(); } }; } /** * Get an {@link Iterable} of {@link Long} from this array. Supports the idiom: *
     *     for (Long item : jsonArray.longs()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link Long} or {@code null}. * * @return an {@link Iterable} of {@link Long} */ public Iterable longs() { return new Iterable() { @Override public Iterator iterator() { return new LongIterator(); } }; } /** * Get an {@link Iterable} of {@link Double} from this array. Supports the idiom: *
     *     for (Double item : jsonArray.doubles()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link Double} or {@code null}. * * @return an {@link Iterable} of {@link Double} */ public Iterable doubles() { return new Iterable() { @Override public Iterator iterator() { return new DoubleIterator(); } }; } /** * Get an {@link Iterable} of {@link Float} from this array. Supports the idiom: *
     *     for (Float item : jsonArray.floats()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link Float} or {@code null}. * * @return an {@link Iterable} of {@link Float} */ public Iterable floats() { return new Iterable() { @Override public Iterator iterator() { return new FloatIterator(); } }; } /** * Get an {@link Iterable} of {@link Boolean} from this array. Supports the idiom: *
     *     for (Boolean item : jsonArray.booleans()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link Boolean} or {@code null}. * * @return an {@link Iterable} of {@link Boolean} */ public Iterable booleans() { return new Iterable() { @Override public Iterator iterator() { return new BooleanIterator(); } }; } /** * Get an {@link Iterable} of {@link JSONArray} from this array. Supports the idiom: *
     *     for (JSONArray item : jsonArray.arrays()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link JSONArray} or {@code null}. * * @return an {@link Iterable} of {@link JSONArray} */ public Iterable arrays() { return new Iterable() { @Override public Iterator iterator() { return new ArrayIterator(); } }; } /** * Get an {@link Iterable} of {@link JSONObject} from this array. Supports the idiom: *
     *     for (JSONObject item : jsonArray.objects()) {
     *         // process each item of the array
     *     }
     * 
* The resulting {@link Iterator} will throw a {@link JSONException} if any item in the * array is not a {@link JSONObject} or {@code null}. * * @return an {@link Iterable} of {@link JSONObject} */ public Iterable objects() { return new Iterable() { @Override public Iterator iterator() { return new ObjectIterator(); } }; } /** * Create the external representation for this JSON array. * * @return the JSON representation for this array * @see JSONValue#toJSON() */ @Override public String toJSON() { int estimate = size() * 20; StringBuilder sb = new StringBuilder(estimate); try { appendJSON(sb); } catch (IOException e) { // can't happen - StringBuilder does not throw IOException } return sb.toString(); } /** * Append the external representation for this JSON array to a given {@link Appendable}. * * @param a the {@link Appendable} * @throws IOException if thrown by the {@link Appendable} * @see JSONValue#appendJSON(Appendable) */ @Override public void appendJSON(Appendable a) throws IOException { a.append('['); if (size() > 0) { int i = 0; for (;;) { JSON.appendJSON(a, get(i++)); if (i >= size()) break; a.append(','); } } a.append(']'); } /** * Test whether the composite is "simple", i.e. it contains only non-composite values (to * assist with formatting). * * @return {@code true} if the composite is simple * @see JSONComposite#isSimple() */ @Override public boolean isSimple() { for (int i = 0; i < size(); i++) if (get(i) instanceof JSONComposite) return false; return true; } /** * Return a string representation of the JSON array. This is the same as the JSON format. * * @return the JSON string */ @Override public String toString() { return toJSON(); } /** * Compare two JSON arrays for equality. * * @param other the other JSON array * @return {@code true} if the other object is a JSON array and the contents are equal */ @Override public boolean equals(Object other) { return other == this || other instanceof JSONArray && super.equals(other); } /** * Convenience method to create a {@code JSONArray}. Supports the idiom: *
     *     JSONArray arr = JSONArray.create().addValue(0).addValue(1).addValue(2);
     * 
* * @return the new {@code JSONArray} */ public static JSONArray create() { return new JSONArray(); } private static T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; } public abstract class BaseIterator implements Iterator { protected Iterator iterator = iterator(); @Override public boolean hasNext() { return iterator.hasNext(); } @Override public void remove() { iterator.remove(); } } public class StringIterator extends BaseIterator { @Override public String next() { return JSON.getString(iterator.next()); } } public class IntegerIterator extends BaseIterator { @Override public Integer next() { JSONValue value = iterator.next(); if (value == null) return null; if (!(value instanceof Number)) throw new JSONException(JSON.NOT_A_NUMBER); return ((Number)value).intValue(); } } public class LongIterator extends BaseIterator { @Override public Long next() { JSONValue value = iterator.next(); if (value == null) return null; if (!(value instanceof Number)) throw new JSONException(JSON.NOT_A_NUMBER); return ((Number)value).longValue(); } } public class DoubleIterator extends BaseIterator { @Override public Double next() { JSONValue value = iterator.next(); if (value == null) return null; if (!(value instanceof Number)) throw new JSONException(JSON.NOT_A_NUMBER); return ((Number)value).doubleValue(); } } public class FloatIterator extends BaseIterator { @Override public Float next() { JSONValue value = iterator.next(); if (value == null) return null; if (!(value instanceof Number)) throw new JSONException(JSON.NOT_A_NUMBER); return ((Number)value).floatValue(); } } public class BooleanIterator extends BaseIterator { @Override public Boolean next() { JSONValue value = iterator.next(); if (value == null) return null; if (!(value instanceof JSONBoolean)) throw new JSONException(JSON.NOT_A_BOOLEAN); return ((JSONBoolean)value).booleanValue(); } } public class ArrayIterator extends BaseIterator { @Override public JSONArray next() { return JSON.getArray(iterator.next()); } } public class ObjectIterator extends BaseIterator { @Override public JSONObject next() { return JSON.getObject(iterator.next()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy