java.lang.Object
edu.internet2.middleware.grouperClientExt.org.apache.commons.jexl2.JexlArithmetic
Direct Known Subclasses:
JexlThreadedArithmetic

public class JexlArithmetic extends Object
Perform arithmetic.

All arithmetic operators (+, - , *, /, %) follow the same rules regarding their arguments.

  1. If both are null, result is 0
  2. If either is a BigDecimal, coerce both to BigDecimal and and perform operation
  3. If either is a floating point number, coerce both to Double and perform operation
  4. If both are BigInteger, treat as BigInteger and perform operation
  5. Else treat as BigInteger, perform operation and attempt to narrow result:
    1. if both arguments can be narrowed to Integer, narrow result to Integer
    2. if both arguments can be narrowed to Long, narrow result to Long
    3. Else return result as BigInteger

Note that the only exception throw by JexlArithmetic is ArithmeticException.
Since:
2.0
  • Field Details

    • BIGD_DOUBLE_MAX_VALUE

      protected static final BigDecimal BIGD_DOUBLE_MAX_VALUE
      Double.MAX_VALUE as BigDecimal.
    • BIGD_DOUBLE_MIN_VALUE

      protected static final BigDecimal BIGD_DOUBLE_MIN_VALUE
      Double.MIN_VALUE as BigDecimal.
    • BIGI_LONG_MAX_VALUE

      protected static final BigInteger BIGI_LONG_MAX_VALUE
      Long.MAX_VALUE as BigInteger.
    • BIGI_LONG_MIN_VALUE

      protected static final BigInteger BIGI_LONG_MIN_VALUE
      Long.MIN_VALUE as BigInteger.
    • BIGD_SCALE

      protected static final int BIGD_SCALE
      Default BigDecimal scale.
      Since:
      2.1
      See Also:
    • mathContext

      protected final MathContext mathContext
      The big decimal math context.
      Since:
      2.1
    • mathScale

      protected final int mathScale
      The big decimal scale.
      Since:
      2.1
  • Constructor Details

    • JexlArithmetic

      public JexlArithmetic(boolean lenient)
      Creates a JexlArithmetic.
      Parameters:
      lenient - whether this arithmetic is lenient or strict
    • JexlArithmetic

      public JexlArithmetic(boolean lenient, MathContext bigdContext, int bigdScale)
      Creates a JexlArithmetic.
      Parameters:
      lenient - whether this arithmetic is lenient or strict
      bigdContext - the math context instance to use for +,-,/,*,% operations on big decimals.
      bigdScale - the scale used for big decimals.
      Since:
      2.1
  • Method Details

    • isLenient

      public boolean isLenient()
      Checks whether this JexlArithmetic instance triggers errors during evaluation when null is used as an operand.
      Returns:
      true if lenient, false if strict
    • getMathContext

      public MathContext getMathContext()
      The MathContext instance used for +,-,/,*,% operations on big decimals.
      Returns:
      the math context
      Since:
      2.1
    • getMathScale

      public int getMathScale()
      The BigDecimal scale used for comparison and coercion operations.
      Returns:
      the scale
      Since:
      2.1
    • roundBigDecimal

      public BigDecimal roundBigDecimal(BigDecimal number)
      Ensure a big decimal is rounded by this arithmetic scale and rounding mode.
      Parameters:
      number - the big decimal to round
      Returns:
      the rounded big decimal
      Since:
      2.1
    • controlNullNullOperands

      protected Object controlNullNullOperands()
      The result of +,/,-,*,% when both operands are null.
      Returns:
      Integer(0) if lenient
      Throws:
      ArithmeticException - if strict
    • controlNullOperand

      protected void controlNullOperand()
      Throw a NPE if arithmetic is strict.
      Throws:
      ArithmeticException - if strict
    • isFloatingPointType

      protected boolean isFloatingPointType(Object left, Object right)
      Test if either left or right are either a Float or Double.
      Parameters:
      left - one object to test
      right - the other
      Returns:
      the result of the test.
    • isFloatingPointNumber

      protected boolean isFloatingPointNumber(Object val)
      Test if the passed value is a floating point number, i.e. a float, double or string with ( "." | "E" | "e").
      Parameters:
      val - the object to be tested
      Returns:
      true if it is, false otherwise.
    • isFloatingPoint

      protected boolean isFloatingPoint(Object o)
      Is Object a floating point number.
      Parameters:
      o - Object to be analyzed.
      Returns:
      true if it is a Float or a Double.
    • isNumberable

      protected boolean isNumberable(Object o)
      Is Object a whole number.
      Parameters:
      o - Object to be analyzed.
      Returns:
      true if Integer, Long, Byte, Short or Character.
    • narrowBigInteger

      protected Number narrowBigInteger(Object lhs, Object rhs, BigInteger bigi)
      Given a BigInteger, narrow it to an Integer or Long if it fits and the arguments class allow it.

      The rules are: if either arguments is a BigInteger, no narrowing will occur if either arguments is a Long, no narrowing to Integer will occur

      Parameters:
      lhs - the left hand side operand that lead to the bigi result
      rhs - the right hand side operand that lead to the bigi result
      bigi - the BigInteger to narrow
      Returns:
      an Integer or Long if narrowing is possible, the original BigInteger otherwise
    • narrowBigDecimal

      protected Number narrowBigDecimal(Object lhs, Object rhs, BigDecimal bigd)
      Given a BigDecimal, attempt to narrow it to an Integer or Long if it fits if one of the arguments is a numberable.
      Parameters:
      lhs - the left hand side operand that lead to the bigd result
      rhs - the right hand side operand that lead to the bigd result
      bigd - the BigDecimal to narrow
      Returns:
      an Integer or Long if narrowing is possible, the original BigInteger otherwise
      Since:
      2.1
    • narrowArrayType

      protected Object narrowArrayType(Object[] untyped)
      Given an array of objects, attempt to type it more strictly.
      • If all objects are of the same type, the array returned will be an array of that same type
      • If all objects are Numbers, the array returned will be an array of Numbers
      • If all objects are convertible to a primitive type, the array returned will be an array of the primitive type
      Parameters:
      untyped - an untyped array
      Returns:
      the original array if the attempt to strictly type the array fails, a typed array otherwise
    • narrowArguments

      protected boolean narrowArguments(Object[] args)
      Replace all numbers in an arguments array with the smallest type that will fit.
      Parameters:
      args - the argument array
      Returns:
      true if some arguments were narrowed and args array is modified, false if no narrowing occured and args array has not been modified
    • add

      public Object add(Object left, Object right)
      Add two values together.

      If any numeric add fails on coercion to the appropriate type, treat as Strings and do concatenation.

      Parameters:
      left - first value
      right - second value
      Returns:
      left + right.
    • divide

      public Object divide(Object left, Object right)
      Divide the left value by the right.
      Parameters:
      left - first value
      right - second value
      Returns:
      left / right
      Throws:
      ArithmeticException - if right == 0
    • mod

      public Object mod(Object left, Object right)
      left value mod right.
      Parameters:
      left - first value
      right - second value
      Returns:
      left mod right
      Throws:
      ArithmeticException - if right == 0.0
    • multiply

      public Object multiply(Object left, Object right)
      Multiply the left value by the right.
      Parameters:
      left - first value
      right - second value
      Returns:
      left * right.
    • subtract

      public Object subtract(Object left, Object right)
      Subtract the right value from the left.
      Parameters:
      left - first value
      right - second value
      Returns:
      left - right.
    • negate

      public Object negate(Object val)
      Negates a value (unary minus for numbers).
      Parameters:
      val - the value to negate
      Returns:
      the negated value
      Since:
      2.1
    • matches

      public boolean matches(Object left, Object right)
      Test if left regexp matches right.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
      Since:
      2.1
    • bitwiseAnd

      public Object bitwiseAnd(Object left, Object right)
      Performs a bitwise and.
      Parameters:
      left - the left operand
      right - the right operator
      Returns:
      left & right
      Since:
      2.1
    • bitwiseOr

      public Object bitwiseOr(Object left, Object right)
      Performs a bitwise or.
      Parameters:
      left - the left operand
      right - the right operator
      Returns:
      left | right
      Since:
      2.1
    • bitwiseXor

      public Object bitwiseXor(Object left, Object right)
      Performs a bitwise xor.
      Parameters:
      left - the left operand
      right - the right operator
      Returns:
      left right
      Since:
      2.1
    • bitwiseComplement

      public Object bitwiseComplement(Object val)
      Performs a bitwise complement.
      Parameters:
      val - the operand
      Returns:
      ~val
      Since:
      2.1
    • compare

      protected int compare(Object left, Object right, String operator)
      Performs a comparison.
      Parameters:
      left - the left operand
      right - the right operator
      operator - the operator
      Returns:
      -1 if left < right; +1 if left &gt > right; 0 if left == right
      Throws:
      ArithmeticException - if either left or right is null
      Since:
      2.1
    • equals

      public boolean equals(Object left, Object right)
      Test if left and right are equal.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
    • lessThan

      public boolean lessThan(Object left, Object right)
      Test if left < right.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
    • greaterThan

      public boolean greaterThan(Object left, Object right)
      Test if left > right.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
    • lessThanOrEqual

      public boolean lessThanOrEqual(Object left, Object right)
      Test if left <= right.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
    • greaterThanOrEqual

      public boolean greaterThanOrEqual(Object left, Object right)
      Test if left >= right.
      Parameters:
      left - first value
      right - second value
      Returns:
      test result.
    • toBoolean

      public boolean toBoolean(Object val)
      Coerce to a boolean (not a java.lang.Boolean).
      Parameters:
      val - Object to be coerced.
      Returns:
      The boolean coerced value, or false if none possible.
    • toInteger

      public int toInteger(Object val)
      Coerce to a int.
      Parameters:
      val - Object to be coerced.
      Returns:
      The int coerced value.
    • toLong

      public long toLong(Object val)
      Coerce to a long (not a java.lang.Long).
      Parameters:
      val - Object to be coerced.
      Returns:
      The long coerced value.
    • toBigInteger

      public BigInteger toBigInteger(Object val)
      Get a BigInteger from the object passed. Null and empty string maps to zero.
      Parameters:
      val - the object to be coerced.
      Returns:
      a BigDecimal.
      Throws:
      NullPointerException - if val is null and mode is strict.
    • toBigDecimal

      public BigDecimal toBigDecimal(Object val)
      Get a BigDecimal from the object passed. Null and empty string maps to zero.
      Parameters:
      val - the object to be coerced.
      Returns:
      a BigDecimal.
      Throws:
      NullPointerException - if val is null and mode is strict.
    • toDouble

      public double toDouble(Object val)
      Coerce to a double.
      Parameters:
      val - Object to be coerced.
      Returns:
      The double coerced value.
      Throws:
      NullPointerException - if val is null and mode is strict.
    • toString

      public String toString(Object val)
      Coerce to a string.
      Parameters:
      val - Object to be coerced.
      Returns:
      The String coerced value.
      Throws:
      NullPointerException - if val is null and mode is strict.
    • narrow

      public Number narrow(Number original)
      Given a Number, return back the value using the smallest type the result will fit into. This works hand in hand with parameter 'widening' in java method calls, e.g. a call to substring(int,int) with an int and a long will fail, but a call to substring(int,int) with an int and a short will succeed.
      Parameters:
      original - the original number.
      Returns:
      a value of the smallest type the original number will fit into.
    • narrowAccept

      protected boolean narrowAccept(Class<?> narrow, Class<?> source)
      Whether we consider the narrow class as a potential candidate for narrowing the source.
      Parameters:
      narrow - the target narrow class
      source - the orginal source class
      Returns:
      true if attempt to narrow source to target is accepted
      Since:
      2.1
    • narrowNumber

      protected Number narrowNumber(Number original, Class<?> narrow)
      Given a Number, return back the value attempting to narrow it to a target class.
      Parameters:
      original - the original number
      narrow - the attempted target class
      Returns:
      the narrowed number or the source if no narrowing was possible
      Since:
      2.1