use of org.apache.camel.language.simple.types.SimpleToken in project camel by apache.
the class SimpleFunctionStart method doCreateCompositeExpression.
private Expression doCreateCompositeExpression(final String expression) {
final SimpleToken token = getToken();
return new Expression() {
@Override
public <T> T evaluate(Exchange exchange, Class<T> type) {
StringBuilder sb = new StringBuilder();
boolean quoteEmbeddedFunctions = false;
// we need to concat the block so we have the expression
for (SimpleNode child : block.getChildren()) {
// whether a nested function should be lazy evaluated or not
boolean lazy = true;
if (child instanceof SimpleFunctionStart) {
lazy = ((SimpleFunctionStart) child).lazyEval(child);
}
if (child instanceof LiteralNode) {
String text = ((LiteralNode) child).getText();
sb.append(text);
quoteEmbeddedFunctions |= ((LiteralNode) child).quoteEmbeddedNodes();
// if its quoted literal then embed that as text
} else if (!lazy || child instanceof SingleQuoteStart || child instanceof DoubleQuoteStart) {
try {
// pass in null when we evaluate the nested expressions
Expression nested = child.createExpression(null);
String text = nested.evaluate(exchange, String.class);
if (text != null) {
if (quoteEmbeddedFunctions && !StringHelper.isQuoted(text)) {
sb.append("'").append(text).append("'");
} else {
sb.append(text);
}
}
} catch (SimpleParserException e) {
// must rethrow parser exception as illegal syntax with details about the location
throw new SimpleIllegalSyntaxException(expression, e.getIndex(), e.getMessage(), e);
}
// if its an inlined function then embed that function as text so it can be evaluated lazy
} else if (child instanceof SimpleFunctionStart) {
sb.append(child);
}
}
// we have now concat the block as a String which contains the function expression
// which we then need to evaluate as a function
String exp = sb.toString();
SimpleFunctionExpression function = new SimpleFunctionExpression(token);
function.addText(exp);
try {
return function.createExpression(exp).evaluate(exchange, type);
} catch (SimpleParserException e) {
// must rethrow parser exception as illegal syntax with details about the location
throw new SimpleIllegalSyntaxException(expression, e.getIndex(), e.getMessage(), e);
}
}
@Override
public String toString() {
return expression;
}
};
}
use of org.apache.camel.language.simple.types.SimpleToken in project camel by apache.
the class SimpleBackwardsCompatibleParser method doParseExpression.
private static Expression doParseExpression(String expression, boolean allowEscape) {
// should have no function tokens
for (int i = 0; i < expression.length(); i++) {
SimpleToken token = SimpleTokenizer.nextToken(expression, i, allowEscape, TokenType.functionStart, TokenType.functionEnd);
if (token.getType().getType() == TokenType.functionStart || token.getType().getType() == TokenType.functionEnd) {
return null;
}
}
// okay there is no function tokens, then try to parse it as a simple function expression
SimpleToken token = new SimpleToken(new SimpleTokenType(TokenType.functionStart, expression), 0);
SimpleFunctionExpression function = new SimpleFunctionExpression(token);
function.addText(expression);
return function.createExpression(expression, false);
}
use of org.apache.camel.language.simple.types.SimpleToken in project camel by apache.
the class SimpleExpressionParser method parseAndCreateAstModel.
protected void parseAndCreateAstModel() {
// we loop the tokens and create a sequence of ast nodes
// counter to keep track of number of functions in the tokens
AtomicInteger functions = new AtomicInteger();
LiteralNode imageToken = null;
for (SimpleToken token : tokens) {
// break if eol
if (token.getType().isEol()) {
break;
}
// create a node from the token
SimpleNode node = createNode(token, functions);
if (node != null) {
// a new token was created so the current image token need to be added first
if (imageToken != null) {
nodes.add(imageToken);
imageToken = null;
}
// and then add the created node
nodes.add(node);
// continue to next
continue;
}
// which we need to add together in the same image
if (imageToken == null) {
imageToken = new LiteralExpression(token);
}
imageToken.addText(token.getText());
}
// append any leftover image tokens (when we reached eol)
if (imageToken != null) {
nodes.add(imageToken);
}
}
use of org.apache.camel.language.simple.types.SimpleToken in project camel by apache.
the class SimplePredicateParser method parseTokensAndCreateNodes.
/**
* Parses the tokens and crates the AST nodes.
* <p/>
* After the initial parsing of the input (input -> tokens) then we
* parse again (tokens -> ast).
* <p/>
* In this parsing the balance of the blocks is checked, so that each block has a matching
* start and end token. For example a single quote block, or a function block etc.
*/
protected void parseTokensAndCreateNodes() {
// we loop the tokens and create a sequence of ast nodes
// we need to keep a bit of state for keeping track of single and double quotes
// which need to be balanced and have matching start/end pairs
SimpleNode lastSingle = null;
SimpleNode lastDouble = null;
SimpleNode lastFunction = null;
AtomicBoolean startSingle = new AtomicBoolean(false);
AtomicBoolean startDouble = new AtomicBoolean(false);
AtomicBoolean startFunction = new AtomicBoolean(false);
LiteralNode imageToken = null;
for (SimpleToken token : tokens) {
// break if eol
if (token.getType().isEol()) {
break;
}
// create a node from the token
SimpleNode node = createNode(token, startSingle, startDouble, startFunction);
if (node != null) {
// keep state of last single/double
if (node instanceof SingleQuoteStart) {
lastSingle = node;
} else if (node instanceof DoubleQuoteStart) {
lastDouble = node;
} else if (node instanceof SimpleFunctionStart) {
lastFunction = node;
}
// a new token was created so the current image token need to be added first
if (imageToken != null) {
nodes.add(imageToken);
imageToken = null;
}
// and then add the created node
nodes.add(node);
// continue to next
continue;
}
// which we need to add together in the same image
if (imageToken == null) {
imageToken = new LiteralExpression(token);
}
imageToken.addText(token.getText());
}
// append any leftover image tokens (when we reached eol)
if (imageToken != null) {
nodes.add(imageToken);
}
// validate the single, double quote pairs and functions is in balance
if (startSingle.get()) {
int index = lastSingle != null ? lastSingle.getToken().getIndex() : 0;
throw new SimpleParserException("single quote has no ending quote", index);
}
if (startDouble.get()) {
int index = lastDouble != null ? lastDouble.getToken().getIndex() : 0;
throw new SimpleParserException("double quote has no ending quote", index);
}
if (startFunction.get()) {
// we have a start function, but no ending function
int index = lastFunction != null ? lastFunction.getToken().getIndex() : 0;
throw new SimpleParserException("function has no ending token", index);
}
}
use of org.apache.camel.language.simple.types.SimpleToken in project camel by apache.
the class SimpleTokenizer method doNextToken.
private static SimpleToken doNextToken(String expression, int index, boolean allowEscape, TokenType... filters) {
boolean numericAllowed = acceptType(TokenType.numericValue, filters);
if (numericAllowed) {
// is it a numeric value
StringBuilder sb = new StringBuilder();
boolean digit = true;
while (digit && index < expression.length()) {
digit = Character.isDigit(expression.charAt(index));
if (digit) {
char ch = expression.charAt(index);
sb.append(ch);
index++;
continue;
}
// is it a dot or comma as part of a floating point number
boolean decimalSeparator = '.' == expression.charAt(index) || ',' == expression.charAt(index);
if (decimalSeparator && sb.length() > 0) {
char ch = expression.charAt(index);
sb.append(ch);
index++;
// assume its still a digit
digit = true;
continue;
}
}
if (sb.length() > 0) {
return new SimpleToken(new SimpleTokenType(TokenType.numericValue, sb.toString()), index);
}
}
boolean escapeAllowed = allowEscape && acceptType(TokenType.escape, filters);
if (escapeAllowed) {
StringBuilder sb = new StringBuilder();
char ch = expression.charAt(index);
boolean escaped = '\\' == ch;
if (escaped && index < expression.length() - 1) {
// grab next character to escape
char next = expression.charAt(++index);
// special for new line, tabs and carriage return
boolean special = false;
if ('n' == next) {
sb.append("\n");
special = true;
} else if ('t' == next) {
sb.append("\t");
special = true;
} else if ('r' == next) {
sb.append("\r");
special = true;
} else if ('}' == next) {
sb.append("}");
special = true;
} else {
// not special just a regular character
sb.append(ch);
}
// force 2 as length if special
return new SimpleToken(new SimpleTokenType(TokenType.character, sb.toString()), index, special ? 2 : 1);
}
}
// it could be any of the known tokens
String text = expression.substring(index);
for (SimpleTokenType token : KNOWN_TOKENS) {
if (acceptType(token.getType(), filters)) {
if (acceptToken(token, text, expression, index)) {
return new SimpleToken(token, index);
}
}
}
// fallback and create a character token
char ch = expression.charAt(index);
SimpleToken token = new SimpleToken(new SimpleTokenType(TokenType.character, "" + ch), index);
return token;
}
Aggregations