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 */
017 package org.apache.camel.builder;
018
019 import java.io.File;
020 import java.io.FileNotFoundException;
021 import java.io.InputStream;
022 import java.nio.channels.ReadableByteChannel;
023 import java.text.SimpleDateFormat;
024 import java.util.Collection;
025 import java.util.Date;
026 import java.util.Scanner;
027 import java.util.regex.Pattern;
028
029 import org.apache.camel.Exchange;
030 import org.apache.camel.Expression;
031 import org.apache.camel.Message;
032 import org.apache.camel.RuntimeCamelException;
033 import org.apache.camel.language.bean.BeanLanguage;
034 import org.apache.camel.language.simple.SimpleLanguage;
035
036 /**
037 * A helper class for working with <a href="http://activemq.apache.org/camel/expression.html">expressions</a>.
038 *
039 * @version $Revision: 698848 $
040 */
041 public final class ExpressionBuilder {
042
043 /**
044 * Utility classes should not have a public constructor.
045 */
046 private ExpressionBuilder() {
047 }
048
049 /**
050 * Returns an expression for the header value with the given name
051 *
052 * @param headerName the name of the header the expression will return
053 * @return an expression object which will return the header value
054 */
055 public static <E extends Exchange> Expression<E> headerExpression(final String headerName) {
056 return new Expression<E>() {
057 public Object evaluate(E exchange) {
058 Object header = exchange.getIn().getHeader(headerName);
059 if (header == null) {
060 // lets try the exchange header
061 header = exchange.getProperty(headerName);
062 }
063 return header;
064 }
065
066 @Override
067 public String toString() {
068 return "header(" + headerName + ")";
069 }
070 };
071 }
072
073 /**
074 * Returns an expression for the inbound message headers
075 *
076 * @see Message#getHeaders()
077 * @return an expression object which will return the inbound headers
078 */
079 public static <E extends Exchange> Expression<E> headersExpression() {
080 return new Expression<E>() {
081 public Object evaluate(E exchange) {
082 return exchange.getIn().getHeaders();
083 }
084
085 @Override
086 public String toString() {
087 return "headers";
088 }
089 };
090 }
091
092 /**
093 * Returns an expression for the out header value with the given name
094 *
095 * @param headerName the name of the header the expression will return
096 * @return an expression object which will return the header value
097 */
098 public static <E extends Exchange> Expression<E> outHeaderExpression(final String headerName) {
099 return new Expression<E>() {
100 public Object evaluate(E exchange) {
101 Message out = exchange.getOut(false);
102 if (out == null) {
103 return null;
104 }
105 Object header = out.getHeader(headerName);
106 if (header == null) {
107 // lets try the exchange header
108 header = exchange.getProperty(headerName);
109 }
110 return header;
111 }
112
113 @Override
114 public String toString() {
115 return "outHeader(" + headerName + ")";
116 }
117 };
118 }
119
120 /**
121 * Returns an expression for the outbound message headers
122 *
123 * @see Message#getHeaders()
124 * @return an expression object which will return the inbound headers
125 */
126 public static <E extends Exchange> Expression<E> outHeadersExpression() {
127 return new Expression<E>() {
128 public Object evaluate(E exchange) {
129 return exchange.getOut().getHeaders();
130 }
131
132 @Override
133 public String toString() {
134 return "outHeaders";
135 }
136 };
137 }
138
139 /**
140 * Returns an expression for the property value with the given name
141 *
142 * @see Exchange#getProperty(String)
143 * @param propertyName the name of the property the expression will return
144 * @return an expression object which will return the property value
145 */
146 public static <E extends Exchange> Expression<E> propertyExpression(final String propertyName) {
147 return new Expression<E>() {
148 public Object evaluate(E exchange) {
149 return exchange.getProperty(propertyName);
150 }
151
152 @Override
153 public String toString() {
154 return "property(" + propertyName + ")";
155 }
156 };
157 }
158
159
160 /**
161 * Returns an expression for the property value with the given name
162 *
163 * @see Exchange#getProperties()
164 * @return an expression object which will return the properties
165 */
166 public static <E extends Exchange> Expression<E> propertiesExpression() {
167 return new Expression<E>() {
168 public Object evaluate(E exchange) {
169 return exchange.getProperties();
170 }
171
172 @Override
173 public String toString() {
174 return "properties";
175 }
176 };
177 }
178
179 /**
180 * Returns an expression for a system property value with the given name
181 *
182 * @param propertyName the name of the system property the expression will
183 * return
184 * @return an expression object which will return the system property value
185 */
186 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName) {
187 return systemPropertyExpression(propertyName, null);
188 }
189
190 /**
191 * Returns an expression for a system property value with the given name
192 *
193 * @param propertyName the name of the system property the expression will
194 * return
195 * @return an expression object which will return the system property value
196 */
197 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName,
198 final String defaultValue) {
199 return new Expression<E>() {
200 public Object evaluate(E exchange) {
201 return System.getProperty(propertyName, defaultValue);
202 }
203
204 @Override
205 public String toString() {
206 return "systemProperty(" + propertyName + ")";
207 }
208 };
209 }
210
211 /**
212 * Returns an expression for the constant value
213 *
214 * @param value the value the expression will return
215 * @return an expression object which will return the constant value
216 */
217 public static <E extends Exchange> Expression<E> constantExpression(final Object value) {
218 return new Expression<E>() {
219 public Object evaluate(E exchange) {
220 return value;
221 }
222
223 @Override
224 public String toString() {
225 return "" + value;
226 }
227 };
228 }
229
230 /**
231 * Returns the expression for the exchanges inbound message body
232 */
233 public static <E extends Exchange> Expression<E> bodyExpression() {
234 return new Expression<E>() {
235 public Object evaluate(E exchange) {
236 return exchange.getIn().getBody();
237 }
238
239 @Override
240 public String toString() {
241 return "body";
242 }
243 };
244 }
245
246 /**
247 * Returns the expression for the exchanges inbound message body converted
248 * to the given type
249 */
250 public static <E extends Exchange, T> Expression<E> bodyExpression(final Class<T> type) {
251 return new Expression<E>() {
252 public Object evaluate(E exchange) {
253 return exchange.getIn().getBody(type);
254 }
255
256 @Override
257 public String toString() {
258 return "bodyAs[" + type.getName() + "]";
259 }
260 };
261 }
262
263 /**
264 * Returns the expression for the out messages body
265 */
266 public static <E extends Exchange> Expression<E> outBodyExpression() {
267 return new Expression<E>() {
268 public Object evaluate(E exchange) {
269 Message out = exchange.getOut(false);
270 if (out == null) {
271 return null;
272 }
273 return out.getBody();
274 }
275
276 @Override
277 public String toString() {
278 return "outBody";
279 }
280 };
281 }
282
283 /**
284 * Returns the expression for the exchanges outbound message body converted
285 * to the given type
286 */
287 public static <E extends Exchange, T> Expression<E> outBodyExpression(final Class<T> type) {
288 return new Expression<E>() {
289 public Object evaluate(E exchange) {
290 Message out = exchange.getOut(false);
291 if (out == null) {
292 return null;
293 }
294 return out.getBody(type);
295 }
296
297 @Override
298 public String toString() {
299 return "outBodyAs[" + type.getName() + "]";
300 }
301 };
302 }
303
304 /**
305 * Returns the expression for the fault messages body
306 */
307 public static <E extends Exchange> Expression<E> faultBodyExpression() {
308 return new Expression<E>() {
309 public Object evaluate(E exchange) {
310 return exchange.getFault().getBody();
311 }
312
313 @Override
314 public String toString() {
315 return "faultBody";
316 }
317 };
318 }
319
320 /**
321 * Returns the expression for the exchanges fault message body converted
322 * to the given type
323 */
324 public static <E extends Exchange, T> Expression<E> faultBodyExpression(final Class<T> type) {
325 return new Expression<E>() {
326 public Object evaluate(E exchange) {
327 return exchange.getFault().getBody(type);
328 }
329
330 @Override
331 public String toString() {
332 return "faultBodyAs[" + type.getName() + "]";
333 }
334 };
335 }
336
337 /**
338 * Returns the expression for the exchange
339 */
340 public static <E extends Exchange> Expression<E> exchangeExpression() {
341 return new Expression<E>() {
342 public Object evaluate(E exchange) {
343 return exchange;
344 }
345
346 @Override
347 public String toString() {
348 return "exchange";
349 }
350 };
351 }
352
353 /**
354 * Returns the expression for the IN message
355 */
356 public static <E extends Exchange> Expression<E> inMessageExpression() {
357 return new Expression<E>() {
358 public Object evaluate(E exchange) {
359 return exchange.getIn();
360 }
361
362 @Override
363 public String toString() {
364 return "inMessage";
365 }
366 };
367 }
368
369 /**
370 * Returns the expression for the OUT message
371 */
372 public static <E extends Exchange> Expression<E> outMessageExpression() {
373 return new Expression<E>() {
374 public Object evaluate(E exchange) {
375 return exchange.getOut();
376 }
377
378 @Override
379 public String toString() {
380 return "outMessage";
381 }
382 };
383 }
384
385 /**
386 * Returns an expression which converts the given expression to the given
387 * type
388 */
389 public static <E extends Exchange> Expression<E> convertTo(final Expression expression, final Class type) {
390 return new Expression<E>() {
391 public Object evaluate(E exchange) {
392 Object value = expression.evaluate(exchange);
393 return exchange.getContext().getTypeConverter().convertTo(type, exchange, value);
394 }
395
396 @Override
397 public String toString() {
398 return "" + expression + ".convertTo(" + type.getName() + ".class)";
399 }
400 };
401 }
402
403 /**
404 * Returns a tokenize expression which will tokenize the string with the
405 * given token
406 */
407 public static <E extends Exchange> Expression<E> tokenizeExpression(final Expression<E> expression,
408 final String token) {
409 return new Expression<E>() {
410 public Object evaluate(E exchange) {
411 Object value = expression.evaluate(exchange);
412 Scanner scanner = getScanner(exchange, value);
413 scanner.useDelimiter(token);
414 return scanner;
415 }
416
417 @Override
418 public String toString() {
419 return "tokenize(" + expression + ", " + token + ")";
420 }
421 };
422 }
423
424 /**
425 * Returns a tokenize expression which will tokenize the string with the
426 * given regex
427 */
428 public static <E extends Exchange> Expression<E> regexTokenize(final Expression<E> expression,
429 final String regexTokenizer) {
430 final Pattern pattern = Pattern.compile(regexTokenizer);
431 return new Expression<E>() {
432 public Object evaluate(E exchange) {
433 Object value = expression.evaluate(exchange);
434 Scanner scanner = getScanner(exchange, value);
435 scanner.useDelimiter(regexTokenizer);
436 return scanner;
437 }
438
439 @Override
440 public String toString() {
441 return "regexTokenize(" + expression + ", " + pattern.pattern() + ")";
442 }
443 };
444 }
445
446 private static Scanner getScanner(Exchange exchange, Object value) {
447 String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
448
449 Scanner scanner = null;
450 if (value instanceof Readable) {
451 scanner = new Scanner((Readable)value);
452 } else if (value instanceof InputStream) {
453 scanner = charset == null ? new Scanner((InputStream)value)
454 : new Scanner((InputStream)value, charset);
455 } else if (value instanceof File) {
456 try {
457 scanner = charset == null ? new Scanner((File)value) : new Scanner((File)value, charset);
458 } catch (FileNotFoundException e) {
459 throw new RuntimeCamelException(e);
460 }
461 } else if (value instanceof String) {
462 scanner = new Scanner((String)value);
463 } else if (value instanceof ReadableByteChannel) {
464 scanner = charset == null ? new Scanner((ReadableByteChannel)value)
465 : new Scanner((ReadableByteChannel)value, charset);
466 }
467
468 if (scanner == null) {
469 // value is not a suitable type, try to convert value to a string
470 String text = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
471 if (text != null) {
472 scanner = new Scanner(text);
473 }
474 }
475
476 if (scanner == null) {
477 scanner = new Scanner("");
478 }
479 return scanner;
480 }
481
482 /**
483 * Transforms the expression into a String then performs the regex
484 * replaceAll to transform the String and return the result
485 */
486 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
487 final String regex, final String replacement) {
488 final Pattern pattern = Pattern.compile(regex);
489 return new Expression<E>() {
490 public Object evaluate(E exchange) {
491 String text = evaluateStringExpression(expression, exchange);
492 if (text == null) {
493 return null;
494 }
495 return pattern.matcher(text).replaceAll(replacement);
496 }
497
498 @Override
499 public String toString() {
500 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
501 }
502 };
503 }
504
505 /**
506 * Transforms the expression into a String then performs the regex
507 * replaceAll to transform the String and return the result
508 */
509 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
510 String regex,
511 final Expression<E> replacementExpression) {
512 final Pattern pattern = Pattern.compile(regex);
513 return new Expression<E>() {
514 public Object evaluate(E exchange) {
515 String text = evaluateStringExpression(expression, exchange);
516 String replacement = evaluateStringExpression(replacementExpression, exchange);
517 if (text == null || replacement == null) {
518 return null;
519 }
520 return pattern.matcher(text).replaceAll(replacement);
521 }
522
523 @Override
524 public String toString() {
525 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
526 }
527 };
528 }
529
530 /**
531 * Appends the String evaluations of the two expressions together
532 */
533 public static <E extends Exchange> Expression<E> append(final Expression<E> left,
534 final Expression<E> right) {
535 return new Expression<E>() {
536 public Object evaluate(E exchange) {
537 return evaluateStringExpression(left, exchange) + evaluateStringExpression(right, exchange);
538 }
539
540 @Override
541 public String toString() {
542 return "append(" + left + ", " + right + ")";
543 }
544 };
545 }
546
547 /**
548 * Evaluates the expression on the given exchange and returns the String
549 * representation
550 *
551 * @param expression the expression to evaluate
552 * @param exchange the exchange to use to evaluate the expression
553 * @return the String representation of the expression or null if it could
554 * not be evaluated
555 */
556 public static <E extends Exchange> String evaluateStringExpression(Expression<E> expression, E exchange) {
557 Object value = expression.evaluate(exchange);
558 return exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
559 }
560
561 /**
562 * Returns an expression for the given system property
563 */
564 public static <E extends Exchange> Expression<E> systemProperty(final String name) {
565 return systemProperty(name, null);
566 }
567
568 /**
569 * Returns an expression for the given system property
570 */
571 public static <E extends Exchange> Expression<E> systemProperty(final String name,
572 final String defaultValue) {
573 return new Expression<E>() {
574 public Object evaluate(E exchange) {
575 return System.getProperty(name, defaultValue);
576 }
577 };
578 }
579
580 /**
581 * Returns an expression which returns the string concatenation value of the various
582 * expressions
583 *
584 * @param expressions the expression to be concatenated dynamically
585 * @return an expression which when evaluated will return the concatenated values
586 */
587 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions) {
588 return concatExpression(expressions, null);
589 }
590
591 /**
592 * Returns an expression which returns the string concatenation value of the various
593 * expressions
594 *
595 * @param expressions the expression to be concatenated dynamically
596 * @param expression the text description of the expression
597 * @return an expression which when evaluated will return the concatenated values
598 */
599 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions, final String expression) {
600 return new Expression<E>() {
601 public Object evaluate(E exchange) {
602 StringBuffer buffer = new StringBuffer();
603 for (Expression<E> expression : expressions) {
604 String text = evaluateStringExpression(expression, exchange);
605 if (text != null) {
606 buffer.append(text);
607 }
608 }
609 return buffer.toString();
610 }
611
612 @Override
613 public String toString() {
614 if (expression != null) {
615 return expression;
616 } else {
617 return "concat" + expressions;
618 }
619 }
620 };
621 }
622
623 /**
624 * Returns an Expression for the inbound message id
625 */
626 public static <E extends Exchange> Expression<E> messageIdExpression() {
627 return new Expression<E>() {
628 public Object evaluate(E exchange) {
629 return exchange.getIn().getMessageId();
630 }
631
632 @Override
633 public String toString() {
634 return "messageId";
635 }
636 };
637 }
638
639 public static <E extends Exchange> Expression<E> dateExpression(final String command, final String pattern) {
640 return new Expression<E>() {
641 public Object evaluate(E exchange) {
642 Date date;
643 if ("now".equals(command)) {
644 date = new Date();
645 } else if (command.startsWith("header.") || command.startsWith("in.header.")) {
646 String key = command.substring(command.lastIndexOf(".") + 1);
647 date = exchange.getIn().getHeader(key, Date.class);
648 if (date == null) {
649 throw new IllegalArgumentException("Could not find java.util.Date object at " + command);
650 }
651 } else if (command.startsWith("out.header.")) {
652 String key = command.substring(command.lastIndexOf(".") + 1);
653 date = exchange.getOut().getHeader(key, Date.class);
654 if (date == null) {
655 throw new IllegalArgumentException("Could not find java.util.Date object at " + command);
656 }
657 } else {
658 throw new IllegalArgumentException("Command not supported for dateExpression: " + command);
659 }
660
661 SimpleDateFormat df = new SimpleDateFormat(pattern);
662 return df.format(date);
663 }
664
665 @Override
666 public String toString() {
667 return "date(" + command + ":" + pattern + ")";
668 }
669 };
670 }
671
672 public static <E extends Exchange> Expression<E> simpleExpression(final String simple) {
673 return new Expression<E>() {
674 public Object evaluate(E exchange) {
675 // must call evalute to return the nested langauge evaluate when evaluating
676 // stacked expressions
677 return SimpleLanguage.simple(simple).evaluate(exchange);
678 }
679
680 @Override
681 public String toString() {
682 return "simple(" + simple + ")";
683 }
684 };
685 }
686
687 public static <E extends Exchange> Expression<E> beanExpression(final String bean) {
688 return new Expression<E>() {
689 public Object evaluate(E exchange) {
690 // must call evalute to return the nested langauge evaluate when evaluating
691 // stacked expressions
692 return BeanLanguage.bean(bean).evaluate(exchange);
693 }
694
695 @Override
696 public String toString() {
697 return "bean(" + bean + ")";
698 }
699 };
700 }
701
702 }