001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.web.util;
018    
019    import org.apache.camel.builder.ExpressionClause;
020    import org.apache.camel.model.language.ExpressionDefinition;
021    import org.apache.camel.model.language.MethodCallExpression;
022    import org.apache.camel.model.language.XPathExpression;
023    
024    public final class ExpressionRenderer {
025    
026        private ExpressionRenderer() {
027            // Utility class, no public or protected default constructor
028        }    
029    
030        /**
031         * a common render method to process the expressionDefinition
032         */
033        public static void render(StringBuilder buffer, ExpressionDefinition expression) {
034    
035            if (buffer.toString().endsWith(")")) {
036                buffer.append(".");
037            }
038    
039            if (expression instanceof ExpressionClause) {
040                renderExpressionClause(buffer, (ExpressionClause)expression);
041            } else if (expression.getExpressionValue() instanceof ExpressionClause) {
042                render(buffer, (ExpressionClause)expression.getExpressionValue());
043            } else {
044                if (expression.getExpressionValue() != null) {
045                    renderExpression(buffer, expression.getExpressionValue().toString());
046                } else if (expression.getLanguage() != null) {
047                    renderLanguageExpression(buffer, expression);
048                }
049            }
050        }
051    
052        /**
053         * Render a constant: constant("")
054         */
055        public static void renderConstant(StringBuilder buffer, ExpressionDefinition expression) {
056            renderConstant(buffer, expression.getExpressionValue().toString());
057        }
058    
059        /**
060         * Render a constant: constant("")
061         */
062        public static void renderConstant(StringBuilder buffer, String expression) {
063            if (buffer.toString().endsWith(")")) {
064                buffer.append(".");
065            }
066            buffer.append("constant(\"").append(expression).append("\")");
067        }
068    
069        /**
070         * Render an expression clause
071         */
072        private static void renderExpressionClause(StringBuilder buffer, ExpressionClause expression) {
073            if (expression.getLanguage() != null) {
074                // render a language expression
075                renderLanguageExpression(buffer, expression);
076            } else if (expression.getExpressionType() instanceof MethodCallExpression) {
077                // render a methodCall expression
078                String exp = expression.getExpressionType().toString();
079                String bean = exp.substring(exp.indexOf('{') + 1, exp.indexOf(','));
080                String method = exp.substring(exp.indexOf('=') + 1, exp.indexOf('}'));
081                buffer.append("method(\"").append(bean).append("\", \"").append(method).append("\")");
082            } else if (expression.getExpressionType() instanceof XPathExpression) {
083                XPathExpression xpath = (XPathExpression)expression.getExpressionType();
084                buffer.append("xpath(\"").append(xpath.getExpression()).append("\", ").append(xpath.getResultType().getSimpleName()).append(".class)");
085            } else {
086                renderExpression(buffer, expression.getExpressionValue().toString());
087            }
088        }
089    
090        /**
091         * Render a language expression
092         * 
093         * @param buffer
094         * @param expression
095         */
096        public static void renderLanguageExpression(StringBuilder buffer, ExpressionDefinition expression) {
097            // render a language expression
098            buffer.append(expression.getLanguage()).append("(\"");
099            if (expression.getExpression() != null) {
100                buffer.append(expression.getExpression()).append("\")");
101            } else if (expression.getExpressionValue() instanceof ExpressionClause) {
102                buffer.append(((ExpressionClause)expression.getExpressionValue()).getExpression()).append("\")");
103            }
104        }
105    
106        /**
107         * Render a simple expression: header(foo) -> header("foo")
108         * tokenize(header(foo), ,) -> header("foo").tokenize(",")
109         */
110        public static void renderExpression(StringBuilder buffer, String expression) {
111            if (!expression.contains(",")) {
112                if (expression.contains("(")) {
113                    // header(foo) -> header("foo")
114                    expression = expression.replaceAll("\\(", "(\"").replaceAll("\\)", "\")");
115                    buffer.append(expression);
116                } else {
117                    // body -> body()
118                    buffer.append(expression).append("()");
119                }
120            } else if (expression.startsWith("tokenize")) {
121                String words[] = expression.split("\\(");
122                if (words.length == 2) {
123                    // tokenize(body, ,) -> body().tokenize(",")
124                    String tokenize = words[1].substring(words[1].indexOf(" ") + 1, words[1].lastIndexOf(")"));
125                    words[1] = words[1].substring(0, words[1].indexOf(","));
126    
127                    if (!words[1].contains("[")) {
128                        // body
129                        buffer.append(words[1]).append("()");
130                    } else {
131                        // bodyAs[clazz]
132                        String word = words[1].substring(0, words[1].indexOf("As"));
133                        String clazz = words[1].substring(words[1].lastIndexOf(".") + 1, words[1].length() - 1);
134                        buffer.append(word).append("(").append(clazz).append(".class)");
135                    }
136    
137                    buffer.append(".").append(words[0]).append("(\"").append(tokenize).append("\")");
138                } else if (words.length == 3) {
139                    // tokenize(header(foo), ,) -> header("foo").tokenize(",")
140                    String symbolName = words[2].substring(0, words[2].indexOf(")"));
141                    String tokenize = words[2].substring(words[2].indexOf(" ") + 1, words[2].lastIndexOf(")"));
142    
143                    buffer.append(words[1]).append("(\"").append(symbolName).append("\").");
144                    buffer.append(words[0]).append("(\"").append(tokenize).append("\")");
145                }
146            } else if (expression.startsWith("append")) {
147                // append(body, World!) -> body().append(" World!")
148                String words[] = expression.split("\\(|, |\\)");
149    
150                buffer.append(words[1]).append("().").append("append(\"").append(words[2]).append("\")");
151            } else if (expression.startsWith("prepend")) {
152                // prepend(body, World!) -> body().prepend(" World!")
153                String words[] = expression.split("\\(|, |\\)");
154    
155                buffer.append(words[1]).append("().").append("prepend(\"").append(words[2]).append("\")");
156            }
157        }
158    }