22
33import ca .trackerforce .path .DotPathFactory ;
44
5+ import java .lang .reflect .Array ;
56import java .util .Collections ;
67import java .util .List ;
78import java .util .Map ;
@@ -33,11 +34,13 @@ public static List<String> parsePaths(String path) {
3334 * @throws ClassCastException if the property is not a map
3435 */
3536 public static Map <String , Object > mapFrom (Map <String , Object > source , String property ) {
36- if (isInvalid (source , property )) {
37+ Object result = getObjectFromSource (source , property );
38+
39+ if (!(result instanceof Map )) {
3740 return Collections .emptyMap ();
3841 }
3942
40- return (Map <String , Object >) source . get ( property ) ;
43+ return (Map <String , Object >) result ;
4144 }
4245
4346 /**
@@ -49,31 +52,84 @@ public static Map<String, Object> mapFrom(Map<String, Object> source, String pro
4952 * @throws ClassCastException if the property is not a list of maps
5053 */
5154 public static List <Map <String , Object >> listFrom (Map <String , Object > source , String property ) {
52- if (isInvalid (source , property )) {
55+ Object result = getObjectFromSource (source , property );
56+
57+ if (!(result instanceof List )) {
5358 return Collections .emptyList ();
5459 }
5560
56- return (List <Map <String , Object >>) source .get (property );
61+ return (List <Map <String , Object >>) result ;
62+ }
63+
64+ /**
65+ * Extracts a typed list from the source map based on the specified property.
66+ *
67+ * @param source the source map
68+ * @param property the property to extract or a dot-notated path for nested properties
69+ * @return the extracted list of maps or an empty list if not found
70+ * @throws ClassCastException if the property is not a list of maps
71+ */
72+ public static <T > List <T > listFrom (Map <String , Object > source , String property , Class <T > clazz ) {
73+ Object result = getObjectFromSource (source , property );
74+
75+ if (!(result instanceof List ) || ((List <?>) result ).isEmpty () || !clazz .isInstance (((List <?>) result ).get (0 ))) {
76+ return Collections .emptyList ();
77+ }
78+
79+ return (List <T >) result ;
5780 }
5881
5982 /**
6083 * Extracts a list of objects from the source map based on the specified property.
6184 *
6285 * @param source the source map
63- * @param property the property to extract
86+ * @param property the property to extract or a dot-notated path for nested properties
6487 * @return the extracted list of objects or an empty list if not found
6588 * @throws ClassCastException if the property is not a list of objects
6689 */
6790 public static Object [] arrayFrom (Map <String , Object > source , String property ) {
68- if (isInvalid (source , property )) {
91+ Object result = getObjectFromSource (source , property );
92+
93+ if (result == null || !result .getClass ().isArray ()) {
6994 return new Object [0 ];
7095 }
7196
72- return ( Object []) source . get ( property );
97+ return convertToObjectArray ( result );
7398 }
7499
75- private static boolean isInvalid (Map <String , Object > source , String property ) {
76- return source == null || property == null || property .isEmpty () || !source .containsKey (property );
100+ private static Object getObjectFromSource (Map <String , Object > source , String property ) {
101+ if (property .contains ("." )) {
102+ String [] keys = property .split ("\\ ." );
103+
104+ for (int i = 0 ; i < keys .length - 1 ; i ++) {
105+ source = (Map <String , Object >) source .get (keys [i ]);
106+ }
107+
108+ return source .get (keys [keys .length - 1 ]);
109+ }
110+
111+ if (source == null || !source .containsKey (property )) {
112+ return null ;
113+ }
114+
115+ return source .get (property );
116+ }
117+
118+ private static Object [] convertToObjectArray (Object array ) {
119+ Class <?> componentType = array .getClass ().getComponentType ();
120+
121+ if (!componentType .isPrimitive ()) {
122+ return (Object []) array ;
123+ }
124+
125+ int length = Array .getLength (array );
126+ Object [] result = new Object [length ];
127+
128+ for (int i = 0 ; i < length ; i ++) {
129+ result [i ] = Array .get (array , i );
130+ }
131+
132+ return result ;
77133 }
78134}
79135
0 commit comments