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    
020    import java.util.regex.Matcher;
021    import java.util.regex.Pattern;
022    
023    import org.apache.camel.Exchange;
024    import org.apache.camel.Expression;
025    import org.apache.camel.Predicate;
026    import org.apache.camel.util.ObjectHelper;
027    
028    import static org.apache.camel.util.ObjectHelper.compare;
029    import static org.apache.camel.util.ObjectHelper.notNull;
030    
031    
032    /**
033     * A helper class for working with predicates
034     *
035     * @version $Revision: 1110 $
036     */
037    public final class PredicateBuilder {
038    
039        /**
040         * Utility classes should not have a public constructor.
041         */
042        private PredicateBuilder() {
043        }
044    
045        /**
046         * Converts the given expression into an {@link Predicate}
047         */
048        public static <E extends Exchange> Predicate<E> toPredicate(final Expression<E> expression) {
049            return new PredicateSupport<E>() {
050                public boolean matches(E exchange) {
051                    Object value = expression.evaluate(exchange);
052                    return ObjectHelper.evaluateValuePredicate(value);
053                }
054    
055                @Override
056                public String toString() {
057                    return expression.toString();
058                }
059            };
060        }
061    
062        /**
063         * A helper method to return the logical not of the given predicate
064         */
065        public static <E extends Exchange> Predicate<E> not(final Predicate<E> predicate) {
066            notNull(predicate, "predicate");
067            return new PredicateSupport<E>() {
068                public boolean matches(E exchange) {
069                    return !predicate.matches(exchange);
070                }
071    
072                @Override
073                public String toString() {
074                    return "not " + predicate;
075                }
076            };
077        }
078    
079        /**
080         * A helper method to combine multiple predicates by a logical AND
081         */
082        public static <E extends Exchange> Predicate<E> and(final Predicate<E> left, final Predicate<E> right) {
083            notNull(left, "left");
084            notNull(right, "right");
085            return new PredicateSupport<E>() {
086                public boolean matches(E exchange) {
087                    return left.matches(exchange) && right.matches(exchange);
088                }
089    
090                @Override
091                public String toString() {
092                    return "(" + left + ") and (" + right + ")";
093                }
094            };
095        }
096    
097        /**
098         * A helper method to combine multiple predicates by a logical OR
099         */
100        public static <E extends Exchange> Predicate<E> or(final Predicate<E> left, final Predicate<E> right) {
101            notNull(left, "left");
102            notNull(right, "right");
103            return new PredicateSupport<E>() {
104                public boolean matches(E exchange) {
105                    return left.matches(exchange) || right.matches(exchange);
106                }
107    
108                @Override
109                public String toString() {
110                    return "(" + left + ") or (" + right + ")";
111                }
112            };
113        }
114    
115        public static <E extends Exchange> Predicate<E> isEqualTo(final Expression<E> left,
116                                                                  final Expression<E> right) {
117            return new BinaryPredicateSupport<E>(left, right) {
118    
119                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
120                    return ObjectHelper.equal(leftValue, rightValue);
121                }
122    
123                protected String getOperationText() {
124                    return "==";
125                }
126            };
127        }
128    
129        public static <E extends Exchange> Predicate<E> isNotEqualTo(final Expression<E> left,
130                                                                     final Expression<E> right) {
131            return new BinaryPredicateSupport<E>(left, right) {
132    
133                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
134                    return !ObjectHelper.equal(leftValue, rightValue);
135                }
136    
137                protected String getOperationText() {
138                    return "!=";
139                }
140            };
141        }
142    
143        public static <E extends Exchange> Predicate<E> isLessThan(final Expression<E> left,
144                                                                   final Expression<E> right) {
145            return new BinaryPredicateSupport<E>(left, right) {
146    
147                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
148                    return compare(leftValue, rightValue) < 0;
149                }
150    
151                protected String getOperationText() {
152                    return "<";
153                }
154            };
155        }
156    
157        public static <E extends Exchange> Predicate<E> isLessThanOrEqualTo(final Expression<E> left,
158                                                                            final Expression<E> right) {
159            return new BinaryPredicateSupport<E>(left, right) {
160    
161                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
162                    return compare(leftValue, rightValue) <= 0;
163                }
164    
165                protected String getOperationText() {
166                    return "<=";
167                }
168            };
169        }
170    
171        public static <E extends Exchange> Predicate<E> isGreaterThan(final Expression<E> left,
172                                                                      final Expression<E> right) {
173            return new BinaryPredicateSupport<E>(left, right) {
174    
175                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
176                    return compare(leftValue, rightValue) > 0;
177                }
178    
179                protected String getOperationText() {
180                    return ">";
181                }
182            };
183        }
184    
185        public static <E extends Exchange> Predicate<E> isGreaterThanOrEqualTo(final Expression<E> left,
186                                                                               final Expression<E> right) {
187            return new BinaryPredicateSupport<E>(left, right) {
188    
189                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
190                    return compare(leftValue, rightValue) >= 0;
191                }
192    
193                protected String getOperationText() {
194                    return ">=";
195                }
196            };
197        }
198    
199        public static <E extends Exchange> Predicate<E> contains(final Expression<E> left,
200                                                                 final Expression<E> right) {
201            return new BinaryPredicateSupport<E>(left, right) {
202    
203                protected boolean matches(E exchange, Object leftValue, Object rightValue) {
204                    return ObjectHelper.contains(leftValue, rightValue);
205                }
206    
207                protected String getOperationText() {
208                    return "contains";
209                }
210            };
211        }
212    
213        public static <E extends Exchange> Predicate<E> isNull(final Expression<E> expression) {
214            return isEqualTo(expression, ExpressionBuilder.<E> constantExpression(null));
215        }
216    
217        public static <E extends Exchange> Predicate<E> isNotNull(final Expression<E> expression) {
218            return isNotEqualTo(expression, ExpressionBuilder.<E> constantExpression(null));
219        }
220    
221        public static <E extends Exchange> Predicate<E> isInstanceOf(final Expression<E> expression,
222                                                                     final Class type) {
223            notNull(expression, "expression");
224            notNull(type, "type");
225    
226            return new PredicateSupport<E>() {
227                public boolean matches(E exchange) {
228                    Object value = expression.evaluate(exchange);
229                    return type.isInstance(value);
230                }
231    
232                @Override
233                public String toString() {
234                    return expression + " instanceof " + type.getName();
235                }
236    
237                @Override
238                protected String assertionFailureMessage(E exchange) {
239                    return super.assertionFailureMessage(exchange)
240                        + " for <" + expression.evaluate(exchange) + ">";
241                }
242            };
243        }
244    
245        /**
246         * Returns a predicate which is true if the expression matches the given
247         * regular expression
248         *
249         * @param expression the expression to evaluate
250         * @param regex the regular expression to match against
251         * @return a new predicate
252         */
253        public static <E extends Exchange> Predicate<E> regex(final Expression<E> expression, final String regex) {
254            return regex(expression, Pattern.compile(regex));
255        }
256    
257        /**
258         * Returns a predicate which is true if the expression matches the given
259         * regular expression
260         *
261         * @param expression the expression to evaluate
262         * @param pattern the regular expression to match against
263         * @return a new predicate
264         */
265        public static <E extends Exchange> Predicate<E> regex(final Expression<E> expression,
266                                                              final Pattern pattern) {
267            notNull(expression, "expression");
268            notNull(pattern, "pattern");
269    
270            return new PredicateSupport<E>() {
271                public boolean matches(E exchange) {
272                    Object value = expression.evaluate(exchange);
273                    if (value != null) {
274                        Matcher matcher = pattern.matcher(value.toString());
275                        return matcher.matches();
276                    }
277                    return false;
278                }
279    
280                @Override
281                public String toString() {
282                    return expression + ".matches(" + pattern + ")";
283                }
284    
285                @Override
286                protected String assertionFailureMessage(E exchange) {
287                    return super.assertionFailureMessage(exchange) + " for <" + expression.evaluate(exchange)
288                           + ">";
289                }
290    
291            };
292        }
293    }