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