org.rythmengine.internal.parser.build_in.NullableExpressionParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rythm-engine Show documentation
Show all versions of rythm-engine Show documentation
A strong typed high performance Java Template engine with .Net Razor like syntax
/**
* Copyright (C) 2013-2016 The Rythm Engine project
* for LICENSE and other details see:
* https://github.com/rythmengine/rythmengine
*/
package org.rythmengine.internal.parser.build_in;
import com.stevesoft.pat.Regex;
import org.rythmengine.internal.*;
import org.rythmengine.internal.parser.CodeToken;
import org.rythmengine.internal.parser.ParserBase;
import org.rythmengine.utils.S;
import java.util.ArrayList;
import java.util.List;
/**
* Parse groovy nullable expression, e.g. @foo?.bar()?.zee
*
* Must be invoked behind invoking of the normal ExpressionParser
*
* @author luog
*/
public class NullableExpressionParser extends CaretParserFactoryBase {
@Override
public IParser create(IContext ctx) {
final IDialect dialect = ctx.getDialect();
//if (!(dialect instanceof Rythm)) throw new DialectNotSupportException(dialect.id());
return new ParserBase(ctx) {
@Override
public Token go() {
final String caret_ = dialect.a();
final Regex r1 = new Regex(String.format(patternStr1(), caret_));
final Regex r2 = new Regex(String.format(patternStr2(), caret_));
final Regex r3 = new Regex(patternStr3());
final Regex r4 = new Regex(patternStr4());
String s = remain();
String exp;
int step;
if (r1.search(s)) {
exp = r1.stringMatched(2);
step = r1.stringMatched(1).length();
} else if (r2.search(s)) {
exp = r2.stringMatched(2);
exp = S.stripBrace(exp);
step = r2.stringMatched().length();
} else {
return null;
}
exp = exp.trim();
if (!exp.contains("?")) return null; // leave it to normal expression handler
if (!r4.search(exp)) {
//raiseParseException("nullable expression can contain only expression, \"[]\", \"()\", \".\", \"?\", found: %s", exp);
return null; // the foo == null ? "bar" : foo style expression?
}
step(step);
StringBuilder curExp = new StringBuilder();
final List statements = new ArrayList();
ExtensionManager jem = ctx().getEngine().extensionManager();
while (r3.search(exp)) {
String s0 = r3.stringMatched().trim();
if (jem.isJavaExtension(s0)) break;
if (s0.endsWith("?.")) {
s0 = s0.replace("?.", "");
curExp.append(s0);
String e = curExp.toString();
curExp.append(".");
statements.add(e);
} else if (s0.endsWith(".")) {
curExp.append(s0);
}
}
//exp = exp.replaceAll("\\?", "");
//exp = exp.replaceAll("(\".*?\"|\\?)", "$1§").replaceAll("\\??§", "");
//see http://stackoverflow.com/questions/20466535
String regex = "(?s)(\"(?>[^\\\\\"]++|\\\\{2}|\\\\.)*\")|\\?";
exp = exp.replaceAll(regex, "$1");
return new CodeToken(exp, ctx()) {
@Override
public void output() {
outputExpression(statements);
}
};
}
};
}
protected String patternStr1() {
return "^(%s(([a-zA-Z_][\\w]*((?@())(?@[])?|(?@[])(?@())?)?(\\??\\.)?)+)).*";
}
protected String patternStr2() {
//return "^(%s(@?()))";
return "^(%s((?@())))";
}
protected String patternStr3() {
return "\\G([a-zA-Z_][\\w]*((?@())(?@[])?|(?@[])(?@())?)?(\\??\\.)?)";
}
protected String patternStr4() {
return "^([a-zA-Z_][\\w]*((?@())(?@[])?|(?@[])(?@())?)?(\\??\\.)?)+$";
}
}