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