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: 52207 $ 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 }