001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.camel.builder; 018 019 import java.io.File; 020 import java.io.FileNotFoundException; 021 import java.io.InputStream; 022 import java.nio.channels.ReadableByteChannel; 023 import java.util.ArrayList; 024 import java.util.Collection; 025 import java.util.List; 026 import java.util.Scanner; 027 import java.util.regex.Pattern; 028 029 import org.apache.camel.Exchange; 030 import org.apache.camel.Expression; 031 import org.apache.camel.Message; 032 import org.apache.camel.RuntimeCamelException; 033 034 /** 035 * A helper class for working with <a href="http://activemq.apache.org/camel/expression.html">expressions</a>. 036 * 037 * @version $Revision: 51090 $ 038 */ 039 public final class ExpressionBuilder { 040 041 /** 042 * Utility classes should not have a public constructor. 043 */ 044 private ExpressionBuilder() { 045 } 046 047 /** 048 * Returns an expression for the header value with the given name 049 * 050 * @param headerName the name of the header the expression will return 051 * @return an expression object which will return the header value 052 */ 053 public static <E extends Exchange> Expression<E> headerExpression(final String headerName) { 054 return new Expression<E>() { 055 public Object evaluate(E exchange) { 056 Object header = exchange.getIn().getHeader(headerName); 057 if (header == null) { 058 // lets try the exchange header 059 header = exchange.getProperty(headerName); 060 } 061 return header; 062 } 063 064 @Override 065 public String toString() { 066 return "header(" + headerName + ")"; 067 } 068 }; 069 } 070 071 /** 072 * Returns an expression for the inbound message headers 073 * 074 * @see Message#getHeaders() 075 * @return an expression object which will return the inbound headers 076 */ 077 public static <E extends Exchange> Expression<E> headersExpression() { 078 return new Expression<E>() { 079 public Object evaluate(E exchange) { 080 return exchange.getIn().getHeaders(); 081 } 082 083 @Override 084 public String toString() { 085 return "headers"; 086 } 087 }; 088 } 089 090 /** 091 * Returns an expression for the out header value with the given name 092 * 093 * @param headerName the name of the header the expression will return 094 * @return an expression object which will return the header value 095 */ 096 public static <E extends Exchange> Expression<E> outHeaderExpression(final String headerName) { 097 return new Expression<E>() { 098 public Object evaluate(E exchange) { 099 Message out = exchange.getOut(false); 100 if (out == null) { 101 return null; 102 } 103 Object header = out.getHeader(headerName); 104 if (header == null) { 105 // lets try the exchange header 106 header = exchange.getProperty(headerName); 107 } 108 return header; 109 } 110 111 @Override 112 public String toString() { 113 return "outHeader(" + headerName + ")"; 114 } 115 }; 116 } 117 118 /** 119 * Returns an expression for the outbound message headers 120 * 121 * @see Message#getHeaders() 122 * @return an expression object which will return the inbound headers 123 */ 124 public static <E extends Exchange> Expression<E> outHeadersExpression() { 125 return new Expression<E>() { 126 public Object evaluate(E exchange) { 127 return exchange.getOut().getHeaders(); 128 } 129 130 @Override 131 public String toString() { 132 return "outHeaders"; 133 } 134 }; 135 } 136 137 /** 138 * Returns an expression for the property value with the given name 139 * 140 * @see Exchange#getProperty(String) 141 * @param propertyName the name of the property the expression will return 142 * @return an expression object which will return the property value 143 */ 144 public static <E extends Exchange> Expression<E> propertyExpression(final String propertyName) { 145 return new Expression<E>() { 146 public Object evaluate(E exchange) { 147 return exchange.getProperty(propertyName); 148 } 149 150 @Override 151 public String toString() { 152 return "property(" + propertyName + ")"; 153 } 154 }; 155 } 156 157 158 /** 159 * Returns an expression for the property value with the given name 160 * 161 * @see Exchange#getProperties() 162 * @return an expression object which will return the properties 163 */ 164 public static <E extends Exchange> Expression<E> propertiesExpression() { 165 return new Expression<E>() { 166 public Object evaluate(E exchange) { 167 return exchange.getProperties(); 168 } 169 170 @Override 171 public String toString() { 172 return "properties"; 173 } 174 }; 175 } 176 177 /** 178 * Returns an expression for a system property value with the given name 179 * 180 * @param propertyName the name of the system property the expression will 181 * return 182 * @return an expression object which will return the system property value 183 */ 184 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName) { 185 return systemPropertyExpression(propertyName, null); 186 } 187 188 /** 189 * Returns an expression for a system property value with the given name 190 * 191 * @param propertyName the name of the system property the expression will 192 * return 193 * @return an expression object which will return the system property value 194 */ 195 public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName, 196 final String defaultValue) { 197 return new Expression<E>() { 198 public Object evaluate(E exchange) { 199 return System.getProperty(propertyName, defaultValue); 200 } 201 202 @Override 203 public String toString() { 204 return "systemProperty(" + propertyName + ")"; 205 } 206 }; 207 } 208 209 /** 210 * Returns an expression for the constant value 211 * 212 * @param value the value the expression will return 213 * @return an expression object which will return the constant value 214 */ 215 public static <E extends Exchange> Expression<E> constantExpression(final Object value) { 216 return new Expression<E>() { 217 public Object evaluate(E exchange) { 218 return value; 219 } 220 221 @Override 222 public String toString() { 223 return "" + value; 224 } 225 }; 226 } 227 228 /** 229 * Returns the expression for the exchanges inbound message body 230 */ 231 public static <E extends Exchange> Expression<E> bodyExpression() { 232 return new Expression<E>() { 233 public Object evaluate(E exchange) { 234 return exchange.getIn().getBody(); 235 } 236 237 @Override 238 public String toString() { 239 return "body"; 240 } 241 }; 242 } 243 244 /** 245 * Returns the expression for the exchanges inbound message body converted 246 * to the given type 247 */ 248 public static <E extends Exchange, T> Expression<E> bodyExpression(final Class<T> type) { 249 return new Expression<E>() { 250 public Object evaluate(E exchange) { 251 return exchange.getIn().getBody(type); 252 } 253 254 @Override 255 public String toString() { 256 return "bodyAs[" + type.getName() + "]"; 257 } 258 }; 259 } 260 261 /** 262 * Returns the expression for the out messages body 263 */ 264 public static <E extends Exchange> Expression<E> outBodyExpression() { 265 return new Expression<E>() { 266 public Object evaluate(E exchange) { 267 Message out = exchange.getOut(false); 268 if (out == null) { 269 return null; 270 } 271 return out.getBody(); 272 } 273 274 @Override 275 public String toString() { 276 return "outBody"; 277 } 278 }; 279 } 280 281 /** 282 * Returns the expression for the exchanges outbound message body converted 283 * to the given type 284 */ 285 public static <E extends Exchange, T> Expression<E> outBodyExpression(final Class<T> type) { 286 return new Expression<E>() { 287 public Object evaluate(E exchange) { 288 Message out = exchange.getOut(false); 289 if (out == null) { 290 return null; 291 } 292 return out.getBody(type); 293 } 294 295 @Override 296 public String toString() { 297 return "outBodyAs[" + type.getName() + "]"; 298 } 299 }; 300 } 301 302 /** 303 * Returns the expression for the fault messages body 304 */ 305 public static <E extends Exchange> Expression<E> faultBodyExpression() { 306 return new Expression<E>() { 307 public Object evaluate(E exchange) { 308 return exchange.getFault().getBody(); 309 } 310 311 @Override 312 public String toString() { 313 return "faultBody"; 314 } 315 }; 316 } 317 318 /** 319 * Returns the expression for the exchanges fault message body converted 320 * to the given type 321 */ 322 public static <E extends Exchange, T> Expression<E> faultBodyExpression(final Class<T> type) { 323 return new Expression<E>() { 324 public Object evaluate(E exchange) { 325 return exchange.getFault().getBody(type); 326 } 327 328 @Override 329 public String toString() { 330 return "faultBodyAs[" + type.getName() + "]"; 331 } 332 }; 333 } 334 335 /** 336 * Returns the expression for the exchange 337 */ 338 public static <E extends Exchange> Expression<E> exchangeExpression() { 339 return new Expression<E>() { 340 public Object evaluate(E exchange) { 341 return exchange; 342 } 343 344 @Override 345 public String toString() { 346 return "exchange"; 347 } 348 }; 349 } 350 351 /** 352 * Returns the expression for the IN message 353 */ 354 public static <E extends Exchange> Expression<E> inMessageExpression() { 355 return new Expression<E>() { 356 public Object evaluate(E exchange) { 357 return exchange.getIn(); 358 } 359 360 @Override 361 public String toString() { 362 return "inMessage"; 363 } 364 }; 365 } 366 367 /** 368 * Returns the expression for the OUT message 369 */ 370 public static <E extends Exchange> Expression<E> outMessageExpression() { 371 return new Expression<E>() { 372 public Object evaluate(E exchange) { 373 return exchange.getOut(); 374 } 375 376 @Override 377 public String toString() { 378 return "outMessage"; 379 } 380 }; 381 } 382 383 /** 384 * Returns an expression which converts the given expression to the given 385 * type 386 */ 387 public static <E extends Exchange> Expression<E> convertTo(final Expression expression, final Class type) { 388 return new Expression<E>() { 389 public Object evaluate(E exchange) { 390 Object value = expression.evaluate(exchange); 391 return exchange.getContext().getTypeConverter().convertTo(type, exchange, value); 392 } 393 394 @Override 395 public String toString() { 396 return "" + expression + ".convertTo(" + type.getName() + ".class)"; 397 } 398 }; 399 } 400 401 /** 402 * Returns a tokenize expression which will tokenize the string with the 403 * given token 404 */ 405 public static <E extends Exchange> Expression<E> tokenizeExpression(final Expression<E> expression, 406 final String token) { 407 return new Expression<E>() { 408 public Object evaluate(E exchange) { 409 Object value = expression.evaluate(exchange); 410 Scanner scanner = getScanner(exchange, value); 411 scanner.useDelimiter(token); 412 return scanner; 413 } 414 415 @Override 416 public String toString() { 417 return "tokenize(" + expression + ", " + token + ")"; 418 } 419 }; 420 } 421 422 /** 423 * Returns a tokenize expression which will tokenize the string with the 424 * given regex 425 */ 426 public static <E extends Exchange> Expression<E> regexTokenize(final Expression<E> expression, 427 final String regexTokenizer) { 428 final Pattern pattern = Pattern.compile(regexTokenizer); 429 return new Expression<E>() { 430 public Object evaluate(E exchange) { 431 Object value = expression.evaluate(exchange); 432 Scanner scanner = getScanner(exchange, value); 433 scanner.useDelimiter(regexTokenizer); 434 return scanner; 435 } 436 437 @Override 438 public String toString() { 439 return "regexTokenize(" + expression + ", " + pattern.pattern() + ")"; 440 } 441 }; 442 } 443 444 private static Scanner getScanner(Exchange exchange, Object value) { 445 String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class); 446 447 Scanner scanner = null; 448 if (value instanceof Readable) { 449 scanner = new Scanner((Readable)value); 450 } else if (value instanceof InputStream) { 451 scanner = charset == null ? new Scanner((InputStream)value) 452 : new Scanner((InputStream)value, charset); 453 } else if (value instanceof File) { 454 try { 455 scanner = charset == null ? new Scanner((File)value) : new Scanner((File)value, charset); 456 } catch (FileNotFoundException e) { 457 throw new RuntimeCamelException(e); 458 } 459 } else if (value instanceof String) { 460 scanner = new Scanner((String)value); 461 } else if (value instanceof ReadableByteChannel) { 462 scanner = charset == null ? new Scanner((ReadableByteChannel)value) 463 : new Scanner((ReadableByteChannel)value, charset); 464 } 465 466 if (scanner == null) { 467 // value is not a suitable type, try to convert value to a string 468 String text = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value); 469 if (text != null) { 470 scanner = new Scanner(text); 471 } 472 } 473 474 if (scanner == null) { 475 scanner = new Scanner(""); 476 } 477 return scanner; 478 } 479 480 /** 481 * Transforms the expression into a String then performs the regex 482 * replaceAll to transform the String and return the result 483 */ 484 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression, 485 final String regex, final String replacement) { 486 final Pattern pattern = Pattern.compile(regex); 487 return new Expression<E>() { 488 public Object evaluate(E exchange) { 489 String text = evaluateStringExpression(expression, exchange); 490 if (text == null) { 491 return null; 492 } 493 return pattern.matcher(text).replaceAll(replacement); 494 } 495 496 @Override 497 public String toString() { 498 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 499 } 500 }; 501 } 502 503 /** 504 * Transforms the expression into a String then performs the regex 505 * replaceAll to transform the String and return the result 506 */ 507 public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression, 508 String regex, 509 final Expression<E> replacementExpression) { 510 final Pattern pattern = Pattern.compile(regex); 511 return new Expression<E>() { 512 public Object evaluate(E exchange) { 513 String text = evaluateStringExpression(expression, exchange); 514 String replacement = evaluateStringExpression(replacementExpression, exchange); 515 if (text == null || replacement == null) { 516 return null; 517 } 518 return pattern.matcher(text).replaceAll(replacement); 519 } 520 521 @Override 522 public String toString() { 523 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")"; 524 } 525 }; 526 } 527 528 /** 529 * Appends the String evaluations of the two expressions together 530 */ 531 public static <E extends Exchange> Expression<E> append(final Expression<E> left, 532 final Expression<E> right) { 533 return new Expression<E>() { 534 public Object evaluate(E exchange) { 535 return evaluateStringExpression(left, exchange) + evaluateStringExpression(right, exchange); 536 } 537 538 @Override 539 public String toString() { 540 return "append(" + left + ", " + right + ")"; 541 } 542 }; 543 } 544 545 /** 546 * Evaluates the expression on the given exchange and returns the String 547 * representation 548 * 549 * @param expression the expression to evaluate 550 * @param exchange the exchange to use to evaluate the expression 551 * @return the String representation of the expression or null if it could 552 * not be evaluated 553 */ 554 public static <E extends Exchange> String evaluateStringExpression(Expression<E> expression, E exchange) { 555 Object value = expression.evaluate(exchange); 556 return exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value); 557 } 558 559 /** 560 * Returns an expression for the given system property 561 */ 562 public static <E extends Exchange> Expression<E> systemProperty(final String name) { 563 return systemProperty(name, null); 564 } 565 566 /** 567 * Returns an expression for the given system property 568 */ 569 public static <E extends Exchange> Expression<E> systemProperty(final String name, 570 final String defaultValue) { 571 return new Expression<E>() { 572 public Object evaluate(E exchange) { 573 return System.getProperty(name, defaultValue); 574 } 575 }; 576 } 577 578 /** 579 * Returns an expression which returns the string concatenation value of the various 580 * expressions 581 * 582 * @param expressions the expression to be concatenated dynamically 583 * @return an expression which when evaluated will return the concatenated values 584 */ 585 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions) { 586 return concatExpression(expressions, null); 587 } 588 589 /** 590 * Returns an expression which returns the string concatenation value of the various 591 * expressions 592 * 593 * @param expressions the expression to be concatenated dynamically 594 * @param expression the text description of the expression 595 * @return an expression which when evaluated will return the concatenated values 596 */ 597 public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions, final String expression) { 598 return new Expression<E>() { 599 public Object evaluate(E exchange) { 600 StringBuffer buffer = new StringBuffer(); 601 for (Expression<E> expression : expressions) { 602 String text = evaluateStringExpression(expression, exchange); 603 if (text != null) { 604 buffer.append(text); 605 } 606 } 607 return buffer.toString(); 608 } 609 610 @Override 611 public String toString() { 612 if (expression != null) { 613 return expression; 614 } else { 615 return "concat" + expressions; 616 } 617 } 618 }; 619 } 620 621 /** 622 * Returns an Expression for the inbound message id 623 */ 624 public static <E extends Exchange> Expression<E> messageIdExpression() { 625 return new Expression<E>() { 626 public Object evaluate(E exchange) { 627 return exchange.getIn().getMessageId(); 628 } 629 630 @Override 631 public String toString() { 632 return "messageId"; 633 } 634 }; 635 } 636 637 638 }