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.builder;
018    
019    import java.util.Map;
020    
021    import org.apache.camel.CamelContext;
022    import org.apache.camel.Expression;
023    import org.apache.camel.builder.xml.Namespaces;
024    import org.apache.camel.model.language.ConstantExpression;
025    import org.apache.camel.model.language.ELExpression;
026    import org.apache.camel.model.language.ExpressionDefinition;
027    import org.apache.camel.model.language.GroovyExpression;
028    import org.apache.camel.model.language.HeaderExpression;
029    import org.apache.camel.model.language.JXPathExpression;
030    import org.apache.camel.model.language.JavaScriptExpression;
031    import org.apache.camel.model.language.LanguageExpression;
032    import org.apache.camel.model.language.MethodCallExpression;
033    import org.apache.camel.model.language.MvelExpression;
034    import org.apache.camel.model.language.OgnlExpression;
035    import org.apache.camel.model.language.PhpExpression;
036    import org.apache.camel.model.language.PropertyExpression;
037    import org.apache.camel.model.language.PythonExpression;
038    import org.apache.camel.model.language.RefExpression;
039    import org.apache.camel.model.language.RubyExpression;
040    import org.apache.camel.model.language.SimpleExpression;
041    import org.apache.camel.model.language.SpELExpression;
042    import org.apache.camel.model.language.SqlExpression;
043    import org.apache.camel.model.language.TokenizerExpression;
044    import org.apache.camel.model.language.XPathExpression;
045    import org.apache.camel.model.language.XQueryExpression;
046    
047    /**
048     * A support class for building expression clauses.
049     *
050     * @version 
051     */
052    public class ExpressionClauseSupport<T> {
053    
054        private T result;
055        private Expression expressionValue;
056        private ExpressionDefinition expressionType;
057    
058        public ExpressionClauseSupport(T result) {
059            this.result = result;
060        }
061    
062        // Helper expressions
063        // -------------------------------------------------------------------------
064    
065        /**
066         * Specify an {@link org.apache.camel.Expression} instance
067         */
068        public T expression(Expression expression) {
069            setExpressionValue(expression);
070            return result;
071        }
072    
073        public T expression(ExpressionDefinition expression) {
074            setExpressionType(expression);
075            return result;
076        }
077    
078        /**
079         * Specify the constant expression value
080         */
081        public T constant(Object value) {
082            if (value instanceof String) {
083                return expression(new ConstantExpression((String) value));
084            } else {
085                return expression(ExpressionBuilder.constantExpression(value));
086            }
087        }
088    
089        /**
090         * An expression of the exchange
091         */
092        public T exchange() {
093            return expression(ExpressionBuilder.exchangeExpression());
094        }
095    
096        /**
097         * An expression of an inbound message
098         */
099        public T inMessage() {
100            return expression(ExpressionBuilder.inMessageExpression());
101        }
102    
103        /**
104         * An expression of an inbound message
105         */
106        public T outMessage() {
107            return expression(ExpressionBuilder.outMessageExpression());
108        }
109    
110        /**
111         * An expression of an inbound message body
112         */
113        public T body() {
114            return expression(ExpressionBuilder.bodyExpression());
115        }
116    
117        /**
118         * An expression of an inbound message body converted to the expected type
119         */
120        public T body(Class<?> expectedType) {
121            return expression(ExpressionBuilder.bodyExpression(expectedType));
122        }
123    
124        /**
125         * An expression of an outbound message body
126         */
127        public T outBody() {
128            return expression(ExpressionBuilder.outBodyExpression());
129        }
130    
131        /**
132         * An expression of an outbound message body converted to the expected type
133         */
134        public T outBody(Class<?> expectedType) {
135            return expression(ExpressionBuilder.outBodyExpression(expectedType));
136        }
137    
138        /**
139         * An expression of an inbound message header of the given name
140         */
141        public T header(String name) {
142            return expression(new HeaderExpression(name));
143        }
144    
145        /**
146         * An expression of the inbound headers
147         */
148        public T headers() {
149            return expression(ExpressionBuilder.headersExpression());
150        }
151    
152        /**
153         * An expression of an outbound message header of the given name
154         */
155        public T outHeader(String name) {
156            return expression(ExpressionBuilder.outHeaderExpression(name));
157        }
158    
159        /**
160         * An expression of the outbound headers
161         */
162        public T outHeaders() {
163            return expression(ExpressionBuilder.outHeadersExpression());
164        }
165    
166        /**
167         * An expression of the inbound message attachments
168         */
169        public T attachments() {
170            return expression(ExpressionBuilder.attachmentValuesExpression());
171        }
172    
173        /**
174         * An expression of the exchange pattern
175         */
176        public T exchangePattern() {
177            return expression(ExpressionBuilder.exchangePatternExpression());
178        }
179    
180        /**
181         * An expression of an exchange property of the given name
182         */
183        public T property(String name) {
184            return expression(new PropertyExpression(name));
185        }
186    
187        /**
188         * An expression of the exchange properties
189         */
190        public T properties() {
191            return expression(ExpressionBuilder.propertiesExpression());
192        }
193    
194        // Languages
195        // -------------------------------------------------------------------------
196    
197        /**
198         * Evaluates an expression using the <a
199         * href="http://camel.apache.org/bean-language.html>bean language</a>
200         * which basically means the bean is invoked to determine the expression
201         * value.
202         *
203         * @param bean the name of the bean looked up the registry
204         * @return the builder to continue processing the DSL
205         */
206        public T method(String bean) {
207            return expression(new MethodCallExpression(bean));
208        }
209    
210        /**
211         * Evaluates an expression using the <a
212         * href="http://camel.apache.org/bean-language.html>bean language</a>
213         * which basically means the bean is invoked to determine the expression
214         * value.
215         *
216         * @param instance the instance of the bean
217         * @return the builder to continue processing the DSL
218         */
219        public T method(Object instance) {
220            return expression(new MethodCallExpression(instance));
221        }
222    
223        /**
224         * Evaluates an expression using the <a
225         * href="http://camel.apache.org/bean-language.html>bean language</a>
226         * which basically means the bean is invoked to determine the expression
227         * value.
228         *
229         * @param beanType the Class of the bean which we want to invoke
230         * @return the builder to continue processing the DSL
231         */
232        public T method(Class<?> beanType) {
233            return expression(new MethodCallExpression(beanType));
234        }
235    
236        /**
237         * Evaluates an expression using the <a
238         * href="http://camel.apache.org/bean-language.html>bean language</a>
239         * which basically means the bean is invoked to determine the expression
240         * value.
241         *
242         * @param bean the name of the bean looked up the registry
243         * @param method the name of the method to invoke on the bean
244         * @return the builder to continue processing the DSL
245         */
246        public T method(String bean, String method) {
247            return expression(new MethodCallExpression(bean, method));
248        }
249    
250        /**
251         * Evaluates an expression using the <a
252         * href="http://camel.apache.org/bean-language.html>bean language</a>
253         * which basically means the bean is invoked to determine the expression
254         * value.
255         *
256         * @param instance the instance of the bean
257         * @param method the name of the method to invoke on the bean
258         * @return the builder to continue processing the DSL
259         */
260        public T method(Object instance, String method) {
261            return expression(new MethodCallExpression(instance, method));
262        }
263    
264        /**
265         * Evaluates an expression using the <a
266         * href="http://camel.apache.org/bean-language.html>bean language</a>
267         * which basically means the bean is invoked to determine the expression
268         * value.
269         *
270         * @param beanType the Class of the bean which we want to invoke
271         * @param method the name of the method to invoke on the bean
272         * @return the builder to continue processing the DSL
273         */
274        public T method(Class<?> beanType, String method) {
275            return expression(new MethodCallExpression(beanType, method));
276        }
277    
278        /**
279         * Evaluates the <a href="http://camel.apache.org/el.html">EL
280         * Language from JSP and JSF</a> using the <a
281         * href="http://camel.apache.org/juel.html">JUEL library</a>
282         *
283         * @param text the expression to be evaluated
284         * @return the builder to continue processing the DSL
285         */
286        public T el(String text) {
287            return expression(new ELExpression(text));
288        }
289    
290        /**
291         * Evaluates a <a href="http://camel.apache.org/groovy.html">Groovy
292         * expression</a>
293         *
294         * @param text the expression to be evaluated
295         * @return the builder to continue processing the DSL
296         */
297        public T groovy(String text) {
298            return expression(new GroovyExpression(text));
299        }
300    
301        /**
302         * Evaluates a <a
303         * href="http://camel.apache.org/java-script.html">JavaScript
304         * expression</a>
305         *
306         * @param text the expression to be evaluated
307         * @return the builder to continue processing the DSL
308         */
309        public T javaScript(String text) {
310            return expression(new JavaScriptExpression(text));
311        }
312    
313        /**
314         * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
315         *
316         * @param text the expression to be evaluated
317         * @return the builder to continue processing the DSL
318         */
319        public T jxpath(String text) {
320            return expression(new JXPathExpression(text));
321        }
322    
323        /**
324         * Evaluates an <a href="http://camel.apache.org/ognl.html">OGNL
325         * expression</a>
326         *
327         * @param text the expression to be evaluated
328         * @return the builder to continue processing the DSL
329         */
330        public T ognl(String text) {
331            return expression(new OgnlExpression(text));
332        }
333    
334        /**
335         * Evaluates a <a href="http://camel.apache.org/mvel.html">MVEL
336         * expression</a>
337         *
338         * @param text the expression to be evaluated
339         * @return the builder to continue processing the DSL
340         */
341        public T mvel(String text) {
342            return expression(new MvelExpression(text));
343        }
344    
345        /**
346         * Evaluates a <a href="http://camel.apache.org/php.html">PHP
347         * expression</a>
348         *
349         * @param text the expression to be evaluated
350         * @return the builder to continue processing the DSL
351         */
352        public T php(String text) {
353            return expression(new PhpExpression(text));
354        }
355    
356        /**
357         * Evaluates a <a href="http://camel.apache.org/python.html">Python
358         * expression</a>
359         *
360         * @param text the expression to be evaluated
361         * @return the builder to continue processing the DSL
362         */
363        public T python(String text) {
364            return expression(new PythonExpression(text));
365        }
366    
367        /**
368         * Evaluates a {@link Expression} by looking up existing {@link Expression}
369         * from the {@link org.apache.camel.spi.Registry}
370         *
371         * @param ref refers to the expression to be evaluated
372         * @return the builder to continue processing the DSL
373         */
374        public T ref(String ref) {
375            return expression(new RefExpression(ref));
376        }
377    
378        /**
379         * Evaluates a <a href="http://camel.apache.org/ruby.html">Ruby
380         * expression</a>
381         *
382         * @param text the expression to be evaluated
383         * @return the builder to continue processing the DSL
384         */
385        public T ruby(String text) {
386            return expression(new RubyExpression(text));
387        }
388    
389        /**
390         * Evaluates an <a href="http://camel.apache.org/spel.html">SpEL
391         * expression</a>
392         *
393         * @param text the expression to be evaluated
394         * @return the builder to continue processing the DSL
395         */
396        public T spel(String text) {
397            return expression(new SpELExpression(text));
398        }
399        
400        /**
401         * Evaluates an <a href="http://camel.apache.org/sql.html">SQL
402         * expression</a>
403         *
404         * @param text the expression to be evaluated
405         * @return the builder to continue processing the DSL
406         */
407        public T sql(String text) {
408            return expression(new SqlExpression(text));
409        }
410    
411        /**
412         * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
413         * expression</a>
414         *
415         * @param text the expression to be evaluated
416         * @return the builder to continue processing the DSL
417         */
418        public T simple(String text) {
419            return expression(new SimpleExpression(text));
420        }
421    
422        /**
423         * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
424         * expression</a>
425         *
426         * @param text the expression to be evaluated
427         * @param resultType the result type
428         * @return the builder to continue processing the DSL
429         */
430        public T simple(String text, Class<?> resultType) {
431            SimpleExpression expression = new SimpleExpression(text);
432            expression.setResultType(resultType);
433            setExpressionType(expression);
434            return result;
435        }
436    
437        /**
438         * Evaluates a token expression on the message body
439         *
440         * @param token the token
441         * @return the builder to continue processing the DSL
442         */
443        public T tokenize(String token) {
444            return tokenize(token, null, false);
445        }
446    
447        /**
448         * Evaluates a token expression on the message body
449         *
450         * @param token the token
451         * @param group to group by the given number
452         * @return the builder to continue processing the DSL
453         */
454        public T tokenize(String token, int group) {
455            return tokenize(token, null, false, group);
456        }
457    
458        /**
459         * Evaluates a token expression on the message body
460         *
461         * @param token the token
462         * @param regex whether the token is a regular expression or not
463         * @return the builder to continue processing the DSL
464         */
465        public T tokenize(String token, boolean regex) {
466            return tokenize(token, null, regex);
467        }
468    
469        /**
470         * Evaluates a token expression on the message body
471         *
472         * @param token the token
473         * @param regex whether the token is a regular expression or not
474         * @param group to group by the given number
475         * @return the builder to continue processing the DSL
476         */
477        public T tokenize(String token, boolean regex, int group) {
478            return tokenize(token, null, regex, group);
479        }
480    
481        /**
482         * Evaluates a token expression on the given header
483         *
484         * @param token the token
485         * @param headerName name of header to tokenize
486         * @return the builder to continue processing the DSL
487         */
488        public T tokenize(String token, String headerName) {
489            return tokenize(token, headerName, false);
490        }
491    
492        /**
493         * Evaluates a token expression on the given header
494         *
495         * @param token the token
496         * @param headerName name of header to tokenize
497         * @param regex whether the token is a regular expression or not
498         * @return the builder to continue processing the DSL
499         */
500        public T tokenize(String token, String headerName, boolean regex) {
501            TokenizerExpression expression = new TokenizerExpression();
502            expression.setToken(token);
503            expression.setHeaderName(headerName);
504            expression.setRegex(regex);
505            setExpressionType(expression);
506            return result;
507        }
508    
509        /**
510         * Evaluates a token expression on the given header
511         *
512         * @param token the token
513         * @param headerName name of header to tokenize
514         * @param regex whether the token is a regular expression or not
515         * @param group to group by number of parts
516         * @return the builder to continue processing the DSL
517         */
518        public T tokenize(String token, String headerName, boolean regex, int group) {
519            TokenizerExpression expression = new TokenizerExpression();
520            expression.setToken(token);
521            expression.setHeaderName(headerName);
522            expression.setRegex(regex);
523            expression.setGroup(group);
524            setExpressionType(expression);
525            return result;
526        }
527    
528        /**
529         * Evaluates a token pair expression on the message body
530         *
531         * @param startToken the start token
532         * @param endToken   the end token
533         * @param includeTokens whether to include tokens
534         * @return the builder to continue processing the DSL
535         */
536        public T tokenizePair(String startToken, String endToken, boolean includeTokens) {
537            TokenizerExpression expression = new TokenizerExpression();
538            expression.setToken(startToken);
539            expression.setEndToken(endToken);
540            expression.setIncludeTokens(includeTokens);
541            setExpressionType(expression);
542            return result;
543        }
544    
545        /**
546         * Evaluates a token pair expression on the message body with XML content
547         *
548         * @param tagName the the tag name of the child nodes to tokenize
549         * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
550         * @param group to group by the given number
551         * @return the builder to continue processing the DSL
552         */
553        public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, int group) {
554            TokenizerExpression expression = new TokenizerExpression();
555            expression.setToken(tagName);
556            expression.setInheritNamespaceTagName(inheritNamespaceTagName);
557            expression.setXml(true);
558            if (group > 0) {
559                expression.setGroup(group);
560            }
561            setExpressionType(expression);
562            return result;
563        }
564    
565        /**
566         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
567         * expression</a>
568         *
569         * @param text the expression to be evaluated
570         * @return the builder to continue processing the DSL
571         */
572        public T xpath(String text) {
573            return expression(new XPathExpression(text));
574        }
575    
576        /**
577         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
578         * expression</a> with the specified result type
579         *
580         * @param text the expression to be evaluated
581         * @param resultType the return type expected by the expression
582         * @return the builder to continue processing the DSL
583         */
584        public T xpath(String text, Class<?> resultType) {
585            XPathExpression expression = new XPathExpression(text);
586            expression.setResultType(resultType);
587            setExpressionType(expression);
588            return result;
589        }
590    
591        /**
592         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
593         * expression</a> with the specified result type and set of namespace
594         * prefixes and URIs
595         *
596         * @param text the expression to be evaluated
597         * @param resultType the return type expected by the expression
598         * @param namespaces the namespace prefix and URIs to use
599         * @return the builder to continue processing the DSL
600         */
601        public T xpath(String text, Class<?> resultType, Namespaces namespaces) {
602            return xpath(text, resultType, namespaces.getNamespaces());
603        }
604    
605        /**
606         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
607         * expression</a> with the specified result type and set of namespace
608         * prefixes and URIs
609         *
610         * @param text the expression to be evaluated
611         * @param resultType the return type expected by the expression
612         * @param namespaces the namespace prefix and URIs to use
613         * @return the builder to continue processing the DSL
614         */
615        public T xpath(String text, Class<?> resultType, Map<String, String> namespaces) {
616            XPathExpression expression = new XPathExpression(text);
617            expression.setResultType(resultType);
618            expression.setNamespaces(namespaces);
619            setExpressionType(expression);
620            return result;
621        }
622    
623        /**
624         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
625         * expression</a> with the specified set of namespace prefixes and URIs
626         *
627         * @param text the expression to be evaluated
628         * @param namespaces the namespace prefix and URIs to use
629         * @return the builder to continue processing the DSL
630         */
631        public T xpath(String text, Namespaces namespaces) {
632            return xpath(text, namespaces.getNamespaces());
633        }
634    
635        /**
636         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
637         * expression</a> with the specified set of namespace prefixes and URIs
638         *
639         * @param text the expression to be evaluated
640         * @param namespaces the namespace prefix and URIs to use
641         * @return the builder to continue processing the DSL
642         */
643        public T xpath(String text, Map<String, String> namespaces) {
644            XPathExpression expression = new XPathExpression(text);
645            expression.setNamespaces(namespaces);
646            setExpressionType(expression);
647            return result;
648        }
649    
650        /**
651         * Evaluates an <a
652         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
653         *
654         * @param text the expression to be evaluated
655         * @return the builder to continue processing the DSL
656         */
657        public T xquery(String text) {
658            return expression(new XQueryExpression(text));
659        }
660    
661        /**
662         * Evaluates an <a
663         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
664         * with the specified result type
665         *
666         * @param text the expression to be evaluated
667         * @param resultType the return type expected by the expression
668         * @return the builder to continue processing the DSL
669         */
670        public T xquery(String text, Class<?> resultType) {
671            XQueryExpression expression = new XQueryExpression(text);
672            expression.setResultType(resultType);
673            setExpressionType(expression);
674            return result;
675        }
676    
677        /**
678         * Evaluates an <a
679         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
680         * with the specified result type and set of namespace prefixes and URIs
681         *
682         * @param text the expression to be evaluated
683         * @param resultType the return type expected by the expression
684         * @param namespaces the namespace prefix and URIs to use
685         * @return the builder to continue processing the DSL
686         */
687        public T xquery(String text, Class<?> resultType, Namespaces namespaces) {
688            return xquery(text, resultType, namespaces.getNamespaces());
689        }
690    
691        /**
692         * Evaluates an <a
693         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
694         * with the specified result type and set of namespace prefixes and URIs
695         *
696         * @param text the expression to be evaluated
697         * @param resultType the return type expected by the expression
698         * @param namespaces the namespace prefix and URIs to use
699         * @return the builder to continue processing the DSL
700         */
701        public T xquery(String text, Class<?> resultType, Map<String, String> namespaces) {
702            XQueryExpression expression = new XQueryExpression(text);
703            expression.setResultType(resultType);
704            expression.setNamespaces(namespaces);
705            setExpressionType(expression);
706            return result;
707        }
708    
709        /**
710         * Evaluates an <a
711         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
712         * with the specified set of namespace prefixes and URIs
713         *
714         * @param text the expression to be evaluated
715         * @param namespaces the namespace prefix and URIs to use
716         * @return the builder to continue processing the DSL
717         */
718        public T xquery(String text, Namespaces namespaces) {
719            return xquery(text, namespaces.getNamespaces());
720        }
721    
722        /**
723         * Evaluates an <a
724         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
725         * with the specified set of namespace prefixes and URIs
726         *
727         * @param text the expression to be evaluated
728         * @param namespaces the namespace prefix and URIs to use
729         * @return the builder to continue processing the DSL
730         */
731        public T xquery(String text, Map<String, String> namespaces) {
732            XQueryExpression expression = new XQueryExpression(text);
733            expression.setNamespaces(namespaces);
734            setExpressionType(expression);
735            return result;
736        }
737    
738        /**
739         * Evaluates a given language name with the expression text
740         *
741         * @param language the name of the language
742         * @param expression the expression in the given language
743         * @return the builder to continue processing the DSL
744         */
745        public T language(String language, String expression) {
746            LanguageExpression exp = new LanguageExpression(language, expression);
747            setExpressionType(exp);
748            return result;
749        }
750    
751        // Properties
752        // -------------------------------------------------------------------------
753    
754        public Expression getExpressionValue() {
755            return expressionValue;
756        }
757    
758        public void setExpressionValue(Expression expressionValue) {
759            this.expressionValue = expressionValue;
760        }
761    
762        public ExpressionDefinition getExpressionType() {
763            return expressionType;
764        }
765    
766        public void setExpressionType(ExpressionDefinition expressionType) {
767            this.expressionType = expressionType;
768        }
769    
770        protected Expression createExpression(CamelContext camelContext) {
771            if (getExpressionValue() == null) {
772                if (getExpressionType() != null) {
773                    setExpressionValue(getExpressionType().createExpression(camelContext));
774                } else {
775                    throw new IllegalStateException("No expression value configured");
776                }
777            }
778            return getExpressionValue();
779        }
780    
781        protected void configureExpression(CamelContext camelContext, Expression expression) {
782        }
783    
784    }