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 */ 017package org.apache.camel.builder; 018 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.text.SimpleDateFormat; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.Comparator; 025import java.util.Date; 026import java.util.Iterator; 027import java.util.List; 028import java.util.Random; 029import java.util.Scanner; 030import java.util.concurrent.atomic.AtomicReference; 031import java.util.regex.Pattern; 032 033import org.apache.camel.CamelContext; 034import org.apache.camel.Component; 035import org.apache.camel.Endpoint; 036import org.apache.camel.Exchange; 037import org.apache.camel.Expression; 038import org.apache.camel.InvalidPayloadException; 039import org.apache.camel.Message; 040import org.apache.camel.NoSuchEndpointException; 041import org.apache.camel.NoSuchLanguageException; 042import org.apache.camel.Producer; 043import org.apache.camel.component.bean.BeanInvocation; 044import org.apache.camel.component.properties.PropertiesComponent; 045import org.apache.camel.language.bean.BeanLanguage; 046import org.apache.camel.model.language.MethodCallExpression; 047import org.apache.camel.spi.Language; 048import org.apache.camel.spi.RouteContext; 049import org.apache.camel.spi.UnitOfWork; 050import org.apache.camel.support.ExpressionAdapter; 051import org.apache.camel.support.TokenPairExpressionIterator; 052import org.apache.camel.support.TokenXMLExpressionIterator; 053import org.apache.camel.support.XMLTokenExpressionIterator; 054import org.apache.camel.util.ExchangeHelper; 055import org.apache.camel.util.FileUtil; 056import org.apache.camel.util.GroupIterator; 057import org.apache.camel.util.IOHelper; 058import org.apache.camel.util.ObjectHelper; 059import org.apache.camel.util.OgnlHelper; 060 061/** 062 * A helper class for working with <a href="http://camel.apache.org/expression.html">expressions</a>. 063 * 064 * @version 065 */ 066public final class ExpressionBuilder { 067 068 /** 069 * Utility classes should not have a public constructor. 070 */ 071 private ExpressionBuilder() { 072 } 073 074 /** 075 * Returns an expression for the inbound message attachments 076 * 077 * @return an expression object which will return the inbound message attachments 078 */ 079 public static Expression attachmentsExpression() { 080 return new ExpressionAdapter() { 081 public Object evaluate(Exchange exchange) { 082 return exchange.getIn().getAttachments(); 083 } 084 085 @Override 086 public String toString() { 087 return "attachments"; 088 } 089 }; 090 } 091 092 /** 093 * Returns an expression for the inbound message attachments 094 * 095 * @return an expression object which will return the inbound message attachments 096 */ 097 public static Expression attachmentValuesExpression() { 098 return new ExpressionAdapter() { 099 public Object evaluate(Exchange exchange) { 100 return exchange.getIn().getAttachments().values(); 101 } 102 103 @Override 104 public String toString() { 105 return "attachments"; 106 } 107 }; 108 } 109 110 /** 111 * Returns an expression for the header value with the given name 112 * <p/> 113 * Will fallback and look in properties if not found in headers. 114 * 115 * @param headerName the name of the header the expression will return 116 * @return an expression object which will return the header value 117 */ 118 public static Expression headerExpression(final String headerName) { 119 return new ExpressionAdapter() { 120 public Object evaluate(Exchange exchange) { 121 Object header = exchange.getIn().getHeader(headerName); 122 if (header == null) { 123 // fall back on a property 124 header = exchange.getProperty(headerName); 125 } 126 return header; 127 } 128 129 @Override 130 public String toString() { 131 return "header(" + headerName + ")"; 132 } 133 }; 134 } 135 136 /** 137 * Returns an expression for the header value with the given name converted to the given type 138 * <p/> 139 * Will fallback and look in properties if not found in headers. 140 * 141 * @param headerName the name of the header the expression will return 142 * @param type the type to convert to 143 * @return an expression object which will return the header value 144 */ 145 public static <T> Expression headerExpression(final String headerName, final Class<T> type) { 146 return new ExpressionAdapter() { 147 public Object evaluate(Exchange exchange) { 148 Object header = exchange.getIn().getHeader(headerName, type); 149 if (header == null) { 150 // fall back on a property 151 header = exchange.getProperty(headerName, type); 152 } 153 return header; 154 } 155 156 @Override 157 public String toString() { 158 return "headerAs(" + headerName + ", " + type + ")"; 159 } 160 }; 161 } 162 163 /** 164 * Returns an expression for the header value with the given name converted to the given type 165 * <p/> 166 * Will fallback and look in properties if not found in headers. 167 * 168 * @param headerName the name of the header the expression will return 169 * @param name the type to convert to as a FQN class name 170 * @return an expression object which will return the header value 171 */ 172 public static Expression headerExpression(final String headerName, final String name) { 173 return new ExpressionAdapter() { 174 public Object evaluate(Exchange exchange) { 175 Class<?> type; 176 try { 177 type = exchange.getContext().getClassResolver().resolveMandatoryClass(name); 178 } catch (ClassNotFoundException e) { 179 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 180 } 181 182 Object header = exchange.getIn().getHeader(headerName, type); 183 if (header == null) { 184 // fall back on a property 185 header = exchange.getProperty(headerName, type); 186 } 187 return header; 188 } 189 190 @Override 191 public String toString() { 192 return "headerAs(" + headerName + ", " + name + ")"; 193 } 194 }; 195 } 196 197 /** 198 * Returns the expression for the exchanges inbound message header invoking methods defined 199 * in a simple OGNL notation 200 * 201 * @param ognl methods to invoke on the header in a simple OGNL syntax 202 */ 203 public static Expression headersOgnlExpression(final String ognl) { 204 return new KeyedOgnlExpressionAdapter(ognl, "headerOgnl(" + ognl + ")", 205 new KeyedOgnlExpressionAdapter.KeyedEntityRetrievalStrategy() { 206 public Object getKeyedEntity(Exchange exchange, String key) { 207 return exchange.getIn().getHeader(key); 208 } 209 }); 210 } 211 212 /** 213 * Returns an expression for the inbound message headers 214 * 215 * @return an expression object which will return the inbound headers 216 */ 217 public static Expression headersExpression() { 218 return new ExpressionAdapter() { 219 public Object evaluate(Exchange exchange) { 220 return exchange.getIn().getHeaders(); 221 } 222 223 @Override 224 public String toString() { 225 return "headers"; 226 } 227 }; 228 } 229 230 /** 231 * Returns an expression for the out header value with the given name 232 * <p/> 233 * Will fallback and look in properties if not found in headers. 234 * 235 * @param headerName the name of the header the expression will return 236 * @return an expression object which will return the header value 237 */ 238 public static Expression outHeaderExpression(final String headerName) { 239 return new ExpressionAdapter() { 240 public Object evaluate(Exchange exchange) { 241 if (!exchange.hasOut()) { 242 return null; 243 } 244 245 Message out = exchange.getOut(); 246 Object header = out.getHeader(headerName); 247 if (header == null) { 248 // let's try the exchange header 249 header = exchange.getProperty(headerName); 250 } 251 return header; 252 } 253 254 @Override 255 public String toString() { 256 return "outHeader(" + headerName + ")"; 257 } 258 }; 259 } 260 261 /** 262 * Returns an expression for the outbound message headers 263 * 264 * @return an expression object which will return the headers, will be <tt>null</tt> if the 265 * exchange is not out capable. 266 */ 267 public static Expression outHeadersExpression() { 268 return new ExpressionAdapter() { 269 public Object evaluate(Exchange exchange) { 270 // only get out headers if the MEP is out capable 271 if (ExchangeHelper.isOutCapable(exchange)) { 272 return exchange.getOut().getHeaders(); 273 } else { 274 return null; 275 } 276 } 277 278 @Override 279 public String toString() { 280 return "outHeaders"; 281 } 282 }; 283 } 284 285 /** 286 * Returns an expression for the exchange pattern 287 * 288 * @see org.apache.camel.Exchange#getPattern() 289 * @return an expression object which will return the exchange pattern 290 */ 291 public static Expression exchangePatternExpression() { 292 return new ExpressionAdapter() { 293 public Object evaluate(Exchange exchange) { 294 return exchange.getPattern(); 295 } 296 297 @Override 298 public String toString() { 299 return "exchangePattern"; 300 } 301 }; 302 } 303 304 /** 305 * Returns an expression for an exception set on the exchange 306 * 307 * @see Exchange#getException() 308 * @return an expression object which will return the exception set on the exchange 309 */ 310 public static Expression exchangeExceptionExpression() { 311 return new ExpressionAdapter() { 312 public Object evaluate(Exchange exchange) { 313 Exception exception = exchange.getException(); 314 if (exception == null) { 315 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); 316 } 317 return exception; 318 } 319 320 @Override 321 public String toString() { 322 return "exchangeException"; 323 } 324 }; 325 } 326 327 /** 328 * Returns an expression for an exception set on the exchange 329 * <p/> 330 * Is used to get the caused exception that typically have been wrapped in some sort 331 * of Camel wrapper exception 332 * @param type the exception type 333 * @see Exchange#getException(Class) 334 * @return an expression object which will return the exception set on the exchange 335 */ 336 public static Expression exchangeExceptionExpression(final Class<Exception> type) { 337 return new ExpressionAdapter() { 338 public Object evaluate(Exchange exchange) { 339 Exception exception = exchange.getException(type); 340 if (exception == null) { 341 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); 342 return ObjectHelper.getException(type, exception); 343 } 344 return exception; 345 } 346 347 @Override 348 public String toString() { 349 return "exchangeException[" + type + "]"; 350 } 351 }; 352 } 353 354 /** 355 * Returns the expression for the exchanges exception invoking methods defined 356 * in a simple OGNL notation 357 * 358 * @param ognl methods to invoke on the body in a simple OGNL syntax 359 */ 360 public static Expression exchangeExceptionOgnlExpression(final String ognl) { 361 return new ExpressionAdapter() { 362 public Object evaluate(Exchange exchange) { 363 Object exception = exchange.getException(); 364 if (exception == null) { 365 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); 366 } 367 368 if (exception == null) { 369 return null; 370 } 371 return new MethodCallExpression(exception, ognl).evaluate(exchange); 372 } 373 374 @Override 375 public String toString() { 376 return "exchangeExceptionOgnl(" + ognl + ")"; 377 } 378 }; 379 } 380 381 /** 382 * Returns an expression for the type converter 383 * 384 * @return an expression object which will return the type converter 385 */ 386 public static Expression typeConverterExpression() { 387 return new ExpressionAdapter() { 388 public Object evaluate(Exchange exchange) { 389 return exchange.getContext().getTypeConverter(); 390 } 391 392 @Override 393 public String toString() { 394 return "typeConverter"; 395 } 396 }; 397 } 398 399 /** 400 * Returns an expression for the {@link org.apache.camel.spi.Registry} 401 * 402 * @return an expression object which will return the registry 403 */ 404 public static Expression registryExpression() { 405 return new ExpressionAdapter() { 406 public Object evaluate(Exchange exchange) { 407 return exchange.getContext().getRegistry(); 408 } 409 410 @Override 411 public String toString() { 412 return "registry"; 413 } 414 }; 415 } 416 417 /** 418 * Returns an expression for lookup a bean in the {@link org.apache.camel.spi.Registry} 419 * 420 * @return an expression object which will return the bean 421 */ 422 public static Expression refExpression(final String ref) { 423 return new ExpressionAdapter() { 424 public Object evaluate(Exchange exchange) { 425 return exchange.getContext().getRegistry().lookupByName(ref); 426 } 427 428 @Override 429 public String toString() { 430 return "ref(" + ref + ")"; 431 } 432 }; 433 } 434 435 /** 436 * Returns an expression for the {@link org.apache.camel.CamelContext} 437 * 438 * @return an expression object which will return the camel context 439 */ 440 public static Expression camelContextExpression() { 441 return new ExpressionAdapter() { 442 public Object evaluate(Exchange exchange) { 443 return exchange.getContext(); 444 } 445 446 @Override 447 public String toString() { 448 return "camelContext"; 449 } 450 }; 451 } 452 453 /** 454 * Returns an expression for the {@link org.apache.camel.CamelContext} name 455 * 456 * @return an expression object which will return the camel context name 457 */ 458 public static Expression camelContextNameExpression() { 459 return new ExpressionAdapter() { 460 public Object evaluate(Exchange exchange) { 461 return exchange.getContext().getName(); 462 } 463 464 @Override 465 public String toString() { 466 return "camelContextName"; 467 } 468 }; 469 } 470 471 /** 472 * Returns an expression for an exception message set on the exchange 473 * 474 * @see <tt>Exchange.getException().getMessage()</tt> 475 * @return an expression object which will return the exception message set on the exchange 476 */ 477 public static Expression exchangeExceptionMessageExpression() { 478 return new ExpressionAdapter() { 479 public Object evaluate(Exchange exchange) { 480 Exception exception = exchange.getException(); 481 if (exception == null) { 482 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); 483 } 484 return exception != null ? exception.getMessage() : null; 485 } 486 487 @Override 488 public String toString() { 489 return "exchangeExceptionMessage"; 490 } 491 }; 492 } 493 494 /** 495 * Returns an expression for an exception stacktrace set on the exchange 496 * 497 * @return an expression object which will return the exception stacktrace set on the exchange 498 */ 499 public static Expression exchangeExceptionStackTraceExpression() { 500 return new ExpressionAdapter() { 501 public Object evaluate(Exchange exchange) { 502 Exception exception = exchange.getException(); 503 if (exception == null) { 504 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); 505 } 506 if (exception != null) { 507 StringWriter sw = new StringWriter(); 508 PrintWriter pw = new PrintWriter(sw); 509 exception.printStackTrace(pw); 510 IOHelper.close(pw, sw); 511 return sw.toString(); 512 } else { 513 return null; 514 } 515 } 516 517 @Override 518 public String toString() { 519 return "exchangeExceptionStackTrace"; 520 } 521 }; 522 } 523 524 /** 525 * Returns an expression for the property value of exchange with the given name 526 * 527 * @param propertyName the name of the property the expression will return 528 * @return an expression object which will return the property value 529 * @deprecated use {@link #exchangePropertyExpression(String)} instead 530 */ 531 @Deprecated 532 public static Expression propertyExpression(final String propertyName) { 533 return new ExpressionAdapter() { 534 public Object evaluate(Exchange exchange) { 535 return exchange.getProperty(propertyName); 536 } 537 538 @Override 539 public String toString() { 540 return "exchangeProperty(" + propertyName + ")"; 541 } 542 }; 543 } 544 545 /** 546 * Returns an expression for the property value of exchange with the given name 547 * 548 * @param propertyName the name of the property the expression will return 549 * @return an expression object which will return the property value 550 */ 551 public static Expression exchangePropertyExpression(final String propertyName) { 552 return new ExpressionAdapter() { 553 public Object evaluate(Exchange exchange) { 554 return exchange.getProperty(propertyName); 555 } 556 557 @Override 558 public String toString() { 559 return "exchangeProperty(" + propertyName + ")"; 560 } 561 }; 562 } 563 564 /** 565 * Returns an expression for the property value of exchange with the given name invoking methods defined 566 * in a simple OGNL notation 567 * 568 * @param ognl methods to invoke on the property in a simple OGNL syntax 569 */ 570 public static Expression propertyOgnlExpression(final String ognl) { 571 return new KeyedOgnlExpressionAdapter(ognl, "propertyOgnl(" + ognl + ")", 572 new KeyedOgnlExpressionAdapter.KeyedEntityRetrievalStrategy() { 573 public Object getKeyedEntity(Exchange exchange, String key) { 574 return exchange.getProperty(key); 575 } 576 }); 577 } 578 579 /** 580 * Returns an expression for the properties of exchange 581 * 582 * @return an expression object which will return the properties 583 */ 584 public static Expression propertiesExpression() { 585 return new ExpressionAdapter() { 586 public Object evaluate(Exchange exchange) { 587 return exchange.getProperties(); 588 } 589 590 @Override 591 public String toString() { 592 return "properties"; 593 } 594 }; 595 } 596 597 /** 598 * Returns an expression for the properties of the camel context 599 * 600 * @return an expression object which will return the properties 601 */ 602 public static Expression camelContextPropertiesExpression() { 603 return new ExpressionAdapter() { 604 public Object evaluate(Exchange exchange) { 605 return exchange.getContext().getProperties(); 606 } 607 608 @Override 609 public String toString() { 610 return "camelContextProperties"; 611 } 612 }; 613 } 614 615 /** 616 * Returns an expression for the property value of the camel context with the given name 617 * 618 * @param propertyName the name of the property the expression will return 619 * @return an expression object which will return the property value 620 */ 621 public static Expression camelContextPropertyExpression(final String propertyName) { 622 return new ExpressionAdapter() { 623 public Object evaluate(Exchange exchange) { 624 return exchange.getContext().getProperty(propertyName); 625 } 626 627 @Override 628 public String toString() { 629 return "camelContextProperty(" + propertyName + ")"; 630 } 631 }; 632 } 633 634 /** 635 * Returns an expression for a system property value with the given name 636 * 637 * @param propertyName the name of the system property the expression will return 638 * @return an expression object which will return the system property value 639 */ 640 public static Expression systemPropertyExpression(final String propertyName) { 641 return systemPropertyExpression(propertyName, null); 642 } 643 644 /** 645 * Returns an expression for a system property value with the given name 646 * 647 * @param propertyName the name of the system property the expression will return 648 * @param defaultValue default value to return if no system property exists 649 * @return an expression object which will return the system property value 650 */ 651 public static Expression systemPropertyExpression(final String propertyName, 652 final String defaultValue) { 653 return new ExpressionAdapter() { 654 public Object evaluate(Exchange exchange) { 655 return System.getProperty(propertyName, defaultValue); 656 } 657 658 @Override 659 public String toString() { 660 return "systemProperty(" + propertyName + ")"; 661 } 662 }; 663 } 664 665 /** 666 * Returns an expression for a system environment value with the given name 667 * 668 * @param propertyName the name of the system environment the expression will return 669 * @return an expression object which will return the system property value 670 */ 671 public static Expression systemEnvironmentExpression(final String propertyName) { 672 return systemEnvironmentExpression(propertyName, null); 673 } 674 675 /** 676 * Returns an expression for a system environment value with the given name 677 * 678 * @param propertyName the name of the system environment the expression will return 679 * @param defaultValue default value to return if no system environment exists 680 * @return an expression object which will return the system environment value 681 */ 682 public static Expression systemEnvironmentExpression(final String propertyName, 683 final String defaultValue) { 684 return new ExpressionAdapter() { 685 public Object evaluate(Exchange exchange) { 686 String answer = System.getenv(propertyName); 687 if (answer == null) { 688 answer = defaultValue; 689 } 690 return answer; 691 } 692 693 @Override 694 public String toString() { 695 return "systemEnvironment(" + propertyName + ")"; 696 } 697 }; 698 } 699 700 /** 701 * Returns an expression for the constant value 702 * 703 * @param value the value the expression will return 704 * @return an expression object which will return the constant value 705 */ 706 public static Expression constantExpression(final Object value) { 707 return new ExpressionAdapter() { 708 public Object evaluate(Exchange exchange) { 709 return value; 710 } 711 712 @Override 713 public String toString() { 714 return "" + value; 715 } 716 }; 717 } 718 719 /** 720 * Returns an expression for evaluating the expression/predicate using the given language 721 * 722 * @param expression the expression or predicate 723 * @return an expression object which will evaluate the expression/predicate using the given language 724 */ 725 public static Expression languageExpression(final String language, final String expression) { 726 return new ExpressionAdapter() { 727 public Object evaluate(Exchange exchange) { 728 Language lan = exchange.getContext().resolveLanguage(language); 729 if (lan != null) { 730 return lan.createExpression(expression).evaluate(exchange, Object.class); 731 } else { 732 throw new NoSuchLanguageException(language); 733 } 734 } 735 736 @Override 737 public boolean matches(Exchange exchange) { 738 Language lan = exchange.getContext().resolveLanguage(language); 739 if (lan != null) { 740 return lan.createPredicate(expression).matches(exchange); 741 } else { 742 throw new NoSuchLanguageException(language); 743 } 744 } 745 746 @Override 747 public String toString() { 748 return "language[" + language + ":" + expression + "]"; 749 } 750 }; 751 } 752 753 /** 754 * Returns an expression for a type value 755 * 756 * @param name the type name 757 * @return an expression object which will return the type value 758 */ 759 public static Expression typeExpression(final String name) { 760 return new ExpressionAdapter() { 761 public Object evaluate(Exchange exchange) { 762 // it may refer to a class type 763 Class<?> type = exchange.getContext().getClassResolver().resolveClass(name); 764 if (type != null) { 765 return type; 766 } 767 768 int pos = name.lastIndexOf("."); 769 if (pos > 0) { 770 String before = name.substring(0, pos); 771 String after = name.substring(pos + 1); 772 type = exchange.getContext().getClassResolver().resolveClass(before); 773 if (type != null) { 774 return ObjectHelper.lookupConstantFieldValue(type, after); 775 } 776 } 777 778 throw ObjectHelper.wrapCamelExecutionException(exchange, new ClassNotFoundException("Cannot find type " + name)); 779 } 780 781 @Override 782 public String toString() { 783 return "type:" + name; 784 } 785 }; 786 } 787 788 /** 789 * Returns an expression that caches the evaluation of another expression 790 * and returns the cached value, to avoid re-evaluating the expression. 791 * 792 * @param expression the target expression to cache 793 * @return the cached value 794 */ 795 public static Expression cacheExpression(final Expression expression) { 796 return new ExpressionAdapter() { 797 private final AtomicReference<Object> cache = new AtomicReference<Object>(); 798 799 public Object evaluate(Exchange exchange) { 800 Object answer = cache.get(); 801 if (answer == null) { 802 answer = expression.evaluate(exchange, Object.class); 803 cache.set(answer); 804 } 805 return answer; 806 } 807 808 @Override 809 public String toString() { 810 return expression.toString(); 811 } 812 }; 813 } 814 815 /** 816 * Returns the expression for the exchanges inbound message body 817 */ 818 public static Expression bodyExpression() { 819 return new ExpressionAdapter() { 820 public Object evaluate(Exchange exchange) { 821 return exchange.getIn().getBody(); 822 } 823 824 @Override 825 public String toString() { 826 return "body"; 827 } 828 }; 829 } 830 831 /** 832 * Returns the expression for the exchanges inbound message body invoking methods defined 833 * in a simple OGNL notation 834 * 835 * @param ognl methods to invoke on the body in a simple OGNL syntax 836 */ 837 public static Expression bodyOgnlExpression(final String ognl) { 838 return new ExpressionAdapter() { 839 public Object evaluate(Exchange exchange) { 840 Object body = exchange.getIn().getBody(); 841 if (body == null) { 842 return null; 843 } 844 return new MethodCallExpression(body, ognl).evaluate(exchange); 845 } 846 847 @Override 848 public String toString() { 849 return "bodyOgnl(" + ognl + ")"; 850 } 851 }; 852 } 853 854 /** 855 * Returns the expression for invoking a method (support OGNL syntax) on the given expression 856 * 857 * @param exp the expression to evaluate and invoke the method on its result 858 * @param ognl methods to invoke on the evaluated expression in a simple OGNL syntax 859 */ 860 public static Expression ognlExpression(final Expression exp, final String ognl) { 861 return new ExpressionAdapter() { 862 public Object evaluate(Exchange exchange) { 863 Object value = exp.evaluate(exchange, Object.class); 864 if (value == null) { 865 return null; 866 } 867 return new MethodCallExpression(value, ognl).evaluate(exchange); 868 } 869 870 @Override 871 public String toString() { 872 return "ognl(" + exp + ", " + ognl + ")"; 873 } 874 }; 875 } 876 877 /** 878 * Returns the expression for the exchanges camelContext invoking methods defined 879 * in a simple OGNL notation 880 * 881 * @param ognl methods to invoke on the context in a simple OGNL syntax 882 */ 883 public static Expression camelContextOgnlExpression(final String ognl) { 884 return new ExpressionAdapter() { 885 public Object evaluate(Exchange exchange) { 886 CamelContext context = exchange.getContext(); 887 if (context == null) { 888 return null; 889 } 890 return new MethodCallExpression(context, ognl).evaluate(exchange); 891 } 892 893 @Override 894 public String toString() { 895 return "camelContextOgnl(" + ognl + ")"; 896 } 897 }; 898 } 899 900 /** 901 * Returns the expression for the exchange invoking methods defined 902 * in a simple OGNL notation 903 * 904 * @param ognl methods to invoke on the exchange in a simple OGNL syntax 905 */ 906 public static Expression exchangeOgnlExpression(final String ognl) { 907 return new ExpressionAdapter() { 908 public Object evaluate(Exchange exchange) { 909 return new MethodCallExpression(exchange, ognl).evaluate(exchange); 910 } 911 912 @Override 913 public String toString() { 914 return "exchangeOgnl(" + ognl + ")"; 915 } 916 }; 917 } 918 919 /** 920 * Returns the expression for the exchanges inbound message body converted 921 * to the given type 922 */ 923 public static <T> Expression bodyExpression(final Class<T> type) { 924 return new ExpressionAdapter() { 925 public Object evaluate(Exchange exchange) { 926 return exchange.getIn().getBody(type); 927 } 928 929 @Override 930 public String toString() { 931 return "bodyAs[" + type.getName() + "]"; 932 } 933 }; 934 } 935 936 /** 937 * Returns the expression for the exchanges inbound message body converted 938 * to the given type 939 */ 940 public static Expression bodyExpression(final String name) { 941 return new ExpressionAdapter() { 942 public Object evaluate(Exchange exchange) { 943 Class<?> type; 944 try { 945 type = exchange.getContext().getClassResolver().resolveMandatoryClass(name); 946 } catch (ClassNotFoundException e) { 947 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 948 } 949 return exchange.getIn().getBody(type); 950 } 951 952 @Override 953 public String toString() { 954 return "bodyAs[" + name + "]"; 955 } 956 }; 957 } 958 959 /** 960 * Returns the expression for the exchanges inbound message body converted 961 * to the given type 962 */ 963 public static Expression mandatoryBodyExpression(final String name) { 964 return new ExpressionAdapter() { 965 public Object evaluate(Exchange exchange) { 966 Class<?> type; 967 try { 968 type = exchange.getContext().getClassResolver().resolveMandatoryClass(name); 969 } catch (ClassNotFoundException e) { 970 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 971 } 972 try { 973 return exchange.getIn().getMandatoryBody(type); 974 } catch (InvalidPayloadException e) { 975 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 976 } 977 } 978 979 @Override 980 public String toString() { 981 return "mandatoryBodyAs[" + name + "]"; 982 } 983 }; 984 } 985 986 /** 987 * Returns the expression for the current thread name 988 */ 989 public static Expression threadNameExpression() { 990 return new ExpressionAdapter() { 991 public Object evaluate(Exchange exchange) { 992 return Thread.currentThread().getName(); 993 } 994 995 @Override 996 public String toString() { 997 return "threadName"; 998 } 999 }; 1000 } 1001 1002 /** 1003 * Returns the expression for the {@code null} value 1004 */ 1005 public static Expression nullExpression() { 1006 return new ExpressionAdapter() { 1007 public Object evaluate(Exchange exchange) { 1008 return null; 1009 } 1010 1011 @Override 1012 public String toString() { 1013 return "null"; 1014 } 1015 }; 1016 } 1017 1018 /** 1019 * Returns the expression for the exchanges inbound message body converted 1020 * to the given type. 1021 * <p/> 1022 * Does <b>not</b> allow null bodies. 1023 */ 1024 public static <T> Expression mandatoryBodyExpression(final Class<T> type) { 1025 return mandatoryBodyExpression(type, false); 1026 } 1027 1028 /** 1029 * Returns the expression for the exchanges inbound message body converted 1030 * to the given type 1031 * 1032 * @param type the type 1033 * @param nullBodyAllowed whether null bodies is allowed and if so a null is returned, 1034 * otherwise an exception is thrown 1035 */ 1036 public static <T> Expression mandatoryBodyExpression(final Class<T> type, final boolean nullBodyAllowed) { 1037 return new ExpressionAdapter() { 1038 public Object evaluate(Exchange exchange) { 1039 if (nullBodyAllowed) { 1040 if (exchange.getIn().getBody() == null) { 1041 return null; 1042 } 1043 1044 // if its a bean invocation then if it has no arguments then it should be threaded as null body allowed 1045 if (exchange.getIn().getBody() instanceof BeanInvocation) { 1046 // BeanInvocation would be stored directly as the message body 1047 // do not force any type conversion attempts as it would just be unnecessary and cost a bit performance 1048 // so a regular instanceof check is sufficient 1049 BeanInvocation bi = (BeanInvocation) exchange.getIn().getBody(); 1050 if (bi.getArgs() == null || bi.getArgs().length == 0 || bi.getArgs()[0] == null) { 1051 return null; 1052 } 1053 } 1054 } 1055 1056 try { 1057 return exchange.getIn().getMandatoryBody(type); 1058 } catch (InvalidPayloadException e) { 1059 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 1060 } 1061 } 1062 1063 @Override 1064 public String toString() { 1065 return "mandatoryBodyAs[" + type.getName() + "]"; 1066 } 1067 }; 1068 } 1069 1070 /** 1071 * Returns the expression for the exchanges inbound message body type 1072 */ 1073 public static Expression bodyTypeExpression() { 1074 return new ExpressionAdapter() { 1075 public Object evaluate(Exchange exchange) { 1076 return exchange.getIn().getBody().getClass(); 1077 } 1078 1079 @Override 1080 public String toString() { 1081 return "bodyType"; 1082 } 1083 }; 1084 } 1085 1086 /** 1087 * Returns the expression for the out messages body 1088 */ 1089 public static Expression outBodyExpression() { 1090 return new ExpressionAdapter() { 1091 public Object evaluate(Exchange exchange) { 1092 if (exchange.hasOut()) { 1093 return exchange.getOut().getBody(); 1094 } else { 1095 return null; 1096 } 1097 } 1098 1099 @Override 1100 public String toString() { 1101 return "outBody"; 1102 } 1103 }; 1104 } 1105 1106 /** 1107 * Returns the expression for the exchanges outbound message body converted 1108 * to the given type 1109 */ 1110 public static <T> Expression outBodyExpression(final Class<T> type) { 1111 return new ExpressionAdapter() { 1112 public Object evaluate(Exchange exchange) { 1113 if (exchange.hasOut()) { 1114 return exchange.getOut().getBody(type); 1115 } else { 1116 return null; 1117 } 1118 } 1119 1120 @Override 1121 public String toString() { 1122 return "outBodyAs[" + type.getName() + "]"; 1123 } 1124 }; 1125 } 1126 1127 /** 1128 * Returns the expression for the fault messages body 1129 */ 1130 public static Expression faultBodyExpression() { 1131 return new ExpressionAdapter() { 1132 public Object evaluate(Exchange exchange) { 1133 Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn(); 1134 return msg.isFault() ? msg.getBody() : null; 1135 } 1136 1137 @Override 1138 public String toString() { 1139 return "faultBody"; 1140 } 1141 }; 1142 } 1143 1144 /** 1145 * Returns the expression for the exchanges fault message body converted 1146 * to the given type 1147 */ 1148 public static <T> Expression faultBodyExpression(final Class<T> type) { 1149 return new ExpressionAdapter() { 1150 public Object evaluate(Exchange exchange) { 1151 Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn(); 1152 return msg.isFault() ? msg.getBody(type) : null; 1153 } 1154 1155 @Override 1156 public String toString() { 1157 return "faultBodyAs[" + type.getName() + "]"; 1158 } 1159 }; 1160 } 1161 1162 /** 1163 * Returns the expression for the exchange 1164 */ 1165 public static Expression exchangeExpression() { 1166 return new ExpressionAdapter() { 1167 public Object evaluate(Exchange exchange) { 1168 return exchange; 1169 } 1170 1171 @Override 1172 public String toString() { 1173 return "exchange"; 1174 } 1175 }; 1176 } 1177 1178 /** 1179 * Returns the expression for the IN message 1180 */ 1181 public static Expression inMessageExpression() { 1182 return new ExpressionAdapter() { 1183 public Object evaluate(Exchange exchange) { 1184 return exchange.getIn(); 1185 } 1186 1187 @Override 1188 public String toString() { 1189 return "inMessage"; 1190 } 1191 }; 1192 } 1193 1194 /** 1195 * Returns the expression for the OUT message 1196 */ 1197 public static Expression outMessageExpression() { 1198 return new ExpressionAdapter() { 1199 public Object evaluate(Exchange exchange) { 1200 return exchange.getOut(); 1201 } 1202 1203 @Override 1204 public String toString() { 1205 return "outMessage"; 1206 } 1207 }; 1208 } 1209 1210 /** 1211 * Returns an expression which converts the given expression to the given type 1212 */ 1213 public static Expression convertToExpression(final Expression expression, final Class<?> type) { 1214 return new ExpressionAdapter() { 1215 public Object evaluate(Exchange exchange) { 1216 if (type != null) { 1217 return expression.evaluate(exchange, type); 1218 } else { 1219 return expression; 1220 } 1221 } 1222 1223 @Override 1224 public String toString() { 1225 return "" + expression; 1226 } 1227 }; 1228 } 1229 1230 /** 1231 * Returns an expression which converts the given expression to the given type the type 1232 * expression is evaluated to 1233 */ 1234 public static Expression convertToExpression(final Expression expression, final Expression type) { 1235 return new ExpressionAdapter() { 1236 public Object evaluate(Exchange exchange) { 1237 Object result = type.evaluate(exchange, Object.class); 1238 if (result != null) { 1239 return expression.evaluate(exchange, result.getClass()); 1240 } else { 1241 return expression; 1242 } 1243 } 1244 1245 @Override 1246 public String toString() { 1247 return "" + expression; 1248 } 1249 }; 1250 } 1251 1252 /** 1253 * Returns a tokenize expression which will tokenize the string with the 1254 * given token 1255 */ 1256 public static Expression tokenizeExpression(final Expression expression, 1257 final String token) { 1258 return new ExpressionAdapter() { 1259 public Object evaluate(Exchange exchange) { 1260 Object value = expression.evaluate(exchange, Object.class); 1261 Scanner scanner = ObjectHelper.getScanner(exchange, value); 1262 scanner.useDelimiter(token); 1263 return scanner; 1264 } 1265 1266 @Override 1267 public String toString() { 1268 return "tokenize(" + expression + ", " + token + ")"; 1269 } 1270 }; 1271 } 1272 1273 /** 1274 * Returns an {@link TokenPairExpressionIterator} expression 1275 */ 1276 public static Expression tokenizePairExpression(String startToken, String endToken, boolean includeTokens) { 1277 return new TokenPairExpressionIterator(startToken, endToken, includeTokens); 1278 } 1279 1280 /** 1281 * Returns an {@link TokenXMLExpressionIterator} expression 1282 */ 1283 public static Expression tokenizeXMLExpression(String tagName, String inheritNamespaceTagName) { 1284 ObjectHelper.notEmpty(tagName, "tagName"); 1285 1286 // must be XML tokens 1287 if (!tagName.startsWith("<")) { 1288 tagName = "<" + tagName; 1289 } 1290 if (!tagName.endsWith(">")) { 1291 tagName = tagName + ">"; 1292 } 1293 1294 if (inheritNamespaceTagName != null) { 1295 if (!inheritNamespaceTagName.startsWith("<")) { 1296 inheritNamespaceTagName = "<" + inheritNamespaceTagName; 1297 } 1298 if (!inheritNamespaceTagName.endsWith(">")) { 1299 inheritNamespaceTagName = inheritNamespaceTagName + ">"; 1300 } 1301 } 1302 return new TokenXMLExpressionIterator(tagName, inheritNamespaceTagName); 1303 } 1304 1305 public static Expression tokenizeXMLAwareExpression(String path, char mode) { 1306 ObjectHelper.notEmpty(path, "path"); 1307 1308 return new XMLTokenExpressionIterator(path, mode); 1309 } 1310 1311 public static Expression tokenizeXMLAwareExpression(String path, char mode, int group) { 1312 ObjectHelper.notEmpty(path, "path"); 1313 1314 return new XMLTokenExpressionIterator(path, mode, group); 1315 } 1316 1317 /** 1318 * Returns a tokenize expression which will tokenize the string with the 1319 * given regex 1320 */ 1321 public static Expression regexTokenizeExpression(final Expression expression, 1322 final String regexTokenizer) { 1323 final Pattern pattern = Pattern.compile(regexTokenizer); 1324 return new ExpressionAdapter() { 1325 public Object evaluate(Exchange exchange) { 1326 Object value = expression.evaluate(exchange, Object.class); 1327 Scanner scanner = ObjectHelper.getScanner(exchange, value); 1328 scanner.useDelimiter(pattern); 1329 return scanner; 1330 } 1331 1332 @Override 1333 public String toString() { 1334 return "regexTokenize(" + expression + ", " + pattern.pattern() + ")"; 1335 } 1336 }; 1337 } 1338 1339 public static Expression groupIteratorExpression(final Expression expression, final String token, final int group) { 1340 return new ExpressionAdapter() { 1341 public Object evaluate(Exchange exchange) { 1342 // evaluate expression as iterator 1343 Iterator<?> it = expression.evaluate(exchange, Iterator.class); 1344 ObjectHelper.notNull(it, "expression: " + expression + " evaluated on " + exchange + " must return an java.util.Iterator"); 1345 return new GroupIterator(exchange, it, token, group); 1346 } 1347 1348 @Override 1349 public String toString() { 1350 return "group " + expression + " " + group + " times"; 1351 } 1352 }; 1353 } 1354 1355 /** 1356 * Returns a sort expression which will sort the expression with the given comparator. 1357 * <p/> 1358 * The expression is evaluated as a {@link List} object to allow sorting. 1359 */ 1360 @SuppressWarnings({"unchecked", "rawtypes"}) 1361 public static Expression sortExpression(final Expression expression, final Comparator comparator) { 1362 return new ExpressionAdapter() { 1363 public Object evaluate(Exchange exchange) { 1364 List<?> list = expression.evaluate(exchange, List.class); 1365 Collections.sort(list, comparator); 1366 return list; 1367 } 1368 1369 @Override 1370 public String toString() { 1371 return "sort(" + expression + " by: " + comparator + ")"; 1372 } 1373 }; 1374 } 1375 1376 /** 1377 * Transforms the expression into a String then performs the regex 1378 * replaceAll to transform the String and return the result 1379 */ 1380 public static Expression regexReplaceAll(final Expression expression, 1381 final String regex, final String replacement) { 1382 final Pattern pattern = Pattern.compile(regex); 1383 return new ExpressionAdapter() { 1384 public Object evaluate(Exchange exchange) { 1385 String text = expression.evaluate(exchange, String.class); 1386 if (text == null) { 1387 return null; 1388 } 1389 return pattern.matcher(text).replaceAll(replacement); 1390 } 1391 1392 @Override 1393 public String toString() { 1394 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 1395 } 1396 }; 1397 } 1398 1399 /** 1400 * Transforms the expression into a String then performs the regex 1401 * replaceAll to transform the String and return the result 1402 */ 1403 public static Expression regexReplaceAll(final Expression expression, 1404 final String regex, final Expression replacementExpression) { 1405 1406 final Pattern pattern = Pattern.compile(regex); 1407 return new ExpressionAdapter() { 1408 public Object evaluate(Exchange exchange) { 1409 String text = expression.evaluate(exchange, String.class); 1410 String replacement = replacementExpression.evaluate(exchange, String.class); 1411 if (text == null || replacement == null) { 1412 return null; 1413 } 1414 return pattern.matcher(text).replaceAll(replacement); 1415 } 1416 1417 @Override 1418 public String toString() { 1419 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 1420 } 1421 }; 1422 } 1423 1424 /** 1425 * Appends the String evaluations of the two expressions together 1426 */ 1427 public static Expression append(final Expression left, final Expression right) { 1428 return new ExpressionAdapter() { 1429 public Object evaluate(Exchange exchange) { 1430 return left.evaluate(exchange, String.class) + right.evaluate(exchange, String.class); 1431 } 1432 1433 @Override 1434 public String toString() { 1435 return "append(" + left + ", " + right + ")"; 1436 } 1437 }; 1438 } 1439 1440 /** 1441 * Prepends the String evaluations of the two expressions together 1442 */ 1443 public static Expression prepend(final Expression left, final Expression right) { 1444 return new ExpressionAdapter() { 1445 public Object evaluate(Exchange exchange) { 1446 return right.evaluate(exchange, String.class) + left.evaluate(exchange, String.class); 1447 } 1448 1449 @Override 1450 public String toString() { 1451 return "prepend(" + left + ", " + right + ")"; 1452 } 1453 }; 1454 } 1455 1456 /** 1457 * Returns an expression which returns the string concatenation value of the various 1458 * expressions 1459 * 1460 * @param expressions the expression to be concatenated dynamically 1461 * @return an expression which when evaluated will return the concatenated values 1462 */ 1463 public static Expression concatExpression(final Collection<Expression> expressions) { 1464 return concatExpression(expressions, null); 1465 } 1466 1467 /** 1468 * Returns an expression which returns the string concatenation value of the various 1469 * expressions 1470 * 1471 * @param expressions the expression to be concatenated dynamically 1472 * @param expression the text description of the expression 1473 * @return an expression which when evaluated will return the concatenated values 1474 */ 1475 public static Expression concatExpression(final Collection<Expression> expressions, final String expression) { 1476 return new ExpressionAdapter() { 1477 public Object evaluate(Exchange exchange) { 1478 StringBuilder buffer = new StringBuilder(); 1479 for (Expression expression : expressions) { 1480 String text = expression.evaluate(exchange, String.class); 1481 if (text != null) { 1482 buffer.append(text); 1483 } 1484 } 1485 return buffer.toString(); 1486 } 1487 1488 @Override 1489 public String toString() { 1490 if (expression != null) { 1491 return expression; 1492 } else { 1493 return "concat" + expressions; 1494 } 1495 } 1496 }; 1497 } 1498 1499 /** 1500 * Returns an Expression for the inbound message id 1501 */ 1502 public static Expression messageIdExpression() { 1503 return new ExpressionAdapter() { 1504 public Object evaluate(Exchange exchange) { 1505 return exchange.getIn().getMessageId(); 1506 } 1507 1508 @Override 1509 public String toString() { 1510 return "messageId"; 1511 } 1512 }; 1513 } 1514 1515 /** 1516 * Returns an Expression for the exchange id 1517 */ 1518 public static Expression exchangeIdExpression() { 1519 return new ExpressionAdapter() { 1520 public Object evaluate(Exchange exchange) { 1521 return exchange.getExchangeId(); 1522 } 1523 1524 @Override 1525 public String toString() { 1526 return "exchangeId"; 1527 } 1528 }; 1529 } 1530 1531 /** 1532 * Returns an Expression for the route id 1533 */ 1534 public static Expression routeIdExpression() { 1535 return new ExpressionAdapter() { 1536 public Object evaluate(Exchange exchange) { 1537 String answer = null; 1538 UnitOfWork uow = exchange.getUnitOfWork(); 1539 RouteContext rc = uow != null ? uow.getRouteContext() : null; 1540 if (rc != null) { 1541 answer = rc.getRoute().getId(); 1542 } 1543 if (answer == null) { 1544 // fallback and get from route id on the exchange 1545 answer = exchange.getFromRouteId(); 1546 } 1547 return answer; 1548 } 1549 1550 @Override 1551 public String toString() { 1552 return "routeId"; 1553 } 1554 }; 1555 } 1556 1557 public static Expression dateExpression(final String command, final String pattern) { 1558 return new ExpressionAdapter() { 1559 public Object evaluate(Exchange exchange) { 1560 Date date; 1561 if ("now".equals(command)) { 1562 date = new Date(); 1563 } else if (command.startsWith("header.") || command.startsWith("in.header.")) { 1564 String key = command.substring(command.lastIndexOf('.') + 1); 1565 date = exchange.getIn().getHeader(key, Date.class); 1566 if (date == null) { 1567 throw new IllegalArgumentException("Cannot find java.util.Date object at command: " + command); 1568 } 1569 } else if (command.startsWith("out.header.")) { 1570 String key = command.substring(command.lastIndexOf('.') + 1); 1571 date = exchange.getOut().getHeader(key, Date.class); 1572 if (date == null) { 1573 throw new IllegalArgumentException("Cannot find java.util.Date object at command: " + command); 1574 } 1575 } else if ("file".equals(command)) { 1576 Long num = exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Long.class); 1577 if (num != null && num > 0) { 1578 date = new Date(num.longValue()); 1579 } else { 1580 date = exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Date.class); 1581 if (date == null) { 1582 throw new IllegalArgumentException("Cannot find " + Exchange.FILE_LAST_MODIFIED + " header at command: " + command); 1583 } 1584 } 1585 } else { 1586 throw new IllegalArgumentException("Command not supported for dateExpression: " + command); 1587 } 1588 1589 SimpleDateFormat df = new SimpleDateFormat(pattern); 1590 return df.format(date); 1591 } 1592 1593 @Override 1594 public String toString() { 1595 return "date(" + command + ":" + pattern + ")"; 1596 } 1597 }; 1598 } 1599 1600 public static Expression simpleExpression(final String expression) { 1601 return new ExpressionAdapter() { 1602 public Object evaluate(Exchange exchange) { 1603 // resolve language using context to have a clear separation of packages 1604 // must call evaluate to return the nested language evaluate when evaluating 1605 // stacked expressions 1606 Language language = exchange.getContext().resolveLanguage("simple"); 1607 return language.createExpression(expression).evaluate(exchange, Object.class); 1608 } 1609 1610 @Override 1611 public String toString() { 1612 return "simple(" + expression + ")"; 1613 } 1614 }; 1615 } 1616 1617 public static Expression beanExpression(final String expression) { 1618 return new ExpressionAdapter() { 1619 public Object evaluate(Exchange exchange) { 1620 // resolve language using context to have a clear separation of packages 1621 // must call evaluate to return the nested language evaluate when evaluating 1622 // stacked expressions 1623 Language language = exchange.getContext().resolveLanguage("bean"); 1624 return language.createExpression(expression).evaluate(exchange, Object.class); 1625 } 1626 1627 @Override 1628 public String toString() { 1629 return "bean(" + expression + ")"; 1630 } 1631 }; 1632 } 1633 1634 public static Expression beanExpression(final Class<?> beanType, final String methodName) { 1635 return BeanLanguage.bean(beanType, methodName); 1636 } 1637 1638 public static Expression beanExpression(final Object bean, final String methodName) { 1639 return BeanLanguage.bean(bean, methodName); 1640 } 1641 1642 public static Expression beanExpression(final String beanRef, final String methodName) { 1643 String expression = methodName != null ? beanRef + "." + methodName : beanRef; 1644 return beanExpression(expression); 1645 } 1646 1647 /** 1648 * Returns an expression processing the exchange to the given endpoint uri 1649 * 1650 * @param uri endpoint uri to send the exchange to 1651 * @return an expression object which will return the OUT body 1652 */ 1653 public static Expression toExpression(final String uri) { 1654 return new ExpressionAdapter() { 1655 public Object evaluate(Exchange exchange) { 1656 Endpoint endpoint = exchange.getContext().getEndpoint(uri); 1657 if (endpoint == null) { 1658 throw new NoSuchEndpointException(uri); 1659 } 1660 1661 Producer producer; 1662 try { 1663 producer = endpoint.createProducer(); 1664 producer.start(); 1665 producer.process(exchange); 1666 producer.stop(); 1667 } catch (Exception e) { 1668 throw ObjectHelper.wrapRuntimeCamelException(e); 1669 } 1670 1671 // return the OUT body, but check for exchange pattern 1672 if (ExchangeHelper.isOutCapable(exchange)) { 1673 return exchange.getOut().getBody(); 1674 } else { 1675 return exchange.getIn().getBody(); 1676 } 1677 } 1678 1679 @Override 1680 public String toString() { 1681 return "to(" + uri + ")"; 1682 } 1683 }; 1684 } 1685 1686 public static Expression fileNameExpression() { 1687 return new ExpressionAdapter() { 1688 public Object evaluate(Exchange exchange) { 1689 return exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1690 } 1691 1692 @Override 1693 public String toString() { 1694 return "file:name"; 1695 } 1696 }; 1697 } 1698 1699 public static Expression fileOnlyNameExpression() { 1700 return new ExpressionAdapter() { 1701 public Object evaluate(Exchange exchange) { 1702 String answer = exchange.getIn().getHeader(Exchange.FILE_NAME_ONLY, String.class); 1703 if (answer == null) { 1704 answer = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1705 answer = FileUtil.stripPath(answer); 1706 } 1707 return answer; 1708 } 1709 1710 @Override 1711 public String toString() { 1712 return "file:onlyname"; 1713 } 1714 }; 1715 } 1716 1717 public static Expression fileNameNoExtensionExpression() { 1718 return new ExpressionAdapter() { 1719 public Object evaluate(Exchange exchange) { 1720 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1721 return FileUtil.stripExt(name); 1722 } 1723 1724 @Override 1725 public String toString() { 1726 return "file:name.noext"; 1727 } 1728 }; 1729 } 1730 1731 public static Expression fileNameNoExtensionSingleExpression() { 1732 return new ExpressionAdapter() { 1733 public Object evaluate(Exchange exchange) { 1734 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1735 return FileUtil.stripExt(name, true); 1736 } 1737 1738 @Override 1739 public String toString() { 1740 return "file:name.noext.single"; 1741 } 1742 }; 1743 } 1744 1745 public static Expression fileOnlyNameNoExtensionExpression() { 1746 return new ExpressionAdapter() { 1747 public Object evaluate(Exchange exchange) { 1748 String name = fileOnlyNameExpression().evaluate(exchange, String.class); 1749 return FileUtil.stripExt(name); 1750 } 1751 1752 @Override 1753 public String toString() { 1754 return "file:onlyname.noext"; 1755 } 1756 }; 1757 } 1758 1759 public static Expression fileOnlyNameNoExtensionSingleExpression() { 1760 return new ExpressionAdapter() { 1761 public Object evaluate(Exchange exchange) { 1762 String name = fileOnlyNameExpression().evaluate(exchange, String.class); 1763 return FileUtil.stripExt(name, true); 1764 } 1765 1766 @Override 1767 public String toString() { 1768 return "file:onlyname.noext.single"; 1769 } 1770 }; 1771 } 1772 1773 public static Expression fileExtensionExpression() { 1774 return new ExpressionAdapter() { 1775 public Object evaluate(Exchange exchange) { 1776 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1777 return FileUtil.onlyExt(name); 1778 } 1779 1780 @Override 1781 public String toString() { 1782 return "file:ext"; 1783 } 1784 }; 1785 } 1786 1787 public static Expression fileExtensionSingleExpression() { 1788 return new ExpressionAdapter() { 1789 public Object evaluate(Exchange exchange) { 1790 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1791 return FileUtil.onlyExt(name, true); 1792 } 1793 1794 @Override 1795 public String toString() { 1796 return "file:ext.single"; 1797 } 1798 }; 1799 } 1800 1801 public static Expression fileParentExpression() { 1802 return new ExpressionAdapter() { 1803 public Object evaluate(Exchange exchange) { 1804 return exchange.getIn().getHeader("CamelFileParent", String.class); 1805 } 1806 1807 @Override 1808 public String toString() { 1809 return "file:parent"; 1810 } 1811 }; 1812 } 1813 1814 public static Expression filePathExpression() { 1815 return new ExpressionAdapter() { 1816 public Object evaluate(Exchange exchange) { 1817 return exchange.getIn().getHeader("CamelFilePath", String.class); 1818 } 1819 1820 @Override 1821 public String toString() { 1822 return "file:path"; 1823 } 1824 }; 1825 } 1826 1827 public static Expression fileAbsolutePathExpression() { 1828 return new ExpressionAdapter() { 1829 public Object evaluate(Exchange exchange) { 1830 return exchange.getIn().getHeader("CamelFileAbsolutePath", String.class); 1831 } 1832 1833 @Override 1834 public String toString() { 1835 return "file:absolute.path"; 1836 } 1837 }; 1838 } 1839 1840 public static Expression fileAbsoluteExpression() { 1841 return new ExpressionAdapter() { 1842 public Object evaluate(Exchange exchange) { 1843 return exchange.getIn().getHeader("CamelFileAbsolute", Boolean.class); 1844 } 1845 1846 @Override 1847 public String toString() { 1848 return "file:absolute"; 1849 } 1850 }; 1851 } 1852 1853 public static Expression fileSizeExpression() { 1854 return new ExpressionAdapter() { 1855 public Object evaluate(Exchange exchange) { 1856 return exchange.getIn().getHeader(Exchange.FILE_LENGTH, Long.class); 1857 } 1858 1859 @Override 1860 public String toString() { 1861 return "file:length"; 1862 } 1863 }; 1864 } 1865 1866 public static Expression fileLastModifiedExpression() { 1867 return new ExpressionAdapter() { 1868 public Object evaluate(Exchange exchange) { 1869 return exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Long.class); 1870 } 1871 1872 @Override 1873 public String toString() { 1874 return "file:modified"; 1875 } 1876 }; 1877 } 1878 1879 public static Expression propertiesComponentExpression(final String key, final String locations) { 1880 return new ExpressionAdapter() { 1881 public Object evaluate(Exchange exchange) { 1882 try { 1883 if (locations != null) { 1884 // the properties component is optional as we got locations 1885 // getComponent will create a new component if none already exists 1886 Component component = exchange.getContext().getComponent("properties"); 1887 PropertiesComponent pc = exchange.getContext().getTypeConverter() 1888 .mandatoryConvertTo(PropertiesComponent.class, component); 1889 // enclose key with {{ }} to force parsing 1890 String[] paths = locations.split(","); 1891 return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken(), paths); 1892 } else { 1893 // the properties component is mandatory if no locations provided 1894 Component component = exchange.getContext().hasComponent("properties"); 1895 if (component == null) { 1896 throw new IllegalArgumentException("PropertiesComponent with name properties must be defined" 1897 + " in CamelContext to support property placeholders in expressions"); 1898 } 1899 PropertiesComponent pc = exchange.getContext().getTypeConverter() 1900 .mandatoryConvertTo(PropertiesComponent.class, component); 1901 // enclose key with {{ }} to force parsing 1902 return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken()); 1903 } 1904 } catch (Exception e) { 1905 throw ObjectHelper.wrapRuntimeCamelException(e); 1906 } 1907 } 1908 1909 @Override 1910 public String toString() { 1911 return "properties(" + key + ")"; 1912 } 1913 }; 1914 } 1915 1916 /** 1917 * Returns a random number between min and max 1918 */ 1919 public static Expression randomExpression(final int min, final int max) { 1920 return new ExpressionAdapter() { 1921 public Object evaluate(Exchange exchange) { 1922 Random random = new Random(); 1923 int randomNum = random.nextInt(max - min) + min; 1924 return randomNum; 1925 } 1926 1927 @Override 1928 public String toString() { 1929 return "random"; 1930 } 1931 }; 1932 } 1933 1934 /** 1935 * Returns a random number between 0 and upperbound (exclusive) 1936 */ 1937 public static Expression randomExpression(final int upperbound) { 1938 return new ExpressionAdapter() { 1939 public Object evaluate(Exchange exchange) { 1940 Random random = new Random(); 1941 int randomNum = random.nextInt(upperbound); 1942 return randomNum; 1943 } 1944 1945 @Override 1946 public String toString() { 1947 return "random"; 1948 } 1949 }; 1950 } 1951 1952 /** 1953 * Expression adapter for OGNL expression from Message Header or Exchange property 1954 */ 1955 private static class KeyedOgnlExpressionAdapter extends ExpressionAdapter { 1956 private final String ognl; 1957 private final String toStringValue; 1958 private final KeyedEntityRetrievalStrategy keyedEntityRetrievalStrategy; 1959 1960 public KeyedOgnlExpressionAdapter(String ognl, String toStringValue, 1961 KeyedEntityRetrievalStrategy keyedEntityRetrievalStrategy) { 1962 this.ognl = ognl; 1963 this.toStringValue = toStringValue; 1964 this.keyedEntityRetrievalStrategy = keyedEntityRetrievalStrategy; 1965 } 1966 1967 public Object evaluate(Exchange exchange) { 1968 // try with full name first 1969 Object property = keyedEntityRetrievalStrategy.getKeyedEntity(exchange, ognl); 1970 if (property != null) { 1971 return property; 1972 } 1973 1974 // Split ognl except when this is not a Map, Array 1975 // and we would like to keep the dots within the key name 1976 List<String> methods = OgnlHelper.splitOgnl(ognl); 1977 1978 // remove any OGNL operators so we got the pure key name 1979 String key = OgnlHelper.removeOperators(methods.get(0)); 1980 1981 property = keyedEntityRetrievalStrategy.getKeyedEntity(exchange, key); 1982 if (property == null) { 1983 return null; 1984 } 1985 // the remainder is the rest of the ognl without the key 1986 String remainder = ObjectHelper.after(ognl, key); 1987 return new MethodCallExpression(property, remainder).evaluate(exchange); 1988 } 1989 1990 @Override 1991 public String toString() { 1992 return toStringValue; 1993 } 1994 1995 /** 1996 * Strategy to retrieve the value based on the key 1997 */ 1998 public interface KeyedEntityRetrievalStrategy { 1999 Object getKeyedEntity(Exchange exchange, String key); 2000 } 2001 }; 2002 2003}