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 * @deprecated use {@link #exchangePropertyExpression(String)} instead 529 */ 530 @Deprecated 531 public static Expression propertyExpression(final String propertyName) { 532 return new ExpressionAdapter() { 533 public Object evaluate(Exchange exchange) { 534 return exchange.getProperty(propertyName); 535 } 536 537 @Override 538 public String toString() { 539 return "exchangeProperty(" + propertyName + ")"; 540 } 541 }; 542 } 543 544 /** 545 * Returns an expression for the property value of exchange with the given name 546 * 547 * @param propertyName the name of the property the expression will return 548 * @return an expression object which will return the property value 549 */ 550 public static Expression exchangePropertyExpression(final String propertyName) { 551 return new ExpressionAdapter() { 552 public Object evaluate(Exchange exchange) { 553 return exchange.getProperty(propertyName); 554 } 555 556 @Override 557 public String toString() { 558 return "exchangeProperty(" + propertyName + ")"; 559 } 560 }; 561 } 562 563 /** 564 * Returns an expression for the property value of exchange with the given name invoking methods defined 565 * in a simple OGNL notation 566 * 567 * @param ognl methods to invoke on the property in a simple OGNL syntax 568 */ 569 public static Expression propertyOgnlExpression(final String ognl) { 570 return new KeyedOgnlExpressionAdapter(ognl, "propertyOgnl(" + ognl + ")", 571 new KeyedOgnlExpressionAdapter.KeyedEntityRetrievalStrategy() { 572 public Object getKeyedEntity(Exchange exchange, String key) { 573 return exchange.getProperty(key); 574 } 575 }); 576 } 577 578 /** 579 * Returns an expression for the properties of exchange 580 * 581 * @return an expression object which will return the properties 582 */ 583 public static Expression propertiesExpression() { 584 return new ExpressionAdapter() { 585 public Object evaluate(Exchange exchange) { 586 return exchange.getProperties(); 587 } 588 589 @Override 590 public String toString() { 591 return "properties"; 592 } 593 }; 594 } 595 596 /** 597 * Returns an expression for the properties of the camel context 598 * 599 * @return an expression object which will return the properties 600 */ 601 public static Expression camelContextPropertiesExpression() { 602 return new ExpressionAdapter() { 603 public Object evaluate(Exchange exchange) { 604 return exchange.getContext().getProperties(); 605 } 606 607 @Override 608 public String toString() { 609 return "camelContextProperties"; 610 } 611 }; 612 } 613 614 /** 615 * Returns an expression for the property value of the camel context with the given name 616 * 617 * @param propertyName the name of the property the expression will return 618 * @return an expression object which will return the property value 619 */ 620 public static Expression camelContextPropertyExpression(final String propertyName) { 621 return new ExpressionAdapter() { 622 public Object evaluate(Exchange exchange) { 623 return exchange.getContext().getProperty(propertyName); 624 } 625 626 @Override 627 public String toString() { 628 return "camelContextProperty(" + propertyName + ")"; 629 } 630 }; 631 } 632 633 /** 634 * Returns an expression for a system property value with the given name 635 * 636 * @param propertyName the name of the system property the expression will return 637 * @return an expression object which will return the system property value 638 */ 639 public static Expression systemPropertyExpression(final String propertyName) { 640 return systemPropertyExpression(propertyName, null); 641 } 642 643 /** 644 * Returns an expression for a system property value with the given name 645 * 646 * @param propertyName the name of the system property the expression will return 647 * @param defaultValue default value to return if no system property exists 648 * @return an expression object which will return the system property value 649 */ 650 public static Expression systemPropertyExpression(final String propertyName, 651 final String defaultValue) { 652 return new ExpressionAdapter() { 653 public Object evaluate(Exchange exchange) { 654 return System.getProperty(propertyName, defaultValue); 655 } 656 657 @Override 658 public String toString() { 659 return "systemProperty(" + propertyName + ")"; 660 } 661 }; 662 } 663 664 /** 665 * Returns an expression for a system environment value with the given name 666 * 667 * @param propertyName the name of the system environment the expression will return 668 * @return an expression object which will return the system property value 669 */ 670 public static Expression systemEnvironmentExpression(final String propertyName) { 671 return systemEnvironmentExpression(propertyName, null); 672 } 673 674 /** 675 * Returns an expression for a system environment value with the given name 676 * 677 * @param propertyName the name of the system environment the expression will return 678 * @param defaultValue default value to return if no system environment exists 679 * @return an expression object which will return the system environment value 680 */ 681 public static Expression systemEnvironmentExpression(final String propertyName, 682 final String defaultValue) { 683 return new ExpressionAdapter() { 684 public Object evaluate(Exchange exchange) { 685 String answer = System.getenv(propertyName); 686 if (answer == null) { 687 answer = defaultValue; 688 } 689 return answer; 690 } 691 692 @Override 693 public String toString() { 694 return "systemEnvironment(" + propertyName + ")"; 695 } 696 }; 697 } 698 699 /** 700 * Returns an expression for the constant value 701 * 702 * @param value the value the expression will return 703 * @return an expression object which will return the constant value 704 */ 705 public static Expression constantExpression(final Object value) { 706 return new ExpressionAdapter() { 707 public Object evaluate(Exchange exchange) { 708 return value; 709 } 710 711 @Override 712 public String toString() { 713 return "" + value; 714 } 715 }; 716 } 717 718 /** 719 * Returns an expression for evaluating the expression/predicate using the given language 720 * 721 * @param expression the expression or predicate 722 * @return an expression object which will evaluate the expression/predicate using the given language 723 */ 724 public static Expression languageExpression(final String language, final String expression) { 725 return new ExpressionAdapter() { 726 public Object evaluate(Exchange exchange) { 727 Language lan = exchange.getContext().resolveLanguage(language); 728 if (lan != null) { 729 return lan.createExpression(expression).evaluate(exchange, Object.class); 730 } else { 731 throw new NoSuchLanguageException(language); 732 } 733 } 734 735 @Override 736 public boolean matches(Exchange exchange) { 737 Language lan = exchange.getContext().resolveLanguage(language); 738 if (lan != null) { 739 return lan.createPredicate(expression).matches(exchange); 740 } else { 741 throw new NoSuchLanguageException(language); 742 } 743 } 744 745 @Override 746 public String toString() { 747 return "language[" + language + ":" + expression + "]"; 748 } 749 }; 750 } 751 752 /** 753 * Returns an expression for a type value 754 * 755 * @param name the type name 756 * @return an expression object which will return the type value 757 */ 758 public static Expression typeExpression(final String name) { 759 return new ExpressionAdapter() { 760 public Object evaluate(Exchange exchange) { 761 // it may refer to a class type 762 Class<?> type = exchange.getContext().getClassResolver().resolveClass(name); 763 if (type != null) { 764 return type; 765 } 766 767 int pos = name.lastIndexOf("."); 768 if (pos > 0) { 769 String before = name.substring(0, pos); 770 String after = name.substring(pos + 1); 771 type = exchange.getContext().getClassResolver().resolveClass(before); 772 if (type != null) { 773 return ObjectHelper.lookupConstantFieldValue(type, after); 774 } 775 } 776 777 throw ObjectHelper.wrapCamelExecutionException(exchange, new ClassNotFoundException("Cannot find type " + name)); 778 } 779 780 @Override 781 public String toString() { 782 return "type:" + name; 783 } 784 }; 785 } 786 787 /** 788 * Returns an expression that caches the evaluation of another expression 789 * and returns the cached value, to avoid re-evaluating the expression. 790 * 791 * @param expression the target expression to cache 792 * @return the cached value 793 */ 794 public static Expression cacheExpression(final Expression expression) { 795 return new ExpressionAdapter() { 796 private final AtomicReference<Object> cache = new AtomicReference<Object>(); 797 798 public Object evaluate(Exchange exchange) { 799 Object answer = cache.get(); 800 if (answer == null) { 801 answer = expression.evaluate(exchange, Object.class); 802 cache.set(answer); 803 } 804 return answer; 805 } 806 807 @Override 808 public String toString() { 809 return expression.toString(); 810 } 811 }; 812 } 813 814 /** 815 * Returns the expression for the exchanges inbound message body 816 */ 817 public static Expression bodyExpression() { 818 return new ExpressionAdapter() { 819 public Object evaluate(Exchange exchange) { 820 return exchange.getIn().getBody(); 821 } 822 823 @Override 824 public String toString() { 825 return "body"; 826 } 827 }; 828 } 829 830 /** 831 * Returns the expression for the exchanges inbound message body invoking methods defined 832 * in a simple OGNL notation 833 * 834 * @param ognl methods to invoke on the body in a simple OGNL syntax 835 */ 836 public static Expression bodyOgnlExpression(final String ognl) { 837 return new ExpressionAdapter() { 838 public Object evaluate(Exchange exchange) { 839 Object body = exchange.getIn().getBody(); 840 if (body == null) { 841 return null; 842 } 843 return new MethodCallExpression(body, ognl).evaluate(exchange); 844 } 845 846 @Override 847 public String toString() { 848 return "bodyOgnl(" + ognl + ")"; 849 } 850 }; 851 } 852 853 /** 854 * Returns the expression for invoking a method (support OGNL syntax) on the given expression 855 * 856 * @param exp the expression to evaluate and invoke the method on its result 857 * @param ognl methods to invoke on the evaluated expression in a simple OGNL syntax 858 */ 859 public static Expression ognlExpression(final Expression exp, final String ognl) { 860 return new ExpressionAdapter() { 861 public Object evaluate(Exchange exchange) { 862 Object value = exp.evaluate(exchange, Object.class); 863 if (value == null) { 864 return null; 865 } 866 return new MethodCallExpression(value, ognl).evaluate(exchange); 867 } 868 869 @Override 870 public String toString() { 871 return "ognl(" + exp + ", " + ognl + ")"; 872 } 873 }; 874 } 875 876 /** 877 * Returns the expression for the exchanges camelContext invoking methods defined 878 * in a simple OGNL notation 879 * 880 * @param ognl methods to invoke on the body in a simple OGNL syntax 881 */ 882 public static Expression camelContextOgnlExpression(final String ognl) { 883 return new ExpressionAdapter() { 884 public Object evaluate(Exchange exchange) { 885 CamelContext context = exchange.getContext(); 886 if (context == null) { 887 return null; 888 } 889 return new MethodCallExpression(context, ognl).evaluate(exchange); 890 } 891 892 @Override 893 public String toString() { 894 return "camelContextOgnl(" + ognl + ")"; 895 } 896 }; 897 } 898 899 /** 900 * Returns the expression for the exchanges inbound message body converted 901 * to the given type 902 */ 903 public static <T> Expression bodyExpression(final Class<T> type) { 904 return new ExpressionAdapter() { 905 public Object evaluate(Exchange exchange) { 906 return exchange.getIn().getBody(type); 907 } 908 909 @Override 910 public String toString() { 911 return "bodyAs[" + type.getName() + "]"; 912 } 913 }; 914 } 915 916 /** 917 * Returns the expression for the exchanges inbound message body converted 918 * to the given type 919 */ 920 public static Expression bodyExpression(final String name) { 921 return new ExpressionAdapter() { 922 public Object evaluate(Exchange exchange) { 923 Class<?> type; 924 try { 925 type = exchange.getContext().getClassResolver().resolveMandatoryClass(name); 926 } catch (ClassNotFoundException e) { 927 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 928 } 929 return exchange.getIn().getBody(type); 930 } 931 932 @Override 933 public String toString() { 934 return "bodyAs[" + name + "]"; 935 } 936 }; 937 } 938 939 /** 940 * Returns the expression for the exchanges inbound message body converted 941 * to the given type 942 */ 943 public static Expression mandatoryBodyExpression(final String name) { 944 return new ExpressionAdapter() { 945 public Object evaluate(Exchange exchange) { 946 Class<?> type; 947 try { 948 type = exchange.getContext().getClassResolver().resolveMandatoryClass(name); 949 } catch (ClassNotFoundException e) { 950 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 951 } 952 try { 953 return exchange.getIn().getMandatoryBody(type); 954 } catch (InvalidPayloadException e) { 955 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 956 } 957 } 958 959 @Override 960 public String toString() { 961 return "mandatoryBodyAs[" + name + "]"; 962 } 963 }; 964 } 965 966 /** 967 * Returns the expression for the current thread name 968 */ 969 public static Expression threadNameExpression() { 970 return new ExpressionAdapter() { 971 public Object evaluate(Exchange exchange) { 972 return Thread.currentThread().getName(); 973 } 974 975 @Override 976 public String toString() { 977 return "threadName"; 978 } 979 }; 980 } 981 982 /** 983 * Returns the expression for the {@code null} value 984 */ 985 public static Expression nullExpression() { 986 return new ExpressionAdapter() { 987 public Object evaluate(Exchange exchange) { 988 return null; 989 } 990 991 @Override 992 public String toString() { 993 return "null"; 994 } 995 }; 996 } 997 998 /** 999 * Returns the expression for the exchanges inbound message body converted 1000 * to the given type. 1001 * <p/> 1002 * Does <b>not</b> allow null bodies. 1003 */ 1004 public static <T> Expression mandatoryBodyExpression(final Class<T> type) { 1005 return mandatoryBodyExpression(type, false); 1006 } 1007 1008 /** 1009 * Returns the expression for the exchanges inbound message body converted 1010 * to the given type 1011 * 1012 * @param type the type 1013 * @param nullBodyAllowed whether null bodies is allowed and if so a null is returned, 1014 * otherwise an exception is thrown 1015 */ 1016 public static <T> Expression mandatoryBodyExpression(final Class<T> type, final boolean nullBodyAllowed) { 1017 return new ExpressionAdapter() { 1018 public Object evaluate(Exchange exchange) { 1019 if (nullBodyAllowed) { 1020 if (exchange.getIn().getBody() == null) { 1021 return null; 1022 } 1023 1024 // if its a bean invocation then if it has no arguments then it should be threaded as null body allowed 1025 if (exchange.getIn().getBody() instanceof BeanInvocation) { 1026 // BeanInvocation would be stored directly as the message body 1027 // do not force any type conversion attempts as it would just be unnecessary and cost a bit performance 1028 // so a regular instanceof check is sufficient 1029 BeanInvocation bi = (BeanInvocation) exchange.getIn().getBody(); 1030 if (bi.getArgs() == null || bi.getArgs().length == 0 || bi.getArgs()[0] == null) { 1031 return null; 1032 } 1033 } 1034 } 1035 1036 try { 1037 return exchange.getIn().getMandatoryBody(type); 1038 } catch (InvalidPayloadException e) { 1039 throw ObjectHelper.wrapCamelExecutionException(exchange, e); 1040 } 1041 } 1042 1043 @Override 1044 public String toString() { 1045 return "mandatoryBodyAs[" + type.getName() + "]"; 1046 } 1047 }; 1048 } 1049 1050 /** 1051 * Returns the expression for the exchanges inbound message body type 1052 */ 1053 public static Expression bodyTypeExpression() { 1054 return new ExpressionAdapter() { 1055 public Object evaluate(Exchange exchange) { 1056 return exchange.getIn().getBody().getClass(); 1057 } 1058 1059 @Override 1060 public String toString() { 1061 return "bodyType"; 1062 } 1063 }; 1064 } 1065 1066 /** 1067 * Returns the expression for the out messages body 1068 */ 1069 public static Expression outBodyExpression() { 1070 return new ExpressionAdapter() { 1071 public Object evaluate(Exchange exchange) { 1072 if (exchange.hasOut()) { 1073 return exchange.getOut().getBody(); 1074 } else { 1075 return null; 1076 } 1077 } 1078 1079 @Override 1080 public String toString() { 1081 return "outBody"; 1082 } 1083 }; 1084 } 1085 1086 /** 1087 * Returns the expression for the exchanges outbound message body converted 1088 * to the given type 1089 */ 1090 public static <T> Expression outBodyExpression(final Class<T> type) { 1091 return new ExpressionAdapter() { 1092 public Object evaluate(Exchange exchange) { 1093 if (exchange.hasOut()) { 1094 return exchange.getOut().getBody(type); 1095 } else { 1096 return null; 1097 } 1098 } 1099 1100 @Override 1101 public String toString() { 1102 return "outBodyAs[" + type.getName() + "]"; 1103 } 1104 }; 1105 } 1106 1107 /** 1108 * Returns the expression for the fault messages body 1109 */ 1110 public static Expression faultBodyExpression() { 1111 return new ExpressionAdapter() { 1112 public Object evaluate(Exchange exchange) { 1113 Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn(); 1114 return msg.isFault() ? msg.getBody() : null; 1115 } 1116 1117 @Override 1118 public String toString() { 1119 return "faultBody"; 1120 } 1121 }; 1122 } 1123 1124 /** 1125 * Returns the expression for the exchanges fault message body converted 1126 * to the given type 1127 */ 1128 public static <T> Expression faultBodyExpression(final Class<T> type) { 1129 return new ExpressionAdapter() { 1130 public Object evaluate(Exchange exchange) { 1131 Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn(); 1132 return msg.isFault() ? msg.getBody(type) : null; 1133 } 1134 1135 @Override 1136 public String toString() { 1137 return "faultBodyAs[" + type.getName() + "]"; 1138 } 1139 }; 1140 } 1141 1142 /** 1143 * Returns the expression for the exchange 1144 */ 1145 public static Expression exchangeExpression() { 1146 return new ExpressionAdapter() { 1147 public Object evaluate(Exchange exchange) { 1148 return exchange; 1149 } 1150 1151 @Override 1152 public String toString() { 1153 return "exchange"; 1154 } 1155 }; 1156 } 1157 1158 /** 1159 * Returns the expression for the IN message 1160 */ 1161 public static Expression inMessageExpression() { 1162 return new ExpressionAdapter() { 1163 public Object evaluate(Exchange exchange) { 1164 return exchange.getIn(); 1165 } 1166 1167 @Override 1168 public String toString() { 1169 return "inMessage"; 1170 } 1171 }; 1172 } 1173 1174 /** 1175 * Returns the expression for the OUT message 1176 */ 1177 public static Expression outMessageExpression() { 1178 return new ExpressionAdapter() { 1179 public Object evaluate(Exchange exchange) { 1180 return exchange.getOut(); 1181 } 1182 1183 @Override 1184 public String toString() { 1185 return "outMessage"; 1186 } 1187 }; 1188 } 1189 1190 /** 1191 * Returns an expression which converts the given expression to the given type 1192 */ 1193 public static Expression convertToExpression(final Expression expression, final Class<?> type) { 1194 return new ExpressionAdapter() { 1195 public Object evaluate(Exchange exchange) { 1196 if (type != null) { 1197 return expression.evaluate(exchange, type); 1198 } else { 1199 return expression; 1200 } 1201 } 1202 1203 @Override 1204 public String toString() { 1205 return "" + expression; 1206 } 1207 }; 1208 } 1209 1210 /** 1211 * Returns an expression which converts the given expression to the given type the type 1212 * expression is evaluated to 1213 */ 1214 public static Expression convertToExpression(final Expression expression, final Expression type) { 1215 return new ExpressionAdapter() { 1216 public Object evaluate(Exchange exchange) { 1217 Object result = type.evaluate(exchange, Object.class); 1218 if (result != null) { 1219 return expression.evaluate(exchange, result.getClass()); 1220 } else { 1221 return expression; 1222 } 1223 } 1224 1225 @Override 1226 public String toString() { 1227 return "" + expression; 1228 } 1229 }; 1230 } 1231 1232 /** 1233 * Returns a tokenize expression which will tokenize the string with the 1234 * given token 1235 */ 1236 public static Expression tokenizeExpression(final Expression expression, 1237 final String token) { 1238 return new ExpressionAdapter() { 1239 public Object evaluate(Exchange exchange) { 1240 Object value = expression.evaluate(exchange, Object.class); 1241 Scanner scanner = ObjectHelper.getScanner(exchange, value); 1242 scanner.useDelimiter(token); 1243 return scanner; 1244 } 1245 1246 @Override 1247 public String toString() { 1248 return "tokenize(" + expression + ", " + token + ")"; 1249 } 1250 }; 1251 } 1252 1253 /** 1254 * Returns an {@link TokenPairExpressionIterator} expression 1255 */ 1256 public static Expression tokenizePairExpression(String startToken, String endToken, boolean includeTokens) { 1257 return new TokenPairExpressionIterator(startToken, endToken, includeTokens); 1258 } 1259 1260 /** 1261 * Returns an {@link TokenXMLExpressionIterator} expression 1262 */ 1263 public static Expression tokenizeXMLExpression(String tagName, String inheritNamespaceTagName) { 1264 ObjectHelper.notEmpty(tagName, "tagName"); 1265 1266 // must be XML tokens 1267 if (!tagName.startsWith("<")) { 1268 tagName = "<" + tagName; 1269 } 1270 if (!tagName.endsWith(">")) { 1271 tagName = tagName + ">"; 1272 } 1273 1274 if (inheritNamespaceTagName != null) { 1275 if (!inheritNamespaceTagName.startsWith("<")) { 1276 inheritNamespaceTagName = "<" + inheritNamespaceTagName; 1277 } 1278 if (!inheritNamespaceTagName.endsWith(">")) { 1279 inheritNamespaceTagName = inheritNamespaceTagName + ">"; 1280 } 1281 } 1282 return new TokenXMLExpressionIterator(tagName, inheritNamespaceTagName); 1283 } 1284 1285 public static Expression tokenizeXMLAwareExpression(String path, char mode) { 1286 ObjectHelper.notEmpty(path, "path"); 1287 1288 return new XMLTokenExpressionIterator(path, mode); 1289 } 1290 1291 public static Expression tokenizeXMLAwareExpression(String path, char mode, int group) { 1292 ObjectHelper.notEmpty(path, "path"); 1293 1294 return new XMLTokenExpressionIterator(path, mode, group); 1295 } 1296 1297 /** 1298 * Returns a tokenize expression which will tokenize the string with the 1299 * given regex 1300 */ 1301 public static Expression regexTokenizeExpression(final Expression expression, 1302 final String regexTokenizer) { 1303 final Pattern pattern = Pattern.compile(regexTokenizer); 1304 return new ExpressionAdapter() { 1305 public Object evaluate(Exchange exchange) { 1306 Object value = expression.evaluate(exchange, Object.class); 1307 Scanner scanner = ObjectHelper.getScanner(exchange, value); 1308 scanner.useDelimiter(pattern); 1309 return scanner; 1310 } 1311 1312 @Override 1313 public String toString() { 1314 return "regexTokenize(" + expression + ", " + pattern.pattern() + ")"; 1315 } 1316 }; 1317 } 1318 1319 public static Expression groupIteratorExpression(final Expression expression, final String token, final int group) { 1320 return new ExpressionAdapter() { 1321 public Object evaluate(Exchange exchange) { 1322 // evaluate expression as iterator 1323 Iterator<?> it = expression.evaluate(exchange, Iterator.class); 1324 ObjectHelper.notNull(it, "expression: " + expression + " evaluated on " + exchange + " must return an java.util.Iterator"); 1325 return new GroupIterator(exchange, it, token, group); 1326 } 1327 1328 @Override 1329 public String toString() { 1330 return "group " + expression + " " + group + " times"; 1331 } 1332 }; 1333 } 1334 1335 /** 1336 * Returns a sort expression which will sort the expression with the given comparator. 1337 * <p/> 1338 * The expression is evaluated as a {@link List} object to allow sorting. 1339 */ 1340 @SuppressWarnings({"unchecked", "rawtypes"}) 1341 public static Expression sortExpression(final Expression expression, final Comparator comparator) { 1342 return new ExpressionAdapter() { 1343 public Object evaluate(Exchange exchange) { 1344 List<?> list = expression.evaluate(exchange, List.class); 1345 Collections.sort(list, comparator); 1346 return list; 1347 } 1348 1349 @Override 1350 public String toString() { 1351 return "sort(" + expression + " by: " + comparator + ")"; 1352 } 1353 }; 1354 } 1355 1356 /** 1357 * Transforms the expression into a String then performs the regex 1358 * replaceAll to transform the String and return the result 1359 */ 1360 public static Expression regexReplaceAll(final Expression expression, 1361 final String regex, final String replacement) { 1362 final Pattern pattern = Pattern.compile(regex); 1363 return new ExpressionAdapter() { 1364 public Object evaluate(Exchange exchange) { 1365 String text = expression.evaluate(exchange, String.class); 1366 if (text == null) { 1367 return null; 1368 } 1369 return pattern.matcher(text).replaceAll(replacement); 1370 } 1371 1372 @Override 1373 public String toString() { 1374 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 1375 } 1376 }; 1377 } 1378 1379 /** 1380 * Transforms the expression into a String then performs the regex 1381 * replaceAll to transform the String and return the result 1382 */ 1383 public static Expression regexReplaceAll(final Expression expression, 1384 final String regex, final Expression replacementExpression) { 1385 1386 final Pattern pattern = Pattern.compile(regex); 1387 return new ExpressionAdapter() { 1388 public Object evaluate(Exchange exchange) { 1389 String text = expression.evaluate(exchange, String.class); 1390 String replacement = replacementExpression.evaluate(exchange, String.class); 1391 if (text == null || replacement == null) { 1392 return null; 1393 } 1394 return pattern.matcher(text).replaceAll(replacement); 1395 } 1396 1397 @Override 1398 public String toString() { 1399 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 1400 } 1401 }; 1402 } 1403 1404 /** 1405 * Appends the String evaluations of the two expressions together 1406 */ 1407 public static Expression append(final Expression left, final Expression right) { 1408 return new ExpressionAdapter() { 1409 public Object evaluate(Exchange exchange) { 1410 return left.evaluate(exchange, String.class) + right.evaluate(exchange, String.class); 1411 } 1412 1413 @Override 1414 public String toString() { 1415 return "append(" + left + ", " + right + ")"; 1416 } 1417 }; 1418 } 1419 1420 /** 1421 * Prepends the String evaluations of the two expressions together 1422 */ 1423 public static Expression prepend(final Expression left, final Expression right) { 1424 return new ExpressionAdapter() { 1425 public Object evaluate(Exchange exchange) { 1426 return right.evaluate(exchange, String.class) + left.evaluate(exchange, String.class); 1427 } 1428 1429 @Override 1430 public String toString() { 1431 return "prepend(" + left + ", " + right + ")"; 1432 } 1433 }; 1434 } 1435 1436 /** 1437 * Returns an expression which returns the string concatenation value of the various 1438 * expressions 1439 * 1440 * @param expressions the expression to be concatenated dynamically 1441 * @return an expression which when evaluated will return the concatenated values 1442 */ 1443 public static Expression concatExpression(final Collection<Expression> expressions) { 1444 return concatExpression(expressions, null); 1445 } 1446 1447 /** 1448 * Returns an expression which returns the string concatenation value of the various 1449 * expressions 1450 * 1451 * @param expressions the expression to be concatenated dynamically 1452 * @param expression the text description of the expression 1453 * @return an expression which when evaluated will return the concatenated values 1454 */ 1455 public static Expression concatExpression(final Collection<Expression> expressions, final String expression) { 1456 return new ExpressionAdapter() { 1457 public Object evaluate(Exchange exchange) { 1458 StringBuilder buffer = new StringBuilder(); 1459 for (Expression expression : expressions) { 1460 String text = expression.evaluate(exchange, String.class); 1461 if (text != null) { 1462 buffer.append(text); 1463 } 1464 } 1465 return buffer.toString(); 1466 } 1467 1468 @Override 1469 public String toString() { 1470 if (expression != null) { 1471 return expression; 1472 } else { 1473 return "concat" + expressions; 1474 } 1475 } 1476 }; 1477 } 1478 1479 /** 1480 * Returns an Expression for the inbound message id 1481 */ 1482 public static Expression messageIdExpression() { 1483 return new ExpressionAdapter() { 1484 public Object evaluate(Exchange exchange) { 1485 return exchange.getIn().getMessageId(); 1486 } 1487 1488 @Override 1489 public String toString() { 1490 return "messageId"; 1491 } 1492 }; 1493 } 1494 1495 /** 1496 * Returns an Expression for the exchange id 1497 */ 1498 public static Expression exchangeIdExpression() { 1499 return new ExpressionAdapter() { 1500 public Object evaluate(Exchange exchange) { 1501 return exchange.getExchangeId(); 1502 } 1503 1504 @Override 1505 public String toString() { 1506 return "exchangeId"; 1507 } 1508 }; 1509 } 1510 1511 /** 1512 * Returns an Expression for the route id 1513 */ 1514 public static Expression routeIdExpression() { 1515 return new ExpressionAdapter() { 1516 public Object evaluate(Exchange exchange) { 1517 String answer = null; 1518 UnitOfWork uow = exchange.getUnitOfWork(); 1519 RouteContext rc = uow != null ? uow.getRouteContext() : null; 1520 if (rc != null) { 1521 answer = rc.getRoute().getId(); 1522 } 1523 if (answer == null) { 1524 // fallback and get from route id on the exchange 1525 answer = exchange.getFromRouteId(); 1526 } 1527 return answer; 1528 } 1529 1530 @Override 1531 public String toString() { 1532 return "routeId"; 1533 } 1534 }; 1535 } 1536 1537 public static Expression dateExpression(final String command, final String pattern) { 1538 return new ExpressionAdapter() { 1539 public Object evaluate(Exchange exchange) { 1540 Date date; 1541 if ("now".equals(command)) { 1542 date = new Date(); 1543 } else if (command.startsWith("header.") || command.startsWith("in.header.")) { 1544 String key = command.substring(command.lastIndexOf('.') + 1); 1545 date = exchange.getIn().getHeader(key, Date.class); 1546 if (date == null) { 1547 throw new IllegalArgumentException("Cannot find java.util.Date object at command: " + command); 1548 } 1549 } else if (command.startsWith("out.header.")) { 1550 String key = command.substring(command.lastIndexOf('.') + 1); 1551 date = exchange.getOut().getHeader(key, Date.class); 1552 if (date == null) { 1553 throw new IllegalArgumentException("Cannot find java.util.Date object at command: " + command); 1554 } 1555 } else if ("file".equals(command)) { 1556 Long num = exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Long.class); 1557 if (num != null && num > 0) { 1558 date = new Date(num.longValue()); 1559 } else { 1560 date = exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Date.class); 1561 if (date == null) { 1562 throw new IllegalArgumentException("Cannot find " + Exchange.FILE_LAST_MODIFIED + " header at command: " + command); 1563 } 1564 } 1565 } else { 1566 throw new IllegalArgumentException("Command not supported for dateExpression: " + command); 1567 } 1568 1569 SimpleDateFormat df = new SimpleDateFormat(pattern); 1570 return df.format(date); 1571 } 1572 1573 @Override 1574 public String toString() { 1575 return "date(" + command + ":" + pattern + ")"; 1576 } 1577 }; 1578 } 1579 1580 public static Expression simpleExpression(final String expression) { 1581 return new ExpressionAdapter() { 1582 public Object evaluate(Exchange exchange) { 1583 // resolve language using context to have a clear separation of packages 1584 // must call evaluate to return the nested language evaluate when evaluating 1585 // stacked expressions 1586 Language language = exchange.getContext().resolveLanguage("simple"); 1587 return language.createExpression(expression).evaluate(exchange, Object.class); 1588 } 1589 1590 @Override 1591 public String toString() { 1592 return "simple(" + expression + ")"; 1593 } 1594 }; 1595 } 1596 1597 public static Expression beanExpression(final String expression) { 1598 return new ExpressionAdapter() { 1599 public Object evaluate(Exchange exchange) { 1600 // resolve language using context to have a clear separation of packages 1601 // must call evaluate to return the nested language evaluate when evaluating 1602 // stacked expressions 1603 Language language = exchange.getContext().resolveLanguage("bean"); 1604 return language.createExpression(expression).evaluate(exchange, Object.class); 1605 } 1606 1607 @Override 1608 public String toString() { 1609 return "bean(" + expression + ")"; 1610 } 1611 }; 1612 } 1613 1614 public static Expression beanExpression(final Class<?> beanType, final String methodName) { 1615 return BeanLanguage.bean(beanType, methodName); 1616 } 1617 1618 public static Expression beanExpression(final Object bean, final String methodName) { 1619 return BeanLanguage.bean(bean, methodName); 1620 } 1621 1622 public static Expression beanExpression(final String beanRef, final String methodName) { 1623 String expression = methodName != null ? beanRef + "." + methodName : beanRef; 1624 return beanExpression(expression); 1625 } 1626 1627 /** 1628 * Returns an expression processing the exchange to the given endpoint uri 1629 * 1630 * @param uri endpoint uri to send the exchange to 1631 * @return an expression object which will return the OUT body 1632 */ 1633 public static Expression toExpression(final String uri) { 1634 return new ExpressionAdapter() { 1635 public Object evaluate(Exchange exchange) { 1636 Endpoint endpoint = exchange.getContext().getEndpoint(uri); 1637 if (endpoint == null) { 1638 throw new NoSuchEndpointException(uri); 1639 } 1640 1641 Producer producer; 1642 try { 1643 producer = endpoint.createProducer(); 1644 producer.start(); 1645 producer.process(exchange); 1646 producer.stop(); 1647 } catch (Exception e) { 1648 throw ObjectHelper.wrapRuntimeCamelException(e); 1649 } 1650 1651 // return the OUT body, but check for exchange pattern 1652 if (ExchangeHelper.isOutCapable(exchange)) { 1653 return exchange.getOut().getBody(); 1654 } else { 1655 return exchange.getIn().getBody(); 1656 } 1657 } 1658 1659 @Override 1660 public String toString() { 1661 return "to(" + uri + ")"; 1662 } 1663 }; 1664 } 1665 1666 public static Expression fileNameExpression() { 1667 return new ExpressionAdapter() { 1668 public Object evaluate(Exchange exchange) { 1669 return exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1670 } 1671 1672 @Override 1673 public String toString() { 1674 return "file:name"; 1675 } 1676 }; 1677 } 1678 1679 public static Expression fileOnlyNameExpression() { 1680 return new ExpressionAdapter() { 1681 public Object evaluate(Exchange exchange) { 1682 String answer = exchange.getIn().getHeader(Exchange.FILE_NAME_ONLY, String.class); 1683 if (answer == null) { 1684 answer = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1685 answer = FileUtil.stripPath(answer); 1686 } 1687 return answer; 1688 } 1689 1690 @Override 1691 public String toString() { 1692 return "file:onlyname"; 1693 } 1694 }; 1695 } 1696 1697 public static Expression fileNameNoExtensionExpression() { 1698 return new ExpressionAdapter() { 1699 public Object evaluate(Exchange exchange) { 1700 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1701 return FileUtil.stripExt(name); 1702 } 1703 1704 @Override 1705 public String toString() { 1706 return "file:name.noext"; 1707 } 1708 }; 1709 } 1710 1711 public static Expression fileNameNoExtensionSingleExpression() { 1712 return new ExpressionAdapter() { 1713 public Object evaluate(Exchange exchange) { 1714 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1715 return FileUtil.stripExt(name, true); 1716 } 1717 1718 @Override 1719 public String toString() { 1720 return "file:name.noext.single"; 1721 } 1722 }; 1723 } 1724 1725 public static Expression fileOnlyNameNoExtensionExpression() { 1726 return new ExpressionAdapter() { 1727 public Object evaluate(Exchange exchange) { 1728 String name = fileOnlyNameExpression().evaluate(exchange, String.class); 1729 return FileUtil.stripExt(name); 1730 } 1731 1732 @Override 1733 public String toString() { 1734 return "file:onlyname.noext"; 1735 } 1736 }; 1737 } 1738 1739 public static Expression fileOnlyNameNoExtensionSingleExpression() { 1740 return new ExpressionAdapter() { 1741 public Object evaluate(Exchange exchange) { 1742 String name = fileOnlyNameExpression().evaluate(exchange, String.class); 1743 return FileUtil.stripExt(name, true); 1744 } 1745 1746 @Override 1747 public String toString() { 1748 return "file:onlyname.noext.single"; 1749 } 1750 }; 1751 } 1752 1753 public static Expression fileExtensionExpression() { 1754 return new ExpressionAdapter() { 1755 public Object evaluate(Exchange exchange) { 1756 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1757 return FileUtil.onlyExt(name); 1758 } 1759 1760 @Override 1761 public String toString() { 1762 return "file:ext"; 1763 } 1764 }; 1765 } 1766 1767 public static Expression fileExtensionSingleExpression() { 1768 return new ExpressionAdapter() { 1769 public Object evaluate(Exchange exchange) { 1770 String name = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); 1771 return FileUtil.onlyExt(name, true); 1772 } 1773 1774 @Override 1775 public String toString() { 1776 return "file:ext.single"; 1777 } 1778 }; 1779 } 1780 1781 public static Expression fileParentExpression() { 1782 return new ExpressionAdapter() { 1783 public Object evaluate(Exchange exchange) { 1784 return exchange.getIn().getHeader("CamelFileParent", String.class); 1785 } 1786 1787 @Override 1788 public String toString() { 1789 return "file:parent"; 1790 } 1791 }; 1792 } 1793 1794 public static Expression filePathExpression() { 1795 return new ExpressionAdapter() { 1796 public Object evaluate(Exchange exchange) { 1797 return exchange.getIn().getHeader("CamelFilePath", String.class); 1798 } 1799 1800 @Override 1801 public String toString() { 1802 return "file:path"; 1803 } 1804 }; 1805 } 1806 1807 public static Expression fileAbsolutePathExpression() { 1808 return new ExpressionAdapter() { 1809 public Object evaluate(Exchange exchange) { 1810 return exchange.getIn().getHeader("CamelFileAbsolutePath", String.class); 1811 } 1812 1813 @Override 1814 public String toString() { 1815 return "file:absolute.path"; 1816 } 1817 }; 1818 } 1819 1820 public static Expression fileAbsoluteExpression() { 1821 return new ExpressionAdapter() { 1822 public Object evaluate(Exchange exchange) { 1823 return exchange.getIn().getHeader("CamelFileAbsolute", Boolean.class); 1824 } 1825 1826 @Override 1827 public String toString() { 1828 return "file:absolute"; 1829 } 1830 }; 1831 } 1832 1833 public static Expression fileSizeExpression() { 1834 return new ExpressionAdapter() { 1835 public Object evaluate(Exchange exchange) { 1836 return exchange.getIn().getHeader(Exchange.FILE_LENGTH, Long.class); 1837 } 1838 1839 @Override 1840 public String toString() { 1841 return "file:length"; 1842 } 1843 }; 1844 } 1845 1846 public static Expression fileLastModifiedExpression() { 1847 return new ExpressionAdapter() { 1848 public Object evaluate(Exchange exchange) { 1849 return exchange.getIn().getHeader(Exchange.FILE_LAST_MODIFIED, Long.class); 1850 } 1851 1852 @Override 1853 public String toString() { 1854 return "file:modified"; 1855 } 1856 }; 1857 } 1858 1859 public static Expression propertiesComponentExpression(final String key, final String locations) { 1860 return new ExpressionAdapter() { 1861 public Object evaluate(Exchange exchange) { 1862 try { 1863 if (locations != null) { 1864 // the properties component is optional as we got locations 1865 // getComponent will create a new component if none already exists 1866 Component component = exchange.getContext().getComponent("properties"); 1867 PropertiesComponent pc = exchange.getContext().getTypeConverter() 1868 .mandatoryConvertTo(PropertiesComponent.class, component); 1869 // enclose key with {{ }} to force parsing 1870 String[] paths = locations.split(","); 1871 return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken(), paths); 1872 } else { 1873 // the properties component is mandatory if no locations provided 1874 Component component = exchange.getContext().hasComponent("properties"); 1875 if (component == null) { 1876 throw new IllegalArgumentException("PropertiesComponent with name properties must be defined" 1877 + " in CamelContext to support property placeholders in expressions"); 1878 } 1879 PropertiesComponent pc = exchange.getContext().getTypeConverter() 1880 .mandatoryConvertTo(PropertiesComponent.class, component); 1881 // enclose key with {{ }} to force parsing 1882 return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken()); 1883 } 1884 } catch (Exception e) { 1885 throw ObjectHelper.wrapRuntimeCamelException(e); 1886 } 1887 } 1888 1889 @Override 1890 public String toString() { 1891 return "properties(" + key + ")"; 1892 } 1893 }; 1894 } 1895 1896 /** 1897 * Expression adapter for OGNL expression from Message Header or Exchange property 1898 */ 1899 private static class KeyedOgnlExpressionAdapter extends ExpressionAdapter { 1900 private final String ognl; 1901 private final String toStringValue; 1902 private final KeyedEntityRetrievalStrategy keyedEntityRetrievalStrategy; 1903 1904 public KeyedOgnlExpressionAdapter(String ognl, String toStringValue, 1905 KeyedEntityRetrievalStrategy keyedEntityRetrievalStrategy) { 1906 this.ognl = ognl; 1907 this.toStringValue = toStringValue; 1908 this.keyedEntityRetrievalStrategy = keyedEntityRetrievalStrategy; 1909 } 1910 1911 public Object evaluate(Exchange exchange) { 1912 // try with full name first 1913 Object property = keyedEntityRetrievalStrategy.getKeyedEntity(exchange, ognl); 1914 if (property != null) { 1915 return property; 1916 } 1917 1918 // Split ognl except when this is not a Map, Array 1919 // and we would like to keep the dots within the key name 1920 List<String> methods = OgnlHelper.splitOgnl(ognl); 1921 1922 // remove any OGNL operators so we got the pure key name 1923 String key = OgnlHelper.removeOperators(methods.get(0)); 1924 1925 property = keyedEntityRetrievalStrategy.getKeyedEntity(exchange, key); 1926 if (property == null) { 1927 return null; 1928 } 1929 // the remainder is the rest of the ognl without the key 1930 String remainder = ObjectHelper.after(ognl, key); 1931 return new MethodCallExpression(property, remainder).evaluate(exchange); 1932 } 1933 1934 @Override 1935 public String toString() { 1936 return toStringValue; 1937 } 1938 1939 /** 1940 * Strategy to retrieve the value based on the key 1941 */ 1942 public interface KeyedEntityRetrievalStrategy { 1943 Object getKeyedEntity(Exchange exchange, String key); 1944 } 1945 }; 1946 1947}