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     * @deprecated JavaScript is deprecated in Java 11 onwards
337     */
338    @Deprecated
339    public T javaScript(String text) {
340        return expression(new JavaScriptExpression(text));
341    }
342
343    /**
344     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
345     * expression</a>
346     *
347     * @param text the expression to be evaluated
348     * @return the builder to continue processing the DSL
349     */
350    public T jsonpath(String text) {
351        return jsonpath(text, false);
352    }
353
354    /**
355     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
356     * expression</a>
357     *
358     * @param text the expression to be evaluated
359     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
360     * @return the builder to continue processing the DSL
361     */
362    public T jsonpath(String text, boolean suppressExceptions) {
363        JsonPathExpression expression = new JsonPathExpression(text);
364        expression.setSuppressExceptions(suppressExceptions);
365        return expression(expression);
366    }
367
368    /**
369     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
370     * expression</a>
371     *
372     * @param text the expression to be evaluated
373     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
374     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
375     * @return the builder to continue processing the DSL
376     */
377    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple) {
378        JsonPathExpression expression = new JsonPathExpression(text);
379        expression.setSuppressExceptions(suppressExceptions);
380        expression.setAllowSimple(allowSimple);
381        return expression(expression);
382    }
383
384    /**
385     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
386     * expression</a>
387     *
388     * @param text the expression to be evaluated
389     * @param resultType the return type expected by the expression
390     * @return the builder to continue processing the DSL
391     */
392    public T jsonpath(String text, Class<?> resultType) {
393        JsonPathExpression expression = new JsonPathExpression(text);
394        expression.setResultType(resultType);
395        setExpressionType(expression);
396        return result;
397    }
398
399    /**
400     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
401     * expression</a>
402     *
403     * @param text the expression to be evaluated
404     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
405     * @param resultType the return type expected by the expression
406     * @return the builder to continue processing the DSL
407     */
408    public T jsonpath(String text, boolean suppressExceptions, Class<?> resultType) {
409        JsonPathExpression expression = new JsonPathExpression(text);
410        expression.setSuppressExceptions(suppressExceptions);
411        expression.setResultType(resultType);
412        setExpressionType(expression);
413        return result;
414    }
415
416    /**
417     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
418     * expression</a>
419     *
420     * @param text the expression to be evaluated
421     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
422     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
423     * @param resultType the return type expected by the expression
424     * @return the builder to continue processing the DSL
425     */
426    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple, Class<?> resultType) {
427        JsonPathExpression expression = new JsonPathExpression(text);
428        expression.setSuppressExceptions(suppressExceptions);
429        expression.setAllowSimple(allowSimple);
430        expression.setResultType(resultType);
431        setExpressionType(expression);
432        return result;
433    }
434
435    /**
436     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
437     * expression</a>
438     *
439     * @param text the expression to be evaluated
440     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
441     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
442     * @param resultType the return type expected by the expression
443     * @param headerName the name of the header to apply the expression to
444     * @return the builder to continue processing the DSL
445     */
446    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple, Class<?> resultType, String headerName) {
447        JsonPathExpression expression = new JsonPathExpression(text);
448        expression.setSuppressExceptions(suppressExceptions);
449        expression.setAllowSimple(allowSimple);
450        expression.setResultType(resultType);
451        expression.setHeaderName(headerName);
452        setExpressionType(expression);
453        return result;
454    }
455
456    /**
457     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
458     * expression</a> with writeAsString enabled.
459     *
460     * @param text the expression to be evaluated
461     * @return the builder to continue processing the DSL
462     */
463    public T jsonpathWriteAsString(String text) {
464        return jsonpathWriteAsString(text, false);
465    }
466
467    /**
468     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
469     * expression</a> with writeAsString enabled.
470     *
471     * @param text the expression to be evaluated
472     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
473     * @return the builder to continue processing the DSL
474     */
475    public T jsonpathWriteAsString(String text, boolean suppressExceptions) {
476        JsonPathExpression expression = new JsonPathExpression(text);
477        expression.setWriteAsString(true);
478        expression.setSuppressExceptions(suppressExceptions);
479        return expression(expression);
480    }
481
482    /**
483     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
484     * expression</a> with writeAsString enabled.
485     *
486     * @param text the expression to be evaluated
487     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
488     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
489     * @return the builder to continue processing the DSL
490     */
491    public T jsonpathWriteAsString(String text, boolean suppressExceptions, boolean allowSimple) {
492        JsonPathExpression expression = new JsonPathExpression(text);
493        expression.setWriteAsString(true);
494        expression.setSuppressExceptions(suppressExceptions);
495        expression.setAllowSimple(allowSimple);
496        return expression(expression);
497    }
498
499    /**
500     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
501     * expression</a> with writeAsString enabled.
502     *
503     * @param text the expression to be evaluated
504     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
505     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
506     * @param headerName the name of the header to apply the expression to
507     * @return the builder to continue processing the DSL
508     */
509    public T jsonpathWriteAsString(String text, boolean suppressExceptions, boolean allowSimple, String headerName) {
510        JsonPathExpression expression = new JsonPathExpression(text);
511        expression.setWriteAsString(true);
512        expression.setSuppressExceptions(suppressExceptions);
513        expression.setAllowSimple(allowSimple);
514        expression.setHeaderName(headerName);
515        return expression(expression);
516    }
517
518    /**
519     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
520     *
521     * @param text the expression to be evaluated
522     * @return the builder to continue processing the DSL
523     */
524    @Deprecated
525    public T jxpath(String text) {
526        return jxpath(text, false);
527    }
528
529    /**
530     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
531     *
532     * @param text the expression to be evaluated
533     * @param lenient to configure whether lenient is in use or not
534     * @return the builder to continue processing the DSL
535     */
536    @Deprecated
537    public T jxpath(String text, boolean lenient) {
538        JXPathExpression answer = new JXPathExpression(text);
539        answer.setLenient(lenient);
540        return expression(answer);
541    }
542
543    /**
544     * Evaluates an <a href="http://camel.apache.org/ognl.html">OGNL
545     * expression</a>
546     *
547     * @param text the expression to be evaluated
548     * @return the builder to continue processing the DSL
549     */
550    public T ognl(String text) {
551        return expression(new OgnlExpression(text));
552    }
553
554    /**
555     * Evaluates a <a href="http://camel.apache.org/mvel.html">MVEL
556     * expression</a>
557     *
558     * @param text the expression to be evaluated
559     * @return the builder to continue processing the DSL
560     */
561    public T mvel(String text) {
562        return expression(new MvelExpression(text));
563    }
564
565    /**
566     * Evaluates a <a href="http://camel.apache.org/php.html">PHP
567     * expression</a>
568     *
569     * @param text the expression to be evaluated
570     * @return the builder to continue processing the DSL
571     */
572    @Deprecated
573    public T php(String text) {
574        return expression(new PhpExpression(text));
575    }
576
577    /**
578     * Evaluates a <a href="http://camel.apache.org/python.html">Python
579     * expression</a>
580     *
581     * @param text the expression to be evaluated
582     * @return the builder to continue processing the DSL
583     */
584    @Deprecated
585    public T python(String text) {
586        return expression(new PythonExpression(text));
587    }
588
589    /**
590     * Evaluates a {@link Expression} by looking up existing {@link Expression}
591     * from the {@link org.apache.camel.spi.Registry}
592     *
593     * @param ref refers to the expression to be evaluated
594     * @return the builder to continue processing the DSL
595     */
596    public T ref(String ref) {
597        return expression(new RefExpression(ref));
598    }
599
600    /**
601     * Evaluates a <a href="http://camel.apache.org/ruby.html">Ruby
602     * expression</a>
603     *
604     * @param text the expression to be evaluated
605     * @return the builder to continue processing the DSL
606     */
607    @Deprecated
608    public T ruby(String text) {
609        return expression(new RubyExpression(text));
610    }
611
612    /**
613     * Evaluates an <a href="http://camel.apache.org/spel.html">SpEL
614     * expression</a>
615     *
616     * @param text the expression to be evaluated
617     * @return the builder to continue processing the DSL
618     */
619    public T spel(String text) {
620        return expression(new SpELExpression(text));
621    }
622    
623    /**
624     * Evaluates an <a href="http://camel.apache.org/sql.html">SQL
625     * expression</a>
626     *
627     * @param text the expression to be evaluated
628     * @return the builder to continue processing the DSL
629     */
630    @Deprecated
631    public T sql(String text) {
632        return expression(new SqlExpression(text));
633    }
634
635    /**
636     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
637     * expression</a>
638     *
639     * @param text the expression to be evaluated
640     * @return the builder to continue processing the DSL
641     */
642    public T simple(String text) {
643        return expression(new SimpleExpression(text));
644    }
645
646    /**
647     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
648     * expression</a>
649     *
650     * @param text the expression to be evaluated
651     * @param resultType the result type
652     * @return the builder to continue processing the DSL
653     */
654    public T simple(String text, Class<?> resultType) {
655        SimpleExpression expression = new SimpleExpression(text);
656        expression.setResultType(resultType);
657        setExpressionType(expression);
658        return result;
659    }
660
661    /**
662     * Evaluates an <a href="http://camel.apache.org/hl7.html">HL7 Terser
663     * expression</a>
664     *
665     * @param text the expression to be evaluated
666     * @return the builder to continue processing the DSL
667     */
668    public T terser(String text) {
669        return expression(new TerserExpression(text));
670    }
671
672    /**
673     * Evaluates a token expression on the message body
674     *
675     * @param token the token
676     * @return the builder to continue processing the DSL
677     */
678    public T tokenize(String token) {
679        return tokenize(token, null, false);
680    }
681
682    /**
683     * Evaluates a token expression on the message body
684     *
685     * @param token the token
686     * @param group to group by the given number
687     * @return the builder to continue processing the DSL
688     */
689    public T tokenize(String token, int group) {
690        return tokenize(token, null, false, group);
691    }
692
693    /**
694     * Evaluates a token expression on the message body
695     *
696     * @param token the token
697     * @param group to group by the given number
698     * @param skipFirst whether to skip the very first element
699     * @return the builder to continue processing the DSL
700     */
701    public T tokenize(String token, int group, boolean skipFirst) {
702        return tokenize(token, null, false, group, skipFirst);
703    }
704
705    /**
706     * Evaluates a token expression on the message body
707     *
708     * @param token the token
709     * @param regex whether the token is a regular expression or not
710     * @return the builder to continue processing the DSL
711     */
712    public T tokenize(String token, boolean regex) {
713        return tokenize(token, null, regex);
714    }
715
716    /**
717     * Evaluates a token expression on the message body
718     *
719     * @param token the token
720     * @param regex whether the token is a regular expression or not
721     * @param group to group by the given number
722     * @return the builder to continue processing the DSL
723     */
724    public T tokenize(String token, boolean regex, int group) {
725        return tokenize(token, null, regex, group);
726    }
727
728    /**
729     * Evaluates a token expression on the given header
730     *
731     * @param token the token
732     * @param headerName name of header to tokenize
733     * @return the builder to continue processing the DSL
734     */
735    public T tokenize(String token, String headerName) {
736        return tokenize(token, headerName, false);
737    }
738
739    /**
740     * Evaluates a token expression on the given header
741     *
742     * @param token the token
743     * @param headerName name of header to tokenize
744     * @param regex whether the token is a regular expression or not
745     * @return the builder to continue processing the DSL
746     */
747    public T tokenize(String token, String headerName, boolean regex) {
748        TokenizerExpression expression = new TokenizerExpression();
749        expression.setToken(token);
750        expression.setHeaderName(headerName);
751        expression.setRegex(regex);
752        setExpressionType(expression);
753        return result;
754    }
755
756    /**
757     * Evaluates a token expression on the given header
758     *
759     * @param token the token
760     * @param headerName name of header to tokenize
761     * @param regex whether the token is a regular expression or not
762     * @param group to group by number of parts
763     * @return the builder to continue processing the DSL
764     */
765    public T tokenize(String token, String headerName, boolean regex, int group) {
766        return tokenize(token, headerName, regex, group, false);
767    }
768
769    /**
770     * Evaluates a token expression on the given header
771     *
772     * @param token the token
773     * @param headerName name of header to tokenize
774     * @param regex whether the token is a regular expression or not
775     * @param skipFirst whether to skip the very first element
776     * @return the builder to continue processing the DSL
777     */
778    public T tokenize(String token, String headerName, boolean regex, boolean skipFirst) {
779        TokenizerExpression expression = new TokenizerExpression();
780        expression.setToken(token);
781        expression.setHeaderName(headerName);
782        expression.setRegex(regex);
783        expression.setSkipFirst(skipFirst);
784        setExpressionType(expression);
785        return result;
786    }
787
788    /**
789     * Evaluates a token expression on the given header
790     *
791     * @param token the token
792     * @param headerName name of header to tokenize
793     * @param regex whether the token is a regular expression or not
794     * @param group to group by number of parts
795     * @param skipFirst whether to skip the very first element
796     * @return the builder to continue processing the DSL
797     */
798    public T tokenize(String token, String headerName, boolean regex, int group, boolean skipFirst) {
799        return tokenize(token, headerName, regex, "" + group, skipFirst);
800    }
801
802    /**
803     * Evaluates a token expression on the given header
804     *
805     * @param token the token
806     * @param headerName name of header to tokenize
807     * @param regex whether the token is a regular expression or not
808     * @param group to group by number of parts
809     * @param skipFirst whether to skip the very first element
810     * @return the builder to continue processing the DSL
811     */
812    public T tokenize(String token, String headerName, boolean regex, String group, boolean skipFirst) {
813        TokenizerExpression expression = new TokenizerExpression();
814        expression.setToken(token);
815        expression.setHeaderName(headerName);
816        expression.setRegex(regex);
817        expression.setGroup(group);
818        expression.setSkipFirst(skipFirst);
819        setExpressionType(expression);
820        return result;
821    }
822
823    /**
824     * Evaluates a token pair expression on the message body
825     *
826     * @param startToken the start token
827     * @param endToken   the end token
828     * @param includeTokens whether to include tokens
829     * @return the builder to continue processing the DSL
830     */
831    public T tokenizePair(String startToken, String endToken, boolean includeTokens) {
832        TokenizerExpression expression = new TokenizerExpression();
833        expression.setToken(startToken);
834        expression.setEndToken(endToken);
835        expression.setIncludeTokens(includeTokens);
836        setExpressionType(expression);
837        return result;
838    }
839
840    /**
841     * Evaluates a token pair expression on the message body with XML content
842     *
843     * @param tagName the tag name of the child nodes to tokenize
844     * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
845     * @param group to group by the given number
846     * @return the builder to continue processing the DSL
847     */
848    public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, int group) {
849        return tokenizeXMLPair(tagName, inheritNamespaceTagName, "" + group);
850    }
851
852    /**
853     * Evaluates a token pair expression on the message body with XML content
854     *
855     * @param tagName the tag name of the child nodes to tokenize
856     * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
857     * @param group to group by the given number
858     * @return the builder to continue processing the DSL
859     */
860    public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, String group) {
861        TokenizerExpression expression = new TokenizerExpression();
862        expression.setToken(tagName);
863        expression.setInheritNamespaceTagName(inheritNamespaceTagName);
864        expression.setXml(true);
865        expression.setGroup(group);
866        setExpressionType(expression);
867        return result;
868    }
869
870    /**
871     * Evaluates an XML token expression on the message body with XML content
872     * 
873     * @param path the xpath like path notation specifying the child nodes to tokenize
874     * @param mode one of 'i', 'w', or 'u' to inject the namespaces to the token, to
875     *        wrap the token with its ancestor contet, or to unwrap to its element child
876     * @param namespaces the namespace map to the namespace bindings 
877     * @param group to group by the given number
878     * @return the builder to continue processing the DSL
879     */
880    public T xtokenize(String path, char mode, Namespaces namespaces, int group) {
881        XMLTokenizerExpression expression = new XMLTokenizerExpression(path);
882        expression.setMode(Character.toString(mode));
883        expression.setNamespaces(namespaces.getNamespaces());
884
885        if (group > 0) {
886            expression.setGroup(group);
887        }
888        setExpressionType(expression);
889        return result;
890    }
891
892    /**
893     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
894     * expression</a>
895     *
896     * @param text the expression to be evaluated
897     * @return the builder to continue processing the DSL
898     */
899    public T xpath(String text) {
900        return expression(new XPathExpression(text));
901    }
902    
903    /**
904     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
905     * expression</a> on the supplied header name's contents
906     * 
907     * @param text the expression to be evaluated
908     * @param headerName the name of the header to apply the expression to
909     * @return the builder to continue processing the DSL
910     */
911    public T xpath(String text, String headerName) {
912        XPathExpression expression = new XPathExpression(text);
913        expression.setHeaderName(headerName);
914        return expression(expression);
915    }
916    
917    /**
918     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
919     * expression</a> with the specified result type
920     *
921     * @param text the expression to be evaluated
922     * @param resultType the return type expected by the expression
923     * @return the builder to continue processing the DSL
924     */
925    public T xpath(String text, Class<?> resultType) {
926        XPathExpression expression = new XPathExpression(text);
927        expression.setResultType(resultType);
928        setExpressionType(expression);
929        return result;
930    }
931
932    
933    /**
934     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
935     * expression</a> with the specified result type on the supplied
936     * header name's contents
937     *
938     * @param text the expression to be evaluated
939     * @param resultType the return type expected by the expression
940     * @param headerName the name of the header to apply the expression to
941     * @return the builder to continue processing the DSL
942     */
943    public T xpath(String text, Class<?> resultType, String headerName) {
944        XPathExpression expression = new XPathExpression(text);
945        expression.setHeaderName(headerName);
946        setExpressionType(expression);
947        return result;
948    }
949    
950
951    /**
952     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
953     * expression</a> with the specified result type and set of namespace
954     * prefixes and URIs
955     *
956     * @param text the expression to be evaluated
957     * @param resultType the return type expected by the expression
958     * @param namespaces the namespace prefix and URIs to use
959     * @return the builder to continue processing the DSL
960     */
961    public T xpath(String text, Class<?> resultType, Namespaces namespaces) {
962        return xpath(text, resultType, namespaces.getNamespaces());
963    }
964    
965    /**
966     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
967     * expression</a> with the specified result type and set of namespace
968     * prefixes and URIs on the supplied header name's contents
969     *
970     * @param text the expression to be evaluated
971     * @param resultType the return type expected by the expression
972     * @param namespaces the namespace prefix and URIs to use
973     * @param headerName the name of the header to apply the expression to
974     * @return the builder to continue processing the DSL
975     */
976    public T xpath(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
977        XPathExpression expression = new XPathExpression(text);
978        expression.setResultType(resultType);
979        expression.setNamespaces(namespaces.getNamespaces());
980        expression.setHeaderName(headerName);
981        setExpressionType(expression);
982        return result;
983    }
984
985
986    /**
987     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
988     * expression</a> with the specified result type and set of namespace
989     * prefixes and URIs
990     *
991     * @param text the expression to be evaluated
992     * @param resultType the return type expected by the expression
993     * @param namespaces the namespace prefix and URIs to use
994     * @return the builder to continue processing the DSL
995     */
996    public T xpath(String text, Class<?> resultType, Map<String, String> namespaces) {
997        XPathExpression expression = new XPathExpression(text);
998        expression.setResultType(resultType);
999        expression.setNamespaces(namespaces);
1000        setExpressionType(expression);
1001        return result;
1002    }
1003
1004    /**
1005     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
1006     * expression</a> with the specified set of namespace prefixes and URIs
1007     *
1008     * @param text the expression to be evaluated
1009     * @param namespaces the namespace prefix and URIs to use
1010     * @return the builder to continue processing the DSL
1011     */
1012    public T xpath(String text, Namespaces namespaces) {
1013        return xpath(text, namespaces.getNamespaces());
1014    }
1015
1016    /**
1017     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
1018     * expression</a> with the specified set of namespace prefixes and URIs
1019     *
1020     * @param text the expression to be evaluated
1021     * @param namespaces the namespace prefix and URIs to use
1022     * @return the builder to continue processing the DSL
1023     */
1024    public T xpath(String text, Map<String, String> namespaces) {
1025        XPathExpression expression = new XPathExpression(text);
1026        expression.setNamespaces(namespaces);
1027        setExpressionType(expression);
1028        return result;
1029    }
1030
1031    /**
1032     * Evaluates an <a
1033     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1034     *
1035     * @param text the expression to be evaluated
1036     * @return the builder to continue processing the DSL
1037     */
1038    public T xquery(String text) {
1039        return expression(new XQueryExpression(text));
1040    }
1041
1042    /**
1043     * Evaluates an <a href="http://camel.apache.org/xquery.html">XQuery
1044     * expression</a>
1045     * 
1046     * @param text the expression to be evaluated
1047     * @param headerName the name of the header to apply the expression to
1048     * @return the builder to continue processing the DSL
1049     */
1050    public T xquery(String text, String headerName) {
1051        XQueryExpression expression = new XQueryExpression(text);
1052        expression.setHeaderName(headerName);
1053        return expression(expression);
1054    }
1055
1056    /**
1057     * Evaluates an <a
1058     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1059     * with the specified result type
1060     *
1061     * @param text the expression to be evaluated
1062     * @param resultType the return type expected by the expression
1063     * @return the builder to continue processing the DSL
1064     */
1065    public T xquery(String text, Class<?> resultType) {
1066        XQueryExpression expression = new XQueryExpression(text);
1067        expression.setResultType(resultType);
1068        setExpressionType(expression);
1069        return result;
1070    }
1071    
1072    
1073    /**
1074     * Evaluates an <a
1075     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1076     * with the specified result type
1077     *
1078     * @param text the expression to be evaluated
1079     * @param resultType the return type expected by the expression
1080     * @param headerName the name of the header to apply the expression to
1081     * @return the builder to continue processing the DSL
1082     */
1083    public T xquery(String text, Class<?> resultType, String headerName) {
1084        XQueryExpression expression = new XQueryExpression(text);
1085        expression.setHeaderName(headerName);
1086        setExpressionType(expression);
1087        return result;
1088    }
1089
1090    /**
1091     * Evaluates an <a
1092     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1093     * with the specified result type and set of namespace prefixes and URIs
1094     *
1095     * @param text the expression to be evaluated
1096     * @param resultType the return type expected by the expression
1097     * @param namespaces the namespace prefix and URIs to use
1098     * @return the builder to continue processing the DSL
1099     */
1100    public T xquery(String text, Class<?> resultType, Namespaces namespaces) {
1101        return xquery(text, resultType, namespaces.getNamespaces());
1102    }
1103    
1104    /**
1105     * Evaluates an <a
1106     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1107     * with the specified result type and set of namespace prefixes and URIs
1108     *
1109     * @param text the expression to be evaluated
1110     * @param resultType the return type expected by the expression
1111     * @param namespaces the namespace prefix and URIs to use
1112     * @param headerName the name of the header to apply the expression to
1113     * @return the builder to continue processing the DSL
1114     */
1115    public T xquery(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
1116        XQueryExpression expression = new XQueryExpression(text);
1117        expression.setResultType(resultType);
1118        expression.setNamespaces(namespaces.getNamespaces());
1119        expression.setHeaderName(headerName);
1120        setExpressionType(expression);
1121        return result;
1122    }
1123
1124
1125    
1126    /**
1127     * Evaluates an <a
1128     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1129     * with the specified result type and set of namespace prefixes and URIs
1130     *
1131     * @param text the expression to be evaluated
1132     * @param resultType the return type expected by the expression
1133     * @param namespaces the namespace prefix and URIs to use
1134     * @return the builder to continue processing the DSL
1135     */
1136    public T xquery(String text, Class<?> resultType, Map<String, String> namespaces) {
1137        XQueryExpression expression = new XQueryExpression(text);
1138        expression.setResultType(resultType);
1139        expression.setNamespaces(namespaces);
1140        setExpressionType(expression);
1141        return result;
1142    }
1143
1144    /**
1145     * Evaluates an <a
1146     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1147     * with the specified set of namespace prefixes and URIs
1148     *
1149     * @param text the expression to be evaluated
1150     * @param namespaces the namespace prefix and URIs to use
1151     * @return the builder to continue processing the DSL
1152     */
1153    public T xquery(String text, Namespaces namespaces) {
1154        return xquery(text, namespaces.getNamespaces());
1155    }
1156
1157    /**
1158     * Evaluates an <a
1159     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1160     * with the specified set of namespace prefixes and URIs
1161     *
1162     * @param text the expression to be evaluated
1163     * @param namespaces the namespace prefix and URIs to use
1164     * @return the builder to continue processing the DSL
1165     */
1166    public T xquery(String text, Map<String, String> namespaces) {
1167        XQueryExpression expression = new XQueryExpression(text);
1168        expression.setNamespaces(namespaces);
1169        setExpressionType(expression);
1170        return result;
1171    }
1172
1173    /**
1174     * Evaluates a given language name with the expression text
1175     *
1176     * @param language the name of the language
1177     * @param expression the expression in the given language
1178     * @return the builder to continue processing the DSL
1179     */
1180    public T language(String language, String expression) {
1181        LanguageExpression exp = new LanguageExpression(language, expression);
1182        setExpressionType(exp);
1183        return result;
1184    }
1185
1186    // Properties
1187    // -------------------------------------------------------------------------
1188
1189    public Expression getExpressionValue() {
1190        return expressionValue;
1191    }
1192
1193    public void setExpressionValue(Expression expressionValue) {
1194        this.expressionValue = expressionValue;
1195    }
1196
1197    public ExpressionDefinition getExpressionType() {
1198        return expressionType;
1199    }
1200
1201    public void setExpressionType(ExpressionDefinition expressionType) {
1202        this.expressionType = expressionType;
1203    }
1204
1205    protected Expression createExpression(CamelContext camelContext) {
1206        if (getExpressionValue() == null) {
1207            if (getExpressionType() != null) {
1208                setExpressionValue(getExpressionType().createExpression(camelContext));
1209            } else {
1210                throw new IllegalStateException("No expression value configured");
1211            }
1212        }
1213        return getExpressionValue();
1214    }
1215
1216    protected void configureExpression(CamelContext camelContext, Expression expression) {
1217    }
1218
1219}