use of org.structr.core.parser.Expression in project structr by structr.
the class Functions method evaluate.
public static Object evaluate(final ActionContext actionContext, final GraphObject entity, final String expression) throws FrameworkException, UnlicensedException {
final String expressionWithoutNewlines = expression.replace('\n', ' ').replace('\r', ' ');
final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(expressionWithoutNewlines));
tokenizer.eolIsSignificant(true);
tokenizer.ordinaryChar('.');
tokenizer.wordChars('_', '_');
tokenizer.wordChars('.', '.');
tokenizer.wordChars('!', '!');
Expression root = new RootExpression();
Expression current = root;
Expression next = null;
String lastToken = null;
int token = 0;
int level = 0;
while (token != StreamTokenizer.TT_EOF) {
token = nextToken(tokenizer);
switch(token) {
case StreamTokenizer.TT_EOF:
break;
case StreamTokenizer.TT_EOL:
break;
case StreamTokenizer.TT_NUMBER:
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched opening bracket before NUMBER");
}
next = new ConstantExpression(tokenizer.nval);
current.add(next);
lastToken += "NUMBER";
break;
case StreamTokenizer.TT_WORD:
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched opening bracket before " + tokenizer.sval);
}
next = checkReservedWords(tokenizer.sval);
Expression previousExpression = current.getPrevious();
if (tokenizer.sval.startsWith(".") && previousExpression != null && previousExpression instanceof FunctionExpression && next instanceof ValueExpression) {
final FunctionExpression previousFunctionExpression = (FunctionExpression) previousExpression;
final ValueExpression valueExpression = (ValueExpression) next;
current.replacePrevious(new FunctionValueExpression(previousFunctionExpression, valueExpression));
} else {
current.add(next);
}
lastToken = tokenizer.sval;
break;
case '(':
if (((current == null || current instanceof RootExpression) && next == null) || current == next) {
// an additional bracket without a new function,
// this can only be an execution group.
next = new GroupExpression();
current.add(next);
}
current = next;
lastToken += "(";
level++;
break;
case ')':
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched opening bracket before " + lastToken);
}
current = current.getParent();
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched closing bracket after " + lastToken);
}
lastToken += ")";
level--;
break;
case '[':
// bind directly to the previous expression
next = new ArrayExpression();
current.add(next);
current = next;
lastToken += "[";
level++;
break;
case ']':
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched closing bracket before " + lastToken);
}
current = current.getParent();
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched closing bracket after " + lastToken);
}
lastToken += "]";
level--;
break;
case ';':
next = null;
lastToken += ";";
break;
case ',':
next = current;
lastToken += ",";
break;
default:
if (current == null) {
throw new FrameworkException(422, "Invalid expression: mismatched opening bracket before " + tokenizer.sval);
}
current.add(new ConstantExpression(tokenizer.sval));
lastToken = tokenizer.sval;
}
}
if (level > 0) {
throw new FrameworkException(422, "Invalid expression: mismatched closing bracket after " + lastToken);
}
return root.evaluate(actionContext, entity);
}
Aggregations