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.List;
022    import java.util.StringTokenizer;
023    import java.util.regex.Pattern;
024    
025    import org.apache.camel.Exchange;
026    import org.apache.camel.Expression;
027    
028    /**
029     * @version $Revision: $
030     */
031    public class ExpressionBuilder {
032    
033    
034        /**
035         * Utility classes should not have a public constructor.
036         */
037        private ExpressionBuilder() {        
038        }
039        
040        /**
041         * Returns an expression for the header value with the given name
042         * 
043         * @param headerName the name of the header the expression will return
044         * @return an expression object which will return the header value
045         */
046        public static <E extends Exchange> Expression<E> headerExpression(final String headerName) {
047            return new Expression<E>() {
048                public Object evaluate(E exchange) {
049                    Object header = exchange.getIn().getHeader(headerName);
050                    if (header == null) {
051                        // lets try the exchange header
052                        header = exchange.getProperty(headerName);
053                    }
054                    return header;
055                }
056    
057                @Override
058                public String toString() {
059                    return "header(" + headerName + ")";
060                }
061            };
062        }
063    
064        /**
065         * Returns an expression for the out header value with the given name
066         * 
067         * @param headerName the name of the header the expression will return
068         * @return an expression object which will return the header value
069         */
070        public static <E extends Exchange> Expression<E> outHeaderExpression(final String headerName) {
071            return new Expression<E>() {
072                public Object evaluate(E exchange) {
073                    Object header = exchange.getOut().getHeader(headerName);
074                    if (header == null) {
075                        // lets try the exchange header
076                        header = exchange.getProperty(headerName);
077                    }
078                    return header;
079                }
080    
081                @Override
082                public String toString() {
083                    return "outHeader(" + headerName + ")";
084                }
085            };
086        }
087    
088        /**
089         * Returns an expression for the property value with the given name
090         * 
091         * @param propertyName the name of the property the expression will return
092         * @return an expression object which will return the property value
093         */
094        public static <E extends Exchange> Expression<E> propertyExpression(final String propertyName) {
095            return new Expression<E>() {
096                public Object evaluate(E exchange) {
097                    return exchange.getProperty(propertyName);
098                }
099    
100                @Override
101                public String toString() {
102                    return "property(" + propertyName + ")";
103                }
104            };
105        }
106    
107        /**
108         * Returns an expression for a system property value with the given name
109         * 
110         * @param propertyName the name of the system property the expression will
111         *                return
112         * @return an expression object which will return the system property value
113         */
114        public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName) {
115            return systemPropertyExpression(propertyName, null);
116        }
117    
118        /**
119         * Returns an expression for a system property value with the given name
120         * 
121         * @param propertyName the name of the system property the expression will
122         *                return
123         * @return an expression object which will return the system property value
124         */
125        public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName,
126                                                                                  final String defaultValue) {
127            return new Expression<E>() {
128                public Object evaluate(E exchange) {
129                    return System.getProperty(propertyName, defaultValue);
130                }
131    
132                @Override
133                public String toString() {
134                    return "systemProperty(" + propertyName + ")";
135                }
136            };
137        }
138    
139        /**
140         * Returns an expression for the contant value
141         * 
142         * @param value the value the expression will return
143         * @return an expression object which will return the constant value
144         */
145        public static <E extends Exchange> Expression<E> constantExpression(final Object value) {
146            return new Expression<E>() {
147                public Object evaluate(E exchange) {
148                    return value;
149                }
150    
151                @Override
152                public String toString() {
153                    return "" + value;
154                }
155            };
156        }
157    
158        /**
159         * Returns the expression for the exchanges inbound message body
160         */
161        public static <E extends Exchange> Expression<E> bodyExpression() {
162            return new Expression<E>() {
163                public Object evaluate(E exchange) {
164                    return exchange.getIn().getBody();
165                }
166    
167                @Override
168                public String toString() {
169                    return "body";
170                }
171            };
172        }
173    
174        /**
175         * Returns the expression for the exchanges inbound message body converted
176         * to the given type
177         */
178        public static <E extends Exchange, T> Expression<E> bodyExpression(final Class<T> type) {
179            return new Expression<E>() {
180                public Object evaluate(E exchange) {
181                    return exchange.getIn().getBody(type);
182                }
183    
184                @Override
185                public String toString() {
186                    return "bodyAs[" + type.getName() + "]";
187                }
188            };
189        }
190    
191        /**
192         * Returns the expression for the out messages body
193         */
194        public static <E extends Exchange> Expression<E> outBodyExpression() {
195            return new Expression<E>() {
196                public Object evaluate(E exchange) {
197                    return exchange.getOut().getBody();
198                }
199    
200                @Override
201                public String toString() {
202                    return "outBody";
203                }
204            };
205        }
206    
207        /**
208         * Returns the expression for the exchange
209         */
210        public static <E extends Exchange> Expression<E> exchangeExpression() {
211            return new Expression<E>() {
212                public Object evaluate(E exchange) {
213                    return exchange;
214                }
215    
216                @Override
217                public String toString() {
218                    return "exchange";
219                }
220            };
221        }
222    
223        /**
224         * Returns the expression for the IN message
225         */
226        public static <E extends Exchange> Expression<E> inMessageExpression() {
227            return new Expression<E>() {
228                public Object evaluate(E exchange) {
229                    return exchange.getIn();
230                }
231    
232                @Override
233                public String toString() {
234                    return "inMessage";
235                }
236            };
237        }
238    
239        /**
240         * Returns an expression which converts the given expression to the given
241         * type
242         */
243        public static <E extends Exchange> Expression<E> convertTo(final Expression expression, final Class type) {
244            return new Expression<E>() {
245                public Object evaluate(E exchange) {
246                    Object value = expression.evaluate(exchange);
247                    return exchange.getContext().getTypeConverter().convertTo(type, value);
248                }
249    
250                @Override
251                public String toString() {
252                    return "" + expression + ".convertTo(" + type.getName() + ".class)";
253                }
254            };
255        }
256    
257        /**
258         * Returns a tokenize expression which will tokenize the string with the
259         * given token
260         */
261        public static <E extends Exchange> Expression<E> tokenizeExpression(final Expression<E> expression,
262                                                                            final String token) {
263            return new Expression<E>() {
264                public Object evaluate(E exchange) {
265                    String text = evaluateStringExpression(expression, exchange);
266                    if (text == null) {
267                        return null;
268                    }
269                    StringTokenizer iter = new StringTokenizer(text, token);
270                    List<String> answer = new ArrayList<String>();
271                    while (iter.hasMoreTokens()) {
272                        answer.add(iter.nextToken());
273                    }
274                    return answer;
275                }
276    
277                @Override
278                public String toString() {
279                    return "tokenize(" + expression + ", " + token + ")";
280                }
281            };
282        }
283    
284        /**
285         * Returns a tokenize expression which will tokenize the string with the
286         * given regex
287         */
288        public static <E extends Exchange> Expression<E> regexTokenize(final Expression<E> expression,
289                                                                       String regexTokenizer) {
290            final Pattern pattern = Pattern.compile(regexTokenizer);
291            return new Expression<E>() {
292                public Object evaluate(E exchange) {
293                    String text = evaluateStringExpression(expression, exchange);
294                    if (text == null) {
295                        return null;
296                    }
297                    return Arrays.asList(pattern.split(text));
298                }
299    
300                @Override
301                public String toString() {
302                    return "regexTokenize(" + expression + ", " + pattern.pattern() + ")";
303                }
304            };
305        }
306    
307        /**
308         * Transforms the expression into a String then performs the regex
309         * replaceAll to transform the String and return the result
310         */
311        public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
312                                                                         String regex, final String replacement) {
313            final Pattern pattern = Pattern.compile(regex);
314            return new Expression<E>() {
315                public Object evaluate(E exchange) {
316                    String text = evaluateStringExpression(expression, exchange);
317                    if (text == null) {
318                        return null;
319                    }
320                    return pattern.matcher(text).replaceAll(replacement);
321                }
322    
323                @Override
324                public String toString() {
325                    return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
326                }
327            };
328        }
329    
330        /**
331         * Transforms the expression into a String then performs the regex
332         * replaceAll to transform the String and return the result
333         */
334        public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
335                                                                         String regex,
336                                                                         final Expression<E> replacementExpression) {
337            final Pattern pattern = Pattern.compile(regex);
338            return new Expression<E>() {
339                public Object evaluate(E exchange) {
340                    String text = evaluateStringExpression(expression, exchange);
341                    String replacement = evaluateStringExpression(replacementExpression, exchange);
342                    if (text == null || replacement == null) {
343                        return null;
344                    }
345                    return pattern.matcher(text).replaceAll(replacement);
346                }
347    
348                @Override
349                public String toString() {
350                    return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
351                }
352            };
353        }
354    
355        /**
356         * Appends the String evaluations of the two expressions together
357         */
358        public static <E extends Exchange> Expression<E> append(final Expression<E> left,
359                                                                final Expression<E> right) {
360            return new Expression<E>() {
361                public Object evaluate(E exchange) {
362                    return evaluateStringExpression(left, exchange) + evaluateStringExpression(right, exchange);
363                }
364    
365                @Override
366                public String toString() {
367                    return "append(" + left + ", " + right + ")";
368                }
369            };
370        }
371    
372        /**
373         * Evaluates the expression on the given exchange and returns the String
374         * representation
375         * 
376         * @param expression the expression to evaluate
377         * @param exchange the exchange to use to evaluate the expression
378         * @return the String representation of the expression or null if it could
379         *         not be evaluated
380         */
381        public static <E extends Exchange> String evaluateStringExpression(Expression<E> expression, E exchange) {
382            Object value = expression.evaluate(exchange);
383            return exchange.getContext().getTypeConverter().convertTo(String.class, value);
384        }
385    
386        /**
387         * Returns an expression for the given system property
388         */
389        public static <E extends Exchange> Expression<E> systemProperty(final String name) {
390            return systemProperty(name, null);
391        }
392    
393        /**
394         * Returns an expression for the given system property
395         */
396        public static <E extends Exchange> Expression<E> systemProperty(final String name,
397                                                                        final String defaultValue) {
398            return new Expression<E>() {
399                public Object evaluate(E exchange) {
400                    return System.getProperty(name, defaultValue);
401                }
402            };
403        }
404    }