Class Operator
- java.lang.Object
-
- org.apache.commons.jexl3.internal.Operator
-
- All Implemented Interfaces:
JexlArithmetic.Uberspect,JexlOperator.Uberspect
public final class Operator extends java.lang.Object implements JexlOperator.Uberspect
Helper class to deal with operator overloading and specifics.- Since:
- 3.0
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classOperator.AntiCompareMethodThe reverse compare swaps left and right arguments and exploits the symmetry of compare as in: compare(a, b) <=> -compare(b, a)private static classOperator.CompareMethodDelegates a comparison operator to a compare method.
-
Field Summary
Fields Modifier and Type Field Description private JexlArithmeticarithmeticThe arithmetic instance being analyzed.private intcachingCaching state: -1 unknown, 0 false, 1 true.private static java.util.Set<JexlOperator>CMP_OPSThe comparison operators.private JexlArithmetic.UberspectdelegateThe delegate if built as a 3.4 legacy.private static java.lang.StringMETHOD_CONTAINSprivate static java.lang.StringMETHOD_ENDS_WITHprivate static java.lang.StringMETHOD_IS_EMPTYprivate static java.lang.StringMETHOD_SIZEprivate static java.lang.StringMETHOD_STARTS_WITHprivate java.util.Set<JexlOperator>overloadsThe set of overloaded operators.private static java.util.Set<JexlOperator>POSTFIX_OPSThe postfix operators.private JexlUberspectuberspectThe uberspect.
-
Constructor Summary
Constructors Constructor Description Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic)Creates an instance.Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic, java.util.Set<JexlOperator> theOverloads)Creates an instance.Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic, java.util.Set<JexlOperator> theOverloads, int theCache)Creates an instance.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private java.lang.Object[]arguments(JexlOperator operator, java.lang.Object... args)Tidy arguments based on operator arity.private java.lang.BooleanbooleanDuckCall(java.lang.String methodName, java.lang.Object left, java.lang.Object right)Attempts finding a method in left and eventually narrowing right.booleancontains(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)The 'match'/'in' operator implementation.private voidcontrolNullOperands(JexlArithmetic arithmetic, JexlOperator operator, java.lang.Object... args)Throw a NPE if operator is strict and one of the arguments is null.java.lang.Objectempty(JexlCache.Reference node, java.lang.Object object)Check for emptiness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty() method.booleanendsWith(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)The 'endsWith' operator implementation.private JexlMethodgetAlternateOverload(JexlOperator operator, java.lang.Object... args)Special handling of overloads where another attempt at finding a method may be attempted.JexlMethodgetOperator(JexlOperator operator, java.lang.Object... args)Gets the most specific method for an operator.private booleanisCaching()private <T> ToperatorError(JexlCache.Reference ref, JexlOperator operator, java.lang.Throwable cause, T alt)Triggered when an operator fails.booleanoverloads(JexlOperator operator)Checks whether this uberspect has overloads for a given operator.private java.lang.ObjectperformBaseOperation(JexlOperator operator, java.lang.Object... args)Performs the base operation of an assignment.private booleanreturnsBoolean(JexlMethod vm)Checks whether a method returns a boolean or a Boolean.private booleanreturnsInteger(JexlMethod vm)Checks whether a method returns an int or an Integer.java.lang.Objectsize(JexlCache.Reference node, java.lang.Object object)Calculate thesizeof various types: Collection, Array, Map, String, and anything that has an int size() method.booleanstartsWith(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)The 'startsWith' operator implementation.java.lang.ObjecttryAssignOverload(JexlCache.Reference node, JexlOperator operator, java.util.function.Consumer<java.lang.Object> assignFun, java.lang.Object... args)Evaluates an assign operator.private java.lang.ObjecttryEval(JexlCache.Reference node, JexlOperator operator, java.lang.Object... args)Tries operator evaluation, handles method resolution caching.java.lang.ObjecttryOverload(JexlCache.Reference node, JexlOperator operator, java.lang.Object... args)Try to find the most specific method and evaluate an operator.private JexlMethoduberspectOperator(JexlArithmetic arithmetic, JexlOperator operator, java.lang.Object... args)Seeks an implementation of an operator method in an arithmetic instance.
-
-
-
Field Detail
-
METHOD_IS_EMPTY
private static final java.lang.String METHOD_IS_EMPTY
- See Also:
- Constant Field Values
-
METHOD_SIZE
private static final java.lang.String METHOD_SIZE
- See Also:
- Constant Field Values
-
METHOD_CONTAINS
private static final java.lang.String METHOD_CONTAINS
- See Also:
- Constant Field Values
-
METHOD_STARTS_WITH
private static final java.lang.String METHOD_STARTS_WITH
- See Also:
- Constant Field Values
-
METHOD_ENDS_WITH
private static final java.lang.String METHOD_ENDS_WITH
- See Also:
- Constant Field Values
-
CMP_OPS
private static final java.util.Set<JexlOperator> CMP_OPS
The comparison operators.Used to determine if a compare method overload might be used.
-
POSTFIX_OPS
private static final java.util.Set<JexlOperator> POSTFIX_OPS
The postfix operators.Used to determine the returned value in assignment.
-
uberspect
private final JexlUberspect uberspect
The uberspect.
-
arithmetic
private final JexlArithmetic arithmetic
The arithmetic instance being analyzed.
-
overloads
private final java.util.Set<JexlOperator> overloads
The set of overloaded operators.
-
delegate
private final JexlArithmetic.Uberspect delegate
The delegate if built as a 3.4 legacy.
-
caching
private volatile int caching
Caching state: -1 unknown, 0 false, 1 true.
-
-
Constructor Detail
-
Operator
public Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic)
Creates an instance.Mostly used as a compatibility measure by delegating instead of extending.
- Parameters:
theUberspect- the uberspect instancetheArithmetic- the arithmetic instance used to delegate operator overloads
-
Operator
public Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic, java.util.Set<JexlOperator> theOverloads)
Creates an instance.- Parameters:
theUberspect- the uberspect instancetheArithmetic- the arithmetic instancetheOverloads- the overloaded operators
-
Operator
public Operator(JexlUberspect theUberspect, JexlArithmetic theArithmetic, java.util.Set<JexlOperator> theOverloads, int theCache)
Creates an instance.- Parameters:
theUberspect- the uberspect instancetheArithmetic- the arithmetic instancetheOverloads- the overloaded operatorstheCache- the caching state
-
-
Method Detail
-
getOperator
public JexlMethod getOperator(JexlOperator operator, java.lang.Object... args)
Description copied from interface:JexlArithmetic.UberspectGets the most specific method for an operator.- Specified by:
getOperatorin interfaceJexlArithmetic.Uberspect- Parameters:
operator- the operatorargs- the arguments- Returns:
- the most specific method or null if no specific override could be found
-
overloads
public boolean overloads(JexlOperator operator)
Description copied from interface:JexlArithmetic.UberspectChecks whether this uberspect has overloads for a given operator.- Specified by:
overloadsin interfaceJexlArithmetic.Uberspect- Parameters:
operator- the operator to check- Returns:
- true if an overload exists, false otherwise
-
isCaching
private boolean isCaching()
- Returns:
- whether caching is enabled in the engine
-
arguments
private java.lang.Object[] arguments(JexlOperator operator, java.lang.Object... args)
Tidy arguments based on operator arity.The interpreter may add a null to the arguments of operator expecting only one parameter.
- Parameters:
operator- the operatorargs- the arguments (as seen by the interpreter)- Returns:
- the tidied arguments
-
booleanDuckCall
private java.lang.Boolean booleanDuckCall(java.lang.String methodName, java.lang.Object left, java.lang.Object right) throws java.lang.ExceptionAttempts finding a method in left and eventually narrowing right.- Parameters:
methodName- the method nameright- the left argument in the operatorleft- the right argument in the operator- Returns:
- a boolean is call was possible, null otherwise
- Throws:
java.lang.Exception- if invocation fails
-
controlNullOperands
private void controlNullOperands(JexlArithmetic arithmetic, JexlOperator operator, java.lang.Object... args)
Throw a NPE if operator is strict and one of the arguments is null.- Parameters:
arithmetic- the JEXL arithmetic instanceoperator- the operator to checkargs- the operands- Throws:
JexlArithmetic.NullOperand- if operator is strict and an operand is null
-
operatorError
private <T> T operatorError(JexlCache.Reference ref, JexlOperator operator, java.lang.Throwable cause, T alt)
Triggered when an operator fails.- Type Parameters:
T- the return type- Parameters:
ref- the node where the error originated fromoperator- the operator symbolcause- the cause of error (if any)alt- what to return if not strict- Returns:
- throws JexlException if strict and not silent, null otherwise
-
uberspectOperator
private JexlMethod uberspectOperator(JexlArithmetic arithmetic, JexlOperator operator, java.lang.Object... args)
Seeks an implementation of an operator method in an arithmetic instance.Method must <>not/em belong to JexlArithmetic
- Parameters:
arithmetic- the arithmetic instanceoperator- the operatorargs- the arguments- Returns:
- a JexlMethod instance or null
-
returnsBoolean
private boolean returnsBoolean(JexlMethod vm)
Checks whether a method returns a boolean or a Boolean.- Parameters:
vm- the JexlMethod (can be null)- Returns:
- true of false
-
returnsInteger
private boolean returnsInteger(JexlMethod vm)
Checks whether a method returns an int or an Integer.- Parameters:
vm- the JexlMethod (can be null)- Returns:
- true of false
-
empty
public java.lang.Object empty(JexlCache.Reference node, java.lang.Object object)
Description copied from interface:JexlOperator.UberspectCheck for emptiness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty() method.Seeks an overload or use the default arithmetic implementation.
Note that the result may not be a boolean.
- Specified by:
emptyin interfaceJexlOperator.Uberspect- Parameters:
node- the node holding the objectobject- the object to check the emptiness of- Returns:
- the evaluation result
-
size
public java.lang.Object size(JexlCache.Reference node, java.lang.Object object)
Description copied from interface:JexlOperator.UberspectCalculate thesizeof various types: Collection, Array, Map, String, and anything that has an int size() method.Seeks an overload or use the default arithmetic implementation.
Note that the result may not be an integer.
- Specified by:
sizein interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureobject- the object to get the size of- Returns:
- the evaluation result
-
contains
public boolean contains(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)
Description copied from interface:JexlOperator.UberspectThe 'match'/'in' operator implementation.Seeks an overload or use the default arithmetic implementation.
Note that 'x in y' or 'x matches y' means 'y contains x' ; the JEXL operator arguments order syntax is the reverse of this method call.
- Specified by:
containsin interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureoperator- the calling operator, =~ or !~left- the right operandright- the left operand- Returns:
- true if left matches right, false otherwise
-
startsWith
public boolean startsWith(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)
Description copied from interface:JexlOperator.UberspectThe 'startsWith' operator implementation.Seeks an overload or use the default arithmetic implementation.
- Specified by:
startsWithin interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureoperator- the calling operator, $= or $!left- the left operandright- the right operand- Returns:
- true if left starts with right, false otherwise
-
endsWith
public boolean endsWith(JexlCache.Reference node, JexlOperator operator, java.lang.Object left, java.lang.Object right)
Description copied from interface:JexlOperator.UberspectThe 'endsWith' operator implementation.Seeks an overload or use the default arithmetic implementation.
- Specified by:
endsWithin interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureoperator- the calling operator, ^= or ^!left- the left operandright- the right operand- Returns:
- true if left ends with right, false otherwise
-
tryAssignOverload
public java.lang.Object tryAssignOverload(JexlCache.Reference node, JexlOperator operator, java.util.function.Consumer<java.lang.Object> assignFun, java.lang.Object... args)
Description copied from interface:JexlOperator.UberspectEvaluates an assign operator.This takes care of finding and caching the operator method when appropriate. If an overloads returns a value not-equal to TRY_FAILED, it means the side-effect is complete. Otherwise,
a += b <=> a = a + b- Specified by:
tryAssignOverloadin interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureoperator- the operatorassignFun- the actual function that performs the side effectargs- the arguments, the first one being the target of assignment- Returns:
- JexlEngine.TRY_FAILED if no operation was performed, the value to use as the side effect argument otherwise
-
performBaseOperation
private java.lang.Object performBaseOperation(JexlOperator operator, java.lang.Object... args)
Performs the base operation of an assignment.- Parameters:
operator- the operatorargs- the arguments- Returns:
- the result
-
tryOverload
public java.lang.Object tryOverload(JexlCache.Reference node, JexlOperator operator, java.lang.Object... args)
Description copied from interface:JexlOperator.UberspectTry to find the most specific method and evaluate an operator.This method does not call
JexlArithmetic.Uberspect.overloads(JexlOperator)and shall not be called with an assignment operator; useJexlOperator.Uberspect.tryAssignOverload(JexlCache.Reference, JexlOperator, Consumer, Object...)in that case.- Specified by:
tryOverloadin interfaceJexlOperator.Uberspect- Parameters:
node- an optional reference caching resolved method or failing signatureoperator- the operatorargs- the arguments- Returns:
- TRY_FAILED if no specific method could be found, the evaluation result otherwise
-
tryEval
private java.lang.Object tryEval(JexlCache.Reference node, JexlOperator operator, java.lang.Object... args)
Tries operator evaluation, handles method resolution caching.- Parameters:
node- the nodeoperator- the operatorargs- the operator arguments- Returns:
- the operator evaluation result or TRY_FAILED
-
getAlternateOverload
private JexlMethod getAlternateOverload(JexlOperator operator, java.lang.Object... args)
Special handling of overloads where another attempt at finding a method may be attempted.As of 3.5.0, only the comparison operators attempting to use compare() are handled.
- Parameters:
operator- the operatorargs- the arguments- Returns:
- an instance or null
-
-