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