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