package de.neuland.jade4j.compiler;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.neuland.jade4j.expression.ExpressionHandler;
import de.neuland.jade4j.expression.JexlExpressionHandler;
import de.neuland.jade4j.util.CharacterParser;
import org.apache.commons.lang3.StringEscapeUtils;
import de.neuland.jade4j.exceptions.ExpressionException;
import de.neuland.jade4j.model.JadeModel;
import de.neuland.jade4j.parser.node.ExpressionString;
public class Utils {
public static Pattern interpolationPattern = Pattern.compile("(\\\\)?([#!])\\{");
public static CharacterParser characterParser = new CharacterParser();
public static List<Object> prepareInterpolate(String string, boolean xmlEscape) {
List<Object> result = new LinkedList<Object>();
Matcher matcher = interpolationPattern.matcher(string);
int start = 0;
while (matcher.find()) {
String before = string.substring(start, matcher.start(0));
if (xmlEscape) {
before = escapeHTML(before);
}
result.add(before);
boolean escape = matcher.group(1) != null;
String flag = matcher.group(2);
int openBrackets = 1;
boolean closingBracketFound = false;
int closingBracketIndex = matcher.end();
while (!closingBracketFound && closingBracketIndex < string.length()) {
char currentChar = string.charAt(closingBracketIndex);
if (currentChar == '{') {
openBrackets ++;
}
else if (currentChar == '}') {
openBrackets --;
if (openBrackets == 0) {
closingBracketFound = true;
}
}
closingBracketIndex++;
}
String code = string.substring(matcher.end(), closingBracketIndex -1);
if (escape) {
String escapedExpression = string.substring(matcher.start(0), closingBracketIndex).substring(1);
if (xmlEscape) {
escapedExpression = escapeHTML(escapedExpression);
}
result.add(escapedExpression);
} else {
ExpressionString expression = new ExpressionString(code);
if (flag.equals("#")) {
expression.setEscape(true);
}
result.add(expression);
}
start = closingBracketIndex;
}
String last = string.substring(start);
if (xmlEscape) {
last = escapeHTML(last);
}
result.add(last);
return result;
}
// public static String interpolate(String str,boolean interpolate){
// StringBuilder sb = new StringBuilder();
// if (interpolate) {
// Matcher matcher = Pattern.compile("(\\\\)?([#!])\\{((?:.|\\n)*)$").matcher(str);
// if(matcher.find(0))
// sb.append(str.substring(0, matcher.start()));
// if (matcher.group(1)!=null) { // escape
// sb.append(matcher.group(2) + "{");
// sb.append(matcher.group(3));
// return sb.toString();
// } else {
// String rest = matcher.group(3);
// CharacterParser.Match range = characterParser.parseMax(rest);
// String code = (matcher.group(2).equals("!") ? "" : 'jade.escape') + "((jade_interp = " + range.src + ") == null ? '' : jade_interp)";
// this.bufferExpression(code);
// sb.append(rest.substring(range.getEnd() + 1));
// return sb.toString();
// }
// }
//
// str = utils.stringify(str);
// str = str.substr(1, str.length - 2);
//
// }
public static String interpolate(List<Object> prepared, JadeModel model, ExpressionHandler expressionHandler) throws ExpressionException {
StringBuffer result = new StringBuffer();
for (Object entry : prepared) {
if (entry instanceof String) {
result.append(entry);
} else if (entry instanceof ExpressionString) {
ExpressionString expression = (ExpressionString) entry;
String stringValue = "";
String value = expressionHandler.evaluateStringExpression(expression.getValue(), model);
if (value != null) {
stringValue = value;
}
if (expression.isEscape()) {
stringValue = escapeHTML(stringValue);
}
result.append(stringValue);
}
}
return result.toString();
}
private static String escapeHTML(String string) {
return StringEscapeUtils.escapeHtml4(string);
}
public static String interpolate(String string, JadeModel model, boolean escape, ExpressionHandler expressionHandler) throws ExpressionException {
return interpolate(prepareInterpolate(string, escape), model,expressionHandler);
}
}