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: 756318 $ 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 of exchange 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 * Returns an expression for the properties of exchange with the given name 161 * 162 * @see Exchange#getProperties() 163 * @return an expression object which will return the properties 164 */ 165 public static <E extends Exchange> Expression<E> propertiesExpression() { 166 return new Expression<E>() { 167 public Object evaluate(E exchange) { 168 return exchange.getProperties(); 169 } 170 171 @Override 172 public String toString() { 173 return "properties"; 174 } 175 }; 176 } 177 178 /** 179 * Returns an expression for the properties of exchange with the given name 180 * 181 * @see Exchange#getProperties() 182 * @return an expression object which will return the properties 183 */ 184 public static <E extends Exchange> Expression<E> camelContextPropertiesExpression() { 185 return new Expression<E>() { 186 public Object evaluate(E exchange) { 187 return exchange.getContext().getProperties(); 188 } 189 190 @Override 191 public String toString() { 192 return "camelContextProperties"; 193 } 194 }; 195 } 196 197 /** 198 * Returns an expression for the property value of the camel context with the given name 199 * 200 * @see Exchange#getProperty(String) 201 * @param propertyName the name of the property the expression will return 202 * @return an expression object which will return the property value 203 */ 204 public static <E extends Exchange> Expression<E> camelContextPropertyExpression(final String propertyName) { 205 return new Expression<E>() { 206 public Object evaluate(E exchange) { 207 return exchange.getContext().getProperties().get(propertyName); 208 } 209 210 @Override 211 public String toString() { 212 return "camelContextProperty(" + propertyName + ")"; 213 } 214 }; 215 } 216 217 /** 218 * Returns an expression for a system property value with the given name 219 * 220 * @param propertyName the name of the system property the expression will 221 * return 222 * @return an expression object which will return the system property value 223 */ 224 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName) { 225 return systemPropertyExpression(propertyName, null); 226 } 227 228 /** 229 * Returns an expression for a system property value with the given name 230 * 231 * @param propertyName the name of the system property the expression will 232 * return 233 * @return an expression object which will return the system property value 234 */ 235 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName, 236 final String defaultValue) { 237 return new Expression<E>() { 238 public Object evaluate(E exchange) { 239 return System.getProperty(propertyName, defaultValue); 240 } 241 242 @Override 243 public String toString() { 244 return "systemProperty(" + propertyName + ")"; 245 } 246 }; 247 } 248 249 /** 250 * Returns an expression for the constant value 251 * 252 * @param value the value the expression will return 253 * @return an expression object which will return the constant value 254 */ 255 public static <E extends Exchange> Expression<E> constantExpression(final Object value) { 256 return new Expression<E>() { 257 public Object evaluate(E exchange) { 258 return value; 259 } 260 261 @Override 262 public String toString() { 263 return "" + value; 264 } 265 }; 266 } 267 268 /** 269 * Returns the expression for the exchanges inbound message body 270 */ 271 public static <E extends Exchange> Expression<E> bodyExpression() { 272 return new Expression<E>() { 273 public Object evaluate(E exchange) { 274 return exchange.getIn().getBody(); 275 } 276 277 @Override 278 public String toString() { 279 return "body"; 280 } 281 }; 282 } 283 284 /** 285 * Returns the expression for the exchanges inbound message body converted 286 * to the given type 287 */ 288 public static <E extends Exchange, T> Expression<E> bodyExpression(final Class<T> type) { 289 return new Expression<E>() { 290 public Object evaluate(E exchange) { 291 return exchange.getIn().getBody(type); 292 } 293 294 @Override 295 public String toString() { 296 return "bodyAs[" + type.getName() + "]"; 297 } 298 }; 299 } 300 301 /** 302 * Returns the expression for the out messages body 303 */ 304 public static <E extends Exchange> Expression<E> outBodyExpression() { 305 return new Expression<E>() { 306 public Object evaluate(E exchange) { 307 Message out = exchange.getOut(false); 308 if (out == null) { 309 return null; 310 } 311 return out.getBody(); 312 } 313 314 @Override 315 public String toString() { 316 return "outBody"; 317 } 318 }; 319 } 320 321 /** 322 * Returns the expression for the exchanges outbound message body converted 323 * to the given type 324 */ 325 public static <E extends Exchange, T> Expression<E> outBodyExpression(final Class<T> type) { 326 return new Expression<E>() { 327 public Object evaluate(E exchange) { 328 Message out = exchange.getOut(false); 329 if (out == null) { 330 return null; 331 } 332 return out.getBody(type); 333 } 334 335 @Override 336 public String toString() { 337 return "outBodyAs[" + type.getName() + "]"; 338 } 339 }; 340 } 341 342 /** 343 * Returns the expression for the fault messages body 344 */ 345 public static <E extends Exchange> Expression<E> faultBodyExpression() { 346 return new Expression<E>() { 347 public Object evaluate(E exchange) { 348 return exchange.getFault().getBody(); 349 } 350 351 @Override 352 public String toString() { 353 return "faultBody"; 354 } 355 }; 356 } 357 358 /** 359 * Returns the expression for the exchanges fault message body converted 360 * to the given type 361 */ 362 public static <E extends Exchange, T> Expression<E> faultBodyExpression(final Class<T> type) { 363 return new Expression<E>() { 364 public Object evaluate(E exchange) { 365 return exchange.getFault().getBody(type); 366 } 367 368 @Override 369 public String toString() { 370 return "faultBodyAs[" + type.getName() + "]"; 371 } 372 }; 373 } 374 375 /** 376 * Returns the expression for the exchange 377 */ 378 public static <E extends Exchange> Expression<E> exchangeExpression() { 379 return new Expression<E>() { 380 public Object evaluate(E exchange) { 381 return exchange; 382 } 383 384 @Override 385 public String toString() { 386 return "exchange"; 387 } 388 }; 389 } 390 391 /** 392 * Returns the expression for the IN message 393 */ 394 public static <E extends Exchange> Expression<E> inMessageExpression() { 395 return new Expression<E>() { 396 public Object evaluate(E exchange) { 397 return exchange.getIn(); 398 } 399 400 @Override 401 public String toString() { 402 return "inMessage"; 403 } 404 }; 405 } 406 407 /** 408 * Returns the expression for the OUT message 409 */ 410 public static <E extends Exchange> Expression<E> outMessageExpression() { 411 return new Expression<E>() { 412 public Object evaluate(E exchange) { 413 return exchange.getOut(); 414 } 415 416 @Override 417 public String toString() { 418 return "outMessage"; 419 } 420 }; 421 } 422 423 /** 424 * Returns an expression which converts the given expression to the given 425 * type 426 */ 427 public static <E extends Exchange> Expression<E> convertTo(final Expression expression, final Class type) { 428 return new Expression<E>() { 429 public Object evaluate(E exchange) { 430 Object value = expression.evaluate(exchange); 431 return exchange.getContext().getTypeConverter().convertTo(type, exchange, value); 432 } 433 434 @Override 435 public String toString() { 436 return "" + expression + ".convertTo(" + type.getName() + ".class)"; 437 } 438 }; 439 } 440 441 /** 442 * Returns a tokenize expression which will tokenize the string with the 443 * given token 444 */ 445 public static <E extends Exchange> Expression<E> tokenizeExpression(final Expression<E> expression, 446 final String token) { 447 return new Expression<E>() { 448 public Object evaluate(E exchange) { 449 Object value = expression.evaluate(exchange); 450 Scanner scanner = getScanner(exchange, value); 451 scanner.useDelimiter(token); 452 return scanner; 453 } 454 455 @Override 456 public String toString() { 457 return "tokenize(" + expression + ", " + token + ")"; 458 } 459 }; 460 } 461 462 /** 463 * Returns a tokenize expression which will tokenize the string with the 464 * given regex 465 */ 466 public static <E extends Exchange> Expression<E> regexTokenize(final Expression<E> expression, 467 final String regexTokenizer) { 468 final Pattern pattern = Pattern.compile(regexTokenizer); 469 return new Expression<E>() { 470 public Object evaluate(E exchange) { 471 Object value = expression.evaluate(exchange); 472 Scanner scanner = getScanner(exchange, value); 473 scanner.useDelimiter(regexTokenizer); 474 return scanner; 475 } 476 477 @Override 478 public String toString() { 479 return "regexTokenize(" + expression + ", " + pattern.pattern() + ")"; 480 } 481 }; 482 } 483 484 private static Scanner getScanner(Exchange exchange, Object value) { 485 String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class); 486 487 Scanner scanner = null; 488 if (value instanceof Readable) { 489 scanner = new Scanner((Readable)value); 490 } else if (value instanceof InputStream) { 491 scanner = charset == null ? new Scanner((InputStream)value) 492 : new Scanner((InputStream)value, charset); 493 } else if (value instanceof File) { 494 try { 495 scanner = charset == null ? new Scanner((File)value) : new Scanner((File)value, charset); 496 } catch (FileNotFoundException e) { 497 throw new RuntimeCamelException(e); 498 } 499 } else if (value instanceof String) { 500 scanner = new Scanner((String)value); 501 } else if (value instanceof ReadableByteChannel) { 502 scanner = charset == null ? new Scanner((ReadableByteChannel)value) 503 : new Scanner((ReadableByteChannel)value, charset); 504 } 505 506 if (scanner == null) { 507 // value is not a suitable type, try to convert value to a string 508 String text = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value); 509 if (text != null) { 510 scanner = new Scanner(text); 511 } 512 } 513 514 if (scanner == null) { 515 scanner = new Scanner(""); 516 } 517 return scanner; 518 } 519 520 /** 521 * Transforms the expression into a String then performs the regex 522 * replaceAll to transform the String and return the result 523 */ 524 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression, 525 final String regex, final String replacement) { 526 final Pattern pattern = Pattern.compile(regex); 527 return new Expression<E>() { 528 public Object evaluate(E exchange) { 529 String text = evaluateStringExpression(expression, exchange); 530 if (text == null) { 531 return null; 532 } 533 return pattern.matcher(text).replaceAll(replacement); 534 } 535 536 @Override 537 public String toString() { 538 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 539 } 540 }; 541 } 542 543 /** 544 * Transforms the expression into a String then performs the regex 545 * replaceAll to transform the String and return the result 546 */ 547 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression, 548 String regex, 549 final Expression<E> replacementExpression) { 550 final Pattern pattern = Pattern.compile(regex); 551 return new Expression<E>() { 552 public Object evaluate(E exchange) { 553 String text = evaluateStringExpression(expression, exchange); 554 String replacement = evaluateStringExpression(replacementExpression, exchange); 555 if (text == null || replacement == null) { 556 return null; 557 } 558 return pattern.matcher(text).replaceAll(replacement); 559 } 560 561 @Override 562 public String toString() { 563 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 564 } 565 }; 566 } 567 568 /** 569 * Appends the String evaluations of the two expressions together 570 */ 571 public static <E extends Exchange> Expression<E> append(final Expression<E> left, 572 final Expression<E> right) { 573 return new Expression<E>() { 574 public Object evaluate(E exchange) { 575 return evaluateStringExpression(left, exchange) + evaluateStringExpression(right, exchange); 576 } 577 578 @Override 579 public String toString() { 580 return "append(" + left + ", " + right + ")"; 581 } 582 }; 583 } 584 585 /** 586 * Evaluates the expression on the given exchange and returns the String 587 * representation 588 * 589 * @param expression the expression to evaluate 590 * @param exchange the exchange to use to evaluate the expression 591 * @return the String representation of the expression or null if it could 592 * not be evaluated 593 */ 594 public static <E extends Exchange> String evaluateStringExpression(Expression<E> expression, E exchange) { 595 Object value = expression.evaluate(exchange); 596 return exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value); 597 } 598 599 /** 600 * Returns an expression for the given system property 601 */ 602 public static <E extends Exchange> Expression<E> systemProperty(final String name) { 603 return systemProperty(name, null); 604 } 605 606 /** 607 * Returns an expression for the given system property 608 */ 609 public static <E extends Exchange> Expression<E> systemProperty(final String name, 610 final String defaultValue) { 611 return new Expression<E>() { 612 public Object evaluate(E exchange) { 613 return System.getProperty(name, defaultValue); 614 } 615 }; 616 } 617 618 /** 619 * Returns an expression which returns the string concatenation value of the various 620 * expressions 621 * 622 * @param expressions the expression to be concatenated dynamically 623 * @return an expression which when evaluated will return the concatenated values 624 */ 625 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions) { 626 return concatExpression(expressions, null); 627 } 628 629 /** 630 * Returns an expression which returns the string concatenation value of the various 631 * expressions 632 * 633 * @param expressions the expression to be concatenated dynamically 634 * @param expression the text description of the expression 635 * @return an expression which when evaluated will return the concatenated values 636 */ 637 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions, final String expression) { 638 return new Expression<E>() { 639 public Object evaluate(E exchange) { 640 StringBuffer buffer = new StringBuffer(); 641 for (Expression<E> expression : expressions) { 642 String text = evaluateStringExpression(expression, exchange); 643 if (text != null) { 644 buffer.append(text); 645 } 646 } 647 return buffer.toString(); 648 } 649 650 @Override 651 public String toString() { 652 if (expression != null) { 653 return expression; 654 } else { 655 return "concat" + expressions; 656 } 657 } 658 }; 659 } 660 661 /** 662 * Returns an Expression for the inbound message id 663 */ 664 public static <E extends Exchange> Expression<E> messageIdExpression() { 665 return new Expression<E>() { 666 public Object evaluate(E exchange) { 667 return exchange.getIn().getMessageId(); 668 } 669 670 @Override 671 public String toString() { 672 return "messageId"; 673 } 674 }; 675 } 676 677 public static <E extends Exchange> Expression<E> dateExpression(final String command, final String pattern) { 678 return new Expression<E>() { 679 public Object evaluate(E exchange) { 680 Date date; 681 if ("now".equals(command)) { 682 date = new Date(); 683 } else if (command.startsWith("header.") || command.startsWith("in.header.")) { 684 String key = command.substring(command.lastIndexOf(".") + 1); 685 date = exchange.getIn().getHeader(key, Date.class); 686 if (date == null) { 687 throw new IllegalArgumentException("Could not find java.util.Date object at " + command); 688 } 689 } else if (command.startsWith("out.header.")) { 690 String key = command.substring(command.lastIndexOf(".") + 1); 691 date = exchange.getOut().getHeader(key, Date.class); 692 if (date == null) { 693 throw new IllegalArgumentException("Could not find java.util.Date object at " + command); 694 } 695 } else { 696 throw new IllegalArgumentException("Command not supported for dateExpression: " + command); 697 } 698 699 SimpleDateFormat df = new SimpleDateFormat(pattern); 700 return df.format(date); 701 } 702 703 @Override 704 public String toString() { 705 return "date(" + command + ":" + pattern + ")"; 706 } 707 }; 708 } 709 710 public static <E extends Exchange> Expression<E> simpleExpression(final String simple) { 711 return new Expression<E>() { 712 public Object evaluate(E exchange) { 713 // must call evalute to return the nested langauge evaluate when evaluating 714 // stacked expressions 715 return SimpleLanguage.simple(simple).evaluate(exchange); 716 } 717 718 @Override 719 public String toString() { 720 return "simple(" + simple + ")"; 721 } 722 }; 723 } 724 725 public static <E extends Exchange> Expression<E> beanExpression(final String bean) { 726 return new Expression<E>() { 727 public Object evaluate(E exchange) { 728 // must call evalute to return the nested langauge evaluate when evaluating 729 // stacked expressions 730 return BeanLanguage.bean(bean).evaluate(exchange); 731 } 732 733 @Override 734 public String toString() { 735 return "bean(" + bean + ")"; 736 } 737 }; 738 } 739 740 }