001/*
002 * #%L
003 * Netarchivesuite - deploy
004 * %%
005 * Copyright (C) 2005 - 2018 The Royal Danish Library, 
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.deploy;
024
025import java.util.Map;
026
027/**
028 * Simple template engine functions that replaces ${...} in an array of strings or a single string. Error handling can
029 * be deduced from the unit test.
030 */
031public class Template {
032
033    /**
034     * Prohibit external construction for now.
035     */
036    protected Template() {
037    }
038
039    /**
040     * Takes an array of strings and returns a concatenated string with all ${...} occurrences replaced according to the
041     * env map.
042     *
043     * @param strArray array of strings to be processed with env strings
044     * @param env map of replacement strings
045     * @param bFailOnMissing throw an exception on missing replacement string or not
046     * @param separator separator to insert between lines or null
047     * @return concatenated and processed string
048     */
049    public static String untemplate(String[] strArray, Map<String, String> env, boolean bFailOnMissing, String separator) {
050        StringBuilder sb = new StringBuilder();
051        for (int i = 0; i < strArray.length; ++i) {
052            sb.append(untemplate(strArray[i], env, bFailOnMissing));
053            if (separator != null) {
054                sb.append(separator);
055            }
056        }
057        return sb.toString();
058    }
059
060    /**
061     * Takes a string and replaces all ${...} occurrences with env map strings.
062     *
063     * @param str string to be processed
064     * @param env map of replacement strings
065     * @param bFailOnMissing throw an exception on missing replacement string or not
066     * @return processed string
067     */
068    public static String untemplate(String str, Map<String, String> env, boolean bFailOnMissing) {
069        int strLen = str.length();
070        String lookupStr;
071        String replaceStr;
072        StringBuilder sb = new StringBuilder();
073        int pIdx = 0;
074        int sIdx = 0;
075        int fIdx;
076        int tIdx;
077        int c;
078        while (sIdx != -1) {
079            sIdx = str.indexOf('$', pIdx);
080            if (sIdx != -1) {
081                if (sIdx + 1 < strLen) {
082                    c = str.charAt(sIdx + 1);
083                    if (c == '$') {
084                        sb.append(str, pIdx, sIdx);
085                        sb.append('$');
086                        sIdx += 2;
087                        pIdx = sIdx;
088                    } else if (c == '{') {
089                        fIdx = sIdx + 2;
090                        tIdx = str.indexOf('}', fIdx);
091                        if (tIdx != -1) {
092                            sb.append(str, pIdx, sIdx);
093                            lookupStr = str.substring(fIdx, tIdx);
094                            replaceStr = env.get(lookupStr);
095                            if (replaceStr == null) {
096                                if (!bFailOnMissing) {
097                                    replaceStr = "";
098                                } else {
099                                    throw new IllegalArgumentException("Env is missing replacement for: " + lookupStr);
100                                }
101                            }
102                            sb.append(replaceStr);
103                            sIdx = tIdx + 1;
104                            pIdx = sIdx;
105                        } else {
106                            sb.append(str, pIdx, fIdx);
107                            sIdx = fIdx;
108                            pIdx = sIdx;
109                        }
110                    } else {
111                        sIdx = -1;
112                    }
113                } else {
114                    sIdx = -1;
115                }
116            }
117        }
118        if (strLen > pIdx) {
119            sb.append(str, pIdx, strLen);
120        }
121        return sb.toString();
122    }
123
124}