package io.monokkel.core.utils; import java.util.*; import static java.util.stream.Collectors.toMap; /** * Created by tarjei on 20/09/14. */ public class MapTransformation { /** * * A function that transforms a map by utilizing data from a matching map. The target map is filtered and the expressions * map is sent to the supplied function. The function supports sub-maps i.e. a map within the map. The expression object * CAN (but do not need to) match this sub-map structure and only expressions in the sub-map will be passed to the function. * * Example of mapToBeTransformed in JSON format: * { * "key1":"value", * "key2":{ * "subkey":"value" * } * } * * Example of corresponding expressions in JSON format: * { * "key1":"some transformation value", * "key2":{ * "subkey":"some transformation value" * } * } * * The calls to the function object will in this case be: * * transform("key1","some transformation value",{"key1":"some transformation value", "key2":{"subkey":"some transformation value"}} * transform("subkey","some transformation value","subkey":"some transformation value"} * * @return a transformed map containing all key values in the original map */ public static Map<String, Object> transformAgainstMap(final Map<String, Object> mapToBeTransformed, final Map<String, Object> expressions, final MapTransformationFunction<String,Object> mapTransformationFunction) { return mapToBeTransformed.entrySet().stream().collect(toMap(Map.Entry::getKey, entry -> applyOnMap(entry.getKey(), entry.getValue(), expressions, mapTransformationFunction))); } @SuppressWarnings("unchecked") private static Object applyOnMap(String key, Object value, final Map<String, Object> expressionObject, final MapTransformationFunction<String,Object> mapTransformationFunction) { if (ParserUtils.isAValidJsonBaseType(value)) { return mapTransformationFunction.transform(key, value, expressionObject); } else if (value instanceof Map) { final Map expressionSubObject = (Map) expressionObject.getOrDefault(key, new LinkedHashMap<>()); final Map uncleaned = (Map) value; return transformAgainstMap(uncleaned, expressionSubObject, mapTransformationFunction); } else if (value instanceof ArrayList) { // Not supported yet return value; } else { return value; } } }