Class Struct
A structured map is any implementation of the Map
interface, in which every key is a String
, and every value is either a
primitive wrapper type (String
, Long
,
Integer
, etc...), a structured map or a structured list.
A structured list is any implementation of the List
interface,
of which every value is a primitive wrapper type, a structured map or a structured list.
In this way, arbitrarily complex objects can be created and passed between Struts code and the business layer, or Struts code and the JSP layer, without resorting to the creation of application-specific datatypes. These datatypes are also used by the Spring JdbcTemplate framework to return values from a database, so it is useful to have some generic functions that operate on them.
- Author:
- knoxg
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Backwards compatible class until this is removedstatic class
A Comparator which performs comparisons between two rows in a structured list (used in sorting).static class
A Comparator which performs comparisons between two rows in a structured list (used in sorting), keyed on a case-insensitive String value.static interface
This class can be serialised as a JSON value by calling it's toJson() methodstatic interface
This class can be serialised as a JSON value by calling it's toJson(String) method.static interface
This class can be serialised as a JSON value by calling it's toString() methodstatic interface
This class can be serialised as a JSON value by calling it's writeJsonFormat() method Multiple json formats are supported by supplying a jsonFormat string; e.g. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic void
Add a structured column containing a constant value.static String
arrayToString
(String topLevelName, Object list) This method returns a human-readable version of an array object that contains structured lists/maps/sets.static List
getStructuredListColumn
(List list, String columnName) Searches a structured list for a particular column.static Map
getStructuredListItem
(List list, String keyField, long longValue) As pergetStructuredListItem(List, String, Object)
, with a numeric key.static Map
getStructuredListItem
(List list, String keyField, Object key) Searches a structured list for a particular row.static Map
getStructuredListItem2
(List list, String keyField, long longValue, String keyField2, long longValue2) As pergetStructuredListItem(List, String, long)
, with a compound key.static Object
getStructuredListObject
(List list, String keyField, long longValue) As pergetStructuredListObject(List, String, Object)
, with a numeric key.static Object
getStructuredListObject
(List list, String keyField, Object key) Searches a structured list for a particular row.static Object
Return a single value from a structured map.newStructuredMap
(Object... keyValuePairs) Create a structured Map out of key / value pairs.static void
renameStructuredListColumn
(List<Map<String, Object>> rows, String srcColumnName, String destColumnName) Rename a structured column, as returned from a Spring JdbcTemplate query.static void
setFromMap
(Object obj, Map map, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements) Similar to thesetFromRequest(Object, HttpServletRequest)
method, but uses a Map instead of a request.static void
setFromMap
(Object obj, Map map, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements, String[] fields) Similar to thesetFromRequest(Object, HttpServletRequest, String[])
method, but uses a Map instead of a request.static void
setFromObject
(Object targetObj, Object sourceObj, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements, String[] fields) Similar to thesetFromRequest(Object, HttpServletRequest, String[])
method, but uses a Map instead of a request.static void
setFromRequest
(Object obj, jakarta.servlet.http.HttpServletRequest request) Set all fields in object 'obj' using values in request.static void
setFromRequest
(Object obj, jakarta.servlet.http.HttpServletRequest request, String[] fields) Set all fields in object 'obj' using values in request.static void
setListElement
(List list, int index, Object object) Sets the element at a particular list index to a particular object.static void
setValue
(Object object, String key, Object value, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements) Sets a single value in a structured object.static void
sortStructuredList
(List list, String keyField) Sorts a structured list on the supplied key fieldstatic void
sortStructuredListIgnoreCase
(List list, String keyField) Sorts a structured list on the supplied key field; the key value is sorted case-insensitively (it must be of type String or a ClassCastException will occur).static void
structuredListToFilteredJson
(Writer w, List list, String jsonFormat, String... validKeys) static String
structuredListToFilteredJson
(List list, String jsonFormat, String... validKeys) Converts a java List into javascript, whilst filtering the keys of any Maps to only those in validKeysstatic void
structuredListToJson
(Writer w, List list, String jsonFormat) static String
structuredListToJson
(List list) Converts a java List into javascriptstatic String
structuredListToJson
(List list, String jsonFormat) Converts a java List into javascriptstatic String
structuredListToString
(String topLevelName, List list) This method returns a human-readable version of a structured list.static void
structuredMapToFilteredJson
(Writer w, Map map, String jsonFormat, String... validKeys) static String
structuredMapToFilteredJson
(Map map, String jsonFormat, String... validKeys) Converts a java Map into javascript, whilst filtering the keys of any Maps to only those in validKeysstatic void
structuredMapToJson
(Writer w, Map map, String jsonFormat) static String
structuredMapToJson
(Map map) Converts a java map into javascriptstatic String
structuredMapToJson
(Map map, String jsonFormat) Converts a java map into javascriptstatic String
structuredMapToString
(String topLevelName, Map map) This method returns a human-readable version of a structured map.static String
structuredSetToString
(String topLevelName, Set set) This method returns a human-readable version of a structured set.static String
Convert a date object to it's JSON representation.
-
Field Details
-
DATE_FORMAT_MICROSOFT
Serialise Date objects using the Microsoft convention for Dates, which is a String in the form"/Date(millisSinceEpoch)/"
- See Also:
-
DATE_FORMAT_NUMERIC
Serialise Date objects as milliseconds since the epoch- See Also:
-
-
Constructor Details
-
Struct
public Struct()
-
-
Method Details
-
sortStructuredList
Sorts a structured list on the supplied key field- Parameters:
list
- The list to search.keyField
- The name of the key field.- Throws:
NullPointerException
- if list or keyField is set to null.IllegalStateException
- if the list is not composed of Maps
-
sortStructuredListIgnoreCase
Sorts a structured list on the supplied key field; the key value is sorted case-insensitively (it must be of type String or a ClassCastException will occur).- Parameters:
list
- The list to search.keyField
- The name of the key field.- Throws:
NullPointerException
- if list or keyField is set to null.IllegalStateException
- if the list is not composed of Maps
-
setFromRequest
Set all fields in object 'obj' using values in request. Each request parameter is checked against the object to see if a bean setter method exists for that parameter name. If it does, then it is invoked, using the parameter value as the setter argument. This method uses thesetValue(Object, String, Object, boolean, boolean, boolean)
method to dynamically create map and list elements as required if the object being set implements the Map interface.e.g. if passed a Map object, and the HttpServletRequest has a parameter named "
table[12].id
" with the value "1234
", then:- a List object named "table" is created in the Map,
- the list is increased to allow at least 12 elements,
- that element is set to a new Map object ...
- ... which contains the String key "id", which is assigned the value "1234".
This processing allows developers to pass arbitrarily complex structures through from HttpServletRequest name/value pairs.
This method operates on both structured objects (Maps/Lists) or data-transfer objects (DTOs). For example, if passed a bean-like Object which had a getTable() method that returned a List, then this would be used to perform the processing above. (If the List returned a Map at index 12, then an 'id' key would be created as before; if the List returned another Object at index 12, then the setId() method would be called instead; if the list returned null at index 12, then a Map would be created as before).
NB: If an object is not a Map, and does not have the appropriate setter() method, then this function will *not* raise an exception. This is intentional behaviour - (use
setValue(Object, String, Object, boolean, boolean, boolean)
if you need more fine-grained control.You can limit the setters that are invoked by using the
setFromRequest(Object, HttpServletRequest, String[])
form of this method.- Parameters:
obj
- The object being set.request
- The request containing the source data- Throws:
RuntimeException
- if an invocation target exception occurred whilst calling the object's set() methods.
-
setFromRequest
public static void setFromRequest(Object obj, jakarta.servlet.http.HttpServletRequest request, String[] fields) Set all fields in object 'obj' using values in request. Only the request parameter names passed in through the 'fields' argument will be used to populate the object. If the named parameter does not exist in the request, then the setter for that parameter is not invoked.See
setFromRequest(Object, HttpServletRequest)
for more information on how this method operates.- Parameters:
obj
- The object being set.request
- The request containing the source datafields
- An array of strings, denoting the fields that are sourced from the request. All other parameters in the request are ignored.- Throws:
RuntimeException
- if an invocation target exception occurred whilst calling the object's set() methods.
-
setFromMap
public static void setFromMap(Object obj, Map map, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements) Similar to thesetFromRequest(Object, HttpServletRequest)
method, but uses a Map instead of a request.- Parameters:
obj
- The object being set.map
- The Map containing the source dataignoreMissingSetter
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
convertStrings
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
createMissingElements
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
-
setFromMap
public static void setFromMap(Object obj, Map map, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements, String[] fields) Similar to thesetFromRequest(Object, HttpServletRequest, String[])
method, but uses a Map instead of a request.- Parameters:
obj
- The object being set.map
- The Map containing the source dataignoreMissingSetter
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
convertStrings
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
createMissingElements
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
fields
- An array of strings, denoting the fields that are sourced from the request. All other parameters in the request are ignored.
-
setFromObject
public static void setFromObject(Object targetObj, Object sourceObj, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements, String[] fields) Similar to thesetFromRequest(Object, HttpServletRequest, String[])
method, but uses a Map instead of a request.- Parameters:
targetObj
- The object being set.sourceObj
- The Map containing the source dataignoreMissingSetter
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
convertStrings
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
createMissingElements
- passed tosetValue(Object, String, Object, boolean, boolean, boolean)
fields
- An array of strings, denoting the fields that are sourced from the request. All other parameters in the request are ignored.
-
getValue
Return a single value from a structured map. Returns null if the value does not exist, or if an error occurred retrieving it.- Parameters:
object
- The structure mapkey
- The key of the value we wish to retrieve (e.g. "abc.def[12].ghi")- Returns:
- The value
-
setValue
public static void setValue(Object object, String key, Object value, boolean ignoreMissingSetter, boolean convertStrings, boolean createMissingElements) throws NumberFormatException Sets a single value in a structured object. The object may be composed of javabean-style objects, Map/List classes, or a combination of the two.There is a possible denial-of-service attack that can be used against this method which you should probably be aware of, but can't do anything about: if a large list index is supplied, e.g. "
abc[1293921]
", then a list will be generated with this many elements in it. There are workarounds for this, but none are really satisfactory.It should also be noted that even if an exception is thrown within this method, the data structure underneath it may still have been modified, e.g. setting "
abc.def.ghi
" may successfully construct 'def' but later fail on 'ghi'.- Parameters:
object
- The structure map or listkey
- The key of the value we wish to set (e.g. "abc.def[12].ghi"). Note that map keys are assumed; i.e. they are not enclosed in 'curly braces'.value
- The value to set this toignoreMissingSetter
- If we are asked to set a value in an object which does not have an appropriate setter, don't raise an exception (just does nothing instead).convertStrings
- If we are asked to set a string value in an object which has a setter, but of a different type (e.g. setCustomerId(Long)), performs conversions to that type automatically. (Useful when setting values sourced from a HttpServletRequest, which will always be of String type).createMissingElements
- If we are asked to set a value in a Map or List that does not exist, will create the required Map keys or extend the List so that the value can be set.- Throws:
IllegalArgumentException
- if- An null map or list is navigated down
- A non-List object is invoked with the '[]' operator
- A non-Map object is invoked with the '.' operator, or the object has no getter/setter method with the appropriate name
- An empty mapped property is supplied e.g. bob..something
- An invalid key was supplied (e.g. 'bob[123' -- no closing square bracket)
NumberFormatException
- if an array index cannot be converted to an integer viaInteger.parseInt(java.lang.String)
.
-
setListElement
Sets the element at a particular list index to a particular object. This differs from the standard List.set() method inasmuch as the list is allowed to grow in the case where index>=List.size(). If the list needs to grow to accomodate the new element, then null objects are appended until the list is large enough.- Parameters:
list
- The list to modifyindex
- The position within the list we wish to set to this objectobject
- The object to be placed into the list.
-
getStructuredListItem
As pergetStructuredListItem(List, String, Object)
, with a numeric key.- Parameters:
list
- The list to search.keyField
- The name of the key field.longValue
- The key value to search for- Returns:
- The requested element in the list, or null if the element cannot be found.
- Throws:
NullPointerException
- if list or keyField is set to null.IllegalStateException
- if the list is not composed of Maps
-
getStructuredListObject
As pergetStructuredListObject(List, String, Object)
, with a numeric key.- Parameters:
list
- The list to search.keyField
- The name of the key field.longValue
- The key value to search for- Returns:
- The requested element in the list, or null if the element cannot be found.
- Throws:
NullPointerException
- if list or keyField is set to null.IllegalStateException
- if the list is not composed of Maps
-
getStructuredListItem
Searches a structured list for a particular row. The list is presumed to be a List of Maps, each of which contains a key field. Lists are searched sequentially until the desired row is found. It is permitted to search on null key values. If the row cannot be found, null is returned.For example, in the list:
list = [ 0: { systemId = "abc", systemTimezone = "dalby" } 1: { systemId = "def", systemTimezone = "london" } 2: { systemId = "ghi", systemTimezone = "new york" } ]
getStructuredListItem(list, "systemId", "def")
would return a reference to the second element in the list, i.e. the Map:{ systemId = "def", systemTimezone = "london" }
- Parameters:
list
- The list to search.keyField
- The name of the key field.key
- The key value to search for- Returns:
- The requested element in the list, or null if the element cannot be found.
- Throws:
NullPointerException
- if list or keyField is set to null.IllegalArgumentException
- if the list is not composed of Maps
-
getStructuredListItem2
public static Map getStructuredListItem2(List list, String keyField, long longValue, String keyField2, long longValue2) As pergetStructuredListItem(List, String, long)
, with a compound key.- Parameters:
list
- The list to search.keyField
- The name of the key field.longValue
- The key value to search forkeyField2
- The name of the second key field.longValue2
- The second key value to search for- Returns:
- The requested element in the list, or null if the element cannot be found.
- Throws:
NullPointerException
- if list or keyField is set to null.IllegalStateException
- if the list is not composed of Maps
-
getStructuredListObject
Searches a structured list for a particular row. The list may be composed of arbitrary objects.- Parameters:
list
- The list to search.keyField
- The name of the key field.key
- The key value to search for- Returns:
- The requested element in the list, or null if the element cannot be found.
- Throws:
NullPointerException
- if list or keyField is set to null.IllegalArgumentException
- if the list is not composed of Maps
-
getStructuredListColumn
Searches a structured list for a particular column. The list is presumed to be a List of Maps, each of which contains a particular key. The value of this key is retrieved from each Map, and added to a new List, which is then returned to the user. If the value of that key is null for a particular Map, then the null value is added to the returned list.For example, in the list:
list = [ 0: { systemId = "abc", systemTimezone = "dalby" } 1: { systemId = "def", systemTimezone = "london" } 2: { systemId = "ghi", systemTimezone = "new york" } 3: null 4: { systemId = "jkl", systemTimezone = "melbourne" } ]
getStructuredListColumn(list, "systemId")
would return a new List with three elements, i.e.list = [ 0: "abc" 1: "def" 2: "ghi" 3: null 4: "jkl" ]
- Parameters:
list
- The list to search.columnName
- The key of the entry in each map to retrieve- Returns:
- a List of Objects
- Throws:
NullPointerException
- if list or columnName is set to null.
-
structuredListToString
This method returns a human-readable version of a structured list. The output of this list looks similar to the following:topLevelName = [ 0: 'stringValue' 1: null 2: (WeirdObjectClass) "toString() output of weirdObject" 3 = { mapElement => ..., ... } 4 = [ 0: listElement ... ] 5 = ( setElement ) ... ]
Strings are represented as their own values in quotes; null values are represented with the textnull
, and structured maps and structured lists contained within this list are recursed into.- Parameters:
topLevelName
- The name to assign to the list in the first row of outputlist
- The list we wish to represent as a string- Returns:
- A human-readable version of a structured list
-
structuredSetToString
This method returns a human-readable version of a structured set. The output of this set looks similar to the following:topLevelName = ( 0: 'stringValue' 1: null 2: (WeirdObjectClass) "toString() output of weirdObject" 3 = { mapElement => ..., ... } 4 = [ 0: listElement ... ] 5 = ( setElement ) ... )
Strings are represented as their own values in quotes; null values are represented with the textnull
, and structured maps and structured lists contained within this list are recursed into.- Parameters:
topLevelName
- The name to assign to the list in the first row of outputset
- The set we wish to represent as a string- Returns:
- A human-readable version of a structured list
-
structuredMapToString
This method returns a human-readable version of a structured map. The output of this list looks similar to the following:topLevelName = { apples => 'stringValue' rhinocerouseses => null weirdObjectValue => (WeirdObjectClass) "toString() output of weirdObject" mapValue = { mapElement => ... ... } listValue = [ 0: listElement ... ] setValue = ( setElement ) ... ]
Keys within the map are sorted alphabetically before being enumerated. Strings are represented as their own values in quotes; null values are represented with the textnull
, and structured maps and structured lists contained within this list are recursed into.- Parameters:
topLevelName
- The name to assign to the list in the first row of outputmap
- The map we wish to represent as a string- Returns:
- A human-readable version of a structured map
-
arrayToString
This method returns a human-readable version of an array object that contains structured lists/maps/sets. Bear in mind that the array object itself isn't considered 'structured' by the definitions at the top of this class, or at least, it won't until this is added to the other structured parsers/readers.topLevelName[] = [ 0: 'stringValue' 1: null 2: (WeirdObjectClass) "toString() output of weirdObject" 3 = { mapElement => ..., ... } 4 = [ 0: listElement ... ] 5 = ( setElement ) ... ]
Strings are represented as their own values in quotes; null values are represented with the textnull
, and structured maps and structured lists contained within this list are recursed into.- Parameters:
topLevelName
- The name to assign to the list in the first row of outputlist
- The list we wish to represent as a string- Returns:
- A human-readable version of a structured list
-
structuredListToJson
Converts a java List into javascript- Parameters:
list
- the list to convert into javascript- Returns:
- the javascript version of this list.
-
structuredListToJson
Converts a java List into javascript- Parameters:
list
- the list to convert into javascript- Returns:
- the javascript version of this list.
-
structuredListToJson
- Throws:
IOException
-
structuredMapToJson
Converts a java map into javascript- Parameters:
map
- the Map to convert into javascript- Returns:
- a javascript version of this Map
-
structuredMapToJson
Converts a java map into javascript- Parameters:
map
- the Map to convert into javascript- Returns:
- a javascript version of this Map
-
structuredMapToJson
- Throws:
IOException
-
structuredListToFilteredJson
public static String structuredListToFilteredJson(List list, String jsonFormat, String... validKeys) Converts a java List into javascript, whilst filtering the keys of any Maps to only those in validKeys- Parameters:
list
- the list to convert into javascriptjsonFormat
- the jsonFormatvalidKeys
-- Returns:
- the javascript version of this list.
-
structuredMapToFilteredJson
Converts a java Map into javascript, whilst filtering the keys of any Maps to only those in validKeys- Parameters:
map
- the map to convert into javascriptjsonFormat
- the jsonFormatvalidKeys
-- Returns:
- the javascript version of this list.
-
structuredListToFilteredJson
public static void structuredListToFilteredJson(Writer w, List list, String jsonFormat, String... validKeys) throws IOException - Throws:
IOException
-
structuredMapToFilteredJson
public static void structuredMapToFilteredJson(Writer w, Map map, String jsonFormat, String... validKeys) throws IOException - Throws:
IOException
-
toDate
Convert a date object to it's JSON representation.As there's no real standard for this, a type format is used to define what kind of Dates your going to get on the Json side.
- Parameters:
d
- a Date objectjsonFormat
- either "microsoft" or "numeric"- Returns:
- A date in json representation.
- See Also:
-
newStructuredMap
Create a structured Map out of key / value pairs. Keys must be Strings.So the value of
Struct.newStructuredMap("thing", 1L, "otherThing", "value");
is a map with two entries:- an entry with key "thing" and value new Long(1), and
- an entry with key "otherThing" and value "value".
- Parameters:
keyValuePairs
- a list of key / value pairs- Returns:
- a Map as described above
- Throws:
ClassCastException
- if any of the supplied keys is not a String
-
renameStructuredListColumn
public static void renameStructuredListColumn(List<Map<String, Object>> rows, String srcColumnName, String destColumnName) Rename a structured column, as returned from a Spring JdbcTemplate query. This method will iterate throw all rows of a table, replacing any srcColumnName keys with destColumnName- Parameters:
rows
- the table being modifiedsrcColumnName
- the name of the row key (column) being replaceddestColumnName
- the new name of the row key (column)
-
addStructuredListColumn
public static void addStructuredListColumn(List<Map<String, Object>> rows, String newColumnName, Object value) Add a structured column containing a constant value. This method will iterate through all rows of a table, adding a new newColumnName key with the supplied value.- Parameters:
rows
- the table being modifiednewColumnName
- the name of the row key (column) being addedvalue
- the value to add to the row
-