Class JSONObject

java.lang.Object
org.klojang.util.JSONObject

public final class JSONObject extends Object

An elaborate reader/writer class for Map<String, Object> (map-in-map) pseudo-objects. A JSONObject lets you read/write deeply nested values using JSON path strings (e.g. person.address.street). When writing deeply nested values, intermediate maps are created as and when necessary. Map keys must be non-null strings. Map values can be anything except Map objects. null values are allowed, however.

Note that, notwithstanding its name, this class does not require that you use it within the context of JSON serialization or deserialization. It is more akin to a MapDecorator.

Example 1 (writing):


 Map<String, Object> map = JSONObject.empty()
     .set("person.address.street", "12 Revolutionary Rd.")
     .set("person.address.state", "CA")
     .set("person.firstName", "John")
     .set("person.lastName", "Smith")
     .set("person.dateOfBirth", LocalDate.of(1967, 4, 4));
     .build();
 

Example 2 (writing):


 Map<String, Object> map = JSONObject.empty()
     .in("person")
         .set("firstName", "John")
         .set("lastName", "Smith")
         .set("dateOfBirth", LocalDate.of(1967, 4, 4))
         .in("address")
             .set("street", "12 Revolutionary Rd.")
             .set("state", "CA")
             .backTo("person")
         .in("medicalStatus")
             .set("allergies", List.of("peanuts"))
             .set("smoker", true)
             .set("prescriptions", null)
     .build();
 

Example 3 (reading):


 String street = JSONObject.of(someMap).get("person.address.street");
 

