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