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