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
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classThrown 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). -
Constructor Summary
ConstructorsConstructorDescriptionCreates a newMapBuilder.MapBuilder(Map<String, Object> map) Creates aMapBuilderthat starts out with the entries in the specified map. -
Method Summary
Modifier and TypeMethodDescriptionAppends the specified element to theCollectionfound at the specified path.static MapBuilderbegin()Creates a newMapBuilder.static MapBuilderCreates aMapBuilderthat starts out with the entries in the specified map.Returns theMapresulting from the write actions.<T> TReturns the value of the specified path if set, elsenull.Returns aMapBuilderfor the map at the specified path.booleanReturns whether the specified path is set to a terminal value (and hence cannot be extended).Jumps to another branch in the tree of nested maps.Returns aResultobject containing the value of the specified path, orResult.notAvailable()if the path is not set.reset()Takes you back to the root map.Sets the specified path to the specified value.toString()Returns a string representation of the map created thus far.Unsets the value of the specified path.Returns aMapBuilderfor the parent map of the map currently being written.where()Returns the current branch within tree of nestedMapobjects.
-
Constructor Details
-
MapBuilder
public MapBuilder()Creates a newMapBuilder. -
MapBuilder
Creates aMapBuilderthat starts out with the entries in the specified map. The map is read, but not modified.- Parameters:
map- The initialMap
-
-
Method Details
-
begin
Creates a newMapBuilder.- Returns:
- a new
MapBuilder
-
begin
Creates aMapBuilderthat starts out with the entries in the specified map. The map is read, but not modified.- Parameters:
map- The initialMap- Returns:
- a
MapBuilderthat starts out with the entries in the specified map
-
set
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, useunset(String)to unset the path's value first.It is not allowed to directly set the path to a value of type
Map. Use theinmethod to create a new map at the specified path. It is allowed to set a path's value tonull.- Parameters:
path- the path at which to write the valuevalue- the value- Returns:
- this
MapBuilder
-
add
Appends the specified element to the
Collectionfound 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-Collectiontype, aMapBuilder.PathBlockedExceptionis thrown.- Parameters:
path- the pathelement- the element to add to the collection found or created at the specified path- Returns:
- this
MapBuilder
-
poll
Returns aResultobject containing the value of the specified path, orResult.notAvailable()if the path is not set.- Parameters:
path- the path- Returns:
- a
Resultobject containing the value of the specified path, orResult.notAvailable()if the path is not set - See Also:
-
get
Returns the value of the specified path if set, elsenull.- 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
Returns aMapBuilderfor the map at the specified path. Once this method has been called, all subsequently specified paths (including for subsequent calls toin()) 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, aMapBuilder.PathBlockedExceptionis 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
MapBuilderfor the map found or created at the specified path
-
jump
Jumps to another branch in the tree of nested maps. The difference betweenjumpandinis that the path passed tojumpis always taken as an absolute path (i.e. relative to the root map), while the path passed toinis taken relative to the path(s) passed to previous calls toinandjump.- Parameters:
path- the absolute path to be used as the base path- Returns:
- a
MapBuilderfor the map found or created at the specified path - See Also:
-
up
Returns a
MapBuilderfor the parent map of the map currently being written. All subsequently specified paths will be taken relative to the parent map's path. AnIllegalStateExceptionis 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). AnIllegalArgumentExceptionis 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
exitcalls. To exit from a map directly under the root map, specifynullor""(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
MapBuilderfor the parent map of the map currently being written to
-
reset
Takes you back to the root map. All paths you specify will be interpreted as absolute paths again.- Returns:
- a
MapBuilderfor the root map
-
where
Returns the current branch within tree of nestedMapobjects. That is, the base path relative to which all paths are taken.- Returns:
- the current branch within tree of nested
Mapobjects
-
isSet
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
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
Returns theMapresulting 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 theMapBuilderafter a call to this method.- Returns:
- the
Mapresulting from the write actions
-
toString
Returns a string representation of the map created thus far.
-