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 jxpath(text, false);
321        }
322    
323        /**
324         * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
325         *
326         * @param text the expression to be evaluated
327         * @param lenient to configure whether lenient is in use or not
328         * @return the builder to continue processing the DSL
329         */
330        public T jxpath(String text, boolean lenient) {
331            JXPathExpression answer = new JXPathExpression(text);
332            answer.setLenient(lenient);
333            return expression(answer);
334        }
335    
336        /**
337         * Evaluates an <a href="http://camel.apache.org/ognl.html">OGNL
338         * expression</a>
339         *
340         * @param text the expression to be evaluated
341         * @return the builder to continue processing the DSL
342         */
343        public T ognl(String text) {
344            return expression(new OgnlExpression(text));
345        }
346    
347        /**
348         * Evaluates a <a href="http://camel.apache.org/mvel.html">MVEL
349         * expression</a>
350         *
351         * @param text the expression to be evaluated
352         * @return the builder to continue processing the DSL
353         */
354        public T mvel(String text) {
355            return expression(new MvelExpression(text));
356        }
357    
358        /**
359         * Evaluates a <a href="http://camel.apache.org/php.html">PHP
360         * expression</a>
361         *
362         * @param text the expression to be evaluated
363         * @return the builder to continue processing the DSL
364         */
365        public T php(String text) {
366            return expression(new PhpExpression(text));
367        }
368    
369        /**
370         * Evaluates a <a href="http://camel.apache.org/python.html">Python
371         * expression</a>
372         *
373         * @param text the expression to be evaluated
374         * @return the builder to continue processing the DSL
375         */
376        public T python(String text) {
377            return expression(new PythonExpression(text));
378        }
379    
380        /**
381         * Evaluates a {@link Expression} by looking up existing {@link Expression}
382         * from the {@link org.apache.camel.spi.Registry}
383         *
384         * @param ref refers to the expression to be evaluated
385         * @return the builder to continue processing the DSL
386         */
387        public T ref(String ref) {
388            return expression(new RefExpression(ref));
389        }
390    
391        /**
392         * Evaluates a <a href="http://camel.apache.org/ruby.html">Ruby
393         * expression</a>
394         *
395         * @param text the expression to be evaluated
396         * @return the builder to continue processing the DSL
397         */
398        public T ruby(String text) {
399            return expression(new RubyExpression(text));
400        }
401    
402        /**
403         * Evaluates an <a href="http://camel.apache.org/spel.html">SpEL
404         * expression</a>
405         *
406         * @param text the expression to be evaluated
407         * @return the builder to continue processing the DSL
408         */
409        public T spel(String text) {
410            return expression(new SpELExpression(text));
411        }
412        
413        /**
414         * Evaluates an <a href="http://camel.apache.org/sql.html">SQL
415         * expression</a>
416         *
417         * @param text the expression to be evaluated
418         * @return the builder to continue processing the DSL
419         */
420        public T sql(String text) {
421            return expression(new SqlExpression(text));
422        }
423    
424        /**
425         * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
426         * expression</a>
427         *
428         * @param text the expression to be evaluated
429         * @return the builder to continue processing the DSL
430         */
431        public T simple(String text) {
432            return expression(new SimpleExpression(text));
433        }
434    
435        /**
436         * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
437         * expression</a>
438         *
439         * @param text the expression to be evaluated
440         * @param resultType the result type
441         * @return the builder to continue processing the DSL
442         */
443        public T simple(String text, Class<?> resultType) {
444            SimpleExpression expression = new SimpleExpression(text);
445            expression.setResultType(resultType);
446            setExpressionType(expression);
447            return result;
448        }
449    
450        /**
451         * Evaluates a token expression on the message body
452         *
453         * @param token the token
454         * @return the builder to continue processing the DSL
455         */
456        public T tokenize(String token) {
457            return tokenize(token, null, false);
458        }
459    
460        /**
461         * Evaluates a token expression on the message body
462         *
463         * @param token the token
464         * @param group to group by the given number
465         * @return the builder to continue processing the DSL
466         */
467        public T tokenize(String token, int group) {
468            return tokenize(token, null, false, group);
469        }
470    
471        /**
472         * Evaluates a token expression on the message body
473         *
474         * @param token the token
475         * @param regex whether the token is a regular expression or not
476         * @return the builder to continue processing the DSL
477         */
478        public T tokenize(String token, boolean regex) {
479            return tokenize(token, null, regex);
480        }
481    
482        /**
483         * Evaluates a token expression on the message body
484         *
485         * @param token the token
486         * @param regex whether the token is a regular expression or not
487         * @param group to group by the given number
488         * @return the builder to continue processing the DSL
489         */
490        public T tokenize(String token, boolean regex, int group) {
491            return tokenize(token, null, regex, group);
492        }
493    
494        /**
495         * Evaluates a token expression on the given header
496         *
497         * @param token the token
498         * @param headerName name of header to tokenize
499         * @return the builder to continue processing the DSL
500         */
501        public T tokenize(String token, String headerName) {
502            return tokenize(token, headerName, false);
503        }
504    
505        /**
506         * Evaluates a token expression on the given header
507         *
508         * @param token the token
509         * @param headerName name of header to tokenize
510         * @param regex whether the token is a regular expression or not
511         * @return the builder to continue processing the DSL
512         */
513        public T tokenize(String token, String headerName, boolean regex) {
514            TokenizerExpression expression = new TokenizerExpression();
515            expression.setToken(token);
516            expression.setHeaderName(headerName);
517            expression.setRegex(regex);
518            setExpressionType(expression);
519            return result;
520        }
521    
522        /**
523         * Evaluates a token expression on the given header
524         *
525         * @param token the token
526         * @param headerName name of header to tokenize
527         * @param regex whether the token is a regular expression or not
528         * @param group to group by number of parts
529         * @return the builder to continue processing the DSL
530         */
531        public T tokenize(String token, String headerName, boolean regex, int group) {
532            TokenizerExpression expression = new TokenizerExpression();
533            expression.setToken(token);
534            expression.setHeaderName(headerName);
535            expression.setRegex(regex);
536            expression.setGroup(group);
537            setExpressionType(expression);
538            return result;
539        }
540    
541        /**
542         * Evaluates a token pair expression on the message body
543         *
544         * @param startToken the start token
545         * @param endToken   the end token
546         * @param includeTokens whether to include tokens
547         * @return the builder to continue processing the DSL
548         */
549        public T tokenizePair(String startToken, String endToken, boolean includeTokens) {
550            TokenizerExpression expression = new TokenizerExpression();
551            expression.setToken(startToken);
552            expression.setEndToken(endToken);
553            expression.setIncludeTokens(includeTokens);
554            setExpressionType(expression);
555            return result;
556        }
557    
558        /**
559         * Evaluates a token pair expression on the message body with XML content
560         *
561         * @param tagName the the tag name of the child nodes to tokenize
562         * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
563         * @param group to group by the given number
564         * @return the builder to continue processing the DSL
565         */
566        public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, int group) {
567            TokenizerExpression expression = new TokenizerExpression();
568            expression.setToken(tagName);
569            expression.setInheritNamespaceTagName(inheritNamespaceTagName);
570            expression.setXml(true);
571            if (group > 0) {
572                expression.setGroup(group);
573            }
574            setExpressionType(expression);
575            return result;
576        }
577    
578        /**
579         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
580         * expression</a>
581         *
582         * @param text the expression to be evaluated
583         * @return the builder to continue processing the DSL
584         */
585        public T xpath(String text) {
586            return expression(new XPathExpression(text));
587        }
588    
589        /**
590         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
591         * expression</a> with the specified result type
592         *
593         * @param text the expression to be evaluated
594         * @param resultType the return type expected by the expression
595         * @return the builder to continue processing the DSL
596         */
597        public T xpath(String text, Class<?> resultType) {
598            XPathExpression expression = new XPathExpression(text);
599            expression.setResultType(resultType);
600            setExpressionType(expression);
601            return result;
602        }
603    
604        /**
605         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
606         * expression</a> with the specified result type and set of namespace
607         * prefixes and URIs
608         *
609         * @param text the expression to be evaluated
610         * @param resultType the return type expected by the expression
611         * @param namespaces the namespace prefix and URIs to use
612         * @return the builder to continue processing the DSL
613         */
614        public T xpath(String text, Class<?> resultType, Namespaces namespaces) {
615            return xpath(text, resultType, namespaces.getNamespaces());
616        }
617    
618        /**
619         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
620         * expression</a> with the specified result type and set of namespace
621         * prefixes and URIs
622         *
623         * @param text the expression to be evaluated
624         * @param resultType the return type expected by the expression
625         * @param namespaces the namespace prefix and URIs to use
626         * @return the builder to continue processing the DSL
627         */
628        public T xpath(String text, Class<?> resultType, Map<String, String> namespaces) {
629            XPathExpression expression = new XPathExpression(text);
630            expression.setResultType(resultType);
631            expression.setNamespaces(namespaces);
632            setExpressionType(expression);
633            return result;
634        }
635    
636        /**
637         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
638         * expression</a> with the specified set of namespace prefixes and URIs
639         *
640         * @param text the expression to be evaluated
641         * @param namespaces the namespace prefix and URIs to use
642         * @return the builder to continue processing the DSL
643         */
644        public T xpath(String text, Namespaces namespaces) {
645            return xpath(text, namespaces.getNamespaces());
646        }
647    
648        /**
649         * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
650         * expression</a> with the specified set of namespace prefixes and URIs
651         *
652         * @param text the expression to be evaluated
653         * @param namespaces the namespace prefix and URIs to use
654         * @return the builder to continue processing the DSL
655         */
656        public T xpath(String text, Map<String, String> namespaces) {
657            XPathExpression expression = new XPathExpression(text);
658            expression.setNamespaces(namespaces);
659            setExpressionType(expression);
660            return result;
661        }
662    
663        /**
664         * Evaluates an <a
665         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
666         *
667         * @param text the expression to be evaluated
668         * @return the builder to continue processing the DSL
669         */
670        public T xquery(String text) {
671            return expression(new XQueryExpression(text));
672        }
673    
674        /**
675         * Evaluates an <a
676         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
677         * with the specified result type
678         *
679         * @param text the expression to be evaluated
680         * @param resultType the return type expected by the expression
681         * @return the builder to continue processing the DSL
682         */
683        public T xquery(String text, Class<?> resultType) {
684            XQueryExpression expression = new XQueryExpression(text);
685            expression.setResultType(resultType);
686            setExpressionType(expression);
687            return result;
688        }
689    
690        /**
691         * Evaluates an <a
692         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
693         * with the specified result type and set of namespace prefixes and URIs
694         *
695         * @param text the expression to be evaluated
696         * @param resultType the return type expected by the expression
697         * @param namespaces the namespace prefix and URIs to use
698         * @return the builder to continue processing the DSL
699         */
700        public T xquery(String text, Class<?> resultType, Namespaces namespaces) {
701            return xquery(text, resultType, namespaces.getNamespaces());
702        }
703    
704        /**
705         * Evaluates an <a
706         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
707         * with the specified result type and set of namespace prefixes and URIs
708         *
709         * @param text the expression to be evaluated
710         * @param resultType the return type expected by the expression
711         * @param namespaces the namespace prefix and URIs to use
712         * @return the builder to continue processing the DSL
713         */
714        public T xquery(String text, Class<?> resultType, Map<String, String> namespaces) {
715            XQueryExpression expression = new XQueryExpression(text);
716            expression.setResultType(resultType);
717            expression.setNamespaces(namespaces);
718            setExpressionType(expression);
719            return result;
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, Namespaces namespaces) {
732            return xquery(text, namespaces.getNamespaces());
733        }
734    
735        /**
736         * Evaluates an <a
737         * href="http://camel.apache.org/xquery.html">XQuery expression</a>
738         * with the specified set of namespace prefixes and URIs
739         *
740         * @param text the expression to be evaluated
741         * @param namespaces the namespace prefix and URIs to use
742         * @return the builder to continue processing the DSL
743         */
744        public T xquery(String text, Map<String, String> namespaces) {
745            XQueryExpression expression = new XQueryExpression(text);
746            expression.setNamespaces(namespaces);
747            setExpressionType(expression);
748            return result;
749        }
750    
751        /**
752         * Evaluates a given language name with the expression text
753         *
754         * @param language the name of the language
755         * @param expression the expression in the given language
756         * @return the builder to continue processing the DSL
757         */
758        public T language(String language, String expression) {
759            LanguageExpression exp = new LanguageExpression(language, expression);
760            setExpressionType(exp);
761            return result;
762        }
763    
764        // Properties
765        // -------------------------------------------------------------------------
766    
767        public Expression getExpressionValue() {
768            return expressionValue;
769        }
770    
771        public void setExpressionValue(Expression expressionValue) {
772            this.expressionValue = expressionValue;
773        }
774    
775        public ExpressionDefinition getExpressionType() {
776            return expressionType;
777        }
778    
779        public void setExpressionType(ExpressionDefinition expressionType) {
780            this.expressionType = expressionType;
781        }
782    
783        protected Expression createExpression(CamelContext camelContext) {
784            if (getExpressionValue() == null) {
785                if (getExpressionType() != null) {
786                    setExpressionValue(getExpressionType().createExpression(camelContext));
787                } else {
788                    throw new IllegalStateException("No expression value configured");
789                }
790            }
791            return getExpressionValue();
792        }
793    
794        protected void configureExpression(CamelContext camelContext, Expression expression) {
795        }
796    
797    }