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    public T properties() {
205        return expression(ExpressionBuilder.propertiesExpression());
206    }
207
208    // Languages
209    // -------------------------------------------------------------------------
210
211    /**
212     * Evaluates an expression using the <a
213     * href="http://camel.apache.org/bean-language.html>bean language</a>
214     * which basically means the bean is invoked to determine the expression
215     * value.
216     *
217     * @param bean the name of the bean looked up the registry
218     * @return the builder to continue processing the DSL
219     */
220    public T method(String bean) {
221        return expression(new MethodCallExpression(bean));
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 instance the instance of the bean
231     * @return the builder to continue processing the DSL
232     */
233    public T method(Object instance) {
234        return expression(new MethodCallExpression(instance));
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 beanType the Class of the bean which we want to invoke
244     * @return the builder to continue processing the DSL
245     */
246    public T method(Class<?> beanType) {
247        return expression(new MethodCallExpression(beanType));
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 bean the name of the bean looked up the registry
257     * @param method the name of the method to invoke on the bean
258     * @return the builder to continue processing the DSL
259     */
260    public T method(String bean, String method) {
261        return expression(new MethodCallExpression(bean, method));
262    }
263
264    /**
265     * Evaluates an expression using the <a
266     * href="http://camel.apache.org/bean-language.html>bean language</a>
267     * which basically means the bean is invoked to determine the expression
268     * value.
269     *
270     * @param instance the instance of the bean
271     * @param method the name of the method to invoke on the bean
272     * @return the builder to continue processing the DSL
273     */
274    public T method(Object instance, String method) {
275        return expression(new MethodCallExpression(instance, method));
276    }
277
278    /**
279     * Evaluates an expression using the <a
280     * href="http://camel.apache.org/bean-language.html>bean language</a>
281     * which basically means the bean is invoked to determine the expression
282     * value.
283     *
284     * @param beanType the Class of the bean which we want to invoke
285     * @param method the name of the method to invoke on the bean
286     * @return the builder to continue processing the DSL
287     */
288    public T method(Class<?> beanType, String method) {
289        return expression(new MethodCallExpression(beanType, method));
290    }
291
292    /**
293     * Evaluates the <a href="http://camel.apache.org/el.html">EL
294     * Language from JSP and JSF</a> using the <a
295     * href="http://camel.apache.org/juel.html">JUEL library</a>
296     *
297     * @param text the expression to be evaluated
298     * @return the builder to continue processing the DSL
299     */
300    public T el(String text) {
301        return expression(new ELExpression(text));
302    }
303
304    /**
305     * Evaluates a <a href="http://camel.apache.org/groovy.html">Groovy
306     * expression</a>
307     *
308     * @param text the expression to be evaluated
309     * @return the builder to continue processing the DSL
310     */
311    public T groovy(String text) {
312        return expression(new GroovyExpression(text));
313    }
314
315    /**
316     * Evaluates a <a
317     * href="http://camel.apache.org/java-script.html">JavaScript
318     * expression</a>
319     *
320     * @param text the expression to be evaluated
321     * @return the builder to continue processing the DSL
322     */
323    public T javaScript(String text) {
324        return expression(new JavaScriptExpression(text));
325    }
326
327    /**
328     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
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 jsonpath(String text) {
335        return jsonpath(text, false);
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     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
344     * @return the builder to continue processing the DSL
345     */
346    public T jsonpath(String text, boolean suppressExceptions) {
347        JsonPathExpression expression = new JsonPathExpression(text);
348        expression.setSuppressExceptions(suppressExceptions);
349        return expression(expression);
350    }
351
352    /**
353     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
354     * expression</a>
355     *
356     * @param text the expression to be evaluated
357     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
358     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
359     * @return the builder to continue processing the DSL
360     */
361    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple) {
362        JsonPathExpression expression = new JsonPathExpression(text);
363        expression.setSuppressExceptions(suppressExceptions);
364        expression.setAllowSimple(allowSimple);
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 resultType the return type expected by the expression
374     * @return the builder to continue processing the DSL
375     */
376    public T jsonpath(String text, Class<?> resultType) {
377        JsonPathExpression expression = new JsonPathExpression(text);
378        expression.setResultType(resultType);
379        setExpressionType(expression);
380        return result;
381    }
382
383    /**
384     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
385     * expression</a>
386     *
387     * @param text the expression to be evaluated
388     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
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, boolean suppressExceptions, Class<?> resultType) {
393        JsonPathExpression expression = new JsonPathExpression(text);
394        expression.setSuppressExceptions(suppressExceptions);
395        expression.setResultType(resultType);
396        setExpressionType(expression);
397        return result;
398    }
399
400    /**
401     * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path
402     * expression</a>
403     *
404     * @param text the expression to be evaluated
405     * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException
406     * @param allowSimple whether to allow in inlined simple exceptions in the json path expression
407     * @param resultType the return type expected by the expression
408     * @return the builder to continue processing the DSL
409     */
410    public T jsonpath(String text, boolean suppressExceptions, boolean allowSimple, Class<?> resultType) {
411        JsonPathExpression expression = new JsonPathExpression(text);
412        expression.setSuppressExceptions(suppressExceptions);
413        expression.setAllowSimple(allowSimple);
414        expression.setResultType(resultType);
415        setExpressionType(expression);
416        return result;
417    }
418
419    /**
420     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
421     *
422     * @param text the expression to be evaluated
423     * @return the builder to continue processing the DSL
424     */
425    public T jxpath(String text) {
426        return jxpath(text, false);
427    }
428
429    /**
430     * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a>
431     *
432     * @param text the expression to be evaluated
433     * @param lenient to configure whether lenient is in use or not
434     * @return the builder to continue processing the DSL
435     */
436    public T jxpath(String text, boolean lenient) {
437        JXPathExpression answer = new JXPathExpression(text);
438        answer.setLenient(lenient);
439        return expression(answer);
440    }
441
442    /**
443     * Evaluates an <a href="http://camel.apache.org/ognl.html">OGNL
444     * expression</a>
445     *
446     * @param text the expression to be evaluated
447     * @return the builder to continue processing the DSL
448     */
449    public T ognl(String text) {
450        return expression(new OgnlExpression(text));
451    }
452
453    /**
454     * Evaluates a <a href="http://camel.apache.org/mvel.html">MVEL
455     * expression</a>
456     *
457     * @param text the expression to be evaluated
458     * @return the builder to continue processing the DSL
459     */
460    public T mvel(String text) {
461        return expression(new MvelExpression(text));
462    }
463
464    /**
465     * Evaluates a <a href="http://camel.apache.org/php.html">PHP
466     * expression</a>
467     *
468     * @param text the expression to be evaluated
469     * @return the builder to continue processing the DSL
470     */
471    public T php(String text) {
472        return expression(new PhpExpression(text));
473    }
474
475    /**
476     * Evaluates a <a href="http://camel.apache.org/python.html">Python
477     * expression</a>
478     *
479     * @param text the expression to be evaluated
480     * @return the builder to continue processing the DSL
481     */
482    public T python(String text) {
483        return expression(new PythonExpression(text));
484    }
485
486    /**
487     * Evaluates a {@link Expression} by looking up existing {@link Expression}
488     * from the {@link org.apache.camel.spi.Registry}
489     *
490     * @param ref refers to the expression to be evaluated
491     * @return the builder to continue processing the DSL
492     */
493    public T ref(String ref) {
494        return expression(new RefExpression(ref));
495    }
496
497    /**
498     * Evaluates a <a href="http://camel.apache.org/ruby.html">Ruby
499     * expression</a>
500     *
501     * @param text the expression to be evaluated
502     * @return the builder to continue processing the DSL
503     */
504    public T ruby(String text) {
505        return expression(new RubyExpression(text));
506    }
507
508    /**
509     * Evaluates an <a href="http://camel.apache.org/spel.html">SpEL
510     * expression</a>
511     *
512     * @param text the expression to be evaluated
513     * @return the builder to continue processing the DSL
514     */
515    public T spel(String text) {
516        return expression(new SpELExpression(text));
517    }
518    
519    /**
520     * Evaluates an <a href="http://camel.apache.org/sql.html">SQL
521     * expression</a>
522     *
523     * @param text the expression to be evaluated
524     * @return the builder to continue processing the DSL
525     */
526    public T sql(String text) {
527        return expression(new SqlExpression(text));
528    }
529
530    /**
531     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
532     * expression</a>
533     *
534     * @param text the expression to be evaluated
535     * @return the builder to continue processing the DSL
536     */
537    public T simple(String text) {
538        return expression(new SimpleExpression(text));
539    }
540
541    /**
542     * Evaluates a <a href="http://camel.apache.org/simple.html">Simple
543     * expression</a>
544     *
545     * @param text the expression to be evaluated
546     * @param resultType the result type
547     * @return the builder to continue processing the DSL
548     */
549    public T simple(String text, Class<?> resultType) {
550        SimpleExpression expression = new SimpleExpression(text);
551        expression.setResultType(resultType);
552        setExpressionType(expression);
553        return result;
554    }
555
556    /**
557     * Evaluates an <a href="http://camel.apache.org/hl7.html">HL7 Terser
558     * expression</a>
559     *
560     * @param text the expression to be evaluated
561     * @return the builder to continue processing the DSL
562     */
563    public T terser(String text) {
564        return expression(new TerserExpression(text));
565    }
566
567    /**
568     * Evaluates a token expression on the message body
569     *
570     * @param token the token
571     * @return the builder to continue processing the DSL
572     */
573    public T tokenize(String token) {
574        return tokenize(token, null, false);
575    }
576
577    /**
578     * Evaluates a token expression on the message body
579     *
580     * @param token the token
581     * @param group to group by the given number
582     * @return the builder to continue processing the DSL
583     */
584    public T tokenize(String token, int group) {
585        return tokenize(token, null, false, group);
586    }
587
588    /**
589     * Evaluates a token expression on the message body
590     *
591     * @param token the token
592     * @param group to group by the given number
593     * @param skipFirst whether to skip the very first element
594     * @return the builder to continue processing the DSL
595     */
596    public T tokenize(String token, int group, boolean skipFirst) {
597        return tokenize(token, null, false, group, skipFirst);
598    }
599
600    /**
601     * Evaluates a token expression on the message body
602     *
603     * @param token the token
604     * @param regex whether the token is a regular expression or not
605     * @return the builder to continue processing the DSL
606     */
607    public T tokenize(String token, boolean regex) {
608        return tokenize(token, null, regex);
609    }
610
611    /**
612     * Evaluates a token expression on the message body
613     *
614     * @param token the token
615     * @param regex whether the token is a regular expression or not
616     * @param group to group by the given number
617     * @return the builder to continue processing the DSL
618     */
619    public T tokenize(String token, boolean regex, int group) {
620        return tokenize(token, null, regex, group);
621    }
622
623    /**
624     * Evaluates a token expression on the given header
625     *
626     * @param token the token
627     * @param headerName name of header to tokenize
628     * @return the builder to continue processing the DSL
629     */
630    public T tokenize(String token, String headerName) {
631        return tokenize(token, headerName, false);
632    }
633
634    /**
635     * Evaluates a token expression on the given header
636     *
637     * @param token the token
638     * @param headerName name of header to tokenize
639     * @param regex whether the token is a regular expression or not
640     * @return the builder to continue processing the DSL
641     */
642    public T tokenize(String token, String headerName, boolean regex) {
643        TokenizerExpression expression = new TokenizerExpression();
644        expression.setToken(token);
645        expression.setHeaderName(headerName);
646        expression.setRegex(regex);
647        setExpressionType(expression);
648        return result;
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     * @param group to group by number of parts
658     * @return the builder to continue processing the DSL
659     */
660    public T tokenize(String token, String headerName, boolean regex, int group) {
661        return tokenize(token, headerName, regex, group, false);
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 skipFirst whether to skip the very first element
671     * @return the builder to continue processing the DSL
672     */
673    public T tokenize(String token, String headerName, boolean regex, boolean skipFirst) {
674        TokenizerExpression expression = new TokenizerExpression();
675        expression.setToken(token);
676        expression.setHeaderName(headerName);
677        expression.setRegex(regex);
678        expression.setSkipFirst(skipFirst);
679        setExpressionType(expression);
680        return result;
681    }
682
683    /**
684     * Evaluates a token expression on the given header
685     *
686     * @param token the token
687     * @param headerName name of header to tokenize
688     * @param regex whether the token is a regular expression or not
689     * @param group to group by number of parts
690     * @param skipFirst whether to skip the very first element
691     * @return the builder to continue processing the DSL
692     */
693    public T tokenize(String token, String headerName, boolean regex, int group, boolean skipFirst) {
694        TokenizerExpression expression = new TokenizerExpression();
695        expression.setToken(token);
696        expression.setHeaderName(headerName);
697        expression.setRegex(regex);
698        expression.setGroup(group);
699        expression.setSkipFirst(skipFirst);
700        setExpressionType(expression);
701        return result;
702    }
703
704    /**
705     * Evaluates a token pair expression on the message body
706     *
707     * @param startToken the start token
708     * @param endToken   the end token
709     * @param includeTokens whether to include tokens
710     * @return the builder to continue processing the DSL
711     */
712    public T tokenizePair(String startToken, String endToken, boolean includeTokens) {
713        TokenizerExpression expression = new TokenizerExpression();
714        expression.setToken(startToken);
715        expression.setEndToken(endToken);
716        expression.setIncludeTokens(includeTokens);
717        setExpressionType(expression);
718        return result;
719    }
720
721    /**
722     * Evaluates a token pair expression on the message body with XML content
723     *
724     * @param tagName the the tag name of the child nodes to tokenize
725     * @param inheritNamespaceTagName  optional parent or root tag name that contains namespace(s) to inherit
726     * @param group to group by the given number
727     * @return the builder to continue processing the DSL
728     */
729    public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName, int group) {
730        TokenizerExpression expression = new TokenizerExpression();
731        expression.setToken(tagName);
732        expression.setInheritNamespaceTagName(inheritNamespaceTagName);
733        expression.setXml(true);
734        if (group > 0) {
735            expression.setGroup(group);
736        }
737        setExpressionType(expression);
738        return result;
739    }
740
741    /**
742     * Evaluates an XML token expression on the message body with XML content
743     * 
744     * @param path the xpath like path notation specifying the child nodes to tokenize
745     * @param mode one of 'i', 'w', or 'u' to inject the namespaces to the token, to
746     *        wrap the token with its ancestor contet, or to unwrap to its element child
747     * @param namespaces the namespace map to the namespace bindings 
748     * @param group to group by the given number
749     * @return the builder to continue processing the DSL
750     */
751    public T xtokenize(String path, char mode, Namespaces namespaces, int group) {
752        XMLTokenizerExpression expression = new XMLTokenizerExpression(path);
753        expression.setMode(Character.toString(mode));
754        expression.setNamespaces(namespaces.getNamespaces());
755
756        if (group > 0) {
757            expression.setGroup(group);
758        }
759        setExpressionType(expression);
760        return result;
761    }
762
763    /**
764     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
765     * expression</a>
766     *
767     * @param text the expression to be evaluated
768     * @return the builder to continue processing the DSL
769     */
770    public T xpath(String text) {
771        return expression(new XPathExpression(text));
772    }
773    
774    /**
775     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
776     * expression</a> on the supplied header name's contents
777     * 
778     * @param text the expression to be evaluated
779     * @param headerName the name of the header to apply the expression to
780     * @return the builder to continue processing the DSL
781     */
782    public T xpath(String text, String headerName) {
783        XPathExpression expression = new XPathExpression(text);
784        expression.setHeaderName(headerName);
785        return expression(expression);
786    }
787    
788    /**
789     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
790     * expression</a> with the specified result type
791     *
792     * @param text the expression to be evaluated
793     * @param resultType the return type expected by the expression
794     * @return the builder to continue processing the DSL
795     */
796    public T xpath(String text, Class<?> resultType) {
797        XPathExpression expression = new XPathExpression(text);
798        expression.setResultType(resultType);
799        setExpressionType(expression);
800        return result;
801    }
802
803    
804    /**
805     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
806     * expression</a> with the specified result type on the supplied
807     * header name's contents
808     *
809     * @param text the expression to be evaluated
810     * @param resultType the return type expected by the expression
811     * @param headerName the name of the header to apply the expression to
812     * @return the builder to continue processing the DSL
813     */
814    public T xpath(String text, Class<?> resultType, String headerName) {
815        XPathExpression expression = new XPathExpression(text);
816        expression.setHeaderName(headerName);
817        setExpressionType(expression);
818        return result;
819    }
820    
821
822    /**
823     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
824     * expression</a> with the specified result type and set of namespace
825     * prefixes and URIs
826     *
827     * @param text the expression to be evaluated
828     * @param resultType the return type expected by the expression
829     * @param namespaces the namespace prefix and URIs to use
830     * @return the builder to continue processing the DSL
831     */
832    public T xpath(String text, Class<?> resultType, Namespaces namespaces) {
833        return xpath(text, resultType, namespaces.getNamespaces());
834    }
835    
836    /**
837     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
838     * expression</a> with the specified result type and set of namespace
839     * prefixes and URIs on the supplied header name's contents
840     *
841     * @param text the expression to be evaluated
842     * @param resultType the return type expected by the expression
843     * @param namespaces the namespace prefix and URIs to use
844     * @param headerName the name of the header to apply the expression to
845     * @return the builder to continue processing the DSL
846     */
847    public T xpath(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
848        XPathExpression expression = new XPathExpression(text);
849        expression.setResultType(resultType);
850        expression.setNamespaces(namespaces.getNamespaces());
851        expression.setHeaderName(headerName);
852        setExpressionType(expression);
853        return result;
854    }
855
856
857    /**
858     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
859     * expression</a> with the specified result type and set of namespace
860     * prefixes and URIs
861     *
862     * @param text the expression to be evaluated
863     * @param resultType the return type expected by the expression
864     * @param namespaces the namespace prefix and URIs to use
865     * @return the builder to continue processing the DSL
866     */
867    public T xpath(String text, Class<?> resultType, Map<String, String> namespaces) {
868        XPathExpression expression = new XPathExpression(text);
869        expression.setResultType(resultType);
870        expression.setNamespaces(namespaces);
871        setExpressionType(expression);
872        return result;
873    }
874
875    /**
876     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
877     * expression</a> with the specified set of namespace prefixes and URIs
878     *
879     * @param text the expression to be evaluated
880     * @param namespaces the namespace prefix and URIs to use
881     * @return the builder to continue processing the DSL
882     */
883    public T xpath(String text, Namespaces namespaces) {
884        return xpath(text, namespaces.getNamespaces());
885    }
886
887    /**
888     * Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
889     * expression</a> with the specified set of namespace prefixes and URIs
890     *
891     * @param text the expression to be evaluated
892     * @param namespaces the namespace prefix and URIs to use
893     * @return the builder to continue processing the DSL
894     */
895    public T xpath(String text, Map<String, String> namespaces) {
896        XPathExpression expression = new XPathExpression(text);
897        expression.setNamespaces(namespaces);
898        setExpressionType(expression);
899        return result;
900    }
901
902    /**
903     * Evaluates an <a
904     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
905     *
906     * @param text the expression to be evaluated
907     * @return the builder to continue processing the DSL
908     */
909    public T xquery(String text) {
910        return expression(new XQueryExpression(text));
911    }
912
913    /**
914     * Evaluates an <a href="http://camel.apache.org/xquery.html">XQuery
915     * expression</a>
916     * 
917     * @param text the expression to be evaluated
918     * @param headerName the name of the header to apply the expression to
919     * @return the builder to continue processing the DSL
920     */
921    public T xquery(String text, String headerName) {
922        XQueryExpression expression = new XQueryExpression(text);
923        expression.setHeaderName(headerName);
924        return expression(expression);
925    }
926
927    /**
928     * Evaluates an <a
929     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
930     * with the specified result type
931     *
932     * @param text the expression to be evaluated
933     * @param resultType the return type expected by the expression
934     * @return the builder to continue processing the DSL
935     */
936    public T xquery(String text, Class<?> resultType) {
937        XQueryExpression expression = new XQueryExpression(text);
938        expression.setResultType(resultType);
939        setExpressionType(expression);
940        return result;
941    }
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     * @param headerName the name of the header to apply the expression to
952     * @return the builder to continue processing the DSL
953     */
954    public T xquery(String text, Class<?> resultType, String headerName) {
955        XQueryExpression expression = new XQueryExpression(text);
956        expression.setHeaderName(headerName);
957        setExpressionType(expression);
958        return result;
959    }
960
961    /**
962     * Evaluates an <a
963     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
964     * with the specified result type and set of namespace prefixes and URIs
965     *
966     * @param text the expression to be evaluated
967     * @param resultType the return type expected by the expression
968     * @param namespaces the namespace prefix and URIs to use
969     * @return the builder to continue processing the DSL
970     */
971    public T xquery(String text, Class<?> resultType, Namespaces namespaces) {
972        return xquery(text, resultType, namespaces.getNamespaces());
973    }
974    
975    /**
976     * Evaluates an <a
977     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
978     * with the specified result type and set of namespace prefixes and URIs
979     *
980     * @param text the expression to be evaluated
981     * @param resultType the return type expected by the expression
982     * @param namespaces the namespace prefix and URIs to use
983     * @param headerName the name of the header to apply the expression to
984     * @return the builder to continue processing the DSL
985     */
986    public T xquery(String text, Class<?> resultType, Namespaces namespaces, String headerName) {
987        XQueryExpression expression = new XQueryExpression(text);
988        expression.setResultType(resultType);
989        expression.setNamespaces(namespaces.getNamespaces());
990        expression.setHeaderName(headerName);
991        setExpressionType(expression);
992        return result;
993    }
994
995
996    
997    /**
998     * Evaluates an <a
999     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1000     * with the specified result type and set of namespace prefixes and URIs
1001     *
1002     * @param text the expression to be evaluated
1003     * @param resultType the return type expected by the expression
1004     * @param namespaces the namespace prefix and URIs to use
1005     * @return the builder to continue processing the DSL
1006     */
1007    public T xquery(String text, Class<?> resultType, Map<String, String> namespaces) {
1008        XQueryExpression expression = new XQueryExpression(text);
1009        expression.setResultType(resultType);
1010        expression.setNamespaces(namespaces);
1011        setExpressionType(expression);
1012        return result;
1013    }
1014
1015    /**
1016     * Evaluates an <a
1017     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1018     * 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, Namespaces namespaces) {
1025        return xquery(text, namespaces.getNamespaces());
1026    }
1027
1028    /**
1029     * Evaluates an <a
1030     * href="http://camel.apache.org/xquery.html">XQuery expression</a>
1031     * with the specified set of namespace prefixes and URIs
1032     *
1033     * @param text the expression to be evaluated
1034     * @param namespaces the namespace prefix and URIs to use
1035     * @return the builder to continue processing the DSL
1036     */
1037    public T xquery(String text, Map<String, String> namespaces) {
1038        XQueryExpression expression = new XQueryExpression(text);
1039        expression.setNamespaces(namespaces);
1040        setExpressionType(expression);
1041        return result;
1042    }
1043
1044    /**
1045     * Evaluates a given language name with the expression text
1046     *
1047     * @param language the name of the language
1048     * @param expression the expression in the given language
1049     * @return the builder to continue processing the DSL
1050     */
1051    public T language(String language, String expression) {
1052        LanguageExpression exp = new LanguageExpression(language, expression);
1053        setExpressionType(exp);
1054        return result;
1055    }
1056
1057    // Properties
1058    // -------------------------------------------------------------------------
1059
1060    public Expression getExpressionValue() {
1061        return expressionValue;
1062    }
1063
1064    public void setExpressionValue(Expression expressionValue) {
1065        this.expressionValue = expressionValue;
1066    }
1067
1068    public ExpressionDefinition getExpressionType() {
1069        return expressionType;
1070    }
1071
1072    public void setExpressionType(ExpressionDefinition expressionType) {
1073        this.expressionType = expressionType;
1074    }
1075
1076    protected Expression createExpression(CamelContext camelContext) {
1077        if (getExpressionValue() == null) {
1078            if (getExpressionType() != null) {
1079                setExpressionValue(getExpressionType().createExpression(camelContext));
1080            } else {
1081                throw new IllegalStateException("No expression value configured");
1082            }
1083        }
1084        return getExpressionValue();
1085    }
1086
1087    protected void configureExpression(CamelContext camelContext, Expression expression) {
1088    }
1089
1090}