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