001/*
002 * #%L
003 * Netarchivesuite - deploy
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University 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.common.utils;
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. Uses %{..} to avoid replacing ${} strings which are not our concern
030 */
031public class Template {
032        final static char MARKER = '%';
033        
034    /**
035     * Prohibit external construction for now.
036     */
037    protected Template() {
038    }
039
040    /**
041     * Takes an array of strings and returns a concatenated string with all %{...} occurrences replaced according to the
042     * env map.
043     *
044     * @param strArray array of strings to be processed with env strings
045     * @param env map of replacement strings
046     * @param bFailOnMissing throw an exception on missing replacement string or not
047     * @param separator separator to insert between lines or null
048     * @return concatenated and processed string
049     */
050    public static String untemplate(String[] strArray, Map<String, String> env, boolean bFailOnMissing, String separator) {
051        StringBuilder sb = new StringBuilder();
052        for (int i = 0; i < strArray.length; ++i) {
053            sb.append(untemplate(strArray[i], env, bFailOnMissing));
054            if (separator != null) {
055                sb.append(separator);
056            }
057        }
058        return sb.toString();
059    }
060
061    /**
062     * Takes a string and replaces all %{...} occurrences with env map strings.
063     *
064     * @param str string to be processed
065     * @param env map of replacement strings
066     * @param bFailOnMissing throw an exception on missing replacement string or not
067     * @return processed string
068     */
069    public static String untemplate(String str, Map<String, String> env, boolean bFailOnMissing) {
070        int strLen = str.length();
071        String lookupStr;
072        String replaceStr;
073        StringBuilder sb = new StringBuilder();
074        int pIdx = 0;
075        int sIdx = 0;
076        int fIdx;
077        int tIdx;
078        int c;
079        while (sIdx != -1) {
080            sIdx = str.indexOf(MARKER, pIdx);
081            if (sIdx != -1) {
082                if (sIdx + 1 < strLen) {
083                    c = str.charAt(sIdx + 1);
084                    if (c == MARKER) {
085                        sb.append(str, pIdx, sIdx);
086                        sb.append(MARKER);
087                        sIdx += 2;
088                        pIdx = sIdx;
089                    } else if (c == '{') {
090                        fIdx = sIdx + 2;
091                        tIdx = str.indexOf('}', fIdx);
092                        if (tIdx != -1) {
093                            sb.append(str, pIdx, sIdx);
094                            lookupStr = str.substring(fIdx, tIdx);
095                            replaceStr = env.get(lookupStr);
096                            if (replaceStr == null) {
097                                if (!bFailOnMissing) {
098                                    replaceStr = "";
099                                } else {
100                                    throw new IllegalArgumentException("Env is missing replacement for: " + lookupStr);
101                                }
102                            }
103                            sb.append(replaceStr);
104                            sIdx = tIdx + 1;
105                            pIdx = sIdx;
106                        } else {
107                            sb.append(str, pIdx, fIdx);
108                            sIdx = fIdx;
109                            pIdx = sIdx;
110                        }
111                    } else {
112                        sIdx = -1;
113                    }
114                } else {
115                    sIdx = -1;
116                }
117            }
118        }
119        if (strLen > pIdx) {
120            sb.append(str, pIdx, strLen);
121        }
122        return sb.toString();
123    }
124
125}