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