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

com.github.siwenyan.common.EasyBoard Maven / Gradle / Ivy

package com.github.siwenyan.common;

import com.github.siwenyan.query.QueryBase;
import com.github.siwenyan.query.QueryExpression;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.FilenameFilter;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EasyBoard {

    public static final String OWNER_GLOBAL = "GLOBAL";

    public static final String RESERVED_NOW = "now";

    public static final String RESERVED_TODAY = "today";

    public static final String RESERVED_YESTERDAY = "yesterday";

    public static final String RESERVED_TOMORROW = "tomorrow";

    public static final String RESERVED_RANDOM = "random";

    public static final String RESERVED_RANDOM5 = "random5";

    public static final String RESERVED_RANDOM10 = "random10";

    public static final String RESERVED_CVT_DT = "cvtDt";

    public static final String RESERVED_LOWERCASE = "lowercase";

    public static final String RESERVED_UPPERCASE = "uppercase";

    public static final String PARAM_SEPARATOR = ">";

    private static Logger log = Logger.getLogger(EasyBoard.class.getName());

    private final static String REGEX_CONTAINS_VAR_EXPRESSION = ".*\\$\\{[^\\{\\}]+\\}.*";

    private final static Pattern PATTERN_STRING_VAR = Pattern.compile("(\\$\\{([^\\{\\}]+)\\})");
    private final static Pattern PATTERN_MAP_VAR = Pattern.compile("(\\$\\{([^\\{\\}\\.]+)\\.([^\\{\\}]+)\\})");

    private final static Pattern PATTERN_ESCAPE = Pattern.compile("(#\\{([^\\{\\}]+)\\})");
    private final static Pattern PATTERN_ESCAPE_MAP = Pattern.compile("(#\\{([^\\{\\}\\.]+)\\.([^\\{\\}]+)\\})");

    private final Properties conf;

    private Map>> mapVars = new LinkedHashMap>>();
    private Map> stringVars = new LinkedHashMap>();
    private final Map> registeredEvaluators = new HashMap<>();

    private String outputPath;

    private String[] protectedKeys = new String[]{};

    public EasyBoard(Properties conf) {
        this.conf = conf;
        initEscape();
    }

    public void initEscape() {
        putString(OWNER_GLOBAL, "COMMA", ",");
        putString(OWNER_GLOBAL, "DASH", "-");
        putString(OWNER_GLOBAL, "QUOTE", "\"");
        putString(OWNER_GLOBAL, "SQUOTE", "'");
    }

    public List> resolve(String owner, List> maps) {
        List> m = new ArrayList>(maps.size());
        for (Map map : maps) {
            m.add(resolve(owner, map));
        }
        return m;
    }

    public String[] resolveArray(String owner, String[] arrayOfStrings) {
        String[] result = new String[arrayOfStrings.length];

        for (int i = 0; i < arrayOfStrings.length; i++) {
            result[i] = resolve(owner, arrayOfStrings[i]);
        }

        return result;
    }

    public List resolveStringList(String owner, List list) {
        List l = new ArrayList<>(list.size());
        for (String s : list) {
            l.add(resolve(owner, s));
        }
        return l;
    }

    // resolve all var-expression values in map
    public Map resolve(String owner, Map map) {
        Map m = new LinkedHashMap<>(map.size());
        for (String key : map.keySet()) {
            String resolvedKey = resolve(owner, key);
            String resolvedValue = resolve(owner, map.get(key));
            m.put(resolvedKey, resolvedValue);
        }

        return m;
    }

    // return the first non-null result resolving a list of var-expressions
    public String resolve(String owner, String... expressions) {
        if (null == expressions || 0 == expressions.length) {
            throw new RuntimeException("Nothing to resolve.");
        }

        for (String expression : expressions) {
            if (null == expression) {
                continue;
            } else {

                String result = resolveOne(owner, expression);
                if (null != result) {
                    return result;
                }
            }
        }
        return null;
    }

    // resolve all var-expression's in a string like "bla... ${var1} bla... ${t1.stage} bla..."
    // returns null if var-expression invalid
    public String resolveOne(String owner, String expression) {
        String s0 = expression;
        expression = escape(expression);
        List protectedKeyList = Arrays.asList(protectedKeys);

        Pattern pattern = PATTERN_STRING_VAR;
        Matcher matcher = pattern.matcher(expression);
        if (matcher.find()) {
            String key = matcher.group(2);
            if (protectedKeyList.contains(key)) {
                throw new RuntimeException("Not able to resolve protected key: " + key);
            }
            String value = getString(owner, key);
            if (null != value) {
                return resolveOne(owner, matcher.replaceFirst(value.replace("$", "_DOLLAR_").replace("\\", "_SLASH_")).replace("_DOLLAR_", "$").replace("_SLASH_", "\\"));
            }
        }

        pattern = PATTERN_MAP_VAR;
        matcher = pattern.matcher(expression);
        if (matcher.find()) {
            String key = matcher.group(2);
            Map map = getMap(owner, key);
            if (null == map) {
                log.warn("Undefined map variable: " + key + " in expression " + s0);
                return null;
            }

            String field = matcher.group(3);
            String value = map.get(field);
            if (null != value) {
                return resolveOne(owner, matcher.replaceFirst(value.replace("$", "_DOLLAR_").replace("\\", "_SLASH_")).replace("_DOLLAR_", "$").replace("_SLASH_", "\\"));
            } else {
                log.error("Undefined field: " + field + " map object " + key + " in expression " + s0);
                return null;
            }
        }

        return escape(expression);

    }

    // resolve all var-expression's in a string like "bla... #{var1} bla... #{t1.stage} bla..."
    // returns null if var-expression invalid
    public String escape(String expression) {
        String s0 = expression;

        Pattern pattern = PATTERN_ESCAPE;
        Matcher matcher = pattern.matcher(expression);
        if (matcher.find()) {
            String key = matcher.group(2);
            String value = getString(OWNER_GLOBAL, key);
            if (null == value) {
                log.error("Undefined special string: " + key + " in expression " + s0);
                return null;
            }
            return escape(matcher.replaceFirst(value.replace("$", "_DOLLAR_").replace("\\", "_SLASH_")).replace("_DOLLAR_", "$").replace("_SLASH_", "\\"));
        }

        pattern = PATTERN_ESCAPE_MAP;
        matcher = pattern.matcher(expression);
        if (matcher.find()) {
            String key = matcher.group(2);
            Map map = getMap(OWNER_GLOBAL, key);
            if (null == map) {
                log.error("Undefined special map: " + key + " in expression " + s0);
                return null;
            }

            String field = matcher.group(3);
            String value = map.get(field);
            if (null != value) {
                return escape(matcher.replaceFirst(value.replace("$", "_DOLLAR_").replace("\\", "_SLASH_")).replace("_DOLLAR_", "$").replace("_SLASH_", "\\"));
            } else {
                log.error("Undefined special string: " + field + " map object " + key + " in expression " + s0);
                return null;
            }
        }

        return expression;

    }

    public void putAll(Map easyBoardObject, List> daoRows, String prefix, Set ignore) {
        if (0 == daoRows.size()) {
            return;
        }

        prefix = null == prefix ? "" : prefix.trim();
        if (1 == daoRows.size()) {
            for (String key : daoRows.get(0).keySet()) {
                if (!ignore.contains(key)) {
                    easyBoardObject.put(prefix + key, daoRows.get(0).get(key).toString());
                }
            }
        } else {
            for (int i = 0; i < daoRows.size(); i++) {
                Map row = daoRows.get(i);
                for (String key : row.keySet()) {
                    if (!ignore.contains(key)) {
                        easyBoardObject.put(prefix + key + "_" + i, row.get(key).toString());
                    }
                }
            }
        }
    }

    public Map snapshot(Map> group) {
        Map groupPhoto = new TreeMap<>();
        for (String name : group.keySet()) {
            Map map = group.get(name);
            for (String key : map.keySet()) {
                String name_key = name + "-" + key;
                groupPhoto.put(name_key, map.get(key));
            }
        }
        return groupPhoto;
    }

    public void storeMaps(String owner, String prefix, Map> maps) {
        storeMaps(owner, prefix, maps, false);
    }

    public void storeMaps(String owner, String prefix, Map> maps, boolean withRestore) {
        if (null == maps) {
            return;
        }
        if (!StringTools.isEmpty(prefix)) {
            putString(owner, prefix + "_rows", "" + maps.size());
            putString(owner, prefix + "_keys", maps.keySet().toString());
            putList(owner, prefix + "_keyList", new ArrayList<>(maps.keySet()));
        }
        String mapName = null;
        for (String key : maps.keySet()) {
            mapName = StringTools.isEmpty(prefix) ? key : prefix + "_" + key;
            putMap(owner, mapName, maps.get(key), true, withRestore);
        }
    }

    public boolean evaluate(String owner, String conditionExpression) {
        if (conditionExpression.matches(".+\\s+is\\s+empty\\s*")) {
            String[] p = conditionExpression.split("\\s+is\\s+empty", 2);
            return StringTools.isEmpty(resolve(owner, p[0]));
        } else if (conditionExpression.matches(".+\\s+is\\s+not\\s+empty\\s*")) {
            String[] p = conditionExpression.split("\\s+is\\s+not\\s+empty", 2);
            return !StringTools.isEmpty(resolve(owner, p[0]));
        } else if (conditionExpression.matches(".+\\s+is\\s+greater\\s+than\\s+.+")) {
            String[] p = conditionExpression.split("\\s+is\\s+greater\\s+than\\s+", 2);
            String p0 = resolve(owner, p[0]).trim();
            String p1 = resolve(owner, p[1]).trim();
            int left = Integer.parseInt(p0);
            int right = Integer.parseInt(p1);
            return left > right;
        } else if (conditionExpression.matches(".+\\s+is\\s+equal\\s+or\\s+greater\\s+than\\s+.+")) {
            String[] p = conditionExpression.split("\\s+is\\s+equal\\s+or\\s+greater\\s+than\\s+", 2);
            String p0 = resolve(owner, p[0]).trim();
            String p1 = resolve(owner, p[1]).trim();
            int left = Integer.parseInt(p0);
            int right = Integer.parseInt(p1);
            return left >= right;
        } else if (conditionExpression.matches(".+\\s+matches\\s+.+")) {
            String[] p = conditionExpression.split("\\s+matches\\s+", 2);
            String p0 = resolve(owner, p[0]).trim();
            String p1 = resolve(owner, p[1]).trim();
            return p0.equals(p1) || p0.matches(p1);
        } else if (conditionExpression.matches(".+\\s+does\\s+not\\s+matche\\s+.+")) {
            String[] p = conditionExpression.split("\\s+does\\s+not\\s+matche\\s+", 2);
            String p0 = resolve(owner, p[0]).trim();
            String p1 = resolve(owner, p[1]).trim();
            return !(p0.equals(p1) || p0.matches(p1));
        } else if (conditionExpression.matches(".+\\s+is\\s+not\\s.+")) {
            //"a is not b" --> [a, b]
            //"a is not b is not c" --> [a, b is c]
            String[] p = conditionExpression.split("\\s+is\\s+not\\s+", 2);
            String p0 = resolve(owner, p[0]);
            String p1 = resolve(owner, p[1]);
            return !p0.equals(p1);
        } else if (conditionExpression.matches(".+\\s+is\\s.+")) {
            //"a is b" --> [a, b]
            //"a is b is c" --> [a, b is c]
            String[] p = conditionExpression.split("\\s+is\\s+", 2);
            String p0 = resolve(owner, p[0]);
            String p1 = resolve(owner, p[1]);
            return p0.equals(p1);
        } else {
            throw new ImmediateAbortException("Unknown expression: " + conditionExpression);
        }
    }

    public List> resolveListOfStringList(String owner, List> listOfStringList) {
        List> result = new ArrayList<>(listOfStringList.size());
        for (List l : listOfStringList) {
            result.add(resolveStringList(owner, l));
        }
        return result;
    }

    public void removeOwner(String owner) {
        this.mapVars.remove(owner);
        this.stringVars.remove(owner);
    }

    public String putString(String owner, String key, String value) {
        if (null == key || key.trim().isEmpty()) {
            throw new RuntimeException("String variable name is empty or is resolved as empty: " + key);
        }
        if (!this.stringVars.containsKey(owner)) {
            this.stringVars.put(owner, new LinkedHashMap());
        }
        Sys.tryLoggingJsonString(key, value);

        return this.stringVars.get(owner).put(key, value);
    }

    public Map putMap(String owner, String key, Map value) {
        return putMap(owner, key, value, true, false);
    }

    public Map putMap(String owner, String key, Map value, boolean withLogging, boolean withRestore) {
        if (null == key || key.trim().isEmpty()) {
            throw new RuntimeException("Map variable name is empty or is resolved as empty: " + key);
        }
        if (!this.mapVars.containsKey(owner)) {
            this.mapVars.put(owner, newMapDb(owner));
        }
        Map previousMap = this.mapVars.get(owner).put(key, value);

        if (withLogging) {
            Sys.tryLoggingJsonString(key, value);
        }

        if (withRestore) {
            try {
                //for restore
                String jsonString = EasyJson.prettyJson(value);
                Sys.tryOutputFile(key + ".json", jsonString);
            } catch (Exception e) {
                log.debug(e.getMessage());
                // do nothing
            }
        }
        return previousMap;
    }

    public String getString(String owner, String key) {
        switch (key) {
            case RESERVED_NOW:
                //${now}
                ZonedDateTime now = ZonedDateTime.now();
                return DateTimeTools.calcFormat(now, 0, ChronoUnit.DAYS, DateTimeTools.mmDdYyyyHMmA);
            case RESERVED_TODAY:
                //${today}
                return DateTimeTools.mmDdYyyy();
            case RESERVED_YESTERDAY:
                //${yesterday}
                return DateTimeTools.mmDdYyyyYesterday();
            case RESERVED_TOMORROW:
                //${tomorrow}
                return DateTimeTools.mmDdYyyyTomorrow();
            case RESERVED_RANDOM10:
                //${random10}
                return StringTools.randomDigits(10);
            case RESERVED_RANDOM5:
                //${random5}
                return StringTools.randomDigits(5);
        }

        if (key.contains(PARAM_SEPARATOR)) {
            String[] p = key.split(PARAM_SEPARATOR, 2);
            ZonedDateTime now = ZonedDateTime.now();
            switch (p[0]) {
                case RESERVED_TODAY:
                    if (p[1].contains(PARAM_SEPARATOR)) {
                        //${today>-3>MM-dd-yyyy}
                        String[] pp = p[1].split(PARAM_SEPARATOR, 2);
                        int days = Integer.parseInt(pp[0]);
                        return DateTimeTools.calcFormat(now, days, ChronoUnit.DAYS, pp[1]);
                    } else {
                        //${today>MM-dd-yyyy}
                        return DateTimeTools.calcFormat(now, 0, ChronoUnit.DAYS, p[1]);
                    }
                case RESERVED_YESTERDAY:
                    //${yesterday>MM-dd-yyyy}
                    return DateTimeTools.calcFormat(now, -1, ChronoUnit.DAYS, p[1]);
                case RESERVED_TOMORROW:
                    //${tomorrow>MM-dd-yyyy}
                    return DateTimeTools.calcFormat(now, 1, ChronoUnit.DAYS, p[1]);
                case RESERVED_NOW:
                    if (p[1].contains(PARAM_SEPARATOR)) {
                        //${now>-3d>MM-dd-yyyy h:mm a}
                        //${now>+3h>MM-dd-yyyy H:mm}
                        //${now>30m>yyyy-MM-dd'T'HH:mm:ss.SSSZ}
                        String[] pp = p[1].split(PARAM_SEPARATOR, 2);
                        long seconds = DateTimeTools.toSeconds(pp[0]);
                        return DateTimeTools.calcFormat(now, seconds, ChronoUnit.SECONDS, pp[1]);
                    } else {
                        //${now>MM-dd-yyyy h:mm a}
                        return DateTimeTools.calcFormat(now, 0, ChronoUnit.SECONDS, p[1]);
                    }
                case RESERVED_RANDOM:
                    //${radom>7}
                    return StringTools.randomDigits(Integer.parseInt(p[1]));
                case RESERVED_CVT_DT: {
                    String[] pp = p[1].split(PARAM_SEPARATOR);
                    if (5 == pp.length) {
                        //${cvtDt>09-17-2019 9:40 PM>MM-dd-yyyy h:mm a>${timeZoneDb}>MM-dd-yyyy h:mm a>${timeZone}}
                        ZonedDateTime zdt = ZonedDateTime.parse(pp[0], DateTimeFormatter.ofPattern(pp[1]).withZone(ZoneId.of(pp[2])));
                        return DateTimeFormatter.ofPattern(pp[3]).withZone(ZoneId.of(pp[4])).format(zdt);
                    } else if (6 == pp.length) {
                        //${cvtDt>09-17-2019 9:40 PM>MM-dd-yyyy h:mm a>${timeZoneDb}>-3d>MM-dd-yyyy h:mm a>${timeZone}}
                        //${cvtDt>09-17-2019 9:40 PM>MM-dd-yyyy h:mm a>${timeZoneDb}>+3h>MM-dd-yyyy h:mm a>${timeZone}}
                        //${cvtDt>09-17-2019 9:40 PM>MM-dd-yyyy h:mm a>${timeZoneDb}>30m>MM-dd-yyyy h:mm a>${timeZone}}
                        ZonedDateTime zdt = ZonedDateTime.parse(pp[0], DateTimeFormatter.ofPattern(pp[1]).withZone(ZoneId.of(pp[2])));
                        long seconds = DateTimeTools.toSeconds(pp[3]);
                        ZonedDateTime newZdt = zdt.plus(seconds, ChronoUnit.SECONDS);
                        return DateTimeFormatter.ofPattern(pp[4]).withZone(ZoneId.of(pp[5])).format(newZdt);
                    }
                }
                case RESERVED_LOWERCASE:
                    return p[1].toLowerCase();
                case RESERVED_UPPERCASE:
                    return p[1].toUpperCase();
                default: {
                    if (2 == p.length) {
                        try {
                            String queryExpression = resolveOne(owner, p[1]);
                            QueryExpression qe = new QueryExpression(queryExpression);

                            String sourceString = resolveOne(owner, p[0]);
                            String sourceString1 = getOneString(owner, sourceString);
                            if (!StringTools.isEmpty(sourceString1)) {
                                sourceString = resolveOne(owner, sourceString1);
                            }
                            QueryBase q = qe.compile(sourceString);
                            Object result = q.query(qe.getQuery());
                            if (null != result) {
                                return EasyJson.onelineJson(result);
                            }
                        } catch (Exception e) {
                            // do nothing
                        }
                    }
                    //do nothing
                }
            }
        }

        return getOneString(owner, key);
    }

    public String getOneString(String owner, String key) {
        String[] p = key.split("!!", 2);
        if (2 == p.length) {
            IEvaluator evaluator = null;
            if (registeredEvaluators.containsKey(owner)) {
                evaluator = registeredEvaluators.get(owner).get(p[0]);
            }
            if (null == evaluator) {
                return getOneStringSimple(owner, key);
            } else {
                try {
                    if (evaluator.evaluate()) {
                        return getOneStringSimple(owner, p[1]);
                    } else {
                        return null;
                    }
                } catch (Exception e) {
                    return null;
                }
            }
        } else {
            return getOneStringSimple(owner, key);
        }
    }

    private String getOneStringSimple(String owner, String key) {
        String s = this.stringVars.containsKey(owner) ? this.stringVars.get(owner).get(key) : null;
        if (null == s) {
            s = this.stringVars.containsKey(OWNER_GLOBAL) ? this.stringVars.get(OWNER_GLOBAL).get(key) : null;
            if (null == s) {
                s = conf.getProperty(key, null);
            }
        }

        return s;
    }

    public Map getMap(String owner, String key) {
        String[] p = key.split("!!", 2);
        if (2 == p.length) {
            IEvaluator evaluator = null;
            if (registeredEvaluators.containsKey(owner)) {
                evaluator = registeredEvaluators.get(owner).get(p[0]);
            }
            if (null == evaluator) {
                return getMapSimple(owner, key);
            } else {
                try {
                    if (evaluator.evaluate()) {
                        return getMapSimple(owner, p[1]);
                    } else {
                        return null;
                    }
                } catch (Exception e) {
                    return null;
                }
            }
        } else {
            return getMapSimple(owner, key);
        }
    }

    public Map getMapSimple(String owner, String key) {
        Map map = null;
        if (this.mapVars.containsKey(owner)) {
            map = this.mapVars.get(owner).get(key);
        }
        if (null == map) {
            if (this.mapVars.containsKey(OWNER_GLOBAL)) {
                map = this.mapVars.get(OWNER_GLOBAL).get(key);
            } else {
                map = null;
            }
        }
        return map;
    }

    public Map getMapAsObjectByString(String owner, String key) {
        Map map = getMap(owner, key);
        Map objectByString = new LinkedHashMap<>(map.size());
        for (String k : map.keySet()) {
            objectByString.put(k, map.get(k));
        }
        return objectByString;
    }

    public String jsonMapVars(String owner) {
        if (!mapVars.containsKey(owner)) {
            return "Empty";
        }
        Map> vars = new TreeMap<>(mapVars.get(owner));
        for (String mapName : vars.keySet()) {
            vars.put(mapName, protect(vars.get(mapName)));
        }
        return EasyJson.prettyJson(vars);
    }

    public String jsonStringVars(String owner) {
        if (!stringVars.containsKey(owner)) {
            return "Empty";
        }
        Map map = protect(stringVars.get(owner));
        Map vars = new TreeMap<>(map);
        return EasyJson.prettyJson(vars);
    }

    public Map protect(Map map) {
        Map result = new LinkedHashMap<>(map);
        for (String protectedKey : this.protectedKeys) {
            for (String key : result.keySet()) {
                if (key.contains(protectedKey.trim())) {
                    result.put(key, "******");
                }
            }
        }
        return result;
    }

    public List protect(List list) {
        List protectedList = new ArrayList<>(list);
        for (String protectedKey : this.protectedKeys) {
            for (int i = 0; i < protectedList.size(); i++) {
                String s = protectedList.get(i);
                if (s.contains(protectedKey.trim())) {
                    protectedList.set(i, "******");
                }
            }
        }
        return protectedList;
    }

    public void mergeMapVars(String owner, Map>> mapVars1) {
        if (!this.mapVars.containsKey(owner)) {
            this.mapVars.put(owner, newMapDb(owner));
        }
        Map> mapVarsTo = this.mapVars.get(owner);
        for (String ownerFrom : mapVars1.keySet()) {
            Map> mapVarsFrom = mapVars1.get(ownerFrom);
            mapVarsTo.putAll(mapVarsFrom);
        }
    }

    public void mergeStringVars(String owner, Map> stringVars1) {
        if (!this.stringVars.containsKey(owner)) {
            this.stringVars.put(owner, new LinkedHashMap<>());
        }
        Map stringVarsTo = this.stringVars.get(owner);
        for (String ownerFrom : stringVars1.keySet()) {
            Map stringVarsFrom = stringVars1.get(owner);
            stringVarsTo.putAll(stringVarsFrom);
        }
    }

    public Set getMapVars(String owner) {
        return this.mapVars.get(owner).keySet();
    }

    public boolean containsMap(String owner, String key) {
        return this.mapVars.containsKey(owner) && this.mapVars.get(owner).containsKey(key);
    }

    public boolean containsString(String owner, String key) {
        return this.stringVars.containsKey(owner) && this.stringVars.get(owner).containsKey(key);
    }

    public void register(Properties prop) {
        register(OWNER_GLOBAL, prop);
    }

    public void register(String owner, Properties properties) {
        owner = null == owner ? OWNER_GLOBAL : owner;
        for (String key : properties.stringPropertyNames()) {
            String value0 = properties.getProperty(key);
            putString(owner, key, value0);
        }
    }

    public IEvaluator registerEvaluator(String owner, String name, IEvaluator evaluator) {
        if (StringTools.isEmpty(name) || null == evaluator) {
            return null;
        } else {
            if (!registeredEvaluators.containsKey(owner)) {
                registeredEvaluators.put(owner, new HashMap<>());
            }
            return registeredEvaluators.get(owner).put(name, evaluator);
        }
    }

    public IEvaluator unregisterEvaluator(String owner, String name) {
        if (StringTools.isEmpty(name) || !registeredEvaluators.containsKey(owner)) {
            return null;
        } else {
            return registeredEvaluators.get(owner).remove(name);
        }
    }

    public List> combine(String owner, String prefix) {
        try {
            int rows = Integer.parseInt(this.getString(owner, prefix + "_rows"));
            List> maps = new ArrayList<>(rows);
            for (int i = 0; i < rows; i++) {
                maps.add(this.getMap(owner, prefix + "_" + (i + 1)));
            }
            return maps;
        } catch (Exception e) {
            Sys.out.pl("Missing " + prefix + "_rows");
            Map map1 = this.getMap(owner, prefix);
            if (null == map1) {
                throw new ImmediateAbortException("Missing map var: " + prefix);
            } else {
                List> maps = new ArrayList<>(1);
                maps.add(map1);
                return maps;
            }
        }
    }

    public void putList(String owner, String listName, List list) {
        Map map = new LinkedHashMap<>(list.size());
        for (int i = 0; i < list.size(); i++) {
            map.put(i + "", list.get(i));
        }
        putMap(owner, listName, map);
        putString(owner, listName + "_rows", list.size() + "");
    }

    public List getList(String owner, String listName) {
        Map map = getMap(owner, listName);
        List list = new ArrayList<>(map.size());
        for (String index : map.keySet()) {
            list.add(map.get(index));
        }
        return list;
    }

    public void removeMap(String owner, String mapVarName) {
        Map> maps = mapVars.get(owner);
        if (null != maps) {
            maps.remove(mapVarName);
        }
    }

    public void removeAll(String owner, String regex) {
        try {
            if (stringVars.containsKey(owner)) {
                log.warn("Clearing strings: " + owner + "." + regex);
                DataTableTools.removeAll(stringVars.get(owner), regex);
            }
            if (mapVars.containsKey(owner)) {
                log.warn("Clearing maps: " + owner + "." + regex);
                DataTableTools.removeAll(mapVars.get(owner), regex);
                File outputDir = new File(getOutputPath());
                File[] files = outputDir.listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        return name.matches(regex);
                    }
                });
                for (File f : files) {
                    log.warn("Clearing file: " + f);
                    FileUtils.forceDelete(f);
                }
            }
        } catch (Exception e) {
            log.warn("Unable to clear: " + e.getMessage());
        }
    }

    public String getOutputPath() {
        if (StringTools.isEmpty(outputPath)) {
            return Sys.dir();
        }
        return outputPath;
    }

    public void setOutputPath(String outputPath) {
        this.outputPath = outputPath;
    }

    public void setProtectedKeys(String[] protectedKeys) {
        this.protectedKeys = protectedKeys;
    }

    public String[] getProtectedKeys() {
        return this.protectedKeys;
    }

    public boolean combineOwners(String targetOwner, String ownerRegex) {
        if (StringTools.isEmpty(targetOwner)) {
            return false;
        }

        Map> swapStringVars = DataTableTools.removeAll(stringVars, ownerRegex);
        if (null != swapStringVars && swapStringVars.size() > 0) {
            if (!stringVars.containsKey(targetOwner)) {
                stringVars.put(targetOwner, new LinkedHashMap<>());
            }
            for (String oldOwner : swapStringVars.keySet()) {
                stringVars.get(targetOwner).putAll(swapStringVars.get(oldOwner));
            }
        }

        Map>> swapMapVars = DataTableTools.removeAll(mapVars, ownerRegex);
        if (null != swapMapVars && swapMapVars.size() > 0) {
            if (!mapVars.containsKey(targetOwner)) {
                mapVars.put(targetOwner, new LinkedHashMap<>());
            }
            for (String oldOwner : swapStringVars.keySet()) {
                mapVars.get(targetOwner).putAll(swapMapVars.get(oldOwner));
            }
        }
        return true;
    }

    private Map> newMapDb(String owner) {
        return new LinkedHashMap<>();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy