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