/** * Copyright (c) 2014-2017 by the respective copyright holders. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.model.script.lib; import java.math.BigDecimal; import java.math.RoundingMode; import org.eclipse.smarthome.core.library.types.DecimalType; import org.eclipse.smarthome.core.types.Type; /** * This class contains all kinds of extensions to be used by scripts and not * provided by Xbase. These include things like number handling and comparisons. * * @author Kai Kreuzer - Initial contribution and API * */ public class NumberExtensions { /** * It is the definition of Java null pointer for the rules language. * Actually its value is 0 (rules variables are number) but we can use * the null pointer and throws an NPE when a null value is used. * I think this concept should not exist for those who writes the rules. */ public static final BigDecimal NULL_DEFINITION = new BigDecimal(0); // Calculation operators for numbers public static BigDecimal operator_plus(Number x, Number y) { BigDecimal xValue = numberToBigDecimal(x); BigDecimal yValue = numberToBigDecimal(y); if (xValue == null) { return yValue; } else if (yValue == null) { return xValue; } else { return xValue.add(yValue); } } public static BigDecimal operator_minus(Number x) { BigDecimal xValue = numberToBigDecimal(x); if (xValue == null) { return xValue; } else { return xValue.negate(); } } public static BigDecimal operator_minus(Number x, Number y) { BigDecimal xValue = numberToBigDecimal(x); BigDecimal yValue = numberToBigDecimal(y); if (xValue == null) { return operator_minus(yValue); } else if (yValue == null) { return xValue; } else { return xValue.subtract(yValue); } } public static BigDecimal operator_multiply(Number x, Number y) { BigDecimal xValue = numberToBigDecimal(x); BigDecimal yValue = numberToBigDecimal(y); if (xValue == null) { return NULL_DEFINITION; } else if (yValue == null) { return NULL_DEFINITION; } else { return xValue.multiply(yValue); } } public static BigDecimal operator_divide(Number x, Number y) { BigDecimal xValue = numberToBigDecimal(x); BigDecimal yValue = numberToBigDecimal(y); if (xValue == null) { return NULL_DEFINITION.divide(yValue, 8, RoundingMode.HALF_UP); } else if (yValue == null) { return xValue.divide(NULL_DEFINITION, 8, RoundingMode.HALF_UP); // throws an exception } else { return xValue.divide(yValue, 8, RoundingMode.HALF_UP); } } // Comparison operations between numbers public static boolean operator_equals(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return rightValue == null; } else if (rightValue == null) { return false; } else { return leftValue.compareTo(rightValue) == 0; } } public static boolean operator_notEquals(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return rightValue != null; } else if (rightValue == null) { return true; } else { return leftValue.compareTo(rightValue) != 0; } } public static boolean operator_lessThan(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return true; } else if (rightValue == null) { return false; } else { return leftValue.compareTo(rightValue) < 0; } } public static boolean operator_greaterThan(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return false; } else if (rightValue == null) { return true; } else { return leftValue.compareTo(rightValue) > 0; } } public static boolean operator_lessEqualsThan(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return true; } else if (rightValue == null) { return false; } else { return leftValue.compareTo(rightValue) <= 0; } } public static boolean operator_greaterEqualsThan(Number left, Number right) { BigDecimal leftValue = numberToBigDecimal(left); BigDecimal rightValue = numberToBigDecimal(right); if (leftValue == null) { return (rightValue != null) ? false : true; } else if (rightValue == null) { return true; } else { return leftValue.compareTo(rightValue) >= 0; } } // Comparison operators between ESH types and numbers public static boolean operator_equals(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) == 0; } else { return type == x; // both might be null, then we should return true } } public static boolean operator_notEquals(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) != 0; } else { return type != x; // both might be null, then we should return // false, otherwise true } } public static boolean operator_greaterThan(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) > 0; } else { return false; } } public static boolean operator_greaterEqualsThan(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) >= 0; } else { return false; } } public static boolean operator_lessThan(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) < 0; } else { return false; } } public static boolean operator_lessEqualsThan(Type type, Number x) { if (type != null && type instanceof DecimalType && x != null) { return ((DecimalType) type).toBigDecimal().compareTo(numberToBigDecimal(x)) <= 0; } else { return false; } } /** * Convert the given number into a BigDecimal * * @param number * the number to convert * @return the given number as BigDecimal or null if number is null */ public static BigDecimal numberToBigDecimal(Number number) { if (number != null) { return new BigDecimal(number.toString()); } else { return null; } } }