Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.juneau.collections.JsonList Maven / Gradle / Ivy
// ***************************************************************************************************************************
// * 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.juneau.collections;
import static org.apache.juneau.common.internal.ThrowableUtils.*;
import static org.apache.juneau.internal.ConsumerUtils.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.*;
import org.apache.juneau.*;
import org.apache.juneau.common.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.marshaller.*;
import org.apache.juneau.objecttools.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
/**
* Java implementation of a JSON array.
*
*
* An extension of {@link LinkedList}, so all methods available to in that class are also available to this class.
*
*
* Note that the use of this class is optional for generating JSON. The serializers will accept any objects that implement the
* {@link Collection} interface. But this class provides some useful additional functionality when working with JSON
* models constructed from Java Collections Framework objects. For example, a constructor is provided for converting a
* JSON array string directly into a {@link List}. It also contains accessor methods for to avoid common typecasting
* when accessing elements in a list.
*
*
Example:
*
* // Construct an empty List
* JsonList list = JsonList.of ();
*
* // Construct a list of objects using various methods
* list = JsonList.of ().a("foo" ).a(123).a(true );
* list = JsonList.of ().a("foo" , 123, true ); // Equivalent
* list = JsonList.of ("foo" , 123, true ); // Equivalent
*
* // Construct a list of integers from JSON
* list = JsonList.ofJson ("[1,2,3]" );
*
* // Construct a list of generic JsonMap objects from JSON
* list = JsonList.ofJson ("[{foo:'bar'},{baz:'bing'}]" );
*
* // Construct a list of integers from XML
* String xml = "<array><number>1</number><number>2</number><number>3</number></array>" ;
* list = JsonList.of (xml , XmlParser.DEFAULT );
* list = (List)XmlParser.DEFAULT .parse(xml ); // Equivalent
* list = (List)XmlParser.DEFAULT .parse(Object.class , xml ); // Equivalent
* list = XmlParser.DEFAULT .parse(List.class , xml ); // Equivalent
* list = XmlParser.DEFAULT .parse(JsonList.class , xml ); // Equivalent
*
* // Construct JSON from JsonList
* list = JsonList.ofJson ("[{foo:'bar'},{baz:'bing'}]" );
* String json = list .toString(); // Produces "[{foo:'bar'},{baz:'bing'}]"
* json = list .toString(JsonSerializer.DEFAULT ); // Equivalent
* json = JsonSerializer.DEFAULT .serialize(list ); // Equivalent
*
* // Get one of the entries in the list as an Integer
* list = JsonList.ofJson ("[1,2,3]" );
* Integer integer = list .getInt(1);
* list = list .get(Integer.class , 1); // Equivalent
*
* // Get one of the entries in the list as an Float
* list = JsonList.ofJson ("[1,2,3]" );
* Float _float = list .getFloat(1); // Returns 2f
* _float = list .get(Float.class , 1); // Equivalent
*
* // Same as above, except converted to a String
* list = JsonList.ofJson ("[1,2,3]" );
* String string = list .getString(1); // Returns "2"
* string = list .get(String.class , 1); // Equivalent
*
* // Get one of the entries in the list as a bean (converted to a bean if it isn't already one)
* list = JsonList.ofJson ("[{name:'John Smith',age:45}]" );
* Person person = list .get(Person.class , 0);
*
* // Iterate over a list of beans using the elements() method
* list = JsonList.ofJson ("[{name:'John Smith',age:45}]" );
* for (Person person : list .elements(Person.class ) {
* // Do something with p
* }
*
*
* Notes:
* This class is not thread safe.
*
*
* See Also:
*
* @serial exclude
*/
public class JsonList extends LinkedList {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
private static final long serialVersionUID = 1L;
/**
* Parses a string that can consist of either a JSON array or comma-delimited list.
*
*
* The type of string is auto-detected.
*
* @param s The string to parse.
* @return The parsed string.
* @throws ParseException Malformed input encountered.
*/
public static JsonList ofJsonOrCdl(String s) throws ParseException {
if (StringUtils.isEmpty(s))
return null;
if (! StringUtils.isJsonArray(s, true))
return new JsonList((Object[])StringUtils.split(s.trim(), ','));
return new JsonList(s);
}
//-----------------------------------------------------------------------------------------------------------------
// Instance
//-----------------------------------------------------------------------------------------------------------------
transient BeanSession session = null;
private transient ObjectRest objectRest;
/**
* An empty read-only JsonList.
*
* @serial exclude
*/
public static final JsonList EMPTY_LIST = new JsonList() {
private static final long serialVersionUID = 1L;
@Override /* List */
public void add(int location, Object object) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override /* List */
public ListIterator listIterator(final int location) {
return Collections.emptyList().listIterator(location);
}
@Override /* List */
public Object remove(int location) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override /* List */
public Object set(int location, Object object) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override /* List */
public List subList(int start, int end) {
return Collections.emptyList().subList(start, end);
}
};
//------------------------------------------------------------------------------------------------------------------
// Constructors
//------------------------------------------------------------------------------------------------------------------
/**
* Construct an empty list.
*/
public JsonList() {}
/**
* Construct an empty list with the specified bean context.
*
* @param session The bean session to use for creating beans.
*/
public JsonList(BeanSession session) {
this.session = session;
}
/**
* Construct a list initialized with the specified list.
*
* @param copyFrom
* The list to copy.
* Can be null .
*/
public JsonList(Collection> copyFrom) {
super(copyFrom);
}
/**
* Construct a list initialized with the specified JSON.
*
* @param json
* The JSON text to parse.
* Can be normal or simplified JSON.
* @throws ParseException Malformed input encountered.
*/
public JsonList(CharSequence json) throws ParseException {
this(json, JsonParser.DEFAULT);
}
/**
* Construct a list initialized with the specified string.
*
* @param in
* The input being parsed.
* Can be null .
* @param p
* The parser to use to parse the input.
* If null , uses {@link JsonParser}.
* @throws ParseException Malformed input encountered.
*/
public JsonList(CharSequence in, Parser p) throws ParseException {
this(p == null ? BeanContext.DEFAULT_SESSION : p.getBeanContext().getSession());
if (p == null)
p = JsonParser.DEFAULT;
if (in != null)
p.parseIntoCollection(in, this, bs().object());
}
/**
* Construct a list initialized with the specified reader containing JSON.
*
* @param json
* The reader containing JSON text to parse.
* Can contain normal or simplified JSON.
* @throws ParseException Malformed input encountered.
*/
public JsonList(Reader json) throws ParseException {
parse(json, JsonParser.DEFAULT);
}
/**
* Construct a list initialized with the specified string.
*
* @param in
* The reader containing the input being parsed.
* Can contain normal or simplified JSON.
* @param p
* The parser to use to parse the input.
* If null , uses {@link JsonParser}.
* @throws ParseException Malformed input encountered.
*/
public JsonList(Reader in, Parser p) throws ParseException {
this(p == null ? BeanContext.DEFAULT_SESSION : p.getBeanContext().getSession());
parse(in, p);
}
/**
* Construct a list initialized with the contents.
*
* @param entries The entries to add to this list.
*/
public JsonList(Object... entries) {
Collections.addAll(this, entries);
}
//------------------------------------------------------------------------------------------------------------------
// Creators
//------------------------------------------------------------------------------------------------------------------
/**
* Construct an empty list.
*
* @return An empty list.
*/
public static JsonList create() {
return new JsonList();
}
/**
* Construct a list initialized with the specified list.
*
* @param values
* The list to copy.
* Can be null .
* @return A new list or null if the list was null .
*/
public static JsonList of(Collection> values) {
return values == null ? null : new JsonList(values);
}
/**
* Convenience method for creating a list of collection objects.
*
* @param values The initial values.
* @return A new list.
*/
public static JsonList ofCollections(Collection>...values) {
JsonList l = new JsonList();
for (Collection> v : values)
l.add(v);
return l;
}
/**
* Convenience method for creating a list of array objects.
*
* @param values The initial values.
* @return A new list.
*/
public static JsonList ofArrays(Object[]...values) {
JsonList l = new JsonList();
for (Object[] v : values)
l.add(v);
return l;
}
/**
* Construct a list initialized with the specified JSON string.
*
* @param json
* The JSON text to parse.
* Can be normal or simplified JSON.
* @return A new list or null if the string was null.
* @throws ParseException Malformed input encountered.
*/
public static JsonList ofJson(CharSequence json) throws ParseException {
return json == null ? null : new JsonList(json);
}
/**
* Construct a list initialized with the specified string.
*
* @param in
* The input being parsed.
* Can be null .
* @param p
* The parser to use to parse the input.
* If null , uses {@link JsonParser}.
* @return A new list or null if the input was null .
* @throws ParseException Malformed input encountered.
*/
public static JsonList ofText(CharSequence in, Parser p) throws ParseException {
return in == null ? null : new JsonList(in, p);
}
/**
* Construct a list initialized with the specified reader containing JSON.
*
* @param json
* The reader containing JSON text to parse.
* Can contain normal or simplified JSON.
* @return A new list or null if the input was null .
* @throws ParseException Malformed input encountered.
*/
public static JsonList ofJson(Reader json) throws ParseException {
return json == null ? null : new JsonList(json);
}
/**
* Construct a list initialized with the specified string.
*
* @param in
* The reader containing the input being parsed.
* Can contain normal or simplified JSON.
* @param p
* The parser to use to parse the input.
* If null , uses {@link JsonParser}.
* @return A new list or null if the input was null .
* @throws ParseException Malformed input encountered.
*/
public static JsonList ofText(Reader in, Parser p) throws ParseException {
return in == null ? null : new JsonList(in);
}
/**
* Construct a list initialized with the specified values.
*
* @param values The values to add to this list.
* @return A new list, never null .
*/
public static JsonList of(Object... values) {
return new JsonList(values);
}
//------------------------------------------------------------------------------------------------------------------
// Initializers
//------------------------------------------------------------------------------------------------------------------
/**
* Override the default bean session used for converting POJOs.
*
*
* Default is {@link BeanContext#DEFAULT}, which is sufficient in most cases.
*
*
* Useful if you're serializing/parsing beans with transforms defined.
*
* @param session The new bean session.
* @return This object.
*/
public JsonList session(BeanSession session) {
this.session = session;
return this;
}
//------------------------------------------------------------------------------------------------------------------
// Appenders
//------------------------------------------------------------------------------------------------------------------
/**
* Adds the value to this list.
*
* @param value The value to add to this list.
* @return This object.
*/
public JsonList append(Object value) {
add(value);
return this;
}
/**
* Adds all the values in the specified array to this list.
*
* @param values The values to add to this list.
* @return This object.
*/
public JsonList append(Object...values) {
Collections.addAll(this, values);
return this;
}
/**
* Adds all the values in the specified collection to this list.
*
* @param values The values to add to this list.
* @return This object.
*/
public JsonList append(Collection> values) {
if (values != null)
addAll(values);
return this;
}
/**
* Adds an entry to this list if the boolean flag is true .
*
* @param flag The boolean flag.
* @param value The value to add.
* @return This object.
*/
public JsonList appendIf(boolean flag, Object value) {
if (flag)
append(value);
return this;
}
/**
* Adds all the entries in the specified collection to this list in reverse order.
*
* @param values The collection to add to this list.
* @return This object.
*/
public JsonList appendReverse(List> values) {
for (ListIterator> i = values.listIterator(values.size()); i.hasPrevious();)
add(i.previous());
return this;
}
/**
* Adds the contents of the array to the list in reverse order.
*
*
* i.e. add values from the array from end-to-start order to the end of the list.
*
* @param values The collection to add to this list.
* @return This object.
*/
public JsonList appendReverse(Object...values) {
for (int i = values.length - 1; i >= 0; i--)
add(values[i]);
return this;
}
/**
* Add if predicate matches.
*
* @param The type being tested.
* @param test The predicate to match against.
* @param value The value to add if the predicate matches.
* @return This object.
*/
public JsonList appendIf(Predicate test, T value) {
return appendIf(test(test, value), value);
}
//------------------------------------------------------------------------------------------------------------------
// Retrievers
//------------------------------------------------------------------------------------------------------------------
/**
* Get the entry at the specified index, converted to the specified type.
*
*
* This is the preferred get method for simple types.
*
*
Examples:
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Value converted to a string.
* String string = list .get(1, String.class );
*
* // Value converted to a bean.
* MyBean bean = list .get(2, MyBean.class );
*
* // Value converted to a bean array.
* MyBean[] beanArray = list .get(3, MyBean[].class );
*
* // Value converted to a linked-list of objects.
* List list2 = list .get(4, LinkedList.class );
*
* // Value converted to a map of object keys/values.
* Map map = list .get(5, TreeMap.class );
*
*
*
* See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
*
* @param index The index into this list.
* @param type The type of object to convert the entry to.
* @param The type of object to convert the entry to.
* @return The converted entry.
*/
public T get(int index, Class type) {
return bs().convertToType(get(index), type);
}
/**
* Get the entry at the specified index, converted to the specified type.
*
*
* The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
*
*
Examples:
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Value converted to a linked-list of strings.
* List<String> list1 = list .get(1, LinkedList.class , String.class );
*
* // Value converted to a linked-list of beans.
* List<MyBean> list2 = list .get(2, LinkedList.class , MyBean.class );
*
* // Value converted to a linked-list of linked-lists of strings.
* List<List<String>> list3 = list .get(3, LinkedList.class , LinkedList.class , String.class );
*
* // Value converted to a map of string keys/values.
* Map<String,String> map1 = list .get(4, TreeMap.class , String.class , String.class );
*
* // Value converted to a map containing string keys and values of lists containing beans.
* Map<String,List<MyBean>> map2 = list .get(5, TreeMap.class , String.class , List.class , MyBean.class );
*
*
*
* Collection classes are assumed to be followed by zero or one objects indicating the element type.
*
*
* Map classes are assumed to be followed by zero or two meta objects indicating the key and value types.
*
*
* The array can be arbitrarily long to indicate arbitrarily complex data structures.
*
*
* See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
*
* @param index The index into this list.
* @param type The type of object to convert the entry to.
* @param args The type arguments of the type to convert the entry to.
* @param The type of object to convert the entry to.
* @return The converted entry.
*/
public T get(int index, Type type, Type...args) {
return bs().convertToType(get(index), type, args);
}
/**
* Shortcut for calling get(index, String.class )
.
*
* @param index The index.
* @return The converted value.
*/
public String getString(int index) {
return get(index, String.class);
}
/**
* Shortcut for calling get(index, Integer.class )
.
*
* @param index The index.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public Integer getInt(int index) {
return get(index, Integer.class);
}
/**
* Shortcut for calling get(index, Boolean.class )
.
*
* @param index The index.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public Boolean getBoolean(int index) {
return get(index, Boolean.class);
}
/**
* Shortcut for calling get(index, Long.class )
.
*
* @param index The index.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public Long getLong(int index) {
return get(index, Long.class);
}
/**
* Shortcut for calling get(index, JsonMap.class )
.
*
* @param index The index.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public JsonMap getMap(int index) {
return get(index, JsonMap.class);
}
/**
* Same as {@link #getMap(int)} except converts the keys and values to the specified types.
*
* @param The key type class.
* @param The value type class.
* @param index The index.
* @param keyType The key type class.
* @param valType The value type class.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public Map getMap(int index, Class keyType, Class valType) {
return bs().convertToType(get(index), Map.class, keyType, valType);
}
/**
* Shortcut for calling get(index, JsonList.class )
.
*
* @param index The index.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public JsonList getList(int index) {
return get(index, JsonList.class);
}
/**
* Same as {@link #getList(int)} except converts the elements to the specified types.
*
* @param The element type.
* @param index The index.
* @param elementType The element type class.
* @return The converted value.
* @throws InvalidDataConversionException If value cannot be converted.
*/
public List getList(int index, Class elementType) {
return bs().convertToType(get(index), List.class, elementType);
}
//------------------------------------------------------------------------------------------------------------------
// POJO REST methods.
//------------------------------------------------------------------------------------------------------------------
/**
* Same as {@link #get(int,Class) get(int,Class)}, but the key is a slash-delimited path used to traverse entries in
* this POJO.
*
*
* For example, the following code is equivalent:
*
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Long way
* long long1 = list .getMap("0" ).getLong("baz" );
*
* // Using this method
* long long2 = list .getAt("0/baz" , long .class );
*
*
*
* This method uses the {@link ObjectRest} class to perform the lookup, so the map can contain any of the various
* class types that the {@link ObjectRest} class supports (e.g. beans, collections, arrays).
*
* @param path The path to the entry.
* @param type The class type.
*
* @param The class type.
* @return The value, or null if the entry doesn't exist.
*/
public T getAt(String path, Class type) {
return getObjectRest().get(path, type);
}
/**
* Same as {@link #getAt(String,Class)}, but allows for conversion to complex maps and collections.
*
* @param path The path to the entry.
* @param type The class type.
* @param args The class parameter types.
*
* @param The class type.
* @return The value, or null if the entry doesn't exist.
*/
public T getAt(String path, Type type, Type...args) {
return getObjectRest().get(path, type, args);
}
/**
* Same as {@link #set(int,Object) set(int,Object)}, but the key is a slash-delimited path used to traverse entries
* in this POJO.
*
*
* For example, the following code is equivalent:
*
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Long way
* list .getMap("0" ).put("baz" , 123);
*
* // Using this method
* list .putAt("0/baz" , 123);
*
*
*
* This method uses the {@link ObjectRest} class to perform the lookup, so the map can contain any of the various
* class types that the {@link ObjectRest} class supports (e.g. beans, collections, arrays).
*
* @param path The path to the entry.
* @param o The new value.
* @return The previous value, or null if the entry doesn't exist.
*/
public Object putAt(String path, Object o) {
return getObjectRest().put(path, o);
}
/**
* Similar to {@link #putAt(String,Object) putAt(String,Object)}, but used to append to collections and arrays.
*
*
* For example, the following code is equivalent:
*
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Long way
* list .getMap(0).getList("bar" ).append(123);
*
* // Using this method
* list .postAt("0/bar" , 123);
*
*
*
* This method uses the {@link ObjectRest} class to perform the lookup, so the map can contain any of the various
* class types that the {@link ObjectRest} class supports (e.g. beans, collections, arrays).
*
* @param path The path to the entry.
* @param o The new value.
* @return The previous value, or null if the entry doesn't exist.
*/
public Object postAt(String path, Object o) {
return getObjectRest().post(path, o);
}
/**
* Similar to {@link #remove(int) remove(int)},but the key is a slash-delimited path used to traverse entries in
* this POJO.
*
*
* For example, the following code is equivalent:
*
*
* JsonList list = JsonList.ofJson ("..." );
*
* // Long way
* list .getMap(0).getList("bar" ).delete(0);
*
* // Using this method
* list .deleteAt("0/bar/0" );
*
*
*
* This method uses the {@link ObjectRest} class to perform the lookup, so the map can contain any of the various
* class types that the {@link ObjectRest} class supports (e.g. beans, collections, arrays).
*
* @param path The path to the entry.
* @return The previous value, or null if the entry doesn't exist.
*/
public Object deleteAt(String path) {
return getObjectRest().delete(path);
}
//------------------------------------------------------------------------------------------------------------------
// Other methods
//------------------------------------------------------------------------------------------------------------------
/**
* Returns the {@link BeanSession} currently associated with this list.
*
* @return The {@link BeanSession} currently associated with this list.
*/
public BeanSession getBeanSession() {
return session;
}
/**
* Sets the {@link BeanSession} currently associated with this list.
*
* @param value The {@link BeanSession} currently associated with this list.
* @return This object.
*/
public JsonList setBeanSession(BeanSession value) {
this.session = value;
return this;
}
/**
* Creates an {@link Iterable} with elements of the specified child type.
*
*
* Attempts to convert the child objects to the correct type if they aren't already the correct type.
*
*
* The next() method on the returned iterator may throw a {@link InvalidDataConversionException} if
* the next element cannot be converted to the specified type.
*
*
* See {@link BeanSession#convertToType(Object, ClassMeta)} for a description of valid conversions.
*
*
Example:
*
* // Iterate over a list of JsonMaps.
* JsonList list = JsonList.ofJson ("[{foo:'bar'},{baz:123}]" );
* for (JsonMap map : list .elements(JsonMap.class )) {
* // Do something with map.
* }
*
* // Iterate over a list of ints.
* JsonList list = JsonList.ofJson ("[1,2,3]" );
* for (Integer i : list .elements(Integer.class )) {
* // Do something with i.
* }
*
* // Iterate over a list of beans.
* // Automatically converts to beans.
* JsonList list = JsonList.ofJson ("[{name:'John Smith',age:45}]" );
* for (Person p : list .elements(Person.class )) {
* // Do something with p.
* }
*
*
* @param The child object type.
* @param childType The child object type.
* @return A new Iterable object over this list.
*/
public Iterable elements(final Class childType) {
final Iterator> iterator = iterator();
return () -> new Iterator<>() {
@Override /* Iterator */
public boolean hasNext() {
return iterator.hasNext();
}
@Override /* Iterator */
public E next() {
return bs().convertToType(iterator.next(), childType);
}
@Override /* Iterator */
public void remove() {
iterator.remove();
}
};
}
/**
* Returns the {@link ClassMeta} of the class of the object at the specified index.
*
* @param index An index into this list, zero-based.
* @return The data type of the object at the specified index, or null if the value is null.
*/
public ClassMeta> getClassMeta(int index) {
return bs().getClassMetaForObject(get(index));
}
/**
* Serialize this array to a string using the specified serializer.
*
* @param serializer The serializer to use to convert this object to a string.
* @return This object as a serialized string.
*/
public String asString(WriterSerializer serializer) {
return serializer.toString(this);
}
/**
* Serialize this array to Simplified JSON.
*
* @return This object as a serialized string.
*/
public String asString() {
return Json5Serializer.DEFAULT.toString(this);
}
/**
* Returns true if this list is unmodifiable.
*
* @return true if this list is unmodifiable.
*/
public boolean isUnmodifiable() {
return false;
}
/**
* Returns a modifiable copy of this list if it's unmodifiable.
*
* @return A modifiable copy of this list if it's unmodifiable, or this list if it is already modifiable.
*/
public JsonList modifiable() {
if (isUnmodifiable())
return new JsonList(this);
return this;
}
/**
* Returns an unmodifiable copy of this list if it's modifiable.
*
* @return An unmodifiable copy of this list if it's modifiable, or this list if it is already unmodifiable.
*/
public JsonList unmodifiable() {
if (this instanceof UnmodifiableJsonList)
return this;
return new UnmodifiableJsonList(this);
}
/**
* Convenience method for serializing this JsonList to the specified Writer using the JsonSerializer.DEFAULT
* serializer.
*
* @param w The writer to send the serialized contents of this object.
* @return This object.
* @throws IOException If a problem occurred trying to write to the writer.
* @throws SerializeException If a problem occurred trying to convert the output.
*/
public JsonList writeTo(Writer w) throws IOException, SerializeException {
JsonSerializer.DEFAULT.serialize(this, w);
return this;
}
/**
* Converts this object into the specified class type.
*
*
* TODO - The current implementation is very inefficient.
*
* @param cm The class type to convert this object to.
* @return A converted object.
*/
public Object cast(ClassMeta> cm) {
try {
return JsonParser.DEFAULT.parse(Json5Serializer.DEFAULT.serialize(this), cm);
} catch (ParseException | SerializeException e) {
throw asRuntimeException(e);
}
}
//------------------------------------------------------------------------------------------------------------------
// Utility methods
//------------------------------------------------------------------------------------------------------------------
private void parse(Reader r, Parser p) throws ParseException {
if (p == null)
p = JsonParser.DEFAULT;
p.parseIntoCollection(r, this, bs().object());
}
private ObjectRest getObjectRest() {
if (objectRest == null)
objectRest = new ObjectRest(this);
return objectRest;
}
BeanSession bs() {
if (session == null)
session = BeanContext.DEFAULT_SESSION;
return session;
}
private static final class UnmodifiableJsonList extends JsonList {
private static final long serialVersionUID = 1L;
UnmodifiableJsonList(JsonList contents) {
if (contents != null)
this.forEach(super::add);
}
@Override /* List */
public void add(int location, Object object) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override /* List */
public Object remove(int location) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override /* List */
public Object set(int location, Object object) {
throw new UnsupportedOperationException("Not supported on read-only object.");
}
@Override
public boolean isUnmodifiable() {
return true;
}
}
//------------------------------------------------------------------------------------------------------------------
// Overridden methods.
//------------------------------------------------------------------------------------------------------------------
/**
* A synonym for {@link #toString()}
*
* @return This object as a JSON string.
*/
public String asJson() {
return toString();
}
@Override /* Object */
public String toString() {
return Json5.of(this);
}
}