For more flexibility, use the PathWalker class of the klojang-invoke library.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    Thrown when trying to write to a path that has already been set, or that extends beyond a path segment with a terminal value (anything other than a map).
  • Method Summary

    Modifier and Type
    Method
    Description
    addElement(String path, Object element)
    Appends the specified element to the Collection found at the specified path.
    addElement(Path path, Object element)
    Appends the specified element to the Collection found at the specified path.
    backTo(String parentName)
    Returns a JSONObject for the parent map of the map currently being edited.
    Returns the Map resulting all write actions thus far.
    static JSONObject
    Creates a new JSONObject.
    <T> org.klojang.check.extra.Result<T>
    get(String path)
    Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set.
    <T> org.klojang.check.extra.Result<T>
    get(Path path)
    Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set.
    <T> org.klojang.check.extra.Result<T>
    Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set.
    in(String path)
    Returns a JSONObject for the map at the specified path.
    in(Path path)
    Returns a JSONObject for the map at the specified path.
    boolean
    isSet(String path)
    Returns whether the specified path is set to a terminal value (and hence cannot be extended).
    boolean
    isSet(Path path)
    Returns whether the specified path is set to a terminal value (and hence cannot be extended).
    jump(String path)
    Jumps to another branch in the tree of nested maps.
    jump(Path path)
    Jumps to another branch in the tree of nested maps.
    Returns the key used to embed the current map within the parent map.
    static JSONObject
    Creates a JSONObject that starts out with the entries in the specified map.
    Takes you back to the root map.
    set(String path, Object value)
    Sets the specified path to the specified value.
    set(Path path, Object value)
    Sets the specified path to the specified value.
    setPlain(String key, Object value)
    Sets the specified key to the specified value.
    Returns a string representation of the map created thus far.
    unset(String path)
    Unsets the value of the specified path.
    unset(Path path)
    Unsets the value of the specified path.
    Returns the full path to the current map.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Method Details

    • empty

      public static JSONObject empty()
      Creates a new JSONObject.
      Returns:
      a new JSONObject
    • of

      public static JSONObject of(Map<String,Object> map)
      Creates a JSONObject that starts out with the entries in the specified map. The provided map is read, but not modified.
      Parameters:
      map - the initial Map
      Returns:
      a JSONObject that starts out with the entries in the specified map
    • set

      public JSONObject set(String path, Object value)

      Sets the specified path to the specified value. It is not allowed to overwrite the value of a path that has already been set, even if set to null. If necessary, use unset(String) to unset the path's value first.

      The value can be anything except a Map or JSONObject. Use the in() method to create a new map at the specified path. It is allowed to set a path's value to null.

      Parameters:
      path - the path at which to write the value
      value - the value
      Returns:
      this JSONObject
    • setPlain

      public JSONObject setPlain(String key, Object value)
      Sets the specified key to the specified value. The provided key will not be interpreted as a JSON path. This is useful if the key contains one or more dot characters.
      Parameters:
      key - the key
      value - the value
      Returns:
      this JSONObject
    • set

      public JSONObject set(Path path, Object value)

      Sets the specified path to the specified value. It is not allowed to overwrite the value of a path that has already been set, even if set to null. If necessary, use unset(String) to unset the path's value first.

      The value can be anything except a Map or JSONObject. Use the in() method to create a new map at the specified path. It is allowed to set a path's value to null.

      Parameters:
      path - the path at which to write the value
      value - the value
      Returns:
      this JSONObject
    • addElement

      public JSONObject addElement(String path, Object element)

      Appends the specified element to the Collection found at the specified path. If the path has not been set yet, it will first be set to an ArrayList, to which the element will then be added. If the path is already set to a non-Collection type, a JSONObject.PathBlockedException is thrown.

      Parameters:
      path - the path
      element - the element to add to the collection found or created at the specified path
      Returns:
      this JSONObject
    • addElement

      public JSONObject addElement(Path path, Object element)

      Appends the specified element to the Collection found at the specified path. If the path has not been set yet, it will first be set to an ArrayList, to which the element will then be added. If the path is already set to a non-Collection type, a JSONObject.PathBlockedException is thrown.

      Parameters:
      path - the path
      element - the element to add to the collection found or created at the specified path
      Returns:
      this JSONObject
    • get

      public <T> org.klojang.check.extra.Result<T> get(String path)
      Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set.
      Parameters:
      path - the path
      Returns:
      a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set
      See Also:
    • getPlain

      public <T> org.klojang.check.extra.Result<T> getPlain(String key)
      Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set. The provided key will not be interpreted as a JSON path. This is useful if the key contains one or more dot characters.
      Parameters:
      key - the path
      Returns:
      a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set
      See Also:
    • get

      public <T> org.klojang.check.extra.Result<T> get(Path path)
      Returns a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set.
      Parameters:
      path - the path
      Returns:
      a Result object containing the value of the specified path, or Result.notAvailable() if the path is not set
      See Also:
    • in

      public JSONObject in(String path)
      Returns a JSONObject for the map at the specified path. Once this method has been called, all subsequently specified paths (including for subsequent calls to in()) are taken relative to the specified path. If there is no map yet at the specified path, it will be created. Ancestral maps will be created as and when needed. If any of the segments in the path (including the last segment) has already been set, a JSONObject.PathBlockedException is thrown.
      Parameters:
      path - the path to be used as the base path. The path will itself be interpreted as relative to the current base path
      Returns:
      a JSONObject for the map found or created at the specified path
    • in

      public JSONObject in(Path path)
      Returns a JSONObject for the map at the specified path. Once this method has been called, all subsequently specified paths (including for subsequent calls to in()) are taken relative to the specified path. If there is no map yet at the specified path, it will be created. Ancestral maps will be created as and when needed. If any of the segments in the path (including the last segment) has already been set, a JSONObject.PathBlockedException is thrown.
      Parameters:
      path - the path to be used as the base path. The path will itself be interpreted as relative to the current base path
      Returns:
      a JSONObject for the map found or created at the specified path
    • jump

      public JSONObject jump(String path)
      Jumps to another branch in the tree of nested maps. The difference between jump and in is that the path passed to jump is always taken as an absolute path (i.e. relative to the root map), while the path passed to in is taken relative to the path(s) passed to previous calls to in and jump.
      Parameters:
      path - the absolute path to be used as the base path
      Returns:
      a JSONObject for the map found or created at the specified path
      See Also:
    • jump

      public JSONObject jump(Path path)
      Jumps to another branch in the tree of nested maps. The difference between jump and in is that the path passed to jump is always taken as an absolute path (i.e. relative to the root map), while the path passed to in is taken relative to the path(s) passed to previous calls to in and jump.
      Parameters:
      path - the absolute path to be used as the base path
      Returns:
      a JSONObject for the map found or created at the specified path
      See Also:
    • backTo

      public JSONObject backTo(String parentName)

      Returns a JSONObject for the parent map of the map currently being edited. All subsequently specified paths will be taken relative to the parent map's path. An IllegalStateException is thrown when trying to exit out of the root map. You must pass the name of the parent map (the last path segment of the parent map's path). An IllegalArgumentException is thrown if the argument does not equal the parent map's name. This is to make sure you will not accidentally start writing to the wrong map, and it makes the map-building code more intelligible.

      
       Map<String, Object> map = JSONObject.empty()
        .in("person")
          .set("firstName", "John")
          .set("lastName", "Smith")
          .in("address")
            .set("street", "12 Revolutionary Rd.")
            .set("state", "CA")
            .backTo("person")
          .set("dateOfBirth", LocalDate.of(1967, 4, 4))
        .build();
       

      You can chain backTo() calls. To exit from a map directly under the root map, specify null:

      
       MapBuilder mb = JSONObject.empty();
        .in("department.manager.address")
          .set("street", "Sunset Blvd")
          .backTo("manager")
          .backTo("department")
          .backTo(null)
        .set("foo", "bar");
       
      Parameters:
      parentName - the name of the parent map
      Returns:
      a JSONObject for the parent map of the map currently being written to
    • root

      public JSONObject root()
      Takes you back to the root map. All paths you specify will be interpreted as absolute paths again.
      Returns:
      a JSONObject for the root map
    • name

      public String name()
      Returns the key used to embed the current map within the parent map. If the current map is the root map, an empty string is returned.
      Returns:
      the key used to embed the current map within the parent map
    • where

      public String where()
      Returns the full path to the current map. That is, the path relative to which all path arguments (e.g. for the set() method) are taken.
      Returns:
      the full path to the current map
    • isSet

      public boolean isSet(String path)
      Returns whether the specified path is set to a terminal value (and hence cannot be extended).
      Parameters:
      path - the path
      Returns:
      whether it is set to a terminal value
    • isSet

      public boolean isSet(Path path)
      Returns whether the specified path is set to a terminal value (and hence cannot be extended).
      Parameters:
      path - the path
      Returns:
      whether it is set to a terminal value
    • unset

      public JSONObject unset(String path)
      Unsets the value of the specified path. This method returns quietly for non-existent paths.
      Parameters:
      path - the path to unset.
      Returns:
      this JSONObject
    • unset

      public JSONObject unset(Path path)
      Unsets the value of the specified path. This method returns quietly for non-existent paths.
      Parameters:
      path - the path to unset.
      Returns:
      this JSONObject
    • build

      public Map<String,Object> build()
      Returns the Map resulting all write actions thus far. The returned map is modifiable and retains the order in which the paths (now keys) were written. You can continue to use the JSONObject after a call to this method.
      Returns:
      the Map resulting from the write actions
    • toString

      public String toString()
      Returns a string representation of the map created thus far.
      Overrides:
      toString in class Object
      Returns:
      a string representation of the map created thus far