Class MapBuilder

java.lang.Object
org.klojang.path.util.MapBuilder

public final class MapBuilder extends Object

An elaborate builder class for Map<String, Object> pseudo-objects. A MapBuilder lets you write deeply nested values without having to create the intermediate maps first. If they are missing, they will tacitly be created. Map keys must not be null or an empty string. Map values can be anything, including null.

Internally, a MapBuilder works with Path objects. See the documentation for the Path class for how to specify path strings.

Example 1:


 MapBuilder mb = new MapBuilder();
 mb.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));
 Map<String, Object> map = mb.createMap();
 

Example 2:


 Map<String, Object> map = new MapBuilder()
  .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")
      .up("person")
    .in("medical_status")
      .set("allergies", false)
      .set("smoker", true)
      .set("prescriptions", null)
  .createMap();
 
Author:
Ayco Holleman
  • Constructor Details

    • MapBuilder

      public MapBuilder()
      Creates a new MapBuilder.
    • MapBuilder

      public MapBuilder(Map<String,Object> map)
      Creates a MapBuilder that starts out with the entries in the specified map. The map is read, but not modified.
      Parameters:
      map - The initial Map
  • Method Details

    • begin

      public static MapBuilder begin()
      Creates a new MapBuilder.
      Returns:
      a new MapBuilder
    • begin

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

      public MapBuilder 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.

      It is not allowed to directly set the path to a value of type Map. 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 MapBuilder
    • add

      public MapBuilder add(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 empty list, to which the element will be added. If the path is set to a non-Collection type, a MapBuilder.PathBlockedException is thrown.

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

      public Result<Object> poll(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:
    • get

      public <T> T get(String path)
      Returns the value of the specified path if set, else null.
      Type Parameters:
      T - The type to cast the path's value to
      Parameters:
      path - the path
      Returns:
      the value of the specified path if set, else null
    • in

      public MapBuilder in(String path)
      Returns a MapBuilder 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 well, as and when needed. If any of the segments in the path (including the last segment) has already been set, a MapBuilder.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 MapBuilder for the map found or created at the specified path
    • jump

      public MapBuilder 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 MapBuilder for the map found or created at the specified path
      See Also:
    • up

      public MapBuilder up(String parent)

      Returns a MapBuilder for the parent map of the map currently being written. 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. This method must be passed the name of the parent map (the last 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 = new MapBuilder()
        .in("person")
          .set("firstName", "John")
          .set("lastName", "Smith")
          .in("address")
            .set("street", "12 Revolutionary Rd.")
            .set("state", "CA")
            .up("person")
          .set("dateOfBirth", LocalDate.of(1967, 4, 4))
        .createMap();
       

      You can chain exit calls. To exit from a map directly under the root map, specify null or "" (an empty string):

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

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

      public String where()
      Returns the current branch within tree of nested Map objects. That is, the base path relative to which all paths are taken.
      Returns:
      the current branch within tree of nested Map objects
    • 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
    • unset

      public MapBuilder unset(String path)
      Unsets the value of the specified path. If any segment preceding the last segment has a terminal value, or if it is not a key in the map at that point the path, this method returns quietly. If the last segment is a key, it will be removed.
      Parameters:
      path - the path to unset.
      Returns:
      this MapBuilder
    • createMap

      public Map<String,Object> createMap()
      Returns the Map resulting from the write actions. The returned map is modifiable and retains the order in which the paths (now keys) were written. You can continue to use the MapBuilder 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