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