All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fivefaces.cloud.workflow.awsonprem.impl.ObjectValueEnricherImpl Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fivefaces.cloud.workflow.awsonprem.impl;

import com.fivefaces.cloud.workflow.awsonprem.ObjectValueEnricher;
import com.fivefaces.cloud.workflow.awsonprem.model.Execution;
import com.fivefaces.cloud.workflow.awsonprem.utils.JsonUtil;
import com.jayway.jsonpath.JsonPath;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Service
@RequiredArgsConstructor
public class ObjectValueEnricherImpl implements ObjectValueEnricher {

    private final String FUNC_FORMAT = "States.Format(";
    private final String FUNC_STRING_TO_JSON = "States.StringToJson(";
    private final String FUNC_JSON_TO_STRING = "States.JsonToString(";
    private final String FUNC_ARRAY = "States.Array(";

    private final JsonUtil jsonUtil;

    @Override
    public void enrich(Object object, Execution execution) {
        if (object instanceof Map) {
            enrich((Map) object, execution);
        } else if (object instanceof Collection) {
            enrich((Collection) object, execution);
        }
    }

    private void enrich(Map object, Execution execution) {
        Map replacements = new HashMap<>();
        for (String key : object.keySet()) {
            Object currentValue = object.get(key);
            if (currentValue instanceof String) {
                String currentValStr = (String) currentValue;
                if (key.endsWith(".$") && !currentValStr.startsWith("$$")) {
                    if (isStatesFunc(currentValStr)) {
                        replacements.put(key, processStatesFunction(currentValStr, execution));
                    } else {
                        replacements.put(key, execution.getInput().read(JsonPath.compile(currentValStr)));
                    }
                }
            } else {
                enrich(currentValue, execution);
            }
        }
        for (String replacementKey : replacements.keySet()) {
            object.remove(replacementKey);
            object.put(StringUtils.substringBeforeLast(replacementKey, ".$"), replacements.get(replacementKey));
        }
    }

    private boolean isStatesFunc(String currentValStr) {
        return currentValStr.startsWith(FUNC_FORMAT) ||
                currentValStr.startsWith(FUNC_STRING_TO_JSON) ||
                currentValStr.startsWith(FUNC_JSON_TO_STRING) ||
                currentValStr.startsWith(FUNC_ARRAY);
    }

    private Object processStatesFunction(String currentValue, Execution execution) {
        if (currentValue.startsWith(FUNC_FORMAT)) {
            return formatString(currentValue, execution);
        } else if (currentValue.startsWith(FUNC_JSON_TO_STRING)) {
            return jsonToString(currentValue, execution);
        } else if (currentValue.startsWith(FUNC_STRING_TO_JSON)) {
            return stringToJson(currentValue, execution);
        } else if (currentValue.startsWith(FUNC_ARRAY)) {
            return toArray(currentValue, execution);
        }
        throw new IllegalStateException("Could not process States function " + currentValue);
    }

    private String jsonToString(String currentValue, Execution execution) {
        currentValue = removeFunctionExtras(currentValue, FUNC_JSON_TO_STRING).trim();
        Object jsonObject = execution.getInput().read(JsonPath.compile(currentValue));
        return jsonUtil.write(jsonObject);
    }

    private Object stringToJson(String currentValue, Execution execution) {
        currentValue = removeFunctionExtras(currentValue, FUNC_STRING_TO_JSON).trim();
        String jsonObject = execution.getInput().read(JsonPath.compile(currentValue));
        return jsonUtil.read(jsonObject);
    }

    private List toArray(String currentValue, Execution execution) {
        currentValue = removeFunctionExtras(currentValue, FUNC_ARRAY);
        String[] args = StringUtils.split(currentValue, ',');
        return Arrays.asList(enrichArgs(args, execution));
    }

    private String formatString(String currentValue, Execution execution) {
        currentValue = removeFunctionExtras(currentValue, FUNC_FORMAT);
        String[] args = StringUtils.split(currentValue, ',');

        String strToFormat = StringUtils.substringBetween(args[0], "'");
        int i = 0;
        while (strToFormat.contains("{}")) {
            strToFormat = strToFormat.replaceFirst(Pattern.quote("{}"), "{" + i++ + "}");
        }
        String[] remainingArgs = ArrayUtils.subarray(args, 1, args.length);
        Object[] fixedRemainingArgs = enrichArgs(remainingArgs, execution);
        return MessageFormat.format(strToFormat, fixedRemainingArgs);
    }

    @NotNull
    private String removeFunctionExtras(String currentValue, String funcKeyword) {
        currentValue = currentValue.trim();
        currentValue = StringUtils.substringAfter(currentValue, funcKeyword);
        currentValue = StringUtils.removeEnd(currentValue, ")");
        return currentValue;
    }

    private Object[] enrichArgs(String[] remainingArgs, Execution execution) {
        Object[] result = new Object[remainingArgs.length];
        for (int i = 0; i < remainingArgs.length; i++) {
            String currentArg = remainingArgs[i].trim();
            if (currentArg.startsWith("$")) {
                result[i] = execution.getInput().read(JsonPath.compile(currentArg));
            } else if (currentArg.equals("null")) {
                result[i] = null;
            } else if (currentArg.startsWith("'") && currentArg.endsWith("'")) {
                result[i] = StringUtils.substringBetween(currentArg, "'");
            } else if (currentArg.contains(".")) {
                try {
                    result[i] = Double.valueOf(currentArg);
                } catch (Exception e) {
                    result[i] = currentArg;
                }
            } else {
                try {
                    result[i] = Long.valueOf(currentArg);
                } catch (Exception e) {
                    result[i] = currentArg;
                }
            }
        }
        return result;
    }

    private void enrich(Collection objects, Execution execution) {
        for (Object object : objects) {
            enrich(object, execution);
        }
    }

}