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