001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 */
020
021package org.nuxeo.runtime.deployment.preprocessor.template;
022
023import java.util.LinkedHashMap;
024import java.util.Map;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.common.utils.TextTemplate;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public class Template {
034
035    private static final Log log = LogFactory.getLog(Template.class);
036
037    public static final String BEGIN = "BEGIN";
038
039    public static final String END = "END";
040
041    // we should use a linked hash map to preserve the
042    // insertion order when iterating over the elements in the map
043    final LinkedHashMap<String, Part> parts;
044
045    public Template() {
046        parts = new LinkedHashMap<>();
047    }
048
049    public void addPart(String name, String text) {
050        parts.put(name, new Part(name, text));
051    }
052
053    public void update(TemplateContribution tc, Map<String, String> ctx) {
054        String content = tc.getContent();
055        content = new TextTemplate(ctx).processText(content);
056        if (tc.isAppending()) {
057            appendText(tc.getMarker(), content);
058        } else if (tc.isPrepending()) {
059            prependText(tc.getMarker(), content);
060        } else if (tc.isReplacing()) {
061            replaceText(tc.getMarker(), content);
062        }
063    }
064
065    public void appendText(String marker, String text) {
066        Part part = parts.get(marker);
067        if (part != null) {
068            part.append(text);
069        } else {
070            log.debug("Could not find marker: " + marker);
071        }
072    }
073
074    public void prependText(String marker, String text) {
075        Part part = parts.get(marker);
076        if (part != null) {
077            part.prepend(text);
078        } else {
079            log.debug("Could not find marker: " + marker);
080        }
081    }
082
083    public void replaceText(String marker, String text) {
084        Part part = parts.get(marker);
085        if (part != null) {
086            part.replace(text);
087        } else {
088            log.debug("Could not find marker: " + marker);
089        }
090    }
091
092    public String getText() {
093        StringBuilder sb = new StringBuilder();
094        for (Part part : parts.values()) {
095            sb.append(part.text);
096        }
097        return sb.toString();
098    }
099
100    static class Part {
101        public final String name; // the name of the part used in markers
102
103        public final StringBuilder text; // the text before the marker
104
105        public final int offset; // the initial length of the text
106
107        Part(String name, String text) {
108            this.name = name;
109            this.text = text == null ? new StringBuilder() : new StringBuilder(text);
110            offset = this.text.length();
111        }
112
113        public void append(String aText) {
114            text.append(aText);
115        }
116
117        public void prepend(String aText) {
118            text.insert(offset, aText);
119        }
120
121        public void replace(String aText) {
122            text.replace(offset, text.length(), aText);
123        }
124
125        public String getText() {
126            return text.toString();
127        }
128
129        public String getName() {
130            return name;
131        }
132
133    }
134
135}