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 */
017package org.apache.camel.builder;
018
019import java.util.Map;
020
021import org.apache.camel.CamelContext;
022import org.apache.camel.Expression;
023import org.apache.camel.builder.xml.Namespaces;
024import org.apache.camel.model.language.ConstantExpression;
025import org.apache.camel.model.language.ELExpression;
026import org.apache.camel.model.language.ExchangePropertyExpression;
027import org.apache.camel.model.language.ExpressionDefinition;
028import org.apache.camel.model.language.GroovyExpression;
029import org.apache.camel.model.language.HeaderExpression;
030import org.apache.camel.model.language.JXPathExpression;
031import org.apache.camel.model.language.JavaScriptExpression;
032import org.apache.camel.model.language.JsonPathExpression;
033import org.apache.camel.model.language.LanguageExpression;
034import org.apache.camel.model.language.MethodCallExpression;
035import org.apache.camel.model.language.MvelExpression;
036import org.apache.camel.model.language.OgnlExpression;
037import org.apache.camel.model.language.PhpExpression;
038import org.apache.camel.model.language.PythonExpression;
039import org.apache.camel.model.language.RefExpression;
040import org.apache.camel.model.language.RubyExpression;
041import org.apache.camel.model.language.SimpleExpression;
042import org.apache.camel.model.language.SpELExpression;
043import org.apache.camel.model.language.SqlExpression;
044import org.apache.camel.model.language.TerserExpression;
045import org.apache.camel.model.language.TokenizerExpression;
046import org.apache.camel.model.language.XMLTokenizerExpression;
047import org.apache.camel.model.language.XPathExpression;
048import org.apache.camel.model.language.XQueryExpression;
049
050/**
051 * A support class for building expression clauses.
052 *
053 * @version 
054 */
055public class ExpressionClauseSupport<T> {
056
057    private T result;
058    private Expression expressionValue;
059    private ExpressionDefinition expressionType;
060
061    public ExpressionClauseSupport(T result) {
062        this.result = result;
063    }
064
065    // Helper expressions
066    // -------------------------------------------------------------------------
067
068    /**
069     * Specify an {@link org.apache.camel.Expression} instance
070     */
071    public T expression(Expression expression) {
072        setExpressionValue(expression);
073        return result;
074    }
075
076    public T expression(ExpressionDefinition expression) {
077        setExpressionType(expression);
078        return result;
079    }
080
081    /**
082     * Specify the constant expression value
083     */
084    public T constant(Object value) {
085        if (value instanceof String) {
086            return expression(new ConstantExpression((String) value));
087        } else {
088            return expression(ExpressionBuilder.constantExpression(value));
089        }
090    }
091
092    /**
093     * An expression of the exchange
094     */
095    public T exchange() {
096        return expression(ExpressionBuilder.exchangeExpression());
097    }
098
099    /**
100     * An expression of an inbound message
101     */
102    public T inMessage() {
103        return expression(ExpressionBuilder.inMessageExpression());
104    }
105
106    /**
107     * An expression of an inbound message
108     */
109    public T outMessage() {
110        return expression(ExpressionBuilder.outMessageExpression());
111    }
112
113    /**
114     * An expression of an inbound message body
115     */
116    public T body() {
117        // reuse simple as this allows the model to represent this as a known JAXB type
118        return expression(new SimpleExpression("body"));
119    }
120
121    /**
122     * An expression of an inbound message body converted to the expected type
123     */
124    public T body(Class<?> expectedType) {
125        return expression(ExpressionBuilder.bodyExpression(expectedType));
126    }
127
128    /**
129     * An expression of an outbound message body
130     */
131    public T outBody() {
132        return expression(ExpressionBuilder.outBodyExpression());
133    }
134
135    /**
136     * An expression of an outbound message body converted to the expected type
137     */
138    public T outBody(Class<?> expectedType) {
139        return expression(ExpressionBuilder.outBodyExpression(expectedType));
140    }
141
142    /**
143     * An expression of an inbound message header of the given name
144     */
145    public T header(String name) {
146        return expression(new HeaderExpression(name));
147    }
148
149    /**
150     * An expression of the inbound headers
151     */
152    public T headers() {
153        return expression(ExpressionBuilder.headersExpression());
154    }
155
156    /**
157     * An expression of an outbound message header of the given name
158     */
159    public T outHeader(String name) {
160        return expression(ExpressionBuilder.outHeaderExpression(name));
161    }
162
163    /**
164     * An expression of the outbound headers
165     */
166    public T outHeaders() {
167        return expression(ExpressionBuilder.outHeadersExpression());
168    }
169
170    /**
171     * An expression of the inbound message attachments
172     */
173    public T attachments() {
174        return expression(ExpressionBuilder.attachmentObjectValuesExpression());
175    }
176
177    /**
178     * An expression of the exchange pattern
179     */
180    public T exchangePattern() {
181        return expression(ExpressionBuilder.exchangePatternExpression());
182    }
183
184    /**
185     * An expression of an exchange property of the given name
186     *
187     * @deprecated use {@link #exchangeProperty(String)} instead
188     */
189    @Deprecated
190    public T property(String name) {
191        return expression(new ExchangePropertyExpression(name));
192    }
193
194    /**
195     * An expression of an exchange property of the given name
196     */
197    public T exchangeProperty(String name) {
198        return expression(new ExchangePropertyExpression(name));
199    }
200
201    /**
202     * An expression of the exchange properties
203     *
204     * @deprecated use {@link #exchangeProperties()} instead
205     */
206    @Deprecated
207    public T properties() {
208        return exchangeProperties();
209    }
210
211    /**
212     * An expression of the exchange properties
213     */
214    public T exchangeProperties() {
215        return expression(ExpressionBuilder.exchangePropertiesExpression());
216    }
217
218    // Languages
219    // -------------------------------------------------------------------------
220
221    /**
222     * Evaluates an expression using the <a
223     * href="http://camel.apache.org/bean-language.html>bean language</a>
224     * which basically means the bean is invoked to determine the expression
225     * value.
226     *
227     * @param bean the name of the bean looked up the registry
228     * @return the builder to continue processing the DSL
229     */
230    public T method(String bean) {
231        return expression(new MethodCallExpression(bean));
232    }
233
234    /**
235     * Evaluates an expression using the <a
236     * href="http://camel.apache.org/bean-language.html>bean language</a>
237     * which basically means the bean is invoked to determine the expression
238     * value.
239     *
240     * @param instance the instance of the bean
241     * @return the builder to continue processing the DSL
242     */
243    public T method(Object instance) {
244        return expression(new MethodCallExpression(instance));
245    }
246
247    /**
248     * Evaluates an expression using the <a
249     * href="http://camel.apache.org/bean-language.html>bean language</a>
250     * which basically means the bean is invoked to determine the expression
251     * value.
252     *
253     * @param beanType the Class of the bean which we want to invoke
254     * @return the builder to continue processing the DSL
255     */
256    public T method(Class<?> beanType) {
257        return expression(new MethodCallExpression(beanType));
258    }
259
260    /**
261     * Evaluates an expression using the <a
262     * href="http://camel.apache.org/bean-language.html>bean language</a>
263     * which basically means the bean is invoked to determine the expression
264     * value.
265     *
266     * @param bean the name of the bean looked up the registry
267     * @param method the name of the method to invoke on the bean
268     * @return the builder to continue processing the DSL
269     */
270    public T method(String bean, String method) {
271        return expression(new MethodCallExpression(bean, method));
272    }
273
274    /**
275     * Evaluates an expression using the <a
276     * href="http://camel.apache.org/bean-language.html>bean language</a>
277     * which basically means the bean is invoked to determine the expression
278     * value.
279     *
280     * @param instance the instance of the bean
281     * @param method the name of the method to invoke on the bean
282     * @return the builder to continue processing the DSL
283     */
284    public T method(Object instance, String method) {
285        return expression(new MethodCallExpression(instance, method));
286    }
287
288    /**
289     * Evaluates an expression using the <a
290     * href="http://camel.apache.org/bean-language.html>bean language</a>
291     * which basically means the bean is invoked to determine the expression
292     * value.
293     *
294     * @param beanType the Class of the bean which we want to invoke
295     * @param method the name of the method to invoke on the bean
296     * @return the builder to continue processing the DSL
297     */
298    public T method(Class<?> beanType, String method) {
299        return expression(new MethodCallExpression(beanType, method));
300    }
301
302    /**
303     * Evaluates the <a href="http://camel.apache.org/el.html">EL
304     * Language from JSP and JSF</a> using the <a
305     * href="http://camel.apache.org/juel.html">JUEL library</a>
306     *
307     * @param text the expression to be evaluated
308     * @return the builder to continue processing the DSL
309     */
310    @Deprecated
311    public T el(String text) {
312        return expression(new ELExpression(text));
313    }
314
315    /**
316     * Evaluates a <a href="http://camel.apache.org/groovy.html">Groovy
317     * expression</a>
318     *
319     * @param text the expression to be evaluated
320     * @return the builder to continue processing the DSL
321     */
322    public T groovy(String text) {
323        return expression(new GroovyExpression(text));
324    }
325
326    /**
327     * Evaluates a <a
328     * href="http://camel.apache.org/java-script.html">JavaScript
329     * expression</a>
330     *
331     * @param text the expression to be evaluated
332     * @return the builder to continue processing the DSL
333     */
334    public T javaScript(String text) {
335        return expression(new JavaScriptExpression(text));
336    }
337
338    /**
339     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
340     * expression</a>
341     *
342     * @param text the expression to be evaluated
343     * @return the builder to continue processing the DSL
344     */
345    public T jsonpath(String text) {
346        return jsonpath(text, false);
347    }
348
349    /**
350     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
351     * expression</a>
352     *
353     * @param text the expression to be evaluated
354     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
355     * @return the builder to continue processing the DSL
356     */
357    public T jsonpath(String text, boolean suppressExceptions) {
358        JsonPathExpression expression = new JsonPathExpression(text);
359        expression.setSuppressExceptions(suppressExceptions);
360        return expression(expression);
361    }
362
363    /**
364     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
365     * expression</a>
366     *
367     * @param text the expression to be evaluated
368     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
369     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
370     * @return the builder to continue processing the DSL
371     */
372    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple) {
373        JsonPathExpression expression = new JsonPathExpression(text);
374        expression.setSuppressExceptions(suppressExceptions);
375        expression.setAllowSimple(allowSimple);
376        return expression(expression);
377    }
378
379    /**
380     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
381     * expression</a>
382     *
383     * @param text the expression to be evaluated
384     * @param resultType the return type expected by the expression
385     * @return the builder to continue processing the DSL
386     */
387    public T jsonpath(String text, Class<?> resultType) {
388        JsonPathExpression expression = new JsonPathExpression(text);
389        expression.setResultType(resultType);
390        setExpressionType(expression);
391        return result;
392    }
393
394    /**
395     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
396     * expression</a>
397     *
398     * @param text the expression to be evaluated
399     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
400     * @param resultType the return type expected by the expression
401     * @return the builder to continue processing the DSL
402     */
403    public T jsonpath(String text, boolean suppressExceptions, Class<?> resultType) {
404        JsonPathExpression expression = new JsonPathExpression(text);
405        expression.setSuppressExceptions(suppressExceptions);
406        expression.setResultType(resultType);
407        setExpressionType(expression);
408        return result;
409    }
410
411    /**
412     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
413     * expression</a>
414     *
415     * @param text the expression to be evaluated
416     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
417     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
418     * @param resultType the return type expected by the expression
419     * @return the builder to continue processing the DSL
420     */
421    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple, Class<?> resultType) {
422        JsonPathExpression expression = new JsonPathExpression(text);
423        expression.setSuppressExceptions(suppressExceptions);
424        expression.setAllowSimple(allowSimple);
425        expression.setResultType(resultType);
426        setExpressionType(expression);
427        return result;
428    }
429
430    /**
431     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
432     * expression</a>
433     *
434     * @param text the expression to be evaluated
435     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
436     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
437     * @param resultType the return type expected by the expression
438     * @param headerName the name of the header to apply the expression to
439     * @return the builder to continue processing the DSL
440     */
441    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple, Class<?> resultType, String headerName) {
442        JsonPathExpression expression = new JsonPathExpression(text);
443        expression.setSuppressExceptions(suppressExceptions);
444        expression.setAllowSimple(allowSimple);
445        expression.setResultType(resultType);
446        expression.setHeaderName(headerName);
447        setExpressionType(expression);
448        return result;
449    }
450
451    /**
452     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
453     * expression</a> with writeAsString enabled.
454     *
455     * @param text the expression to be evaluated
456     * @return the builder to continue processing the DSL
457     */
458    public T jsonpathWriteAsString(String text) {
459        return jsonpathWriteAsString(text, false);
460    }
461
462    /**
463     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
464     * expression</a> with writeAsString enabled.
465     *
466     * @param text the expression to be evaluated
467     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
468     * @return the builder to continue processing the DSL
469     */
470    public T jsonpathWriteAsString(String text, boolean suppressExceptions) {
471        JsonPathExpression expression = new JsonPathExpression(text);
472        expression.setWriteAsString(true);
473        expression.setSuppressExceptions(suppressExceptions);
474        return expression(expression);
475    }
476
477    /**
478     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
479     * expression</a> with writeAsString enabled.
480     *
481     * @param text the expression to be evaluated
482     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
483     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
484     * @return the builder to continue processing the DSL
485     */
486    public T jsonpathWriteAsString(String text, boolean suppressExceptions, boolean allowSimple) {
487        JsonPathExpression expression = new JsonPathExpression(text);
488        expression.setWriteAsString(true);
489        expression.setSuppressExceptions(suppressExceptions);
490        expression.setAllowSimple(allowSimple);
491        return expression(expression);
492    }
493
494    /**
495     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
496     * expression</a> with writeAsString enabled.
497     *
498     * @param text the expression to be evaluated
499     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
500     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
501     * @param headerName the name of the header to apply the expression to
502     * @return the builder to continue processing the DSL
503     */
504    public T jsonpathWriteAsString(String text, boolean suppressExceptions, boolean allowSimple, String headerName) {
505        JsonPathExpression expression = new JsonPathExpression(text);
506        expression.setWriteAsString(true);
507        expression.setSuppressExceptions(suppressExceptions);
508        expression.setAllowSimple(allowSimple);
509        expression.setHeaderName(headerName);
510        return expression(expression);
511    }
512
513    /**
514     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
515     *
516     * @param text the expression to be evaluated
517     * @return the builder to continue processing the DSL
518     */
519    @Deprecated
520    public T jxpath(String text) {
521        return jxpath(text, false);
522    }
523
524    /**
525     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
526     *
527     * @param text the expression to be evaluated
528     * @param lenient to configure whether lenient is in use or not
529     * @return the builder to continue processing the DSL
530     */
531    @Deprecated
532    public T jxpath(String text, boolean lenient) {
533        JXPathExpression answer = new JXPathExpression(text);
534        answer.setLenient(lenient);
535        return expression(answer);
536    }
537
538    /**
539     * Evaluates an <a href="http://camel.apache.org/ognl.html">OGNL
540     * expression</a>
541     *
542     * @param text the expression to be evaluated
543     * @return the builder to continue processing the DSL
544     */
545    public T ognl(String text) {
546        return expression(new OgnlExpression(text));
547    }
548
549    /**
550     * Evaluates a <a href="http://camel.apache.org/mvel.html">MVEL
551     * expression</a>
552     *
553     * @param text the expression to be evaluated
554     * @return the builder to continue processing the DSL
555     */
556    public T mvel(String text) {
557        return expression(new MvelExpression(text));
558    }
559
560    /**
561     * Evaluates a <a href="http://camel.apache.org/php.html">PHP
562     * expression</a>
563     *
564     * @param text the expression to be evaluated
565     * @return the builder to continue processing the DSL
566     */
567    @Deprecated
568    public T php(String text) {
569        return expression(new PhpExpression(text));
570    }
571
572    /**
573     * Evaluates a <a href="http://camel.apache.org/python.html">Python
574     * expression</a>
575     *
576     * @param text the expression to be evaluated
577     * @return the builder to continue processing the DSL
578     */
579    @Deprecated
580    public T python(String text) {
581        return expression(new PythonExpression(text));
582    }
583
584    /**
585     * Evaluates a {@link Expression} by looking up existing {@link Expression}
586     * from the {@link org.apache.camel.spi.Registry}
587     *
588     * @param ref refers to the expression to be evaluated
589     * @return the builder to continue processing the DSL
590     */
591    public T ref(String ref) {
592        return expression(new RefExpression(ref));
593    }
594
595    /**
596     * Evaluates a <a href="http://camel.apache.org/ruby.html">Ruby
597     * expression</a>
598     *
599     * @param text the expression to be evaluated
600     * @return the builder to continue processing the DSL
601     */
602    @Deprecated
603    public T ruby(String text) {
604        return expression(new RubyExpression(text));
605    }
606
607    /**
608     * Evaluates an <a href="http://camel.apache.org/spel.html">SpEL
609     * expression</a>
610     *
611     * @param text the expression to be evaluated
612     * @return the builder to continue processing the DSL
613     */
614    public T spel(String text) {
615        return expression(new SpELExpression(text));
616    }
617    
618    /**
619     * Evaluates an <a href="http://camel.apache.org/sql.html">SQL
620     * expression</a>
621     *
622     * @param text the expression to be evaluated
623     * @return the builder to continue processing the DSL
624     */
625    @Deprecated
626    public T sql(String text) {
627        return expression(new SqlExpression(text));
628    }
629
630    /**
631     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
632     * expression</a>
633     *
634     * @param text the expression to be evaluated
635     * @return the builder to continue processing the DSL
636     */
637    public T simple(String text) {
638        return expression(new SimpleExpression(text));
639    }
640
641    /**
642     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
643     * expression</a>
644     *
645     * @param text the expression to be evaluated
646     * @param resultType the result type
647     * @return the builder to continue processing the DSL
648     */
649    public T simple(String text, Class<?> resultType) {
650        SimpleExpression expression = new SimpleExpression(text);
651        expression.setResultType(resultType);
652        setExpressionType(expression);
653        return result;
654    }
655
656    /**
657     * Evaluates an <a href="http://camel.apache.org/hl7.html">HL7 Terser
658     * expression</a>
659     *
660     * @param text the expression to be evaluated
661     * @return the builder to continue processing the DSL
662     */
663    public T terser(String text) {
664        return expression(new TerserExpression(text));
665    }
666
667    /**
668     * Evaluates a token expression on the message body
669     *
670     * @param token the token
671     * @return the builder to continue processing the DSL
672     */
673    public T tokenize(String token) {
674        return tokenize(token, null, false);
675    }
676
677    /**
678     * Evaluates a token expression on the message body
679     *
680     * @param token the token
681     * @param group to group by the given number
682     * @return the builder to continue processing the DSL
683     */
684    public T tokenize(String token, int group) {
685        return tokenize(token, null, false, group);
686    }
687
688    /**
689     * Evaluates a token expression on the message body
690     *
691     * @param token the token
692     * @param group to group by the given number
693     * @param skipFirst whether to skip the very first element
694     * @return the builder to continue processing the DSL
695     */
696    public T tokenize(String token, int group, boolean skipFirst) {
697        return tokenize(token, null, false, group, skipFirst);
698    }
699
700    /**
701     * Evaluates a token expression on the message body
702     *
703     * @param token the token
704     * @param regex whether the token is a regular expression or not
705     * @return the builder to continue processing the DSL
706     */
707    public T tokenize(String token, boolean regex) {
708        return tokenize(token, null, regex);
709    }
710
711    /**
712     * Evaluates a token expression on the message body
713     *
714     * @param token the token
715     * @param regex whether the token is a regular expression or not
716     * @param group to group by the given number
717     * @return the builder to continue processing the DSL
718     */
719    public T tokenize(String token, boolean regex, int group) {
720        return tokenize(token, null, regex, group);
721    }
722
723    /**
724     * Evaluates a token expression on the given header
725     *
726     * @param token the token
727     * @param headerName name of header to tokenize
728     * @return the builder to continue processing the DSL
729     */
730    public T tokenize(String token, String headerName) {
731        return tokenize(token, headerName, false);
732    }
733
734    /**
735     * Evaluates a token expression on the given header
736     *
737     * @param token the token
738     * @param headerName name of header to tokenize
739     * @param regex whether the token is a regular expression or not
740     * @return the builder to continue processing the DSL
741     */
742    public T tokenize(String token, String headerName, boolean regex) {
743        TokenizerExpression expression = new TokenizerExpression();
744        expression.setToken(token);
745        expression.setHeaderName(headerName);
746        expression.setRegex(regex);
747        setExpressionType(expression);
748        return result;
749    }
750
751    /**
752     * Evaluates a token expression on the given header
753     *
754     * @param token the token
755     * @param headerName name of header to tokenize
756     * @param regex whether the token is a regular expression or not
757     * @param group to group by number of parts
758     * @return the builder to continue processing the DSL
759     */
760    public T tokenize(String token, String headerName, boolean regex, int group) {
761        return tokenize(token, headerName, regex, group, false);
762    }
763
764    /**
765     * Evaluates a token expression on the given header
766     *
767     * @param token the token
768     * @param headerName name of header to tokenize
769     * @param regex whether the token is a regular expression or not
770     * @param skipFirst whether to skip the very first element
771     * @return the builder to continue processing the DSL
772     */
773    public T tokenize(String token, String headerName, boolean regex, boolean skipFirst) {
774        TokenizerExpression expression = new TokenizerExpression();
775        expression.setToken(token);
776        expression.setHeaderName(headerName);
777        expression.setRegex(regex);
778        expression.setSkipFirst(skipFirst);
779        setExpressionType(expression);
780        return result;
781    }
782
783    /**
784     * Evaluates a token expression on the given header
785     *
786     * @param token the token
787     * @param headerName name of header to tokenize
788     * @param regex whether the token is a regular expression or not
789     * @param group to group by number of parts
790     * @param skipFirst whether to skip the very first element
791     * @return the builder to continue processing the DSL
792     */
793    public T tokenize(String token, String headerName, boolean regex, int group, boolean skipFirst) {
794        return tokenize(token, headerName, regex, "" + group, skipFirst);
795    }
796
797    /**
798     * Evaluates a token expression on the given header
799     *
800     * @param token the token
801     * @param headerName name of header to tokenize
802     * @param regex whether the token is a regular expression or not
803     * @param group to group by number of parts
804     * @param skipFirst whether to skip the very first element
805     * @return the builder to continue processing the DSL
806     */
807    public T tokenize(String token, String headerName, boolean regex, String group, boolean skipFirst) {
808        TokenizerExpression expression = new TokenizerExpression();
809        expression.setToken(token);
810        expression.setHeaderName(headerName);
811        expression.setRegex(regex);
812        expression.setGroup(group);
813        expression.setSkipFirst(skipFirst);
814        setExpressionType(expression);
815        return result;
816    }
817
818    /**
819     * Evaluates a token pair expression on the message body
820     *
821     * @param startToken the start token
822     * @param endToken   the end token
823     * @param includeTokens whether to include tokens
824     * @return the builder to continue processing the DSL
825     */
826    public T tokenizePair(String startToken, String endToken, boolean includeTokens) {
827        TokenizerExpression expression = new TokenizerExpression();
828        expression.setToken(startToken);
829        expression.setEndToken(endToken);
830        expression.setIncludeTokens(includeTokens);
831        setExpressionType(expression);
832        return result;
833    }
834
835    /**
836     * Evaluates a token pair expression on the message body with XML content
837     *
838     * @param tagName the the tag name of the child nodes to tokenize
839     * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
840     * @param group to group by the given number
841     * @return the builder to continue processing the DSL
842     */
843    public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, int group) {
844        return tokenizeXMLPair(tagName, inheritNamespaceTagName, "" + group);
845    }
846
847    /**
848     * Evaluates a token pair expression on the message body with XML content
849     *
850     * @param tagName the the tag name of the child nodes to tokenize
851     * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
852     * @param group to group by the given number
853     * @return the builder to continue processing the DSL
854     */
855    public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, String group) {
856        TokenizerExpression expression = new TokenizerExpression();
857        expression.setToken(tagName);
858        expression.setInheritNamespaceTagName(inheritNamespaceTagName);
859        expression.setXml(true);
860        expression.setGroup(group);
861        setExpressionType(expression);
862        return result;
863    }
864
865    /**
866     * Evaluates an XML token expression on the message body with XML content
867     * 
868     * @param path the xpath like path notation specifying the child nodes to tokenize
869     * @param mode one of 'i', 'w', or 'u' to inject the namespaces to the token, to
870     *        wrap the token with its ancestor contet, or to unwrap to its element child
871     * @param namespaces the namespace map to the namespace bindings 
872     * @param group to group by the given number
873     * @return the builder to continue processing the DSL
874     */
875    public T xtokenize(String path, char mode, Namespaces namespaces, int group) {
876        XMLTokenizerExpression expression = new XMLTokenizerExpression(path);
877        expression.setMode(Character.toString(mode));
878        expression.setNamespaces(namespaces.getNamespaces());
879
880        if (group > 0) {
881            expression.setGroup(group);
882        }
883        setExpressionType(expression);
884        return result;
885    }
886
887    /**
888     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
889     * expression</a>
890     *
891     * @param text the expression to be evaluated
892     * @return the builder to continue processing the DSL
893     */
894    public T xpath(String text) {
895        return expression(new XPathExpression(text));
896    }
897    
898    /**
899     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
900     * expression</a> on the supplied header name's contents
901     * 
902     * @param text the expression to be evaluated
903     * @param headerName the name of the header to apply the expression to
904     * @return the builder to continue processing the DSL
905     */
906    public T xpath(String text, String headerName) {
907        XPathExpression expression = new XPathExpression(text);
908        expression.setHeaderName(headerName);
909        return expression(expression);
910    }
911    
912    /**
913     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
914     * expression</a> with the specified result type
915     *
916     * @param text the expression to be evaluated
917     * @param resultType the return type expected by the expression
918     * @return the builder to continue processing the DSL
919     */
920    public T xpath(String text, Class<?> resultType) {
921        XPathExpression expression = new XPathExpression(text);
922        expression.setResultType(resultType);
923        setExpressionType(expression);
924        return result;
925    }
926
927    
928    /**
929     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
930     * expression</a> with the specified result type on the supplied
931     * header name's contents
932     *
933     * @param text the expression to be evaluated
934     * @param resultType the return type expected by the expression
935     * @param headerName the name of the header to apply the expression to
936     * @return the builder to continue processing the DSL
937     */
938    public T xpath(String text, Class<?> resultType, String headerName) {
939        XPathExpression expression = new XPathExpression(text);
940        expression.setHeaderName(headerName);
941        setExpressionType(expression);
942        return result;
943    }
944    
945
946    /**
947     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
948     * expression</a> with the specified result type and set of namespace
949     * prefixes and URIs
950     *
951     * @param text the expression to be evaluated
952     * @param resultType the return type expected by the expression
953     * @param namespaces the namespace prefix and URIs to use
954     * @return the builder to continue processing the DSL
955     */
956    public T xpath(String text, Class<?> resultType, Namespaces namespaces) {
957        return xpath(text, resultType, namespaces.getNamespaces());
958    }
959    
960    /**
961     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
962     * expression</a> with the specified result type and set of namespace
963     * prefixes and URIs on the supplied header name's contents
964     *
965     * @param text the expression to be evaluated
966     * @param resultType the return type expected by the expression
967     * @param namespaces the namespace prefix and URIs to use
968     * @param headerName the name of the header to apply the expression to
969     * @return the builder to continue processing the DSL
970     */
971    public T xpath(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
972        XPathExpression expression = new XPathExpression(text);
973        expression.setResultType(resultType);
974        expression.setNamespaces(namespaces.getNamespaces());
975        expression.setHeaderName(headerName);
976        setExpressionType(expression);
977        return result;
978    }
979
980
981    /**
982     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
983     * expression</a> with the specified result type and set of namespace
984     * prefixes and URIs
985     *
986     * @param text the expression to be evaluated
987     * @param resultType the return type expected by the expression
988     * @param namespaces the namespace prefix and URIs to use
989     * @return the builder to continue processing the DSL
990     */
991    public T xpath(String text, Class<?> resultType, Map<String, String> namespaces) {
992        XPathExpression expression = new XPathExpression(text);
993        expression.setResultType(resultType);
994        expression.setNamespaces(namespaces);
995        setExpressionType(expression);
996        return result;
997    }
998
999    /**
1000     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
1001     * expression</a> with the specified set of namespace prefixes and URIs
1002     *
1003     * @param text the expression to be evaluated
1004     * @param namespaces the namespace prefix and URIs to use
1005     * @return the builder to continue processing the DSL
1006     */
1007    public T xpath(String text, Namespaces namespaces) {
1008        return xpath(text, namespaces.getNamespaces());
1009    }
1010
1011    /**
1012     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
1013     * expression</a> with the specified set of namespace prefixes and URIs
1014     *
1015     * @param text the expression to be evaluated
1016     * @param namespaces the namespace prefix and URIs to use
1017     * @return the builder to continue processing the DSL
1018     */
1019    public T xpath(String text, Map<String, String> namespaces) {
1020        XPathExpression expression = new XPathExpression(text);
1021        expression.setNamespaces(namespaces);
1022        setExpressionType(expression);
1023        return result;
1024    }
1025
1026    /**
1027     * Evaluates an <a
1028     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1029     *
1030     * @param text the expression to be evaluated
1031     * @return the builder to continue processing the DSL
1032     */
1033    public T xquery(String text) {
1034        return expression(new XQueryExpression(text));
1035    }
1036
1037    /**
1038     * Evaluates an <a href="http://camel.apache.org/xquery.html">XQuery
1039     * expression</a>
1040     * 
1041     * @param text the expression to be evaluated
1042     * @param headerName the name of the header to apply the expression to
1043     * @return the builder to continue processing the DSL
1044     */
1045    public T xquery(String text, String headerName) {
1046        XQueryExpression expression = new XQueryExpression(text);
1047        expression.setHeaderName(headerName);
1048        return expression(expression);
1049    }
1050
1051    /**
1052     * Evaluates an <a
1053     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1054     * with the specified result type
1055     *
1056     * @param text the expression to be evaluated
1057     * @param resultType the return type expected by the expression
1058     * @return the builder to continue processing the DSL
1059     */
1060    public T xquery(String text, Class<?> resultType) {
1061        XQueryExpression expression = new XQueryExpression(text);
1062        expression.setResultType(resultType);
1063        setExpressionType(expression);
1064        return result;
1065    }
1066    
1067    
1068    /**
1069     * Evaluates an <a
1070     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1071     * with the specified result type
1072     *
1073     * @param text the expression to be evaluated
1074     * @param resultType the return type expected by the expression
1075     * @param headerName the name of the header to apply the expression to
1076     * @return the builder to continue processing the DSL
1077     */
1078    public T xquery(String text, Class<?> resultType, String headerName) {
1079        XQueryExpression expression = new XQueryExpression(text);
1080        expression.setHeaderName(headerName);
1081        setExpressionType(expression);
1082        return result;
1083    }
1084
1085    /**
1086     * Evaluates an <a
1087     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1088     * with the specified result type and set of namespace prefixes and URIs
1089     *
1090     * @param text the expression to be evaluated
1091     * @param resultType the return type expected by the expression
1092     * @param namespaces the namespace prefix and URIs to use
1093     * @return the builder to continue processing the DSL
1094     */
1095    public T xquery(String text, Class<?> resultType, Namespaces namespaces) {
1096        return xquery(text, resultType, namespaces.getNamespaces());
1097    }
1098    
1099    /**
1100     * Evaluates an <a
1101     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1102     * with the specified result type and set of namespace prefixes and URIs
1103     *
1104     * @param text the expression to be evaluated
1105     * @param resultType the return type expected by the expression
1106     * @param namespaces the namespace prefix and URIs to use
1107     * @param headerName the name of the header to apply the expression to
1108     * @return the builder to continue processing the DSL
1109     */
1110    public T xquery(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
1111        XQueryExpression expression = new XQueryExpression(text);
1112        expression.setResultType(resultType);
1113        expression.setNamespaces(namespaces.getNamespaces());
1114        expression.setHeaderName(headerName);
1115        setExpressionType(expression);
1116        return result;
1117    }
1118
1119
1120    
1121    /**
1122     * Evaluates an <a
1123     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1124     * with the specified result type and set of namespace prefixes and URIs
1125     *
1126     * @param text the expression to be evaluated
1127     * @param resultType the return type expected by the expression
1128     * @param namespaces the namespace prefix and URIs to use
1129     * @return the builder to continue processing the DSL
1130     */
1131    public T xquery(String text, Class<?> resultType, Map<String, String> namespaces) {
1132        XQueryExpression expression = new XQueryExpression(text);
1133        expression.setResultType(resultType);
1134        expression.setNamespaces(namespaces);
1135        setExpressionType(expression);
1136        return result;
1137    }
1138
1139    /**
1140     * Evaluates an <a
1141     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1142     * with the specified set of namespace prefixes and URIs
1143     *
1144     * @param text the expression to be evaluated
1145     * @param namespaces the namespace prefix and URIs to use
1146     * @return the builder to continue processing the DSL
1147     */
1148    public T xquery(String text, Namespaces namespaces) {
1149        return xquery(text, namespaces.getNamespaces());
1150    }
1151
1152    /**
1153     * Evaluates an <a
1154     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1155     * with the specified set of namespace prefixes and URIs
1156     *
1157     * @param text the expression to be evaluated
1158     * @param namespaces the namespace prefix and URIs to use
1159     * @return the builder to continue processing the DSL
1160     */
1161    public T xquery(String text, Map<String, String> namespaces) {
1162        XQueryExpression expression = new XQueryExpression(text);
1163        expression.setNamespaces(namespaces);
1164        setExpressionType(expression);
1165        return result;
1166    }
1167
1168    /**
1169     * Evaluates a given language name with the expression text
1170     *
1171     * @param language the name of the language
1172     * @param expression the expression in the given language
1173     * @return the builder to continue processing the DSL
1174     */
1175    public T language(String language, String expression) {
1176        LanguageExpression exp = new LanguageExpression(language, expression);
1177        setExpressionType(exp);
1178        return result;
1179    }
1180
1181    // Properties
1182    // -------------------------------------------------------------------------
1183
1184    public Expression getExpressionValue() {
1185        return expressionValue;
1186    }
1187
1188    public void setExpressionValue(Expression expressionValue) {
1189        this.expressionValue = expressionValue;
1190    }
1191
1192    public ExpressionDefinition getExpressionType() {
1193        return expressionType;
1194    }
1195
1196    public void setExpressionType(ExpressionDefinition expressionType) {
1197        this.expressionType = expressionType;
1198    }
1199
1200    protected Expression createExpression(CamelContext camelContext) {
1201        if (getExpressionValue() == null) {
1202            if (getExpressionType() != null) {
1203                setExpressionValue(getExpressionType().createExpression(camelContext));
1204            } else {
1205                throw new IllegalStateException("No expression value configured");
1206            }
1207        }
1208        return getExpressionValue();
1209    }
1210
1211    protected void configureExpression(CamelContext camelContext, Expression expression) {
1212    }
1213
1214}