package com.smtscript.utils;
/*
* Copyright (C) 2011 Miami-Dade County.
*
* Licensed 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.
*
* Note: this file incorporates source code from 3d party entities. Such code
* is copyrighted by those entities as indicated below.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*
* Represents a JSON (JavaScript Object Notation) entity. For more information about JSON, please see
* http://www.json.org.
*
*
*
* A JSON entity can be one of several things: an object (set of name/Json entity pairs), an array (a list of
* other JSON entities), a string, a number, a boolean or null. All of those are represented as Json
* instances. Each of the different types of entities supports a different set of operations. However, this class
* unifies all operations into a single interface so in Java one is always dealing with a single object type: this class.
* The approach effectively amounts to dynamic typing where using an unsupported operation won't be detected at
* compile time, but will throw a runtime {@link UnsupportedOperationException}. It simplifies working with JSON
* structures considerably and it leads to shorter at cleaner Java code. It makes much easier to work
* with JSON structure without the need to convert to "proper" Java representation in the form of
* POJOs and the like. When traversing a JSON, there's no need to type-cast at each step because there's
* only one type: Json.
*
*
*
* One can examine the concrete type of a Json with one of the isXXX methods:
* {@link #isObject()}, {@link #isArray()},{@link #isNumber()},{@link #isBoolean()},{@link #isString()},
* {@link #isNull()}.
*
*
*
* The underlying representation of a given Json instance can be obtained by calling
* the generic {@link #getValue()} method or one of the asXXX methods such
* as {@link #asBoolean()} or {@link #asString()} etc.
* JSON objects are represented as Java {@link Map}s while JSON arrays are represented as Java
* {@link List}s. Because those are mutable aggregate structures, there are two versions of the
* corresponding asXXX methods: {@link #asMap()} which performs a deep copy of the underlying
* map, unwrapping every nested Json entity to its Java representation and {@link #asJsonMap()} which
* simply return the map reference. Similarly there are {@link #asList()} and {@link #asJsonList()}.
*
*
*
Constructing and Modifying JSON Structures
*
*
* There are several static factory methods in this class that allow you to create new
* Json instances:
*
*
*
*
{@link #read(String)}
*
Parse a JSON string and return the resulting Json instance. The syntax
* recognized is as defined in http://www.json.org.
*
*
*
{@link #make(Object)}
*
Creates a Json instance based on the concrete type of the parameter. The types
* recognized are null, numbers, primitives, String, Map, Collection, Java arrays
* and Json itself.
*
*
{@link #nil()}
*
Return a Json instance representing JSON null.
*
*
{@link #object()}
*
Create and return an empty JSON object.
*
*
{@link #object(Object...)}
*
Create and return a JSON object populated with the key/value pairs
* passed as an argument sequence. Each even parameter becomes a key (via
* toString) and each odd parameter is converted to a Json
* value.
*
*
{@link #array()}
*
Create and return an empty JSON array.
*
*
{@link #array(Object...)}
*
Create and return a JSON array from the list of arguments.
*
*
*
*
* To customize how Json elements are represented and to provide your own version of the
* {@link #make(Object)} method, you create an implementation of the {@link Factory} interface
* and configure it either globally with the {@link #setGlobalFactory(Factory)} method or
* on a per-thread basis with the {@link #attachFactory(Factory)}/{@link #dettachFactory()}
* methods.
*
*
*
* If a Json instance is an object, you can set its properties by
* calling the {@link #set(String, Object)} method which will add a new property or replace an existing one.
* Adding elements to an array Json is done with the {@link #add(Object)} method.
* Removing elements by their index (or key) is done with the {@link #delAt(int)} (or
* {@link #delAt(String)}) method. You can also remove an element from an array without
* knowing its index with the {@link #remove(Object)} method. All these methods return the
* Json instance being manipulated so that method calls can be chained.
* If you want to remove an element from an object or array and return the removed element
* as a result of the operation, call {@link #atDel(int)} or {@link #atDel(String)} instead.
*
*
*
* If you want to add properties to an object in bulk or append a sequence of elements to array,
* use the {@link #with(Json)} method. When used on an object, this method expects another
* object as its argument and it will copy all properties of that argument into itself. Similarly,
* when called on array, the method expects another array and it will append all elements of its
* argument to itself.
*
*
*
* To make a clone of a Json object, use the {@link #dup()} method. This method will create a new
* object even for the immutable primitive Json types. Objects and arrays are cloned
* (i.e. duplicated) recursively.
*
*
*
Navigating JSON Structures
*
*
* The {@link #at(int)} method returns the array element at the specified index and the
* {@link #at(String)} method does the same for a property of an object instance. You can
* use the {@link #at(String, Object)} version to create an object property with a default
* value if it doesn't exist already.
*
*
*
* To test just whether a Json object has a given property, use the {@link #has(String)} method. To test
* whether a given object property or an array elements is equal to a particular value, use the
* {@link #is(String, Object)} and {@link #is(int, Object)} methods respectively. Those methods return
* true if the given named property (or indexed element) is equal to the passed in Object as the second
* parameter. They return false if an object doesn't have the specified property or an index array is out
* of bounds. For example is(name, value) is equivalent to 'has(name) && at(name).equals(make(value))'.
*
*
*
* To help in navigating JSON structures, instances of this class contain a reference to the
* enclosing JSON entity (object or array) if any. The enclosing entity can be accessed
* with {@link #up()} method.
*
*
*
* The combination of method chaining when modifying Json instances and
* the ability to navigate "inside" a structure and then go back to the enclosing
* element lets one accomplish a lot in a single Java statement, without the need
* of intermediary variables. Here for example how the following JSON structure can
* be created in one statement using chained calls:
*
* If there's no danger of naming conflicts, a static import of the factory methods (
* import static json.Json.*;) would reduce typing even further and make the code more
* readable.
*
*
*
Converting to String
*
*
* To get a compact string representation, simply use the {@link #toString()} method. If you
* want to wrap it in a JavaScript callback (for JSON with padding), use the {@link #pad(String)}
* method.
*
*
* @author Borislav Iordanov
* @version 1.3
*/
public class Json
{
public static String _jsonPathSplit = "|";
/**
*
* This interface defines how Json instances are constructed. There is a
* default implementation for each kind of Json value, but you can provide
* your own implementation. For example, you might want a different representation of
* an object than a regular HashMap. Or you might want string comparison to be
* case insensitive.
*
*
*
* In addition, the {@link #make(Object)} method allows you plug-in your own mapping
* of arbitrary Java objects to Json instances. You might want to implement
* a Java Beans to JSON mapping or any other JSON serialization that makes sense in your
* project.
*
*
*
* To avoid implementing all methods in that interface, you can extend the {@link DefaultFactory}
* default implementation and simply overwrite the ones you're interested in.
*
*
*
* The factory implementation used by the Json classes is specified simply by calling
* the {@link #setGlobalFactory(Factory)} method. The factory is a static, global variable by default.
* If you need different factories in different areas of a single application, you may attach them
* to different threads of execution using the {@link #attachFactory(Factory)}. Recall a separate
* copy of static variables is made per ClassLoader, so for example in a web application context, that
* global factory can be different for each web application (as Java web servers usually use a separate
* class loader per application). Thread-local factories are really a provision for special cases.
*
*
* @author Borislav Iordanov
*
*/
public static interface Factory
{
Json nil();
Json bool(boolean value);
Json string(String value);
Json number(Number value);
Json object();
Json array();
Json make(Object anything);
}
public static class DefaultFactory implements Factory
{
public Json nil() { return Json.topnull; }
public Json bool(boolean x) { return new BooleanJson(x ? Boolean.TRUE : Boolean.FALSE, null); }
public Json string(String x) { return new StringJson(x, null); }
public Json number(Number x) { return new NumberJson(x, null); }
public Json array() { return new ArrayJson(); }
public Json object() { return new ObjectJson(); }
public Json make(Object anything)
{
if (anything == null)
return topnull;
else if (anything instanceof Json)
return (Json)anything;
else if (anything instanceof String)
return factory().string((String)anything);
else if (anything instanceof Collection>)
{
Json L = array();
for (Object x : (Collection>)anything)
L.add(factory().make(x));
return L;
}
else if (anything instanceof Map,?>)
{
Json O = object();
for (Map.Entry,?> x : ((Map,?>)anything).entrySet())
O.set(x.getKey().toString(), factory().make(x.getValue()));
return O;
}
else if (anything instanceof Boolean)
return factory().bool((Boolean)anything);
else if (anything instanceof Number)
return factory().number((Number)anything);
else if (anything.getClass().isArray())
{
Class> comp = anything.getClass().getComponentType();
if (!comp.isPrimitive())
return Json.array((Object[])anything);
Json A = array();
if (boolean.class == comp)
for (boolean b : (boolean[])anything) A.add(b);
else if (byte.class == comp)
for (byte b : (byte[])anything) A.add(b);
else if (char.class == comp)
for (char b : (char[])anything) A.add(b);
else if (short.class == comp)
for (short b : (short[])anything) A.add(b);
else if (int.class == comp)
for (int b : (int[])anything) A.add(b);
else if (long.class == comp)
for (long b : (long[])anything) A.add(b);
else if (float.class == comp)
for (float b : (float[])anything) A.add(b);
else if (double.class == comp)
for (double b : (double[])anything) A.add(b);
return A;
}
else
throw new IllegalArgumentException("Don't know how to convert to Json : " + anything);
}
}
public static final Factory defaultFactory = new DefaultFactory();
private static Factory globalFactory = defaultFactory;
// TODO1: maybe use initialValue thread-local method to attach global factory by default here...
private static ThreadLocal threadFactory = new ThreadLocal();
public static Factory factory()
{
Factory f = threadFactory.get();
return f != null ? f : globalFactory;
}
/**
*
* Specify a global Json {@link Factory} to be used by all threads that don't have a
* specific thread-local factory attached to them.
*
* Attach a thread-local Json {@link Factory} to be used specifically by this thread. Thread-local
* Json factories are the only means to have different {@link Factory} implementations used simultaneously
* in the same application (well, more accurately, the same ClassLoader).
*
* Clear the thread-local factory previously attached to this thread via the
* {@link #attachFactory(Factory)} method. The global factory takes effect after
* a call to this method.
*
*/
public static void dettachFactory() { threadFactory.remove(); }
/**
*
* Parse a JSON entity from its string representation.
*
*
* @param jsonAsString A valid JSON representation as per the json.org
* grammar. Cannot be null.
* @return The JSON entity parsed: an object, array, string, number or boolean, or null. Note that
* this method will never return the actual Java null.
* @
*/
public static Json read(String jsonAsString, IJsonParseExt propReader) throws RuntimeException {
Reader rd = new Reader();
return (Json)rd.read(jsonAsString, propReader);
}
public static Json read(InputStream stream) throws RuntimeException {
Reader rd = new Reader();
return (Json)rd.read(readJsonStream(stream), null);
}
public static Json read(String jsonAsString)
{
return read(jsonAsString, false);
}
public static Json read(String jsonAsString, boolean convert) throws RuntimeException {
Reader rd = new Reader();
return (Json)rd.read(convert ? convToJsonString(jsonAsString) : jsonAsString, null);
}
public static Json read(File file)
{
return read(file, null, null);
}
public static Json read(File file, IJsonParseExt propReader, String[] defineMap)
{
Reader rd = new Reader();
if(defineMap != null && defineMap.length > 0)
rd.importDefineMap(defineMap);
return (Json)rd.read(file, propReader);
}
private static String readTextStream(InputStream inputStream)
{
InputStreamReader rd = null;
try
{
StringBuilder sb = new StringBuilder();
int size = 0;
char[] data = new char[10240];
rd=new InputStreamReader(inputStream, "UTF-8");
while((size = rd.read(data)) > 0)
{
sb.append(data, 0, size);
}
return sb.toString();
}
catch(Exception ex)
{
throw new RuntimeException(ex);
}
finally
{
if(rd != null)
try {
rd.close();
} catch (IOException e) {
}
}
}
public static String readJsonFile(File file)
{
try
{
FileInputStream fi = new FileInputStream(file);
try
{
return convToJsonString(readTextStream(fi));
}
finally
{
fi.close();
}
}
catch(Exception ex)
{
throw new RuntimeException(String.format("read json file [%s] error", file.getAbsolutePath()), ex);
}
}
public static String readTextFile(File file)
{
try
{
FileInputStream fi = new FileInputStream(file);
try
{
return readTextStream(fi).replace("\r", "");
}
finally
{
fi.close();
}
}
catch(Exception ex)
{
throw new RuntimeException(String.format("read json file [%s] error", file.getAbsolutePath()), ex);
}
}
public static String readJsonStream(InputStream inputStream)
{
return convToJsonString(readTextStream(inputStream));
}
public static String splitJsonMapString(String jsonStr)
{
for(int pos = 0; pos < jsonStr.length(); pos ++)
{
if(jsonStr.charAt(pos) == '{')
{
jsonStr = jsonStr.substring(pos + 1);
break;
}
}
for(int pos = jsonStr.length() - 1; pos >= 0; pos --)
{
if(jsonStr.charAt(pos) == '}')
{
jsonStr = jsonStr.substring(0, pos);
break;
}
}
return jsonStr;
}
private static String convToJsonString(String jsonStr)
{
while(jsonStr.length() > 0 && jsonStr.charAt(0) >= 128)
jsonStr = jsonStr.substring(1);
for(int i = 0; i < jsonStr.length(); i ++)
{
char ch = jsonStr.charAt(i);
if(ch == '[' || ch == '{' || ch =='\r' || ch == '\n')
{
jsonStr = jsonStr.substring(i);
break;
}
if(ch == '=')
{
jsonStr = jsonStr.substring(i + 1);
break;
}
}
return jsonStr.replace("\r", "");
}
/**
*
* Parse a JSON entity from a {@link CharacterIterator}.
*
Return a new JSON object initialized from the passed list of
* name/value pairs. The number of arguments must
* be even. Each argument at an even position is taken to be a name
* for the following value. The name arguments are normally of type
* Java String, but they can be of any other type having an appropriate
* toString method. Each value is first converted
* to a Json instance using the {@link #make(Object)} method.
*
* @param args A sequence of name value pairs.
*/
public static Json object(Object...args)
{
Json j = object();
if (args.length % 2 != 0)
throw new IllegalArgumentException("An even number of arguments is expected.");
for (int i = 0; i < args.length; i++)
j.set(args[i].toString(), factory().make(args[++i]));
return j;
}
/**
*
Return a new JSON array filled up with the list of arguments.
*
* @param args The initial content of the array.
*/
public static Json array(Object...args)
{
Json A = array();
for (Object x : args)
A.add(factory().make(x));
return A;
}
/**
*
* Convert an arbitrary Java instance to a {@link Json} instance.
*
*
*
* Maps, Collections and arrays are recursively copied where each of
* their elements concerted into Json instances as well. The keys
* of a {@link Map} parameter are normally strings, but anything with a meaningful
* toString implementation will work as well.
*
*
* @param anything
* @return The Json. This method will never return null. It will
* throw an {@link IllegalArgumentException} if it doesn't know how to convert the argument
* to a Json instance.
* @throws IllegalArgumentException when the concrete type of the parameter is
* unknown.
*/
public static Json make(Object anything)
{
return factory().make(anything);
}
// end of static utility method section
Json enclosing = null;
protected Json() { }
protected Json(Json enclosing) { this.enclosing = enclosing; }
protected Json getLinkOneTail(Json jsonRoot)
{
return this;
}
public Map safeGetJsonMap(String key)
{
if(!this.has(key))
return null;
return at(key).asJsonMap();
}
public List safeGetJsonList(String key)
{
if(!this.has(key))
return null;
return at(key).asJsonList();
}
public Json safeGetJson(String key)
{
return at(key);
}
public Json getJsonPath(String path, boolean skipNFind) throws RuntimeException
{
try
{
Json jsonRoot = this;
String[] spPath = path.split(_jsonPathSplit.replace("\\", "\\\\").replace("|", "\\|"));
for(int i = 0; i < spPath.length; i ++)
{
String subPath = spPath[i];
if(subPath.length() == 0)
continue;
if(subPath.charAt(0) == '#')
{
int index = Integer.parseInt(subPath.substring(1));
if(skipNFind && index >= jsonRoot.asJsonList().size())
return null;
jsonRoot = jsonRoot.at(index);
}
else
{
if(skipNFind && !jsonRoot.has(spPath[i]))
return null;
jsonRoot = jsonRoot.getJson(spPath[i]);
}
}
return jsonRoot;
}
catch(Exception ex)
{
throw new RuntimeException(String.format("get json path [%s] error:[%s]", path, this.toString()), ex);
}
}
public Json getJsonDefault(String key) throws RuntimeException
{
if(this.has(key))
return this.at(key);
return this.getJson("*default*");
}
public Json getJson(String key)
{
Json jsonRet = at(key);
if(jsonRet == null)
throw new RuntimeException(String.format("can't find json key [%s] for [%s]", key, this.toString()));
return jsonRet;
}
public String safeGetStr(String key, String defValue)
{
if(!this.has(key))
return defValue;
return at(key).asString();
}
public int safeGetInt(String key, int defValue)
{
if(!this.has(key))
return defValue;
return at(key).asInteger();
}
public boolean safeGetBoolean(String key, boolean defValue)
{
if(!this.has(key))
return defValue;
return at(key).asBoolean();
}
/**
*
Explicitly set the parent of this element. The parent is presumably an array
* or an object. Normally, there's no need to call this method as the parent is
* automatically set by the framework. You may need to call it however, if you implement
* your own {@link Factory} with your own implementations of the Json types.
*
*
* @param enclosing The parent element.
*/
public void attachTo(Json enclosing) { this.enclosing = enclosing; }
/**
*
Return the Json entity, if any, enclosing this
* Json. The returned value can be null or
* a Json object or list, but not one of the primitive types.
*/
public final Json up() { return enclosing; }
/**
*
Return a clone (a duplicate) of this Json entity. Note that cloning
* is deep if array and objects. Primitives are also cloned, even though their values are immutable
* because the new enclosing entity (the result of the {@link #up()} method) may be different.
* since they are immutable.
*/
public Json dup() { return this; }
/**
*
Return the Json element at the specified index of this
* Json array. This method applies only to Json arrays.
*
*
* @param index The index of the desired element.
*/
public Json at(int index) { throw new UnsupportedOperationException(); }
/**
*
* Return the specified property of a Json object or null
* if there's no such property. This method applies only to Json objects.
*
*/
public Json at(String property) { throw new UnsupportedOperationException(); }
/**
*
* Return the specified property of a Json object if it exists.
* If it doesn't, then create a new property with value the def
* parameter and return that parameter.
*
*
* @param property The property to return.
* @param def The default value to set and return in case the property doesn't exist.
*/
public final Json at(String property, Json def)
{
Json x = at(property);
if (x == null)
{
set(property, def);
return def;
}
else
return x;
}
/**
*
* Return the specified property of a Json object if it exists.
* If it doesn't, then create a new property with value the def
* parameter and return that parameter.
*
*
* @param property The property to return.
* @param def The default value to set and return in case the property doesn't exist.
*/
public final Json at(String property, Object def)
{
return at(property, make(def));
}
/**
*
* Return true if this Json object has the specified property
* and false otherwise.
*
*
* @param property The name of the property.
*/
public boolean has(String property) { throw new UnsupportedOperationException(); }
/**
*
* Return true if and only if this Json object has a property with
* the specified value. In particular, if the object has no such property false is returned.
*
*
* @param property The property name.
* @param value The value to compare with. Comparison is done via the equals method.
* If the value is not an instance of Json, it is first converted to
* such an instance.
* @return
*/
public boolean is(String property, Object value) { throw new UnsupportedOperationException(); }
/**
*
* Return true if and only if this Json array has an element with
* the specified value at the specified index. In particular, if the array has no element at
* this index, false is returned.
*
*
* @param property The property name.
* @param value The value to compare with. Comparison is done via the equals method.
* If the value is not an instance of Json, it is first converted to
* such an instance.
* @return
*/
public boolean is(int index, Object value) { throw new UnsupportedOperationException(); }
/**
*
* Add the specified Json element to this array.
*
*
* @return this
*/
public Json add(Json el) { throw new UnsupportedOperationException(); }
/**
*
* Add an arbitrary Java object to this Json array. The object
* is first converted to a Json instance by calling the static
* {@link #make} method.
*
*
* @param anything Any Java object that can be converted to a Json instance.
* @return this
*/
public final Json add(Object anything) { return add(make(anything)); }
/**
*
* Remove the specified property from a Json object and return
* that property.
*
*
* @param property The property to be removed.
* @return The property value or null if the object didn't have such
* a property to begin with.
*/
public Json atDel(String property) { throw new UnsupportedOperationException(); }
/**
*
* Remove the element at the specified index from a Json array and return
* that element.
*
*
* @param index The index of the element to delete.
* @return The element value.
*/
public Json atDel(int index) { throw new UnsupportedOperationException(); }
/**
*
* Delete the specified property from a Json object.
*
*
* @param property The property to be removed.
* @return this
*/
public Json delAt(String property) { throw new UnsupportedOperationException(); }
/**
*
* Remove the element at the specified index from a Json array.
*
*
* @param index The index of the element to delete.
* @return this
*/
public Json delAt(int index) { throw new UnsupportedOperationException(); }
/**
*
* Remove the specified element from a Json array.
*
*
* @param el The element to delete.
* @return this
*/
public Json remove(Json el) { throw new UnsupportedOperationException(); }
/**
*
* Remove the specified Java object (converted to a Json instance)
* from a Json array. This is equivalent to
* remove({@link #make(anything)}).
*
*
* @param anything The object to delete.
* @return this
*/
public final Json remove(Object anything) { return remove(make(anything)); }
/**
*
* Set a Json objects's property.
*
*
* @param property The property name.
* @param value The value of the property.
* @return this
*/
public Json set(String property, Json value) { throw new UnsupportedOperationException(); }
/**
*
* Set a Json objects's property.
*
*
* @param property The property name.
* @param value The value of the property, converted to a Json representation
* with {@link #make}.
* @return this
*/
public final Json set(String property, Object value) { return set(property, make(value)); }
/**
*
* Combine this object or array with the passed in object or array. The types of
* this and the object argument must match. If both are
* Json objects, all properties of the parameter are added to this.
* If both are arrays, all elements of the parameter are appended to this
*
* @param object The object or array whose properties or elements must be added to this
* Json object or array.
* @return this
*/
public Json with(Json object) { throw new UnsupportedOperationException(); }
/**
*
Return the underlying value of this Json entity. The actual value will
* be a Java Boolean, String, Number, Map, List or null. For complex entities (objects
* or arrays), the method will perform a deep copy and extra underlying values recursively
* for all nested elements.
*/
public Object getValue() { throw new UnsupportedOperationException(); }
/**
*
Return the boolean value of a boolean Json instance. Call
* {@link #isBoolean()} first if you're not sure this instance is indeed a
* boolean.
*/
public boolean asBoolean() { throw new UnsupportedOperationException(); }
/**
*
Return the string value of a string Json instance. Call
* {@link #isString()} first if you're not sure this instance is indeed a
* string.
*/
public String asString() { throw new UnsupportedOperationException(); }
/**
*
Return the integer value of a number Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public int asInteger() { throw new UnsupportedOperationException(); }
/**
*
Return the float value of a float Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public float asFloat() { throw new UnsupportedOperationException(); }
/**
*
Return the double value of a number Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public double asDouble() { throw new UnsupportedOperationException(); }
/**
*
Return the long value of a number Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public long asLong() { throw new UnsupportedOperationException(); }
/**
*
Return the short value of a number Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public short asShort() { throw new UnsupportedOperationException(); }
/**
*
Return the byte value of a number Json instance. Call
* {@link #isNumber()} first if you're not sure this instance is indeed a
* number.
*/
public byte asByte() { throw new UnsupportedOperationException(); }
/**
*
Return the first character of a string Json instance. Call
* {@link #isString()} first if you're not sure this instance is indeed a
* string.
*/
public char asChar() { throw new UnsupportedOperationException(); }
/**
*
Return a map of the properties of an object Json instance. The map
* is a clone of the object and can be modified safely without affecting it. Call
* {@link #isObject()} first if you're not sure this instance is indeed a
* Json object.
*/
public Map asMap() { throw new UnsupportedOperationException(); }
/**
*
Return the underlying map of properties of a Json object. The returned
* map is the actual object representation so any modifications to it are modifications
* of the Json object itself. Call
* {@link #isObject()} first if you're not sure this instance is indeed a
* Json object.
*
*/
public Map asJsonMap() { throw new UnsupportedOperationException(); }
/**
*
Return a list of the elements of a Json array. The list is a clone
* of the array and can be modified safely without affecting it. Call
* {@link #isArray()} first if you're not sure this instance is indeed a
* Json array.
*