Search in sources :

Example 1 with SimpleToken

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;
        }
    };
}
Also used : SimpleParserException(org.apache.camel.language.simple.types.SimpleParserException) SimpleIllegalSyntaxException(org.apache.camel.language.simple.types.SimpleIllegalSyntaxException) Exchange(org.apache.camel.Exchange) Expression(org.apache.camel.Expression) SimpleToken(org.apache.camel.language.simple.types.SimpleToken)

Example 2 with SimpleToken

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);
}
Also used : SimpleTokenType(org.apache.camel.language.simple.types.SimpleTokenType) SimpleFunctionExpression(org.apache.camel.language.simple.ast.SimpleFunctionExpression) SimpleToken(org.apache.camel.language.simple.types.SimpleToken)

Example 3 with SimpleToken

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);
    }
}
Also used : LiteralNode(org.apache.camel.language.simple.ast.LiteralNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LiteralExpression(org.apache.camel.language.simple.ast.LiteralExpression) SimpleToken(org.apache.camel.language.simple.types.SimpleToken) SimpleNode(org.apache.camel.language.simple.ast.SimpleNode)

Example 4 with SimpleToken

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);
    }
}
Also used : SimpleParserException(org.apache.camel.language.simple.types.SimpleParserException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LiteralNode(org.apache.camel.language.simple.ast.LiteralNode) LiteralExpression(org.apache.camel.language.simple.ast.LiteralExpression) DoubleQuoteStart(org.apache.camel.language.simple.ast.DoubleQuoteStart) SingleQuoteStart(org.apache.camel.language.simple.ast.SingleQuoteStart) SimpleToken(org.apache.camel.language.simple.types.SimpleToken) SimpleNode(org.apache.camel.language.simple.ast.SimpleNode) SimpleFunctionStart(org.apache.camel.language.simple.ast.SimpleFunctionStart)

Example 5 with SimpleToken

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;
}
Also used : SimpleTokenType(org.apache.camel.language.simple.types.SimpleTokenType) SimpleToken(org.apache.camel.language.simple.types.SimpleToken)

Aggregations

SimpleToken (org.apache.camel.language.simple.types.SimpleToken)8 SimpleTokenType (org.apache.camel.language.simple.types.SimpleTokenType)4 LiteralExpression (org.apache.camel.language.simple.ast.LiteralExpression)2 LiteralNode (org.apache.camel.language.simple.ast.LiteralNode)2 SimpleNode (org.apache.camel.language.simple.ast.SimpleNode)2 SimpleParserException (org.apache.camel.language.simple.types.SimpleParserException)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Exchange (org.apache.camel.Exchange)1 Expression (org.apache.camel.Expression)1 DoubleQuoteStart (org.apache.camel.language.simple.ast.DoubleQuoteStart)1 SimpleFunctionExpression (org.apache.camel.language.simple.ast.SimpleFunctionExpression)1 SimpleFunctionStart (org.apache.camel.language.simple.ast.SimpleFunctionStart)1 SingleQuoteStart (org.apache.camel.language.simple.ast.SingleQuoteStart)1 SimpleIllegalSyntaxException (org.apache.camel.language.simple.types.SimpleIllegalSyntaxException)1