/*******************************************************************************
* Copyright (c) 2016 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.util.template;
/**
* Implements a simple Templating language and substitution algorithm.
* <p>
* A template is a string containing template variables of the for '%x' where
* x is any single character other than '%'.
* <p>
* A '%' can be escaped by preceding by repeating it. I.e. '%%' in the template
* expands to a single '%' in the output.
* <p>
* A '%' that occurs at the end of the template is not substituted (i.e. it is automatically
* 'escaped'.
* <p>
* If a template variable is not bound (i.e. {@link TemplateEnv} returns null for it) then it is
* not substituted (the variable just remains in the output string unchanged).
*
* @author Kris De Volder
*/
public class SimpleTemplate implements Template {
/**
* A template variable is a single character preceded by this character.
*/
private final char VAR_CHAR = '%';
private String pattern;
public SimpleTemplate(String pattern) {
this.pattern = pattern;
}
@Override
public String render(TemplateEnv env) {
int len = pattern.length();
int nextChar = 0; //position of next input char to read from the pattern.
StringBuilder output = new StringBuilder();
while (nextChar<len) {
int nextVarAt = pattern.indexOf(VAR_CHAR, nextChar);
if (nextVarAt>=0) {
output.append(pattern.substring(nextChar, nextVarAt));
char varName = getVarName(nextVarAt);
output.append(getValue(varName, env));
//next char should be right after the processed var, and the var is something like "%u"
nextChar = nextVarAt+2;
} else {
//no more vars
output.append(pattern.substring(nextChar));
nextChar = len;
}
}
return output.toString();
}
private Object getValue(char varName, TemplateEnv env) {
if (varName==VAR_CHAR) {
//its not actually a real var, but an escaped '%'
return VAR_CHAR;
}
String resolved = env.getTemplateVar(varName);
return resolved!=null?resolved:new String(new char[]{VAR_CHAR, varName});
}
private char getVarName(int varPos) {
int namePos = varPos+1;
//If there's nothing after a '%' then treat it the same as a escaped '%' (rather than blowing up)
return namePos < pattern.length() ? pattern.charAt(namePos) : VAR_CHAR;
}
}