| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.builder; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.camel.Exchange; |
| import org.apache.camel.Expression; |
| import org.apache.camel.Predicate; |
| import org.apache.camel.util.ExpressionToPredicateAdapter; |
| import org.apache.camel.util.ObjectHelper; |
| |
| import static org.apache.camel.util.ObjectHelper.notNull; |
| |
| |
| /** |
| * A helper class for working with predicates |
| * |
| * @version |
| */ |
| public final class PredicateBuilder { |
| |
| /** |
| * Utility classes should not have a public constructor. |
| */ |
| private PredicateBuilder() { |
| } |
| |
| /** |
| * Converts the given expression into an {@link Predicate} |
| */ |
| public static Predicate toPredicate(final Expression expression) { |
| return ExpressionToPredicateAdapter.toPredicate(expression); |
| } |
| |
| /** |
| * A helper method to return the logical not of the given predicate |
| */ |
| public static Predicate not(final Predicate predicate) { |
| notNull(predicate, "predicate"); |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| return !predicate.matches(exchange); |
| } |
| |
| @Override |
| public String toString() { |
| return "not (" + predicate + ")"; |
| } |
| }; |
| } |
| |
| /** |
| * A helper method to combine multiple predicates by a logical AND |
| */ |
| public static Predicate and(final Predicate left, final Predicate right) { |
| notNull(left, "left"); |
| notNull(right, "right"); |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| return left.matches(exchange) && right.matches(exchange); |
| } |
| |
| @Override |
| public String toString() { |
| return "(" + left + ") and (" + right + ")"; |
| } |
| }; |
| } |
| |
| /** |
| * A helper method to combine multiple predicates by a logical OR |
| */ |
| public static Predicate or(final Predicate left, final Predicate right) { |
| notNull(left, "left"); |
| notNull(right, "right"); |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| return left.matches(exchange) || right.matches(exchange); |
| } |
| |
| @Override |
| public String toString() { |
| return "(" + left + ") or (" + right + ")"; |
| } |
| }; |
| } |
| |
| /** |
| * A helper method to return true if any of the predicates matches. |
| */ |
| public static Predicate in(final Predicate... predicates) { |
| notNull(predicates, "predicates"); |
| |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| for (Predicate in : predicates) { |
| if (in.matches(exchange)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| return "in (" + Arrays.asList(predicates) + ")"; |
| } |
| }; |
| } |
| |
| public static Predicate isEqualTo(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.typeCoerceEquals(exchange.getContext().getTypeConverter(), leftValue, rightValue); |
| } |
| |
| protected String getOperationText() { |
| return "=="; |
| } |
| }; |
| } |
| |
| public static Predicate isNotEqualTo(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return false; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return true; |
| } |
| |
| return ObjectHelper.typeCoerceNotEquals(exchange.getContext().getTypeConverter(), leftValue, rightValue); |
| } |
| |
| protected String getOperationText() { |
| return "!="; |
| } |
| }; |
| } |
| |
| public static Predicate isLessThan(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.typeCoerceCompare(exchange.getContext().getTypeConverter(), leftValue, rightValue) < 0; |
| } |
| |
| protected String getOperationText() { |
| return "<"; |
| } |
| }; |
| } |
| |
| public static Predicate isLessThanOrEqualTo(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.typeCoerceCompare(exchange.getContext().getTypeConverter(), leftValue, rightValue) <= 0; |
| } |
| |
| protected String getOperationText() { |
| return "<="; |
| } |
| }; |
| } |
| |
| public static Predicate isGreaterThan(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return false; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.typeCoerceCompare(exchange.getContext().getTypeConverter(), leftValue, rightValue) > 0; |
| } |
| |
| protected String getOperationText() { |
| return ">"; |
| } |
| }; |
| } |
| |
| public static Predicate isGreaterThanOrEqualTo(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.typeCoerceCompare(exchange.getContext().getTypeConverter(), leftValue, rightValue) >= 0; |
| } |
| |
| protected String getOperationText() { |
| return ">="; |
| } |
| }; |
| } |
| |
| public static Predicate contains(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| |
| return ObjectHelper.contains(leftValue, rightValue); |
| } |
| |
| protected String getOperationText() { |
| return "contains"; |
| } |
| }; |
| } |
| |
| public static Predicate isNull(final Expression expression) { |
| return new BinaryPredicateSupport(expression, ExpressionBuilder.constantExpression(null)) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null) { |
| // the left operator is null so its true |
| return true; |
| } |
| |
| return ObjectHelper.typeCoerceEquals(exchange.getContext().getTypeConverter(), leftValue, rightValue); |
| } |
| |
| protected String getOperationText() { |
| // leave the operation text as "is not" as Camel will insert right and left expression around it |
| // so it will be displayed as: XXX is null |
| return "is"; |
| } |
| }; |
| } |
| |
| public static Predicate isNotNull(final Expression expression) { |
| return new BinaryPredicateSupport(expression, ExpressionBuilder.constantExpression(null)) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue != null) { |
| // the left operator is not null so its true |
| return true; |
| } |
| |
| return ObjectHelper.typeCoerceNotEquals(exchange.getContext().getTypeConverter(), leftValue, rightValue); |
| } |
| |
| protected String getOperationText() { |
| // leave the operation text as "is not" as Camel will insert right and left expression around it |
| // so it will be displayed as: XXX is not null |
| return "is not"; |
| } |
| }; |
| } |
| |
| public static Predicate isInstanceOf(final Expression expression, final Class<?> type) { |
| notNull(expression, "expression"); |
| notNull(type, "type"); |
| |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| Object value = expression.evaluate(exchange, Object.class); |
| return type.isInstance(value); |
| } |
| |
| @Override |
| public String toString() { |
| return expression + " instanceof " + type.getCanonicalName(); |
| } |
| }; |
| } |
| |
| public static Predicate startsWith(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| String leftStr = exchange.getContext().getTypeConverter().convertTo(String.class, leftValue); |
| String rightStr = exchange.getContext().getTypeConverter().convertTo(String.class, rightValue); |
| if (leftStr != null && rightStr != null) { |
| return leftStr.startsWith(rightStr); |
| } else { |
| return false; |
| } |
| } |
| |
| protected String getOperationText() { |
| return "startsWith"; |
| } |
| }; |
| } |
| |
| public static Predicate endsWith(final Expression left, final Expression right) { |
| return new BinaryPredicateSupport(left, right) { |
| |
| protected boolean matches(Exchange exchange, Object leftValue, Object rightValue) { |
| if (leftValue == null && rightValue == null) { |
| // they are equal |
| return true; |
| } else if (leftValue == null || rightValue == null) { |
| // only one of them is null so they are not equal |
| return false; |
| } |
| String leftStr = exchange.getContext().getTypeConverter().convertTo(String.class, leftValue); |
| String rightStr = exchange.getContext().getTypeConverter().convertTo(String.class, rightValue); |
| if (leftStr != null && rightStr != null) { |
| return leftStr.endsWith(rightStr); |
| } else { |
| return false; |
| } |
| } |
| |
| protected String getOperationText() { |
| return "endsWith"; |
| } |
| }; |
| } |
| |
| /** |
| * Returns a predicate which is true if the expression matches the given |
| * regular expression |
| * |
| * @param expression the expression to evaluate |
| * @param regex the regular expression to match against |
| * @return a new predicate |
| */ |
| public static Predicate regex(final Expression expression, final String regex) { |
| return regex(expression, Pattern.compile(regex)); |
| } |
| |
| /** |
| * Returns a predicate which is true if the expression matches the given |
| * regular expression |
| * |
| * @param expression the expression to evaluate |
| * @param pattern the regular expression to match against |
| * @return a new predicate |
| */ |
| public static Predicate regex(final Expression expression, final Pattern pattern) { |
| notNull(expression, "expression"); |
| notNull(pattern, "pattern"); |
| |
| return new Predicate() { |
| public boolean matches(Exchange exchange) { |
| String value = expression.evaluate(exchange, String.class); |
| if (value != null) { |
| Matcher matcher = pattern.matcher(value); |
| return matcher.matches(); |
| } |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| return expression + ".matches('" + pattern + "')"; |
| } |
| }; |
| } |
| |
| /** |
| * Concat the given predicates into a single predicate, which |
| * only matches if all the predicates matches. |
| * |
| * @param predicates predicates |
| * @return a single predicate containing all the predicates |
| */ |
| public static Predicate and(List<Predicate> predicates) { |
| Predicate answer = null; |
| for (Predicate predicate : predicates) { |
| if (answer == null) { |
| answer = predicate; |
| } else { |
| answer = and(answer, predicate); |
| } |
| } |
| return answer; |
| } |
| |
| /** |
| * A constant predicate. |
| * |
| * @param answer the constant matches |
| * @return a predicate that always returns the given answer. |
| */ |
| public static Predicate constant(final boolean answer) { |
| return new Predicate() { |
| @Override |
| public boolean matches(Exchange exchange) { |
| return answer; |
| } |
| |
| @Override |
| public String toString() { |
| return "" + answer; |
| } |
| }; |
| } |
| } |