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