
org.bonitasoft.engine.expression.impl.ConditionExpressionExecutorStrategy Maven / Gradle / Ivy
/**
* Copyright (C) 2012-2013 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.bonitasoft.engine.expression.impl;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bonitasoft.engine.expression.NonEmptyContentExpressionExecutorStrategy;
import org.bonitasoft.engine.expression.exception.SExpressionDependencyMissingException;
import org.bonitasoft.engine.expression.exception.SExpressionEvaluationException;
import org.bonitasoft.engine.expression.exception.SInvalidExpressionException;
import org.bonitasoft.engine.expression.model.ExpressionKind;
import org.bonitasoft.engine.expression.model.SExpression;
/**
* @author Elias Ricken de Medeiros
* @author Matthieu Chaffotte
*/
public class ConditionExpressionExecutorStrategy extends NonEmptyContentExpressionExecutorStrategy {
private static final String LOGICAL_COMPLEMENT_OPERATOR = "!";
private static final String NOT_EQUALS_COMPARATOR = "!=";
private static final String EQUALS_COMPARATOR = "==";
private static final String GREATER_THAN_OR_EQUALS_COMPARATOR = ">=";
private static final String lESS_THAN_OR_EQUALS_COMPARATOR = "<=";
private static final String GREATER_THAN_COMPARATOR = ">";
private static final String LESS_THAN_COMPARATOR = "<";
private final List validOperators;
private final Set numericTypes;
public ConditionExpressionExecutorStrategy() {
validOperators = new ArrayList(7);
validOperators.add(LESS_THAN_COMPARATOR);
validOperators.add(GREATER_THAN_COMPARATOR);
validOperators.add(lESS_THAN_OR_EQUALS_COMPARATOR);
validOperators.add(GREATER_THAN_OR_EQUALS_COMPARATOR);
validOperators.add(EQUALS_COMPARATOR);
validOperators.add(NOT_EQUALS_COMPARATOR);
validOperators.add(LOGICAL_COMPLEMENT_OPERATOR);
numericTypes = new HashSet();
numericTypes.add(Integer.class.getName());
numericTypes.add(Long.class.getName());
numericTypes.add(Double.class.getName());
numericTypes.add(Float.class.getName());
numericTypes.add(Short.class.getName());
numericTypes.add(Byte.class.getName());
numericTypes.add(int.class.getName());
numericTypes.add(long.class.getName());
numericTypes.add(double.class.getName());
numericTypes.add(float.class.getName());
numericTypes.add(short.class.getName());
numericTypes.add(byte.class.getName());
}
@Override
public Object evaluate(final SExpression expression, final Map dependencyValues, final Map resolvedExpressions)
throws SExpressionEvaluationException, SExpressionDependencyMissingException {
final List dependencies = expression.getDependencies();
final String content = expression.getContent();
Object result;
if (!LOGICAL_COMPLEMENT_OPERATOR.equals(content)) {
result = evaluateBinaryComparator(resolvedExpressions, dependencies, content);
} else {
result = evaluateBooleanOperator(resolvedExpressions, dependencies, content);
}
return result;
}
private Object evaluateBooleanOperator(final Map resolvedExpressions, final List dependencies, final String content)
throws SExpressionEvaluationException {
Serializable result;
checkDependenciesSize(dependencies, content, 1);
if (!Boolean.class.getName().equals(dependencies.get(0).getReturnType())) {
throw new SExpressionEvaluationException("The dependency of expression '" + content + "' must have the return type " + Boolean.class.getName());
}
final Boolean dependencyValue = (Boolean) resolvedExpressions.get(dependencies.get(0).getDiscriminant());
result = !dependencyValue;
return result;
}
private Object evaluateBinaryComparator(final Map resolvedExpressions, final List dependencies, final String content)
throws SExpressionEvaluationException {
checkDependenciesSize(dependencies, content, 2);
if (!returnTypeCompatible(dependencies) && !EQUALS_COMPARATOR.equals(content)) {
throw new SExpressionEvaluationException("The two dependencies of expression '" + content + "' must have the same return type.");
}
final Object resolvedLeftExpr = transtypeIfApplicable(dependencies.get(0).getReturnType(),
resolvedExpressions.get(dependencies.get(0).getDiscriminant()));
final Object resolvedRightExpr = transtypeIfApplicable(dependencies.get(1).getReturnType(),
resolvedExpressions.get(dependencies.get(1).getDiscriminant()));
Object result = null;
if (EQUALS_COMPARATOR.equals(content)) {
result = areEquals(resolvedLeftExpr, resolvedRightExpr);
} else if (NOT_EQUALS_COMPARATOR.equals(content)) {
result = !areEquals(resolvedLeftExpr, resolvedRightExpr);
} else {
if (resolvedLeftExpr instanceof Comparable && resolvedRightExpr instanceof Comparable) {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Integer compare = compareTo((Comparable) resolvedLeftExpr, (Comparable) resolvedRightExpr);
if (GREATER_THAN_COMPARATOR.equals(content)) {
result = compare > 0;
} else if (GREATER_THAN_OR_EQUALS_COMPARATOR.equals(content)) {
result = compare >= 0;
} else if (LESS_THAN_COMPARATOR.equals(content)) {
result = compare < 0;
} else if (lESS_THAN_OR_EQUALS_COMPARATOR.equals(content)) {
result = compare <= 0;
}
} else {
throw new SExpressionEvaluationException("The two dependencies of expression '" + content + "' must implements java.lang.Comparable.");
}
}
return result;
}
private boolean returnTypeCompatible(final List dependencies) {
final String r1 = dependencies.get(0).getReturnType();
final String r2 = dependencies.get(1).getReturnType();
return numericTypes.contains(r1) && numericTypes.contains(r2) || r1.equals(r2);
}
/*
* Transtype integer to long and float to double
* see bug ENGINE-1261
*/
private Object transtypeIfApplicable(final String type, final Object object) {
if (object == null) {
return null;
}
if (numericTypes.contains(type)) {
return new BigDecimal(String.valueOf(object));
}
return object;
}
private Boolean areEquals(final T left, final T right) {
if (left == null) {
return right == null;
}
return left.equals(right);
}
private , R extends Comparable
© 2015 - 2025 Weber Informatics LLC | Privacy Policy