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