Skip to content

miktim/JSON

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# Java 7+/Android JSON parser/generator, MIT (c) 2020-2022 miktim@mail.ru

Release notes:
  - Java SE 7+/Android compatible;
  - in accordance with RFC 8259: https://datatracker.ietf.org/doc/rfc8259/?include_text=1 ;
  - JavaScript JSON - like interface.

package org.miktim.json

Overview:

  Class JSON extends LinkedHashMap<String, Object>.

    - parser converts JSON text to Java objects:
      JSON object, String, Number (BigDecimal), Boolean, null, Object[] array of listed types;
    - JSON object members (name/value pairs) are stored in order of appearance/creation;
    - when the names within an object are not unique, parser stores the last value only;
    - JSON object setters accept any Java object, all Java primitives and primitive arrays;
    - AVOID RECURSION!;
    - in addition, the generator converts Java Collections to JSON arrays, Java Maps to JSON objects.
      The null key is converted to a "null" member name.
      Other Java objects are converted to string representation;
    - JSON text is generated as one line.
    
    Put, set, get notes:
    - put, set methods cast Java primitives to the corresponding objects.
      Java objects and arrays are stored "as is" (as reference). 
      For example: int -> Integer, int[] -> int[], String[] -> String[]
    - after JSON text parsing or normalization, they are stored as:
      BigDecimal, Object[] {BigDecimal,...}, Object[] {String,...};
    - getters eliminate these differences by casting types to JSON-declared.

    Constructors:
      JSON(Object... members) throws IndexOutOfBoundsException; // name,value pairs
      JSON(String jsonText) throws IOException, ParseException;
      JSON(Reader reader) throws IOException, ParseException;

    Public methods:
      static Object parse(String jsonText) throws IOException, ParseException;
      static Object parse(Reader reader) throws IOException, ParseException;
      static String generate(Object obj); // generate JSON text
      static void generate(Object obj, Writer writer) throws IOException;

      List<String> listNames(); // returns list of member names
      boolean exists(String memberName); // alias of the inherited containsKey()
      Object put(String memberName, Object value); // inherited
      JSON set(String memberName, Object value);   // create or replace member
      Object get(String memberName);    // inherited
      Object remove(String memberName); // inherited

      Object get(String memberName, int... indices); // returns value or array element
      JSON getJSON(String memberName, int... indices) throws ClassCastException;
      String getString(String memberName, int... indices) throws ClassCastException;
      Number getNumber(String memberName, int... indices) throws ClassCastException;
      Boolean getBoolean(String memberName, int... indices) throws ClassCastException;
      Object[] getArray(String memberName, int... indices) throws ClassCastException;

      <T> T cast(String memberName, T sample, int... indices); // cast value or array by sample
      <T> T cast(String memberName, Class <T> cls, int... indices); // cast value or array by Class

      JSON normalize() throws IOException, ParseException; // not required to generate JSON text

      String gen(String memberName, int... indices); // stringify value or array element
      String toString();  // overridden, stringify JSON object
 

  Class JSONAdapter;

    Casting by sample or Class of a JSON variable or array to a Java primitive or array.
    - sample must be initialized;
    - casting null to a Java primitive returns corresponding initial value;
    - casting null to an array returns an empty array;
    - casting null to String returns "null";
    - casting null to other Java objects returns null;
    - casting to null returns null.

    static <T> T cast(Object obj, T sample);
    static <T> T cast(Object obj, Class <T> cls);


  Abstract class JSONObject;

    Unloads/loads the accessible fields of the Java object to/from the JSON object.
    - Java final, interface, abstract, transient, strict fields are ignored;
    - see JSON set/get/cast rules for Java object fields in the notes for JSON object
      and JSONAdapter.

    Constant:
      static final Object IGNORED; // returns from replacer/reviver to skip the field

    Methods:
      Object toJSON()
        throws IllegalArgumentException, IllegalAccessException;
      protected Object replacer(String name, Object value); 
         // first call with object class name and empty JSON object as value
      JSONObject fromJSON(Object obj)
        throws IllegalArgumentException, IllegalAccessException;
      protected Object reviver(String name, Object value); 
         // first call with object class name and obj argument as value
      static boolean isClassName(String name);
      protected <T> T castMember(String memberName, JSON jsonObj, T sample);
         // returns the sample if JSON member does not exists
      protected void setIgnored(String[] fldNames); // set ignored field names
      protected String[] getIgnored()

Usage see:
  ./test/json/JSONTest.java
  ./test/json/JSONAdapterTest.java
  ./test/json/JSONObjectTest.java

RFC compatibility parsing test result:
  https://miktim.github.io/JSONTestSuite/results/parsing.html