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