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